mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 16:13:15 +00:00
fix(models): make Claude family fallback recognize Bedrock ids
#1651 added the family-aware `provider_fallback_pair` via `_claude_family_of`, but the helper only matched `anthropic:claude-*` ids. This fork serves Claude through Bedrock (`bedrock_converse:us.anthropic.claude-*`), so the family logic was dead code: a dropped Bedrock Sonnet fell back to the Bedrock Opus that sits first in the list instead of staying in the Sonnet family. Teach `_claude_family_of` to parse `bedrock_converse` ids and add regression coverage for the Sonnet-stays-on-Sonnet case.
This commit is contained in:
parent
2a226e2cd1
commit
c16fb915f5
2 changed files with 20 additions and 2 deletions
|
|
@ -99,9 +99,18 @@ def _provider_of(model_id: str) -> str | None:
|
||||||
|
|
||||||
def _claude_family_of(model_id: str) -> str | None:
|
def _claude_family_of(model_id: str) -> str | None:
|
||||||
provider, _, name = model_id.partition(":")
|
provider, _, name = model_id.partition(":")
|
||||||
if provider != "anthropic" or not name.startswith("claude-"):
|
if provider == "anthropic":
|
||||||
|
claude = name
|
||||||
|
elif provider == "bedrock_converse":
|
||||||
|
# Bedrock ids embed the model as a region-prefixed path, e.g.
|
||||||
|
# "us.anthropic.claude-sonnet-5" — take the trailing "claude-*" segment so
|
||||||
|
# our Bedrock Claude models get the same family-aware fallback.
|
||||||
|
claude = name.rpartition(".")[2]
|
||||||
|
else:
|
||||||
return None
|
return None
|
||||||
parts = name.split("-")
|
if not claude.startswith("claude-"):
|
||||||
|
return None
|
||||||
|
parts = claude.split("-")
|
||||||
if len(parts) < 2:
|
if len(parts) < 2:
|
||||||
return None
|
return None
|
||||||
return "-".join(parts[:2])
|
return "-".join(parts[:2])
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,21 @@ from agent.dashboard.team_settings import get_team_default_model
|
||||||
|
|
||||||
STALE_ANTHROPIC = "bedrock_converse:us.anthropic.claude-opus-4-7"
|
STALE_ANTHROPIC = "bedrock_converse:us.anthropic.claude-opus-4-7"
|
||||||
SUPPORTED_ANTHROPIC = "bedrock_converse:us.anthropic.claude-opus-4-8"
|
SUPPORTED_ANTHROPIC = "bedrock_converse:us.anthropic.claude-opus-4-8"
|
||||||
|
STALE_SONNET = "bedrock_converse:us.anthropic.claude-sonnet-4-9"
|
||||||
|
SUPPORTED_SONNET = "bedrock_converse:us.anthropic.claude-sonnet-5"
|
||||||
|
|
||||||
|
|
||||||
def test_provider_fallback_preserves_provider_and_effort() -> None:
|
def test_provider_fallback_preserves_provider_and_effort() -> None:
|
||||||
assert provider_fallback_pair(STALE_ANTHROPIC, "xhigh") == (SUPPORTED_ANTHROPIC, "xhigh")
|
assert provider_fallback_pair(STALE_ANTHROPIC, "xhigh") == (SUPPORTED_ANTHROPIC, "xhigh")
|
||||||
|
|
||||||
|
|
||||||
|
def test_provider_fallback_keeps_bedrock_sonnet_in_family() -> None:
|
||||||
|
# A dropped Bedrock Sonnet must prefer the current Bedrock Sonnet, not cross to
|
||||||
|
# the Bedrock Opus that happens to sit first in the provider's list. Requires
|
||||||
|
# _claude_family_of to understand bedrock_converse ids, not just anthropic:.
|
||||||
|
assert provider_fallback_pair(STALE_SONNET, "high") == (SUPPORTED_SONNET, "high")
|
||||||
|
|
||||||
|
|
||||||
def test_provider_fallback_uses_default_effort_when_unsupported() -> None:
|
def test_provider_fallback_uses_default_effort_when_unsupported() -> None:
|
||||||
assert provider_fallback_pair(STALE_ANTHROPIC, "bogus") == (SUPPORTED_ANTHROPIC, "high")
|
assert provider_fallback_pair(STALE_ANTHROPIC, "bogus") == (SUPPORTED_ANTHROPIC, "high")
|
||||||
assert provider_fallback_pair(STALE_ANTHROPIC, None) == (SUPPORTED_ANTHROPIC, "high")
|
assert provider_fallback_pair(STALE_ANTHROPIC, None) == (SUPPORTED_ANTHROPIC, "high")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue