diff --git a/README.md b/README.md index 8b4bf0a..a9eb346 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ int main() { auto client = ai::openai::create_client(); auto result = client.generate_text({ - .model = ai::openai::models::kGpt4o, // this can also be a string like "gpt-4o" + .model = ai::openai::models::kGpt54, // this can also be a string like "gpt-5.4" .system = "You are a friendly assistant!", .prompt = "Why is the sky blue?" }); @@ -56,7 +56,7 @@ int main() { // Ensure ANTHROPIC_API_KEY environment variable is set auto client = ai::anthropic::create_client(); auto result = client.generate_text({ - .model = ai::anthropic::models::kClaudeSonnet45, + .model = ai::anthropic::models::kClaudeSonnet46, .system = "You are a helpful assistant.", .prompt = "Explain quantum computing in simple terms." }); @@ -80,7 +80,7 @@ int main() { auto client = ai::openai::create_client(); auto stream = client.stream_text({ - .model = ai::openai::models::kGpt4o, // this can also be a string like "gpt-4o" + .model = ai::openai::models::kGpt54, // this can also be a string like "gpt-5.4" .system = "You are a helpful assistant.", .prompt = "Write a short story about a robot." }); @@ -113,7 +113,7 @@ int main() { }; auto result = client.generate_text({ - .model = ai::openai::models::kGpt4o, // this can also be a string like "gpt-4o" + .model = ai::openai::models::kGpt54, // this can also be a string like "gpt-5.4" .messages = messages }); @@ -161,7 +161,7 @@ int main() { }; auto result = client.generate_text({ - .model = ai::openai::models::kGpt4o, + .model = ai::openai::models::kGpt54, .prompt = "What's the weather like in San Francisco?", .tools = tools, .max_steps = 3 // Enable multi-step tool calling @@ -217,7 +217,7 @@ int main() { // Multiple async tools will execute in parallel auto result = client.generate_text({ - .model = ai::openai::models::kGpt4o, + .model = ai::openai::models::kGpt54, .prompt = "Fetch data from the user and product APIs", .tools = tools }); @@ -252,7 +252,7 @@ int main() { // - Network errors // - HTTP 408, 409, 429 (rate limits), and 5xx errors auto result = client.generate_text({ - .model = ai::openai::models::kGpt4o, + .model = ai::openai::models::kGpt54, .prompt = "Hello, world!" }); @@ -286,7 +286,7 @@ int main() { // Use any model available on OpenRouter auto result = client.generate_text({ - .model = "anthropic/claude-3.5-sonnet", // or "meta-llama/llama-3.1-8b-instruct", etc. + .model = "anthropic/claude-sonnet-4-6", // or "meta-llama/llama-3.1-8b-instruct", etc. .system = "You are a helpful assistant.", .prompt = "What are the benefits of using OpenRouter?" }); diff --git a/examples/basic_chat.cpp b/examples/basic_chat.cpp index 76ecebe..d228783 100644 --- a/examples/basic_chat.cpp +++ b/examples/basic_chat.cpp @@ -24,12 +24,12 @@ int main() { std::cout << "================================\n\n"; // Example 1: Simple text generation with OpenAI - std::cout << "1. Generating text with OpenAI GPT-4o:\n"; + std::cout << "1. Generating text with OpenAI GPT-5.4:\n"; std::cout << "Question: What is the capital of France?\n\n"; auto client1 = ai::openai::create_client(); ai::GenerateOptions options1; - options1.model = ai::openai::models::kGpt4o; + options1.model = ai::openai::models::kGpt54; options1.prompt = "What is the capital of France? Please provide a brief answer."; @@ -50,7 +50,7 @@ int main() { std::cout << "Question: Explain what a prime number is.\n\n"; ai::GenerateOptions options2; - options2.model = ai::openai::models::kGpt4o; + options2.model = ai::openai::models::kGpt54; options2.system = "You are a helpful math tutor who explains concepts clearly."; options2.prompt = @@ -80,7 +80,7 @@ int main() { "Which one should I use for frequent insertions in the middle?")}; ai::GenerateOptions options3; - options3.model = ai::openai::models::kGpt4o; + options3.model = ai::openai::models::kGpt54; options3.messages = conversation; auto result3 = client1.generate_text(options3); @@ -98,7 +98,7 @@ int main() { auto client4 = ai::anthropic::create_client(); ai::GenerateOptions options4; - options4.model = ai::anthropic::models::kClaudeSonnet45; + options4.model = ai::anthropic::models::kClaudeSonnet46; options4.prompt = "Write a haiku about programming. Just the haiku, nothing else."; @@ -115,7 +115,7 @@ int main() { std::cout << "5. Using GenerateOptions for fine control:\n"; ai::GenerateOptions options; - options.model = ai::openai::models::kGpt4o; + options.model = ai::openai::models::kGpt54; options.prompt = "List 3 benefits of using C++ for systems programming."; options.max_tokens = 150; options.temperature = 0.7; diff --git a/examples/components/all/main.cpp b/examples/components/all/main.cpp index 3139094..25a21c2 100644 --- a/examples/components/all/main.cpp +++ b/examples/components/all/main.cpp @@ -26,7 +26,7 @@ int main() { // Test core functionality std::cout << "Testing core functionality...\n"; ai::GenerateOptions options; - options.model = "gpt-4o"; + options.model = "gpt-5.4"; options.prompt = "Hello world"; std::cout << "✓ Core types work fine\n\n"; @@ -36,8 +36,8 @@ int main() { try { auto openai_client = ai::openai::create_client(); std::cout << "✓ OpenAI client created successfully\n"; - std::cout << "✓ Available models: " << ai::openai::models::kGpt4o << ", " - << ai::openai::models::kGpt4oMini << "\n"; + std::cout << "✓ Available models: " << ai::openai::models::kGpt54 << ", " + << ai::openai::models::kGpt54Mini << "\n"; } catch (const std::exception& e) { std::cout << "✗ OpenAI client failed: " << e.what() << "\n"; } @@ -52,7 +52,7 @@ int main() { auto anthropic_client = ai::anthropic::create_client(); std::cout << "✓ Anthropic client created successfully\n"; std::cout << "✓ Available models: " - << ai::anthropic::models::kClaudeSonnet45 << ", " + << ai::anthropic::models::kClaudeSonnet46 << ", " << ai::anthropic::models::kClaudeHaiku45 << "\n"; } catch (const std::exception& e) { std::cout << "✗ Anthropic client failed: " << e.what() << "\n"; diff --git a/examples/components/anthropic/main.cpp b/examples/components/anthropic/main.cpp index d5a6340..e329c37 100644 --- a/examples/components/anthropic/main.cpp +++ b/examples/components/anthropic/main.cpp @@ -26,7 +26,7 @@ int main() { // Test core functionality std::cout << "Testing core functionality...\n"; ai::GenerateOptions options; - options.model = "claude-sonnet-4-5-20250929"; + options.model = "claude-sonnet-4-6"; options.prompt = "Hello world"; std::cout << "✓ Core types work fine\n\n"; @@ -37,7 +37,7 @@ int main() { auto client = ai::anthropic::create_client(); std::cout << "✓ Anthropic client created successfully\n"; std::cout << "✓ Available models: " - << ai::anthropic::models::kClaudeSonnet45 << ", " + << ai::anthropic::models::kClaudeSonnet46 << ", " << ai::anthropic::models::kClaudeHaiku45 << "\n"; } catch (const std::exception& e) { std::cout << "✗ Anthropic client failed: " << e.what() << "\n"; diff --git a/examples/components/openai/main.cpp b/examples/components/openai/main.cpp index 5511c9e..a0558a1 100644 --- a/examples/components/openai/main.cpp +++ b/examples/components/openai/main.cpp @@ -26,7 +26,7 @@ int main() { // Test core functionality std::cout << "Testing core functionality...\n"; ai::GenerateOptions options; - options.model = "gpt-4o"; + options.model = "gpt-5.4"; options.prompt = "Hello world"; std::cout << "✓ Core types work fine\n\n"; @@ -36,8 +36,8 @@ int main() { try { auto client = ai::openai::create_client(); std::cout << "✓ OpenAI client created successfully\n"; - std::cout << "✓ Available models: " << ai::openai::models::kGpt4o << ", " - << ai::openai::models::kGpt4oMini << "\n"; + std::cout << "✓ Available models: " << ai::openai::models::kGpt54 << ", " + << ai::openai::models::kGpt54Mini << "\n"; } catch (const std::exception& e) { std::cout << "✗ OpenAI client failed: " << e.what() << "\n"; } diff --git a/examples/error_handling.cpp b/examples/error_handling.cpp index 821f1ce..f954366 100644 --- a/examples/error_handling.cpp +++ b/examples/error_handling.cpp @@ -37,7 +37,7 @@ void demonstrate_api_errors() { // Test with empty prompt std::cout << "Testing with empty prompt:\n"; ai::GenerateOptions options2; - options2.model = ai::openai::models::kGpt4o; + options2.model = ai::openai::models::kGpt54; options2.prompt = ""; auto result2 = client.generate_text(options2); @@ -81,7 +81,7 @@ void demonstrate_validation() { // Test valid options ai::GenerateOptions valid_options; - valid_options.model = ai::openai::models::kGpt4o; + valid_options.model = ai::openai::models::kGpt54; valid_options.prompt = "Hello"; if (valid_options.is_valid()) { @@ -181,8 +181,8 @@ void demonstrate_recovery_patterns() { std::vector fallback_models = { "primary-model-v3", // This will fail - ai::openai::models::kGpt4o, // This should work (if API key is available) - ai::openai::models::kGpt4oMini // Faster fallback + ai::openai::models::kGpt54, // This should work (if API key is available) + ai::openai::models::kGpt54Mini // Faster fallback }; std::string prompt = "What is machine learning?"; diff --git a/examples/multi_provider.cpp b/examples/multi_provider.cpp index 76b65db..a28c24a 100644 --- a/examples/multi_provider.cpp +++ b/examples/multi_provider.cpp @@ -88,13 +88,13 @@ int main() { // Test OpenAI models results1.push_back( - test_provider("OpenAI", ai::openai::models::kGpt4o, simple_question)); + test_provider("OpenAI", ai::openai::models::kGpt54, simple_question)); results1.push_back( - test_provider("OpenAI", ai::openai::models::kGpt4oMini, simple_question)); + test_provider("OpenAI", ai::openai::models::kGpt54Mini, simple_question)); // Test Anthropic models results1.push_back(test_provider( - "Anthropic", ai::anthropic::models::kClaudeSonnet45, simple_question)); + "Anthropic", ai::anthropic::models::kClaudeSonnet46, simple_question)); results1.push_back(test_provider( "Anthropic", ai::anthropic::models::kClaudeHaiku45, simple_question)); @@ -116,9 +116,9 @@ int main() { // Test with different providers for creativity results2.push_back( - test_provider("OpenAI", ai::openai::models::kGpt4o, creative_prompt)); + test_provider("OpenAI", ai::openai::models::kGpt54, creative_prompt)); results2.push_back(test_provider( - "Anthropic", ai::anthropic::models::kClaudeSonnet45, creative_prompt)); + "Anthropic", ai::anthropic::models::kClaudeSonnet46, creative_prompt)); for (const auto& result : results2) { print_result(result); @@ -135,9 +135,9 @@ int main() { std::vector results3; results3.push_back( - test_provider("OpenAI", ai::openai::models::kGpt4o, technical_prompt)); + test_provider("OpenAI", ai::openai::models::kGpt54, technical_prompt)); results3.push_back(test_provider( - "Anthropic", ai::anthropic::models::kClaudeSonnet45, technical_prompt)); + "Anthropic", ai::anthropic::models::kClaudeSonnet46, technical_prompt)); for (const auto& result : results3) { print_result(result); @@ -248,8 +248,8 @@ int main() { std::cout << " - Token usage affects cost - consider model efficiency\n"; std::cout << " - The AI SDK provides a unified interface across providers\n"; std::cout << "\nTip: Choose models based on your specific use case:\n"; - std::cout << " - Fast responses: GPT-4o-mini, Claude-3-5-haiku\n"; - std::cout << " - High quality: GPT-4o, Claude-3-5-sonnet\n"; + std::cout << " - Fast responses: GPT-5.4-mini, Claude-haiku-4.5\n"; + std::cout << " - High quality: GPT-5.5, Claude-sonnet-4.6\n"; std::cout << " - Creative tasks: Models with higher temperature settings\n"; return 0; diff --git a/examples/openrouter_example.cpp b/examples/openrouter_example.cpp index 0175787..3d0bf85 100644 --- a/examples/openrouter_example.cpp +++ b/examples/openrouter_example.cpp @@ -32,11 +32,11 @@ int main() { std::cout << "Testing text generation with OpenRouter...\n\n"; // Using a model that's available on OpenRouter - // Common models: "openai/gpt-4o", "anthropic/claude-sonnet-4-5", + // Common models: "openai/gpt-5.4", "anthropic/claude-sonnet-4-6", // "meta-llama/llama-3.1-8b-instruct" See https://openrouter.ai/models for // available models ai::GenerateOptions options( - "anthropic/claude-sonnet-4-5", "You are a helpful assistant.", + "anthropic/claude-sonnet-4-6", "You are a helpful assistant.", "What are the benefits of using OpenRouter for AI applications? Give a " "brief answer."); @@ -55,7 +55,7 @@ int main() { // Test streaming with OpenRouter std::cout << "\n\nTesting streaming with OpenRouter...\n"; - ai::GenerateOptions stream_opts("anthropic/claude-sonnet-4-5", + ai::GenerateOptions stream_opts("anthropic/claude-sonnet-4-6", "You are a creative writer.", "Write a haiku about API compatibility."); ai::StreamOptions stream_options(stream_opts); diff --git a/examples/retry_config_example.cpp b/examples/retry_config_example.cpp index d6b8e06..03729cb 100644 --- a/examples/retry_config_example.cpp +++ b/examples/retry_config_example.cpp @@ -33,7 +33,7 @@ int main() { auto default_client = ai::openai::create_client(); ai::GenerateOptions options; - options.model = ai::openai::models::kGpt4oMini; + options.model = ai::openai::models::kGpt54Mini; options.prompt = "Say 'Hello with default retry config!'"; auto result1 = default_client.generate_text(options); @@ -138,7 +138,7 @@ int main() { options.prompt = "Generate a list of 5 creative project names for a batch processing " "system."; - options.model = ai::openai::models::kGpt4o; + options.model = ai::openai::models::kGpt54; std::cout << "Processing batch request (this might take a while if retries " "occur)...\n"; diff --git a/examples/streaming_chat.cpp b/examples/streaming_chat.cpp index 060f6ed..797e934 100644 --- a/examples/streaming_chat.cpp +++ b/examples/streaming_chat.cpp @@ -30,7 +30,7 @@ int main() { auto client = ai::openai::create_client(); ai::GenerateOptions gen_options1; - gen_options1.model = ai::openai::models::kGpt4o; + gen_options1.model = ai::openai::models::kGpt54; gen_options1.prompt = "Write a short story about a robot learning " "to paint. Keep it under 200 words."; @@ -77,7 +77,7 @@ int main() { }; ai::GenerateOptions gen_options2; - gen_options2.model = ai::openai::models::kGpt4oMini; + gen_options2.model = ai::openai::models::kGpt54Mini; gen_options2.prompt = "Explain quantum computing in simple terms that a " "high school student could understand."; @@ -102,7 +102,7 @@ int main() { std::cout << "Response: "; ai::GenerateOptions gen_options3; - gen_options3.model = ai::openai::models::kGpt4o; + gen_options3.model = ai::openai::models::kGpt54; gen_options3.messages = conversation; ai::StreamOptions options3(std::move(gen_options3)); auto stream3 = client.stream_text(options3); @@ -139,7 +139,7 @@ int main() { std::cout << "Prompt: Write 3 unusual ice cream flavors.\n\n"; ai::GenerateOptions gen_options4; - gen_options4.model = ai::openai::models::kGpt4o; + gen_options4.model = ai::openai::models::kGpt54; gen_options4.prompt = "Invent 3 unusual but delicious ice cream flavors with creative names."; gen_options4.temperature = 1.2; // High creativity diff --git a/examples/test_anthropic.cpp b/examples/test_anthropic.cpp index a67cc7a..5b72ca3 100644 --- a/examples/test_anthropic.cpp +++ b/examples/test_anthropic.cpp @@ -16,7 +16,7 @@ int main() { // Test simple generation std::cout << "Testing Anthropic text generation...\n\n"; - ai::GenerateOptions options(ai::anthropic::models::kClaudeHaiku35, + ai::GenerateOptions options(ai::anthropic::models::kClaudeHaiku45, "You are a helpful assistant.", "Why is the sky blue? Give a short answer."); @@ -35,7 +35,7 @@ int main() { std::cout << "\nTesting streaming...\n"; ai::GenerateOptions stream_opts( - ai::anthropic::models::kClaudeHaiku35, + ai::anthropic::models::kClaudeHaiku45, "Count from 1 to 5 slowly and with each number say 'tick'"); ai::StreamOptions stream_options(stream_opts); diff --git a/examples/test_openai.cpp b/examples/test_openai.cpp index 34c2865..54db8f5 100644 --- a/examples/test_openai.cpp +++ b/examples/test_openai.cpp @@ -16,7 +16,7 @@ int main() { // Test simple generation std::cout << "Testing OpenAI text generation...\n\n"; - ai::GenerateOptions options(ai::openai::models::kGpt4oMini, + ai::GenerateOptions options(ai::openai::models::kGpt54Mini, "You are a friendly assistant!", "Why is the sky blue? Give a short answer."); @@ -35,7 +35,7 @@ int main() { std::cout << "\nTesting streaming...\n"; ai::GenerateOptions stream_opts( - ai::openai::models::kGpt4oMini, + ai::openai::models::kGpt54Mini, "Count from 1 to 5 slowly and along with each number say 'tick'"); ai::StreamOptions stream_options(stream_opts); diff --git a/examples/test_tool_integration.cpp b/examples/test_tool_integration.cpp index ea7dacc..c1fb3d1 100644 --- a/examples/test_tool_integration.cpp +++ b/examples/test_tool_integration.cpp @@ -42,7 +42,7 @@ void test_openai_tools() { {{"input", "string"}}, simple_test_tool)}}; ai::GenerateOptions options; - options.model = ai::openai::models::kGpt4o; + options.model = ai::openai::models::kGpt54; options.prompt = "Please use the test_tool with input 'hello world'"; options.tools = tools; options.tool_choice = @@ -86,7 +86,7 @@ void test_anthropic_tools() { {{"input", "string"}}, simple_test_tool)}}; ai::GenerateOptions options; - options.model = ai::anthropic::models::kClaudeSonnet45; + options.model = ai::anthropic::models::kClaudeSonnet46; options.prompt = "Please use the test_tool with input 'hello anthropic'"; options.tools = tools; options.tool_choice = @@ -158,7 +158,7 @@ void test_multi_step() { })}}; ai::GenerateOptions options; - options.model = ai::openai::models::kGpt4o; + options.model = ai::openai::models::kGpt54; options.prompt = "Get a number and then multiply it by 2. Show me the steps."; options.tools = tools; options.max_steps = 5; // Enable multi-step diff --git a/examples/tool_calling_async.cpp b/examples/tool_calling_async.cpp index 073383c..f911042 100644 --- a/examples/tool_calling_async.cpp +++ b/examples/tool_calling_async.cpp @@ -207,7 +207,7 @@ int main() { auto start_time = std::chrono::high_resolution_clock::now(); ai::GenerateOptions options1; - options1.model = ai::openai::models::kGpt4o; + options1.model = ai::openai::models::kGpt54; options1.prompt = "Get me the latest tech news articles"; options1.tools = tools; options1.max_tokens = 200; @@ -234,7 +234,7 @@ int main() { start_time = std::chrono::high_resolution_clock::now(); ai::GenerateOptions options2; - options2.model = ai::openai::models::kGpt4o; + options2.model = ai::openai::models::kGpt54; options2.prompt = R"( Please help me with these tasks: 1. Fetch the latest sports news @@ -271,7 +271,7 @@ int main() { start_time = std::chrono::high_resolution_clock::now(); ai::GenerateOptions options3; - options3.model = ai::openai::models::kGpt4o; + options3.model = ai::openai::models::kGpt54; options3.prompt = R"( Please help me with these tasks: 1. Fetch tech news articles @@ -342,7 +342,7 @@ int main() { start_time = std::chrono::high_resolution_clock::now(); ai::GenerateOptions anthropic_options; - anthropic_options.model = ai::anthropic::models::kClaudeSonnet45; + anthropic_options.model = ai::anthropic::models::kClaudeSonnet46; anthropic_options.prompt = R"( Please help me with these THREE tasks. You MUST use the tools to complete ALL of them: 1. Use the fetch_news tool to get tech news articles diff --git a/examples/tool_calling_basic.cpp b/examples/tool_calling_basic.cpp index 89d4bdf..7405c5d 100644 --- a/examples/tool_calling_basic.cpp +++ b/examples/tool_calling_basic.cpp @@ -89,7 +89,7 @@ int main() { std::cout << "Question: What's the weather like in San Francisco?\n\n"; ai::GenerateOptions options1; - options1.model = ai::openai::models::kGpt4o; + options1.model = ai::openai::models::kGpt54; options1.prompt = "What's the weather like in San Francisco?"; options1.tools = tools; options1.max_tokens = 200; @@ -126,7 +126,7 @@ int main() { "weather like and what attractions should I visit?\n\n"; ai::GenerateOptions options2; - options2.model = ai::openai::models::kGpt4o; + options2.model = ai::openai::models::kGpt54; options2.prompt = "I'm planning a trip to San Francisco. What's the weather like and what " "attractions should I visit?"; @@ -157,7 +157,7 @@ int main() { << "Question: Tell me about the weather (forced to use weather tool)\n\n"; ai::GenerateOptions options3; - options3.model = ai::openai::models::kGpt4o; + options3.model = ai::openai::models::kGpt54; options3.prompt = "Tell me about the weather in New York"; options3.tools = tools; options3.tool_choice = @@ -179,7 +179,7 @@ int main() { std::cout << "Question: What's the weather like? (tools disabled)\n\n"; ai::GenerateOptions options4; - options4.model = ai::openai::models::kGpt4o; + options4.model = ai::openai::models::kGpt54; options4.prompt = "What's the weather like in Boston?"; options4.tools = tools; options4.tool_choice = ai::ToolChoice::none(); // Disable tools diff --git a/examples/tool_calling_multistep.cpp b/examples/tool_calling_multistep.cpp index 9cf46c6..c91540a 100644 --- a/examples/tool_calling_multistep.cpp +++ b/examples/tool_calling_multistep.cpp @@ -181,7 +181,7 @@ int main() { "recommendations, and send her an email\n\n"; ai::GenerateOptions options1; - options1.model = ai::openai::models::kGpt4o; + options1.model = ai::openai::models::kGpt54; options1.prompt = R"( Please help me with this task: 1. Look up the user 'alice' to get her information @@ -234,7 +234,7 @@ int main() { << "Task: Look up user 'bob' and create a personalized travel report\n\n"; ai::GenerateOptions options2; - options2.model = ai::openai::models::kGpt4o; + options2.model = ai::openai::models::kGpt54; options2.prompt = R"( Create a personalized travel report for user 'bob': 1. Look up Bob's profile to get his location diff --git a/include/ai/ai.h b/include/ai/ai.h index 9a815d9..696c61b 100644 --- a/include/ai/ai.h +++ b/include/ai/ai.h @@ -43,7 +43,7 @@ /// auto client = ai::openai::create_client(); /// /// auto result = client.generate_text({ -/// .model = ai::openai::models::kGpt4o, +/// .model = ai::openai::models::kGpt54, /// .system = "You are a friendly assistant!", /// .prompt = "Why is the sky blue?" /// }); @@ -58,7 +58,7 @@ /// auto client = ai::openai::create_client(); /// /// auto stream = client.stream_text({ -/// .model = ai::openai::models::kGpt4o, +/// .model = ai::openai::models::kGpt54, /// .system = "You are a helpful assistant.", /// .prompt = "Write a short story about a robot." /// }); @@ -74,7 +74,7 @@ /// ```cpp /// auto client = ai::anthropic::create_client(); /// auto result = client.generate_text({ -/// .model = ai::anthropic::models::kClaudeSonnet45, +/// .model = ai::anthropic::models::kClaudeSonnet46, /// .system = "You are a helpful assistant.", /// .prompt = "Explain quantum computing in simple terms." /// }); diff --git a/include/ai/anthropic.h b/include/ai/anthropic.h index 01ab168..7815a2c 100644 --- a/include/ai/anthropic.h +++ b/include/ai/anthropic.h @@ -14,28 +14,30 @@ namespace ai { namespace anthropic { namespace models { -/// Common Anthropic model identifiers (Latest models) -constexpr const char* kClaudeSonnet45 = - "claude-sonnet-4-5"; // claude-sonnet-4-5-20250929 +/// Latest Anthropic model identifiers +constexpr const char* kClaudeOpus47 = "claude-opus-4-7"; +constexpr const char* kClaudeSonnet46 = "claude-sonnet-4-6"; constexpr const char* kClaudeHaiku45 = "claude-haiku-4-5"; // claude-haiku-4-5-20251001 + +/// Legacy model identifiers (still available; consider migrating) +constexpr const char* kClaudeOpus46 = "claude-opus-4-6"; +constexpr const char* kClaudeOpus45 = + "claude-opus-4-5"; // claude-opus-4-5-20251101 +constexpr const char* kClaudeSonnet45 = + "claude-sonnet-4-5"; // claude-sonnet-4-5-20250929 constexpr const char* kClaudeOpus41 = "claude-opus-4-1"; // claude-opus-4-1-20250805 -/// Legacy model identifiers (retained for backward compatibility) -constexpr const char* kClaudeOpus4 = - "claude-opus-4-0"; // claude-opus-4-20250514 +/// Deprecated identifiers - scheduled for retirement on 2026-06-15. +/// Migrate to kClaudeSonnet46 / kClaudeOpus47 respectively. constexpr const char* kClaudeSonnet4 = - "claude-sonnet-4-0"; // claude-sonnet-4-20250514 -constexpr const char* kClaudeSonnet37 = - "claude-3-7-sonnet-latest"; // claude-3-7-sonnet-20250219 -constexpr const char* kClaudeSonnet35 = - "claude-3-5-sonnet-latest"; // claude-3-5-sonnet-20241022 (DEPRECATED) -constexpr const char* kClaudeHaiku35 = - "claude-3-5-haiku-latest"; // claude-3-5-haiku-20241022 + "claude-sonnet-4-0"; // claude-sonnet-4-20250514 (DEPRECATED) +constexpr const char* kClaudeOpus4 = + "claude-opus-4-0"; // claude-opus-4-20250514 (DEPRECATED) /// Default model used when none is specified -constexpr const char* kDefaultModel = kClaudeSonnet45; +constexpr const char* kDefaultModel = kClaudeSonnet46; } // namespace models /// Create an Anthropic client with default configuration @@ -62,4 +64,4 @@ Client create_client(const std::string& api_key, const std::string& base_url); std::optional try_create_client(); } // namespace anthropic -} // namespace ai \ No newline at end of file +} // namespace ai diff --git a/include/ai/openai.h b/include/ai/openai.h index 1277e5d..54e39a9 100644 --- a/include/ai/openai.h +++ b/include/ai/openai.h @@ -17,36 +17,59 @@ namespace openai { namespace models { /// Common OpenAI model identifiers -// O-series reasoning models -constexpr const char* kO1 = "o1"; -constexpr const char* kO1Mini = "o1-mini"; -constexpr const char* kO1Preview = "o1-preview"; -constexpr const char* kO3 = "o3"; -constexpr const char* kO3Mini = "o3-mini"; -constexpr const char* kO4Mini = "o4-mini"; - -// GPT-4.1 series +// GPT-5.4 series (current general-purpose) +constexpr const char* kGpt54 = "gpt-5.4"; +constexpr const char* kGpt54Pro = "gpt-5.4-pro"; +constexpr const char* kGpt54Mini = "gpt-5.4-mini"; +constexpr const char* kGpt54Nano = "gpt-5.4-nano"; + +// GPT-5 small variants (current) +constexpr const char* kGpt5Mini = "gpt-5-mini"; +constexpr const char* kGpt5Nano = "gpt-5-nano"; + +// GPT-4.1 series (still current non-reasoning leaders) constexpr const char* kGpt41 = "gpt-4.1"; constexpr const char* kGpt41Mini = "gpt-4.1-mini"; -constexpr const char* kGpt41Nano = "gpt-4.1-nano"; -// GPT-4o series -constexpr const char* kGpt4o = "gpt-4o"; -constexpr const char* kGpt4oMini = "gpt-4o-mini"; -constexpr const char* kGpt4oAudioPreview = "gpt-4o-audio-preview"; +// Embeddings +constexpr const char* kTextEmbedding3Small = "text-embedding-3-small"; +constexpr const char* kTextEmbedding3Large = "text-embedding-3-large"; + +/// Legacy / deprecated model identifiers (retained for backward compatibility). +/// These are scheduled for retirement; prefer the GPT-5 series above. + +// Deprecated GPT-5 snapshots (superseded by 5.4) +constexpr const char* kGpt5 = "gpt-5"; // DEPRECATED +constexpr const char* kGpt51 = "gpt-5.1"; // DEPRECATED +constexpr const char* kGpt52 = "gpt-5.2"; // DEPRECATED + +// Deprecated GPT-4.1 nano +constexpr const char* kGpt41Nano = "gpt-4.1-nano"; // DEPRECATED + +// Deprecated GPT-4o family (retired in ChatGPT; deprecated in API) +constexpr const char* kGpt4o = "gpt-4o"; // DEPRECATED +constexpr const char* kGpt4oMini = "gpt-4o-mini"; // DEPRECATED +constexpr const char* kGpt4oAudioPreview = + "gpt-4o-audio-preview"; // DEPRECATED +constexpr const char* kChatGpt4oLatest = "chatgpt-4o-latest"; // DEPRECATED -// GPT-4 series -constexpr const char* kGpt4Turbo = "gpt-4-turbo"; -constexpr const char* kGpt4 = "gpt-4"; +// Deprecated GPT-4 series (shutdown 2026-10-23) +constexpr const char* kGpt4Turbo = "gpt-4-turbo"; // DEPRECATED +constexpr const char* kGpt4 = "gpt-4"; // DEPRECATED -// GPT-3.5 series -constexpr const char* kGpt35Turbo = "gpt-3.5-turbo"; +// Deprecated GPT-3.5 series (shutdown 2026-10-23) +constexpr const char* kGpt35Turbo = "gpt-3.5-turbo"; // DEPRECATED -// Special models -constexpr const char* kChatGpt4oLatest = "chatgpt-4o-latest"; +// Deprecated o-series reasoning models (shutdown 2026-10-23) +constexpr const char* kO1 = "o1"; // DEPRECATED +constexpr const char* kO1Mini = "o1-mini"; // DEPRECATED +constexpr const char* kO1Preview = "o1-preview"; // DEPRECATED +constexpr const char* kO3 = "o3"; // DEPRECATED +constexpr const char* kO3Mini = "o3-mini"; // DEPRECATED +constexpr const char* kO4Mini = "o4-mini"; // DEPRECATED /// Default model used when none is specified -constexpr const char* kDefaultModel = kGpt4o; +constexpr const char* kDefaultModel = kGpt54; } // namespace models diff --git a/src/providers/anthropic/anthropic_client.cpp b/src/providers/anthropic/anthropic_client.cpp index 337de98..c1e18bf 100644 --- a/src/providers/anthropic/anthropic_client.cpp +++ b/src/providers/anthropic/anthropic_client.cpp @@ -59,14 +59,18 @@ std::string AnthropicClient::provider_name() const { } std::vector AnthropicClient::supported_models() const { - return {"claude-sonnet-4-5-20250929", // Latest Sonnet 4.5 - "claude-haiku-4-5-20251001", // Latest Haiku 4.5 - "claude-opus-4-1-20250805", // Latest Opus 4.1 - "claude-sonnet-4-20250514", // Sonnet 4.0 - "claude-3-5-sonnet-20241022", // Legacy 3.5 Sonnet - "claude-3-5-haiku-20241022", // Legacy 3.5 Haiku - "claude-3-opus-20240229", "claude-3-sonnet-20240229", - "claude-3-haiku-20240307"}; + // Both the friendly aliases (e.g. "claude-sonnet-4-5") and their dated + // snapshot variants (e.g. "claude-sonnet-4-5-20250929") are accepted by the + // Anthropic API; list both so identifiers in `ai::anthropic::models::*` + // resolve via `supports_model()`. + return {"claude-opus-4-7", "claude-sonnet-4-6", "claude-opus-4-6", + "claude-haiku-4-5", "claude-haiku-4-5-20251001", "claude-opus-4-5", + "claude-opus-4-5-20251101", "claude-sonnet-4-5", + "claude-sonnet-4-5-20250929", "claude-opus-4-1", + "claude-opus-4-1-20250805", + // Deprecated, retire 2026-06-15: + "claude-sonnet-4-0", "claude-sonnet-4-20250514", "claude-opus-4-0", + "claude-opus-4-20250514"}; } bool AnthropicClient::supports_model(const std::string& model_name) const { diff --git a/src/providers/openai/openai_client.cpp b/src/providers/openai/openai_client.cpp index e2a5baf..7fbc685 100644 --- a/src/providers/openai/openai_client.cpp +++ b/src/providers/openai/openai_client.cpp @@ -79,9 +79,14 @@ std::string OpenAIClient::provider_name() const { } std::vector OpenAIClient::supported_models() const { - return {models::kGpt4o, models::kGpt4oMini, models::kGpt4Turbo, - models::kGpt35Turbo, models::kGpt4, "gpt-4-0125-preview", - "gpt-4-1106-preview", "gpt-3.5-turbo-0125", "gpt-3.5-turbo-1106"}; + return {// Current GPT-5 series + models::kGpt54, models::kGpt54Pro, models::kGpt54Mini, + models::kGpt54Nano, models::kGpt5Mini, models::kGpt5Nano, + // Current GPT-4.1 series + models::kGpt41, models::kGpt41Mini, + // Legacy / deprecated (still functional via API) + models::kGpt4o, models::kGpt4oMini, models::kGpt4Turbo, models::kGpt4, + models::kGpt35Turbo}; } bool OpenAIClient::supports_model(const std::string& model_name) const { diff --git a/tests/integration/anthropic_integration_test.cpp b/tests/integration/anthropic_integration_test.cpp index 4ec6e5c..7010673 100644 --- a/tests/integration/anthropic_integration_test.cpp +++ b/tests/integration/anthropic_integration_test.cpp @@ -474,13 +474,12 @@ TEST_F(AnthropicIntegrationTest, DefaultModelGeneration) { // Verify we're using the expected default model EXPECT_EQ(client_->default_model(), ai::anthropic::models::kDefaultModel); if (result.model.has_value()) { - // Anthropic returns the full model version (e.g., - // "claude-sonnet-4-5-20250929") while kDefaultModel is - // "claude-sonnet-4-5" - EXPECT_TRUE(result.model.value().find("claude-sonnet-4-5") != - std::string::npos) - << "Expected model to contain 'claude-sonnet-4-5', but got: " - << result.model.value(); + // Anthropic returns either the alias (e.g. "claude-sonnet-4-6") or its + // full snapshot. Assert the API echoed back the configured default. + EXPECT_TRUE(result.model.value().find( + ai::anthropic::models::kDefaultModel) != std::string::npos) + << "Expected model to contain '" << ai::anthropic::models::kDefaultModel + << "', but got: " << result.model.value(); } } diff --git a/tests/unit/anthropic_client_test.cpp b/tests/unit/anthropic_client_test.cpp index 07240a3..c98d451 100644 --- a/tests/unit/anthropic_client_test.cpp +++ b/tests/unit/anthropic_client_test.cpp @@ -81,17 +81,17 @@ TEST_F(AnthropicClientTest, ConstructorWithHttpUrl) { TEST_F(AnthropicClientTest, SupportedModelsContainsExpectedModels) { auto models = client_->supported_models(); - EXPECT_THAT(models, testing::Contains("claude-sonnet-4-5-20250929")); + EXPECT_THAT(models, testing::Contains("claude-opus-4-7")); + EXPECT_THAT(models, testing::Contains("claude-sonnet-4-6")); EXPECT_THAT(models, testing::Contains("claude-haiku-4-5-20251001")); - EXPECT_THAT(models, testing::Contains("claude-opus-4-1-20250805")); - EXPECT_THAT(models, testing::Contains("claude-sonnet-4-20250514")); + EXPECT_THAT(models, testing::Contains("claude-sonnet-4-5-20250929")); EXPECT_FALSE(models.empty()); } TEST_F(AnthropicClientTest, SupportsValidModel) { - EXPECT_TRUE(client_->supports_model("claude-sonnet-4-5-20250929")); + EXPECT_TRUE(client_->supports_model("claude-opus-4-7")); + EXPECT_TRUE(client_->supports_model("claude-sonnet-4-6")); EXPECT_TRUE(client_->supports_model("claude-haiku-4-5-20251001")); - EXPECT_TRUE(client_->supports_model("claude-opus-4-1-20250805")); } TEST_F(AnthropicClientTest, DoesNotSupportInvalidModel) { diff --git a/tests/unit/openai_client_test.cpp b/tests/unit/openai_client_test.cpp index 9fef66c..5646fd3 100644 --- a/tests/unit/openai_client_test.cpp +++ b/tests/unit/openai_client_test.cpp @@ -79,22 +79,20 @@ TEST_F(OpenAIClientTest, ConstructorWithHttpUrl) { TEST_F(OpenAIClientTest, SupportedModelsContainsExpectedModels) { auto models = client_->supported_models(); - EXPECT_THAT(models, testing::Contains("gpt-4o")); - EXPECT_THAT(models, testing::Contains("gpt-4o-mini")); - EXPECT_THAT(models, testing::Contains("gpt-4")); - EXPECT_THAT(models, testing::Contains("gpt-3.5-turbo")); + EXPECT_THAT(models, testing::Contains("gpt-5.4")); + EXPECT_THAT(models, testing::Contains("gpt-5-mini")); + EXPECT_THAT(models, testing::Contains("gpt-4.1")); EXPECT_FALSE(models.empty()); } TEST_F(OpenAIClientTest, SupportsValidModel) { - EXPECT_TRUE(client_->supports_model("gpt-4o")); - EXPECT_TRUE(client_->supports_model("gpt-4")); - EXPECT_TRUE(client_->supports_model("gpt-3.5-turbo")); + EXPECT_TRUE(client_->supports_model("gpt-5.4")); + EXPECT_TRUE(client_->supports_model("gpt-4.1")); } TEST_F(OpenAIClientTest, DoesNotSupportInvalidModel) { EXPECT_FALSE(client_->supports_model("invalid-model")); - EXPECT_FALSE(client_->supports_model("claude-3")); + EXPECT_FALSE(client_->supports_model("claude-sonnet-4-6")); EXPECT_FALSE(client_->supports_model("")); } diff --git a/tests/utils/mock_anthropic_client.cpp b/tests/utils/mock_anthropic_client.cpp index fd53888..fb014b3 100644 --- a/tests/utils/mock_anthropic_client.cpp +++ b/tests/utils/mock_anthropic_client.cpp @@ -132,8 +132,8 @@ std::string ControllableAnthropicClient::provider_name() const { } std::vector ControllableAnthropicClient::supported_models() const { - return {"claude-sonnet-4-5-20250929", "claude-haiku-4-5-20251001", - "claude-opus-4-1-20250805", "claude-sonnet-4-20250514"}; + return {"claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5-20251001", + "claude-sonnet-4-5-20250929", "claude-opus-4-1-20250805"}; } bool ControllableAnthropicClient::supports_model( diff --git a/tests/utils/mock_openai_client.cpp b/tests/utils/mock_openai_client.cpp index 78420e5..00e47e9 100644 --- a/tests/utils/mock_openai_client.cpp +++ b/tests/utils/mock_openai_client.cpp @@ -112,7 +112,7 @@ std::string ControllableOpenAIClient::provider_name() const { } std::vector ControllableOpenAIClient::supported_models() const { - return {"gpt-4o", "gpt-4o-mini", "gpt-4", "gpt-3.5-turbo"}; + return {"gpt-5.4", "gpt-5-mini", "gpt-4.1"}; } bool ControllableOpenAIClient::supports_model(