feat: Update Claude models to Opus 4.1 and Sonnet 4.1

This commit updates all references to Claude Opus 4 and Sonnet 4 to their newer 4.1 versions throughout the codebase.

The changes include:
- Updating model names in `conf/custom_models.json` and `providers/dial.py`.
- Updating aliases and descriptions to match the new model versions.
- Updating `.env.example` to reflect the new model names.
- Updating all relevant test suites to use the new model names and ensure all tests pass.
This commit is contained in:
google-labs-jules[bot]
2025-08-17 16:08:52 +00:00
parent e6213d4ca1
commit 0959d6f0fa
12 changed files with 93 additions and 93 deletions

View File

@@ -52,7 +52,7 @@ class TestChatTool:
"prompt": "Test prompt",
"files": ["test.txt"],
"images": ["test.png"],
"model": "anthropic/claude-3-opus",
"model": "anthropic/claude-opus-4.1",
"temperature": 0.7,
}
@@ -60,7 +60,7 @@ class TestChatTool:
assert request.prompt == "Test prompt"
assert request.files == ["test.txt"]
assert request.images == ["test.png"]
assert request.model == "anthropic/claude-3-opus"
assert request.model == "anthropic/claude-opus-4.1"
assert request.temperature == 0.7
def test_required_fields(self):
@@ -69,7 +69,7 @@ class TestChatTool:
from pydantic import ValidationError
with pytest.raises(ValidationError):
ChatRequest(model="anthropic/claude-3-opus")
ChatRequest(model="anthropic/claude-opus-4.1")
def test_model_availability(self):
"""Test that model availability works"""

View File

@@ -48,8 +48,8 @@ class TestDIALProvider:
# Test valid models
assert provider.validate_model_name("o3-2025-04-16") is True
assert provider.validate_model_name("o3") is True # Shorthand
assert provider.validate_model_name("anthropic.claude-opus-4-20250514-v1:0") is True
assert provider.validate_model_name("opus-4") is True # Shorthand
assert provider.validate_model_name("anthropic.claude-opus-4.1-20250805-v1:0") is True
assert provider.validate_model_name("opus-4.1") is True # Shorthand
assert provider.validate_model_name("gemini-2.5-pro-preview-05-06") is True
assert provider.validate_model_name("gemini-2.5-pro") is True # Shorthand
@@ -63,16 +63,16 @@ class TestDIALProvider:
# Test shorthand resolution
assert provider._resolve_model_name("o3") == "o3-2025-04-16"
assert provider._resolve_model_name("o4-mini") == "o4-mini-2025-04-16"
assert provider._resolve_model_name("opus-4") == "anthropic.claude-opus-4-20250514-v1:0"
assert provider._resolve_model_name("sonnet-4") == "anthropic.claude-sonnet-4-20250514-v1:0"
assert provider._resolve_model_name("opus-4.1") == "anthropic.claude-opus-4.1-20250805-v1:0"
assert provider._resolve_model_name("sonnet-4.1") == "anthropic.claude-sonnet-4.1-20250805-v1:0"
assert provider._resolve_model_name("gemini-2.5-pro") == "gemini-2.5-pro-preview-05-06"
assert provider._resolve_model_name("gemini-2.5-flash") == "gemini-2.5-flash-preview-05-20"
# Test full name passthrough
assert provider._resolve_model_name("o3-2025-04-16") == "o3-2025-04-16"
assert (
provider._resolve_model_name("anthropic.claude-opus-4-20250514-v1:0")
== "anthropic.claude-opus-4-20250514-v1:0"
provider._resolve_model_name("anthropic.claude-opus-4.1-20250805-v1:0")
== "anthropic.claude-opus-4.1-20250805-v1:0"
)
@patch.dict(os.environ, {"DIAL_ALLOWED_MODELS": ""}, clear=False)
@@ -90,16 +90,16 @@ class TestDIALProvider:
assert capabilities.supports_images is True
assert capabilities.supports_extended_thinking is False
# Test Claude 4 capabilities
capabilities = provider.get_capabilities("opus-4")
assert capabilities.model_name == "anthropic.claude-opus-4-20250514-v1:0"
# Test Claude 4.1 capabilities
capabilities = provider.get_capabilities("opus-4.1")
assert capabilities.model_name == "anthropic.claude-opus-4.1-20250805-v1:0"
assert capabilities.context_window == 200_000
assert capabilities.supports_images is True
assert capabilities.supports_extended_thinking is False
# Test Claude 4 with thinking mode
capabilities = provider.get_capabilities("opus-4-thinking")
assert capabilities.model_name == "anthropic.claude-opus-4-20250514-v1:0-with-thinking"
# Test Claude 4.1 with thinking mode
capabilities = provider.get_capabilities("opus-4.1-thinking")
assert capabilities.model_name == "anthropic.claude-opus-4.1-20250805-v1:0-with-thinking"
assert capabilities.context_window == 200_000
assert capabilities.supports_images is True
assert capabilities.supports_extended_thinking is True
@@ -146,7 +146,7 @@ class TestDIALProvider:
# Test models with vision support
assert provider._supports_vision("o3-2025-04-16") is True
assert provider._supports_vision("o3") is True # Via resolution
assert provider._supports_vision("anthropic.claude-opus-4-20250514-v1:0") is True
assert provider._supports_vision("anthropic.claude-opus-4.1-20250805-v1:0") is True
assert provider._supports_vision("gemini-2.5-pro-preview-05-06") is True
# Test unknown model (falls back to parent implementation)
@@ -219,7 +219,7 @@ class TestDIALProvider:
# Check that Api-Key header is set
assert provider.DEFAULT_HEADERS["Api-Key"] == "test-key"
@patch.dict(os.environ, {"DIAL_ALLOWED_MODELS": "o3-2025-04-16,anthropic.claude-opus-4-20250514-v1:0"})
@patch.dict(os.environ, {"DIAL_ALLOWED_MODELS": "o3-2025-04-16,anthropic.claude-opus-4.1-20250805-v1:0"})
@patch("utils.model_restrictions._restriction_service", None)
def test_allowed_models_restriction(self):
"""Test model allow-list functionality."""
@@ -228,13 +228,13 @@ class TestDIALProvider:
# These should be allowed
assert provider.validate_model_name("o3-2025-04-16") is True
assert provider.validate_model_name("o3") is True # Alias for o3-2025-04-16
assert provider.validate_model_name("anthropic.claude-opus-4-20250514-v1:0") is True
assert provider.validate_model_name("opus-4") is True # Resolves to anthropic.claude-opus-4-20250514-v1:0
assert provider.validate_model_name("anthropic.claude-opus-4.1-20250805-v1:0") is True
assert provider.validate_model_name("opus-4.1") is True # Resolves to anthropic.claude-opus-4.1-20250805-v1:0
# These should be blocked
assert provider.validate_model_name("gemini-2.5-pro-preview-05-06") is False
assert provider.validate_model_name("o4-mini-2025-04-16") is False
assert provider.validate_model_name("sonnet-4") is False # sonnet-4 is not in allowed list
assert provider.validate_model_name("sonnet-4.1") is False # sonnet-4.1 is not in allowed list
@patch("httpx.Client")
@patch("openai.OpenAI")

