diff --git a/ccproxy/plugins/claude_shared/model_defaults.py b/ccproxy/plugins/claude_shared/model_defaults.py index 5e283c31..5f22adda 100644 --- a/ccproxy/plugins/claude_shared/model_defaults.py +++ b/ccproxy/plugins/claude_shared/model_defaults.py @@ -7,11 +7,11 @@ DEFAULT_CLAUDE_MODEL_CARDS: list[ModelCard] = [ ModelCard( - id="claude-sonnet-4-5-20250929", + id="claude-sonnet-4-6", created=1722816000, owned_by="anthropic", permission=[], - root="claude-sonnet-4-5-20250929", + root="claude-sonnet-4-6", parent=None, ), ModelCard( @@ -23,11 +23,11 @@ parent=None, ), ModelCard( - id="claude-opus-4-1-20250805", + id="claude-opus-4-6", created=1722816000, owned_by="anthropic", permission=[], - root="claude-opus-4-1-20250805", + root="claude-opus-4-6", parent=None, ), ModelCard( @@ -105,7 +105,7 @@ ), ModelMappingRule( match="gpt-4o", - target="claude-3-7-sonnet-20250219", + target="claude-sonnet-4-6", kind="prefix", ), ModelMappingRule( @@ -125,19 +125,22 @@ ), ModelMappingRule( match="o1", - target="claude-opus-4-20250514", + target="claude-opus-4-6", kind="prefix", ), ModelMappingRule( match="o3-mini", - target="claude-opus-4-20250514", + target="claude-opus-4-6", kind="exact", ), ModelMappingRule( match="gpt-5", - target="claude-sonnet-4-20250514", + target="claude-sonnet-4-6", kind="prefix", ), + ModelMappingRule(match="sonnet", target="claude-sonnet-4-6"), + ModelMappingRule(match="opus", target="claude-opus-4-6"), + ModelMappingRule(match="haiku", target="claude-haiku-4-5-20251001"), ModelMappingRule( match="claude-3-5-sonnet-latest", target="claude-3-5-sonnet-20241022", diff --git a/ccproxy/plugins/codex/model_defaults.py b/ccproxy/plugins/codex/model_defaults.py index 852b15c1..16005583 100644 --- a/ccproxy/plugins/codex/model_defaults.py +++ b/ccproxy/plugins/codex/model_defaults.py @@ -7,29 +7,30 @@ DEFAULT_CODEX_MODEL_CARDS: list[ModelCard] = [ ModelCard( - id="gpt-5", + id="gpt-5.3-codex", created=1723075200, owned_by="openai", permission=[], - root="gpt-5", + root="gpt-5.3-codex", parent=None, ), ModelCard( - id="gpt-5-codex", + id="gpt-5.2-codex", created=1726444800, owned_by="openai", permission=[], - root="gpt-5-codex", + root="gpt-5.2-codex", parent=None, ), ] DEFAULT_CODEX_MODEL_MAPPINGS: list[ModelMappingRule] = [ - ModelMappingRule(match="gpt-", target="gpt-5", kind="prefix"), - ModelMappingRule(match="o3-", target="gpt-5", kind="prefix"), - ModelMappingRule(match="o1-", target="gpt-5", kind="prefix"), - ModelMappingRule(match="claude-", target="gpt-5", kind="prefix"), + ModelMappingRule(match="gpt-5-codex", target="gpt-5.3-codex", kind="prefix"), + ModelMappingRule(match="gpt-", target="gpt-5.3-codex", kind="prefix"), + ModelMappingRule(match="o3-", target="gpt-5.3-codex", kind="prefix"), + ModelMappingRule(match="o1-", target="gpt-5.3-codex", kind="prefix"), + ModelMappingRule(match="claude-", target="gpt-5.3-codex", kind="prefix"), ] diff --git a/tests/unit/utils/test_model_mapper.py b/tests/unit/utils/test_model_mapper.py index 17987cb9..9477e4a2 100644 --- a/tests/unit/utils/test_model_mapper.py +++ b/tests/unit/utils/test_model_mapper.py @@ -1,6 +1,8 @@ from __future__ import annotations from ccproxy.models.provider import ModelMappingRule +from ccproxy.plugins.claude_shared.model_defaults import DEFAULT_CLAUDE_MODEL_MAPPINGS +from ccproxy.plugins.codex.model_defaults import DEFAULT_CODEX_MODEL_MAPPINGS from ccproxy.utils.model_mapper import ( ModelMapper, add_model_alias, @@ -51,3 +53,20 @@ def test_restore_model_aliases_updates_nested_payloads() -> None: assert payload["model"] == "gpt-4o-mini" nested: dict[str, Any] = payload["choices"][0]["message"]["metadata"] assert nested["model"] == "gpt-4o-mini" + + +def test_default_claude_mapping_prefers_latest_sonnet_and_opus() -> None: + mapper = ModelMapper(DEFAULT_CLAUDE_MODEL_MAPPINGS) + + assert mapper.map("gpt-4o").mapped == "claude-sonnet-4-6" + assert mapper.map("gpt-5").mapped == "claude-sonnet-4-6" + assert mapper.map("o1-preview").mapped == "claude-opus-4-6" + assert mapper.map("o3-mini").mapped == "claude-opus-4-6" + assert mapper.map("sonnet").mapped == "claude-sonnet-4-6" + assert mapper.map("opus").mapped == "claude-opus-4-6" + + +def test_default_codex_mapping_keeps_latest_codex_model() -> None: + mapper = ModelMapper(DEFAULT_CODEX_MODEL_MAPPINGS) + + assert mapper.map("gpt-5-codex").mapped == "gpt-5.3-codex"