feat: Add Claude Opus 4.5 model via OpenRouter

- Add anthropic/claude-opus-4.5 with aliases: opus, opus4.5, claude-opus
- Set intelligence_score to 18 (matching Gemini 3 Pro)
- Update Opus 4.1 to use opus4.1 alias only
- Update tests to reflect new alias mappings

Note: supports_function_calling and supports_json_mode set to false
following existing project pattern for Claude models, despite
OpenRouter API support for these features.
This commit is contained in:
Robert Hyman
2025-11-29 18:00:31 -05:00
parent bcfaccecd4
commit 813ce5c9f7
3 changed files with 38 additions and 12 deletions

View File

@@ -24,6 +24,23 @@
} }
}, },
"models": [ "models": [
{
"model_name": "anthropic/claude-opus-4.5",
"aliases": [
"opus",
"opus4.5",
"claude-opus"
],
"context_window": 200000,
"max_output_tokens": 64000,
"supports_extended_thinking": false,
"supports_json_mode": false,
"supports_function_calling": false,
"supports_images": true,
"max_image_size_mb": 5.0,
"description": "Claude Opus 4.5 - Anthropic's frontier reasoning model for complex software engineering and agentic workflows",
"intelligence_score": 18
},
{ {
"model_name": "anthropic/claude-sonnet-4.5", "model_name": "anthropic/claude-sonnet-4.5",
"aliases": [ "aliases": [
@@ -43,8 +60,7 @@
{ {
"model_name": "anthropic/claude-opus-4.1", "model_name": "anthropic/claude-opus-4.1",
"aliases": [ "aliases": [
"opus", "opus4.1"
"claude-opus"
], ],
"context_window": 200000, "context_window": 200000,
"max_output_tokens": 64000, "max_output_tokens": 64000,
@@ -53,7 +69,7 @@
"supports_function_calling": false, "supports_function_calling": false,
"supports_images": true, "supports_images": true,
"max_image_size_mb": 5.0, "max_image_size_mb": 5.0,
"description": "Claude Opus 4.1 - Our most capable and intelligent model yet", "description": "Claude Opus 4.1 - Last generation flagship model with strong coding and reasoning",
"intelligence_score": 14 "intelligence_score": 14
}, },
{ {

View File

@@ -79,7 +79,9 @@ class TestOpenRouterProvider:
provider = OpenRouterProvider(api_key="test-key") provider = OpenRouterProvider(api_key="test-key")
# Test alias resolution # Test alias resolution
assert provider._resolve_model_name("opus") == "anthropic/claude-opus-4.1" assert provider._resolve_model_name("opus") == "anthropic/claude-opus-4.5"
assert provider._resolve_model_name("opus4.5") == "anthropic/claude-opus-4.5"
assert provider._resolve_model_name("opus4.1") == "anthropic/claude-opus-4.1"
assert provider._resolve_model_name("sonnet") == "anthropic/claude-sonnet-4.5" assert provider._resolve_model_name("sonnet") == "anthropic/claude-sonnet-4.5"
assert provider._resolve_model_name("sonnet4.1") == "anthropic/claude-sonnet-4.1" assert provider._resolve_model_name("sonnet4.1") == "anthropic/claude-sonnet-4.1"
assert provider._resolve_model_name("o3") == "openai/o3" assert provider._resolve_model_name("o3") == "openai/o3"
@@ -96,7 +98,7 @@ class TestOpenRouterProvider:
assert provider._resolve_model_name("r1") == "deepseek/deepseek-r1-0528" assert provider._resolve_model_name("r1") == "deepseek/deepseek-r1-0528"
# Test case-insensitive # Test case-insensitive
assert provider._resolve_model_name("OPUS") == "anthropic/claude-opus-4.1" assert provider._resolve_model_name("OPUS") == "anthropic/claude-opus-4.5"
assert provider._resolve_model_name("SONNET") == "anthropic/claude-sonnet-4.5" assert provider._resolve_model_name("SONNET") == "anthropic/claude-sonnet-4.5"
assert provider._resolve_model_name("O3") == "openai/o3" assert provider._resolve_model_name("O3") == "openai/o3"
assert provider._resolve_model_name("Mistral") == "mistralai/mistral-large-2411" assert provider._resolve_model_name("Mistral") == "mistralai/mistral-large-2411"
@@ -305,17 +307,22 @@ class TestOpenRouterRegistry:
registry = OpenRouterModelRegistry() registry = OpenRouterModelRegistry()
# Test known model # Test known model (opus alias now points to 4.5)
caps = registry.get_capabilities("opus") caps = registry.get_capabilities("opus")
assert caps is not None assert caps is not None
assert caps.model_name == "anthropic/claude-opus-4.1" assert caps.model_name == "anthropic/claude-opus-4.5"
assert caps.context_window == 200000 # Claude's context window assert caps.context_window == 200000 # Claude's context window
# Test using full model name # Test using full model name for 4.1
caps = registry.get_capabilities("anthropic/claude-opus-4.1") caps = registry.get_capabilities("anthropic/claude-opus-4.1")
assert caps is not None assert caps is not None
assert caps.model_name == "anthropic/claude-opus-4.1" assert caps.model_name == "anthropic/claude-opus-4.1"
# Test opus4.1 alias still works
caps = registry.get_capabilities("opus4.1")
assert caps is not None
assert caps.model_name == "anthropic/claude-opus-4.1"
# Test unknown model # Test unknown model
caps = registry.get_capabilities("non-existent-model") caps = registry.get_capabilities("non-existent-model")
assert caps is None assert caps is None

View File

@@ -88,8 +88,10 @@ class TestOpenRouterModelRegistry:
# Test various aliases # Test various aliases
test_cases = [ test_cases = [
("opus", "anthropic/claude-opus-4.1"), ("opus", "anthropic/claude-opus-4.5"), # opus now points to 4.5
("OPUS", "anthropic/claude-opus-4.1"), # Case insensitive ("OPUS", "anthropic/claude-opus-4.5"), # Case insensitive
("opus4.5", "anthropic/claude-opus-4.5"),
("opus4.1", "anthropic/claude-opus-4.1"), # 4.1 still accessible
("sonnet", "anthropic/claude-sonnet-4.5"), ("sonnet", "anthropic/claude-sonnet-4.5"),
("o3", "openai/o3"), ("o3", "openai/o3"),
("deepseek", "deepseek/deepseek-r1-0528"), ("deepseek", "deepseek/deepseek-r1-0528"),
@@ -131,9 +133,10 @@ class TestOpenRouterModelRegistry:
assert config is not None assert config is not None
# Registry now returns ModelCapabilities objects directly # Registry now returns ModelCapabilities objects directly
# opus alias now points to 4.5
assert config.provider == ProviderType.OPENROUTER assert config.provider == ProviderType.OPENROUTER
assert config.model_name == "anthropic/claude-opus-4.1" assert config.model_name == "anthropic/claude-opus-4.5"
assert config.friendly_name == "OpenRouter (anthropic/claude-opus-4.1)" assert config.friendly_name == "OpenRouter (anthropic/claude-opus-4.5)"
assert config.context_window == 200000 assert config.context_window == 200000
assert not config.supports_extended_thinking assert not config.supports_extended_thinking