chore(models): move the opus alias to claude-opus-5

Claude Opus 5 released today — same $5/$25 sticker, 1M context; Opus 4.8
moves to legacy. The pricing table gains a dedicated claude-opus-5
fragment (the claude-opus-4 substring doesn't cover it, so without the
row the fleet's Opus usage would silently cost-track as $0 — exactly
what test_opus_is_priced now guards).
This commit is contained in:
Renn F
2026-07-25 00:41:13 +02:00
parent 9b407d764d
commit 3c87596685
17 changed files with 29 additions and 26 deletions
+1
View File
@@ -565,6 +565,7 @@ class TestProviderAwareness:
for name in (
"claude-opus-4-6",
"claude-opus-4-8",
"claude-opus-5",
"claude-fable-5",
"opus",
"sonnet",
+1 -1
View File
@@ -106,7 +106,7 @@ def test_build_anthropic_entries_skips_missing_models() -> None:
# Patch MODEL_MAP to be missing one entry → loop hits the `continue` branch.
with patch(
"roboco.models.llm_catalog.MODEL_MAP",
{"opus": "claude-opus-4-8"}, # sonnet+haiku missing
{"opus": "claude-opus-5"}, # sonnet+haiku missing
):
entries = _build_anthropic_entries()
# Only one entry survives — opus.
+3 -4
View File
@@ -12,10 +12,9 @@ def test_sonnet_alias_resolves_to_sonnet_5() -> None:
assert MODEL_MAP["sonnet"] == "claude-sonnet-5"
def test_opus_alias_resolves_to_opus_4_8() -> None:
# CEO upgrade to the newest Opus tier ("Opus 5" does not exist — the
# Claude 5 family is Fable/Mythos/Sonnet; Opus tops out at 4.8).
assert MODEL_MAP["opus"] == "claude-opus-4-8"
def test_opus_alias_resolves_to_opus_5() -> None:
# CEO upgrade to the newest Opus tier (Opus 5, released 2026-07-25).
assert MODEL_MAP["opus"] == "claude-opus-5"
def test_sonnet_5_is_priced() -> None:
+2 -2
View File
@@ -56,7 +56,7 @@ def _spec(**overrides: Any) -> _IntakeRunSpec:
},
"session_id": "sess-abc",
"cwd": "/data/workspaces/roboco/board/intake-1",
"cli_model": "claude-opus-4-8",
"cli_model": "claude-opus-5",
"api_url": "http://roboco-orchestrator:8000",
"provider_base_url": None,
"provider_auth_token": None,
@@ -108,7 +108,7 @@ class TestBuildIntakeRunCmd:
assert "ROBOCO_WORKSPACE=/data/workspaces/roboco/board/intake-1" in cmd
assert "ROBOCO_API_URL=http://roboco-orchestrator:8000" in cmd
assert "ROBOCO_AGENT_ID=intake-1" in cmd
assert "CLAUDE_CODE_SUBAGENT_MODEL=claude-opus-4-8" in cmd
assert "CLAUDE_CODE_SUBAGENT_MODEL=claude-opus-5" in cmd
def test_mounts_prompt_and_workspaces(self) -> None:
cmd = AgentOrchestrator._build_intake_run_cmd(_spec())
@@ -99,7 +99,7 @@ class TestBuildManifestForAgent:
mock_settings.manifest_host_dir = str(tmp_path)
mock_settings.workspaces_root = str(tmp_path / "workspaces")
result = _build_manifest_for_agent("be-dev-1", "claude-opus-4-8")
result = _build_manifest_for_agent("be-dev-1", "claude-opus-5")
assert result is not None
data = json.loads(result.read_text())
+1 -1
View File
@@ -87,7 +87,7 @@ class TestBuildForRole:
role=role,
team="board",
workspace_path=Path("/tmp/x"),
agent_model="claude-opus-4-8",
agent_model="claude-opus-5",
)
)
assert "read_messages" in m.do_tools
+1 -1
View File
@@ -182,7 +182,7 @@ async def test_log_agent_event_resolves_slug_to_uuid(
event_type="agent.spawned",
agent_slug=slug,
task_id=task_id,
details={"container_id": "abc123def456", "model": "claude-opus-4-8"},
details={"container_id": "abc123def456", "model": "claude-opus-5"},
)
# Read back the row.
+2 -2
View File
@@ -945,7 +945,7 @@ class TestGetRecentSessions:
row = MagicMock()
row.id = sid
row.agent_slug = "product-owner"
row.model = "claude-opus-4-8"
row.model = "claude-opus-5"
row.started_at = datetime.datetime(2026, 6, 11, 20, 41, tzinfo=datetime.UTC)
row.ended_at = datetime.datetime(2026, 6, 11, 20, 42, tzinfo=datetime.UTC)
row.tokens_input = exp_in
@@ -966,7 +966,7 @@ class TestGetRecentSessions:
s = out[0]
assert s["id"] == str(sid)
assert s["agent_slug"] == "product-owner"
assert s["model"] == "claude-opus-4-8"
assert s["model"] == "claude-opus-5"
assert s["tokens_input"] == exp_in
assert s["tokens_output"] == exp_out
assert s["tokens_cache"] == exp_cr + exp_cw