Skip to content

Commit f324baa

Browse files
Merge pull request #42 from lucaromagnoli/security/remove-mac-key
Security/remove mac key
2 parents 7dce947 + b428c07 commit f324baa

File tree

7 files changed

+113
-43
lines changed

7 files changed

+113
-43
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,7 @@ docs/build/
5353
!tests/*_sample.*
5454
sample_*
5555
!tests/sample_*
56-
response_samples/
56+
response_samples/
57+
# Never commit signing keys
58+
llmcpp-mac-key.pem
59+

README.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ auto response2 = client.sendRequest(OpenAI::Model::GPT_4_1_Mini, "Summarize this
132132
```
133133

134134
**Available models:**
135+
- GPT_5, GPT_5_Mini, GPT_5_Nano
135136
- O3, O3_Mini
136137
- O1, O1_Mini, O1_Preview, O1_Pro
137138
- O4_Mini, O4_Mini_Deep_Research
@@ -307,14 +308,25 @@ The library provides type-safe model selection using the `OpenAI::Model` enum:
307308

308309
```cpp
309310
// Available model enums
310-
OpenAI::Model::GPT_4_1 // gpt-4.1 - Latest model with superior coding and structured outputs
311-
OpenAI::Model::GPT_4_1_Mini // gpt-4.1-mini - Balanced performance and cost
312-
OpenAI::Model::GPT_4_1_Nano // gpt-4.1-nano - Fastest and cheapest option
313-
OpenAI::Model::GPT_4o // gpt-4o - Good balance of performance and cost
314-
OpenAI::Model::GPT_4o_Mini // gpt-4o-mini - Cost-effective for basic tasks
315-
OpenAI::Model::GPT_4_5 // gpt-4.5 - Preview model (deprecated July 2025)
316-
OpenAI::Model::GPT_3_5_Turbo // gpt-3.5-turbo - Legacy model
317-
OpenAI::Model::Custom // For custom model names
311+
OpenAI::Model::GPT_5 // gpt-5 - Next-generation model
312+
OpenAI::Model::GPT_5_Mini // gpt-5-mini - Smaller, cost-effective variant
313+
OpenAI::Model::GPT_5_Nano // gpt-5-nano - Fastest and cheapest GPT-5 variant
314+
OpenAI::Model::O3 // o3 - Latest reasoning model
315+
OpenAI::Model::O3_Mini // o3-mini - Cost-effective reasoning model
316+
OpenAI::Model::O1 // o1 - Advanced reasoning model
317+
OpenAI::Model::O1_Mini // o1-mini - Cost-effective O1 model
318+
OpenAI::Model::O1_Preview // o1-preview - Preview version
319+
OpenAI::Model::O1_Pro // o1-pro - Professional version
320+
OpenAI::Model::O4_Mini // o4-mini - Latest mini model
321+
OpenAI::Model::O4_Mini_Deep_Research // o4-mini-deep-research - Research focused
322+
OpenAI::Model::GPT_4_1 // gpt-4.1 - Latest model with superior coding and structured outputs
323+
OpenAI::Model::GPT_4_1_Mini // gpt-4.1-mini - Balanced performance and cost
324+
OpenAI::Model::GPT_4_1_Nano // gpt-4.1-nano - Fastest and cheapest option
325+
OpenAI::Model::GPT_4o // gpt-4o - Good balance of performance and cost
326+
OpenAI::Model::GPT_4o_Mini // gpt-4o-mini - Cost-effective for basic tasks
327+
OpenAI::Model::GPT_4_5 // gpt-4.5 - Preview model (deprecated July 2025)
328+
OpenAI::Model::GPT_3_5_Turbo // gpt-3.5-turbo - Legacy model
329+
OpenAI::Model::Custom // For custom model names
318330
```
319331

320332
#### Model Selection Helpers

include/openai/OpenAITypes.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ namespace OpenAI {
1818
*/
1919
enum class Model {
2020
// GPT-5 series (Latest - 2025)
21-
GPT_5, // gpt-5 - Next-generation model
21+
GPT_5, // gpt-5 - Next-generation model
22+
GPT_5_Mini, // gpt-5-mini - Smaller, cost-effective variant
23+
GPT_5_Nano, // gpt-5-nano - Fastest and cheapest GPT-5 variant
2224

2325
// O3 series (Latest - 2025)
2426
O3, // o3 - Latest reasoning model
@@ -61,6 +63,10 @@ inline std::string toString(Model model) {
6163
switch (model) {
6264
case Model::GPT_5:
6365
return "gpt-5";
66+
case Model::GPT_5_Mini:
67+
return "gpt-5-mini";
68+
case Model::GPT_5_Nano:
69+
return "gpt-5-nano";
6470
case Model::O3:
6571
return "o3";
6672
case Model::O3_Mini:
@@ -102,6 +108,8 @@ inline std::string toString(Model model) {
102108
*/
103109
inline Model modelFromString(const std::string& modelStr) {
104110
if (modelStr == "gpt-5") return Model::GPT_5;
111+
if (modelStr == "gpt-5-mini") return Model::GPT_5_Mini;
112+
if (modelStr == "gpt-5-nano") return Model::GPT_5_Nano;
105113
if (modelStr == "o3") return Model::O3;
106114
if (modelStr == "o3-mini") return Model::O3_Mini;
107115
if (modelStr == "o1") return Model::O1;
@@ -126,6 +134,8 @@ inline Model modelFromString(const std::string& modelStr) {
126134
inline bool supportsStructuredOutputs(Model model) {
127135
switch (model) {
128136
case Model::GPT_5:
137+
case Model::GPT_5_Mini:
138+
case Model::GPT_5_Nano:
129139
case Model::O3:
130140
case Model::O3_Mini:
131141
case Model::O1:
@@ -1014,8 +1024,9 @@ std::string getRecommendedApiForModel(const std::string& model);
10141024

10151025
// Model lists for different APIs
10161026
const std::vector<std::string> RESPONSES_MODELS = {
1017-
"gpt-5", "gpt-4o", "gpt-4o-mini", "gpt-4.1", "gpt-4.1-nano", "gpt-4.1-mini",
1018-
"gpt-image-1", "o1", "o3-mini", "o3", "o4-mini", "computer-use-preview"};
1027+
"gpt-5", "gpt-5-mini", "gpt-5-nano", "gpt-4o", "gpt-4o-mini", "gpt-4.1",
1028+
"gpt-4.1-nano", "gpt-4.1-mini", "gpt-image-1", "o1", "o3-mini", "o3",
1029+
"o4-mini", "computer-use-preview"};
10191030

10201031
const std::vector<std::string> CHAT_COMPLETION_MODELS = {"gpt-4", "gpt-4-turbo", "gpt-4o",
10211032
"gpt-4o-mini", "gpt-3.5-turbo"};

llmcpp-mac-key.pem

Lines changed: 0 additions & 27 deletions
This file was deleted.

src/openai/OpenAIClient.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ OpenAI::ResponsesResponse OpenAIClient::sendResponsesRequest(
175175
try {
176176
// Reasonable defaults: wait up to 90s, polling every 2s
177177
response = responsesApi_->waitForCompletion(response.id, /*timeoutSeconds=*/90,
178-
/*pollIntervalSeconds=*/2);
178+
/*pollIntervalSeconds=*/2);
179179
} catch (const std::exception& /*e*/) {
180180
// Fall through and return the last known response (likely non-completed)
181181
}
@@ -352,7 +352,8 @@ OpenAI::Model OpenAIClient::stringToModel(const std::string& modelStr) {
352352
}
353353

354354
std::vector<OpenAI::Model> OpenAIClient::getAvailableModelEnums() {
355-
return {OpenAI::Model::GPT_5, OpenAI::Model::GPT_4_1, OpenAI::Model::GPT_4_1_Mini,
356-
OpenAI::Model::GPT_4_1_Nano, OpenAI::Model::GPT_4o, OpenAI::Model::GPT_4o_Mini,
357-
OpenAI::Model::GPT_4_5, OpenAI::Model::GPT_3_5_Turbo, OpenAI::Model::Custom};
355+
return {OpenAI::Model::GPT_5, OpenAI::Model::GPT_5_Mini, OpenAI::Model::GPT_5_Nano,
356+
OpenAI::Model::GPT_4_1, OpenAI::Model::GPT_4_1_Mini, OpenAI::Model::GPT_4_1_Nano,
357+
OpenAI::Model::GPT_4o, OpenAI::Model::GPT_4o_Mini, OpenAI::Model::GPT_4_5,
358+
OpenAI::Model::GPT_3_5_Turbo, OpenAI::Model::Custom};
358359
}

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ set(UNIT_TEST_SOURCES
2828
set(INTEGRATION_TEST_SOURCES
2929
integration/test_simple_integration.cpp
3030
integration/test_openai_integration.cpp # Re-enabling to check errors
31+
integration/test_benchmarks.cpp
3132
)
3233

3334
# Create test executable with all tests
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include <catch2/catch_test_macros.hpp>
2+
#include <chrono>
3+
#include <cstdlib>
4+
#include <iostream>
5+
#include <string>
6+
7+
#include "openai/OpenAIClient.h"
8+
#include "openai/OpenAITypes.h"
9+
10+
using namespace std::chrono;
11+
12+
static bool isReasoningModel(OpenAI::Model model) {
13+
return model == OpenAI::Model::GPT_5 || model == OpenAI::Model::GPT_5_Mini ||
14+
model == OpenAI::Model::GPT_5_Nano || model == OpenAI::Model::O3 ||
15+
model == OpenAI::Model::O3_Mini || model == OpenAI::Model::O1 ||
16+
model == OpenAI::Model::O1_Mini || model == OpenAI::Model::O1_Preview ||
17+
model == OpenAI::Model::O1_Pro || model == OpenAI::Model::O4_Mini;
18+
}
19+
20+
TEST_CASE("OpenAI model benchmarks (structured outputs)", "[openai][integration][benchmark]") {
21+
const char* runBenchEnv = std::getenv("LLMCPP_RUN_BENCHMARKS");
22+
if (!runBenchEnv || std::string(runBenchEnv) != "1") {
23+
SUCCEED("Benchmarks skipped. Set LLMCPP_RUN_BENCHMARKS=1 to enable.");
24+
return;
25+
}
26+
27+
const char* apiKey = std::getenv("OPENAI_API_KEY");
28+
REQUIRE(apiKey != nullptr);
29+
30+
OpenAIClient client(apiKey);
31+
32+
// Minimal structured output schema
33+
json schema = {{"type", "object"},
34+
{"properties", {{"answer", {{"type", "string"}}}}},
35+
{"required", json::array({"answer"})}};
36+
37+
// Simple input
38+
auto input = OpenAI::ResponsesInput::fromText("Reply with the word OK.");
39+
40+
// Iterate through response-capable models
41+
for (const auto& modelName : OpenAI::RESPONSES_MODELS) {
42+
DYNAMIC_SECTION("Benchmark model: " << modelName) {
43+
OpenAI::ResponsesRequest req;
44+
req.model = modelName;
45+
req.input = input;
46+
req.text = OpenAI::TextOutputConfig("bench_schema", schema, true);
47+
req.maxOutputTokens = 16;
48+
49+
// Tweak reasoning parameters when appropriate
50+
auto modelEnum = OpenAI::modelFromString(modelName);
51+
if (isReasoningModel(modelEnum)) {
52+
req.reasoningEffort = std::string("low");
53+
}
54+
55+
const auto start = steady_clock::now();
56+
auto response = client.sendResponsesRequest(req);
57+
const auto end = steady_clock::now();
58+
59+
const auto elapsedMs = duration_cast<milliseconds>(end - start).count();
60+
std::cout << "[BENCH] model=" << modelName << ", ms=" << elapsedMs
61+
<< ", success=" << (response.isCompleted() && !response.hasError())
62+
<< std::endl;
63+
64+
// Sanity: we should at least get a response object back; don't assert success to avoid
65+
// flakes
66+
REQUIRE(!response.id.empty());
67+
}
68+
}
69+
}

0 commit comments

Comments
 (0)