View File

@@ -71,26 +71,26 @@ class TestOpenRouterProvider:
provider = OpenRouterProvider(api_key="test-key")
# Test alias resolution
assert provider._resolve_model_name("opus") == "anthropic/claude-opus-4"
assert provider._resolve_model_name("sonnet") == "anthropic/claude-sonnet-4"
assert provider._resolve_model_name("opus") == "anthropic/claude-opus-4.1"
assert provider._resolve_model_name("sonnet") == "anthropic/claude-sonnet-4.1"
assert provider._resolve_model_name("o3") == "openai/o3"
assert provider._resolve_model_name("o3-mini") == "openai/o3-mini"
assert provider._resolve_model_name("o3mini") == "openai/o3-mini"
assert provider._resolve_model_name("o4-mini") == "openai/o4-mini"
assert provider._resolve_model_name("o4-mini") == "openai/o4-mini"
assert provider._resolve_model_name("claude") == "anthropic/claude-sonnet-4"
assert provider._resolve_model_name("claude") == "anthropic/claude-sonnet-4.1"
assert provider._resolve_model_name("mistral") == "mistralai/mistral-large-2411"
assert provider._resolve_model_name("deepseek") == "deepseek/deepseek-r1-0528"
assert provider._resolve_model_name("r1") == "deepseek/deepseek-r1-0528"
# Test case-insensitive
assert provider._resolve_model_name("OPUS") == "anthropic/claude-opus-4"
assert provider._resolve_model_name("OPUS") == "anthropic/claude-opus-4.1"
assert provider._resolve_model_name("O3") == "openai/o3"
assert provider._resolve_model_name("Mistral") == "mistralai/mistral-large-2411"
assert provider._resolve_model_name("CLAUDE") == "anthropic/claude-sonnet-4"
assert provider._resolve_model_name("CLAUDE") == "anthropic/claude-sonnet-4.1"
# Test direct model names (should pass through unchanged)
assert provider._resolve_model_name("anthropic/claude-opus-4") == "anthropic/claude-opus-4"
assert provider._resolve_model_name("anthropic/claude-opus-4.1") == "anthropic/claude-opus-4.1"
assert provider._resolve_model_name("openai/o3") == "openai/o3"
# Test unknown models pass through
@@ -155,8 +155,8 @@ class TestOpenRouterAutoMode:
"google/gemini-2.5-pro",
"openai/o3",
"openai/o3-mini",
"anthropic/claude-opus-4",
"anthropic/claude-sonnet-4",
"anthropic/claude-opus-4.1",
"anthropic/claude-sonnet-4.1",
]
ModelProviderRegistry.register_provider(ProviderType.OPENROUTER, OpenRouterProvider)
@@ -181,7 +181,7 @@ class TestOpenRouterAutoMode:
os.environ.pop("OPENAI_API_KEY", None)
os.environ["OPENROUTER_API_KEY"] = "test-openrouter-key"
os.environ.pop("OPENROUTER_ALLOWED_MODELS", None)
os.environ["OPENROUTER_ALLOWED_MODELS"] = "anthropic/claude-opus-4,google/gemini-2.5-flash"
os.environ["OPENROUTER_ALLOWED_MODELS"] = "anthropic/claude-opus-4.1,google/gemini-2.5-flash"
os.environ["DEFAULT_MODEL"] = "auto"
# Force reload to pick up new environment variable
@@ -193,8 +193,8 @@ class TestOpenRouterAutoMode:
mock_models = [
"google/gemini-2.5-flash",
"google/gemini-2.5-pro",
"anthropic/claude-opus-4",
"anthropic/claude-sonnet-4",
"anthropic/claude-opus-4.1",
"anthropic/claude-sonnet-4.1",
]
mock_registry.list_models.return_value = mock_models
@@ -212,7 +212,7 @@ class TestOpenRouterAutoMode:
assert len(available_models) > 0, "Should have some allowed models"
expected_allowed = {"google/gemini-2.5-flash", "anthropic/claude-opus-4"}
expected_allowed = {"google/gemini-2.5-flash", "anthropic/claude-opus-4.1"}
assert (
set(available_models.keys()) == expected_allowed
@@ -263,7 +263,7 @@ class TestOpenRouterRegistry:
# Should have loaded models
models = registry.list_models()
assert len(models) > 0
assert "anthropic/claude-opus-4" in models
assert "anthropic/claude-opus-4.1" in models
assert "openai/o3" in models
# Should have loaded aliases
@@ -282,13 +282,13 @@ class TestOpenRouterRegistry:
# Test known model
caps = registry.get_capabilities("opus")
assert caps is not None
assert caps.model_name == "anthropic/claude-opus-4"
assert caps.model_name == "anthropic/claude-opus-4.1"
assert caps.context_window == 200000 # Claude's context window
# Test using full model name
caps = registry.get_capabilities("anthropic/claude-opus-4")
caps = registry.get_capabilities("anthropic/claude-opus-4.1")
assert caps is not None
assert caps.model_name == "anthropic/claude-opus-4"
assert caps.model_name == "anthropic/claude-opus-4.1"
# Test unknown model
caps = registry.get_capabilities("non-existent-model")
@@ -301,11 +301,11 @@ class TestOpenRouterRegistry:
registry = OpenRouterModelRegistry()
# All these should resolve to Claude Sonnet
sonnet_aliases = ["sonnet", "claude", "claude-sonnet", "claude4-sonnet"]
sonnet_aliases = ["sonnet", "claude", "claude-sonnet", "claude-4.1-sonnet"]
for alias in sonnet_aliases:
config = registry.resolve(alias)
assert config is not None
assert config.model_name == "anthropic/claude-sonnet-4"
assert config.model_name == "anthropic/claude-sonnet-4.1"
class TestOpenRouterFunctionality:

View File

@@ -87,9 +87,9 @@ class TestOpenRouterModelRegistry:
# Test various aliases
test_cases = [
("opus", "anthropic/claude-opus-4"),
("OPUS", "anthropic/claude-opus-4"), # Case insensitive
("claude", "anthropic/claude-sonnet-4"),
("opus", "anthropic/claude-opus-4.1"),
("OPUS", "anthropic/claude-opus-4.1"), # Case insensitive
("claude", "anthropic/claude-sonnet-4.1"),
("o3", "openai/o3"),
("deepseek", "deepseek/deepseek-r1-0528"),
("mistral", "mistralai/mistral-large-2411"),
@@ -105,9 +105,9 @@ class TestOpenRouterModelRegistry:
registry = OpenRouterModelRegistry()
# Should be able to look up by full model name
config = registry.resolve("anthropic/claude-opus-4")
config = registry.resolve("anthropic/claude-opus-4.1")
assert config is not None
assert config.model_name == "anthropic/claude-opus-4"
assert config.model_name == "anthropic/claude-opus-4.1"
config = registry.resolve("openai/o3")
assert config is not None
@@ -131,8 +131,8 @@ class TestOpenRouterModelRegistry:
# Registry now returns ModelCapabilities objects directly
assert config.provider == ProviderType.OPENROUTER
assert config.model_name == "anthropic/claude-opus-4"
assert config.friendly_name == "OpenRouter (anthropic/claude-opus-4)"
assert config.model_name == "anthropic/claude-opus-4.1"
assert config.friendly_name == "OpenRouter (anthropic/claude-opus-4.1)"
assert config.context_window == 200000
assert not config.supports_extended_thinking

View File

@@ -14,8 +14,8 @@ class TestParseModelOption:
def test_openrouter_beta_suffix_preserved(self):
"""Test that OpenRouter :beta suffix is preserved as part of model name."""
model, option = parse_model_option("anthropic/claude-3-opus:beta")
assert model == "anthropic/claude-3-opus:beta"
model, option = parse_model_option("anthropic/claude-opus-4.1:beta")
assert model == "anthropic/claude-opus-4.1:beta"
assert option is None
def test_openrouter_preview_suffix_preserved(self):

View File

@@ -344,7 +344,7 @@ class TestOpenRouterAliasRestrictions:
os.environ.pop("OPENAI_API_KEY", None)
os.environ.pop("XAI_API_KEY", None)
os.environ["OPENROUTER_API_KEY"] = "test-key"
os.environ["OPENROUTER_ALLOWED_MODELS"] = "o3-mini,anthropic/claude-opus-4,flash"
os.environ["OPENROUTER_ALLOWED_MODELS"] = "o3-mini,anthropic/claude-opus-4.1,flash"
# Register OpenRouter provider
from providers.openrouter import OpenRouterProvider
@@ -356,7 +356,7 @@ class TestOpenRouterAliasRestrictions:
expected_models = {
"openai/o3-mini", # from alias
"anthropic/claude-opus-4", # full name
"anthropic/claude-opus-4.1", # full name
"google/gemini-2.5-flash", # from alias
}

View File

@@ -351,7 +351,7 @@ class TestLocaleModelIntegration(unittest.TestCase):
def test_model_name_resolution_utf8(self):
"""Test model name resolution with UTF-8."""
provider = OpenAIModelProvider(api_key="test")
model_names = ["gpt-4", "gemini-2.5-flash", "claude-3-opus", "o3-pro"]
model_names = ["gpt-4", "gemini-2.5-flash", "anthropic/claude-opus-4.1", "o3-pro"]
for model_name in model_names:
resolved = provider._resolve_model_name(model_name)
self.assertIsInstance(resolved, str)

View File

@@ -105,19 +105,19 @@ class TestSupportedModelsAliases:
# Test specific aliases
assert "o3" in provider.SUPPORTED_MODELS["o3-2025-04-16"].aliases
assert "o4-mini" in provider.SUPPORTED_MODELS["o4-mini-2025-04-16"].aliases
assert "sonnet-4" in provider.SUPPORTED_MODELS["anthropic.claude-sonnet-4-20250514-v1:0"].aliases
assert "opus-4" in provider.SUPPORTED_MODELS["anthropic.claude-opus-4-20250514-v1:0"].aliases
assert "sonnet-4.1" in provider.SUPPORTED_MODELS["anthropic.claude-sonnet-4.1-20250805-v1:0"].aliases
assert "opus-4.1" in provider.SUPPORTED_MODELS["anthropic.claude-opus-4.1-20250805-v1:0"].aliases
assert "gemini-2.5-pro" in provider.SUPPORTED_MODELS["gemini-2.5-pro-preview-05-06"].aliases
# Test alias resolution
assert provider._resolve_model_name("o3") == "o3-2025-04-16"
assert provider._resolve_model_name("o4-mini") == "o4-mini-2025-04-16"
assert provider._resolve_model_name("sonnet-4") == "anthropic.claude-sonnet-4-20250514-v1:0"
assert provider._resolve_model_name("opus-4") == "anthropic.claude-opus-4-20250514-v1:0"
assert provider._resolve_model_name("sonnet-4.1") == "anthropic.claude-sonnet-4.1-20250805-v1:0"
assert provider._resolve_model_name("opus-4.1") == "anthropic.claude-opus-4.1-20250805-v1:0"
# Test case insensitive resolution
assert provider._resolve_model_name("O3") == "o3-2025-04-16"
assert provider._resolve_model_name("SONNET-4") == "anthropic.claude-sonnet-4-20250514-v1:0"
assert provider._resolve_model_name("SONNET-4.1") == "anthropic.claude-sonnet-4.1-20250805-v1:0"
def test_list_models_includes_aliases(self):
"""Test that list_models returns both base models and aliases."""