Skip to content

Commit 64227bd

Browse files
Trecekclaude
andauthored
Implementation Plan: T5-P4-A5-WP1 Replace three-way gpt-5.5 collision in CODEX_MODEL_ALIASES (#4097)
## Summary Replace the degenerate three-way `gpt-5.5` collision in `CODEX_MODEL_ALIASES` with three distinct real OpenAI model IDs aligned with `CODEX_EFFORT_MAPPING` semantics: `gpt-5.5` (opus/xhigh), `gpt-5.4` (sonnet/high), `gpt-5.4-mini` (haiku/medium). Implement a `model_class()` utility function for cross-backend opus/sonnet/haiku tier resolution via suffix stripping, identity check on `CLAUDE_MODEL_ALIASES` keys, and reverse-map on `CODEX_MODEL_ALIASES` values. Thread the new symbol through the re-export chain and add architecture and unit tests. ## Implementation Plan Plan file: `/home/talon/projects/autoskillit-runs/impl-20260612-150756-734470/.autoskillit/temp/make-plan/t5_p4_a5_wp1_replace_gpt55_collision_plan_2026-06-12_151500.md` Closes #4022 🤖 Generated with [Claude Code](https://claude.com/claude-code) via AutoSkillit <!-- autoskillit:pipeline-signature steps=prepare_pr,run_arch_lenses,compose_pr,annotate_pr_diff,review_pr --> ## Token Usage Summary | Step | Model | count | uncached | output | cache_read | peak_ctx | turns | cache_write | time | |------|-------|-------|----------|--------|------------|----------|-------|-------------|------| | plan* | opus[1m] | 1 | 67 | 22.1k | 1.7M | 106.3k | 51 | 107.1k | 11m 37s | | verify* | sonnet | 1 | 78 | 16.1k | 407.5k | 61.2k | 26 | 40.3k | 6m 36s | | implement* | MiniMax-M3 | 1 | 1.1M | 6.7k | 0 | 0 | 50 | 0 | 2m 48s | | audit_impl* | sonnet | 1 | 2.3k | 6.3k | 166.5k | 41.7k | 16 | 29.8k | 3m 49s | | prepare_pr* | MiniMax-M3 | 1 | 232.8k | 2.8k | 0 | 0 | 15 | 0 | 1m 8s | | compose_pr* | MiniMax-M3 | 1 | 176.4k | 1.3k | 0 | 0 | 12 | 0 | 36s | | **Total** | | | 1.5M | 55.3k | 2.2M | 106.3k | | 177.2k | 26m 36s | \* *Step used a non-Anthropic provider; caching behavior may differ.* ## Token Efficiency | Step | LoC Changed | cache_read/LoC | cache_write/LoC | output/LoC | |------|-------------|----------------|-----------------|------------| | plan | 0 | — | — | — | | verify | 0 | — | — | — | | implement | 59 | 0.0 | 0.0 | 113.2 | | audit_impl | 0 | — | — | — | | prepare_pr | 0 | — | — | — | | compose_pr | 0 | — | — | — | | **Total** | **59** | 38004.2 | 3003.8 | 936.9 | ## Model Usage Breakdown | Model | steps | uncached | output | cache_read | cache_write | time | |-------|-------|----------|--------|------------|-------------|------| | opus[1m] | 1 | 67 | 22.1k | 1.7M | 107.1k | 11m 37s | | sonnet | 2 | 2.4k | 22.5k | 574.0k | 70.1k | 10m 26s | | MiniMax-M3 | 3 | 1.5M | 10.8k | 0 | 0 | 4m 32s | --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 296a4e2 commit 64227bd

6 files changed

Lines changed: 65 additions & 3 deletions

File tree

src/autoskillit/core/__init__.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ from .types import extract_positional_args as extract_positional_args
359359
from .types import extract_skill_name as extract_skill_name
360360
from .types import fleet_error as fleet_error
361361
from .types import is_path_like_token as is_path_like_token
362+
from .types import model_class as model_class
362363
from .types import resolve_payload_field as resolve_payload_field
363364
from .types import resolve_skill_name as resolve_skill_name
364365
from .types import resolve_target_skill as resolve_target_skill

src/autoskillit/core/types/_type_backend.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"CodexEventData",
3030
"SessionEvent",
3131
"AgentSessionResult",
32+
"model_class",
3233
"strip_context_window_suffix",
3334
]
3435

@@ -169,9 +170,9 @@ class BackendCapabilities:
169170
}
170171

171172
CODEX_MODEL_ALIASES: dict[str, str] = {
172-
"sonnet": "gpt-5.5",
173+
"sonnet": "gpt-5.4",
173174
"opus": "gpt-5.5",
174-
"haiku": "gpt-5.5",
175+
"haiku": "gpt-5.4-mini",
175176
}
176177

177178
CODEX_EFFORT_MAPPING: dict[str, str] = {
@@ -180,6 +181,14 @@ class BackendCapabilities:
180181
"haiku": "medium",
181182
}
182183

184+
_CODEX_MODEL_REVERSE: dict[str, str] = {v: k for k, v in CODEX_MODEL_ALIASES.items()}
185+
_codex_alias_values = list(CODEX_MODEL_ALIASES.values())
186+
assert len(_CODEX_MODEL_REVERSE) == len(CODEX_MODEL_ALIASES), (
187+
"CODEX_MODEL_ALIASES values must be unique — duplicate makes an alias unreachable "
188+
f"via model_class(). Duplicates: "
189+
f"{[v for v in _codex_alias_values if _codex_alias_values.count(v) > 1]}"
190+
)
191+
183192

184193
@dataclass(frozen=True, slots=True)
185194
class ModelTranslation:
@@ -198,6 +207,13 @@ def strip_context_window_suffix(model: str) -> str:
198207
return _CONTEXT_WINDOW_SUFFIX_RE.sub("", model)
199208

200209

210+
def model_class(model: str) -> str:
211+
base = strip_context_window_suffix(model)
212+
if base in CLAUDE_MODEL_ALIASES:
213+
return base
214+
return _CODEX_MODEL_REVERSE.get(base, base)
215+
216+
201217
CLAUDE_CODE_CAPABILITIES: BackendCapabilities = BackendCapabilities(
202218
channel_b_capable=True,
203219
pty_required=True,

tests/arch/test_backend_translate_model.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,19 @@ def test_translate_model_called_at_terminal_model_sites() -> None:
6666
f"{backend_name}.{method_name} appends --model but does not call "
6767
f"self.translate_model"
6868
)
69+
70+
71+
def test_translate_model_distinct_per_alias_class() -> None:
72+
from autoskillit.core.types._type_backend import CLAUDE_MODEL_ALIASES
73+
74+
alias_keys = list(CLAUDE_MODEL_ALIASES.keys())
75+
for backend_name, cls in BACKEND_REGISTRY.items():
76+
try:
77+
backend = cls()
78+
except TypeError:
79+
pytest.skip(f"{backend_name}: requires constructor args — cannot validate")
80+
translated = [backend.translate_model(k) for k in alias_keys]
81+
assert len(translated) == len(set(translated)), (
82+
f"{backend_name}: translate_model produced duplicate outputs for alias keys "
83+
f"{alias_keys}: {translated}"
84+
)

tests/core/test_backend_dataclasses.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ def test_backend_module_all_exhaustive():
204204
"CodexEventData",
205205
"SessionEvent",
206206
"AgentSessionResult",
207+
"model_class",
207208
"strip_context_window_suffix",
208209
}
209210

tests/execution/backends/test_model_translation.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,31 @@ def test_interactive_cmd_has_effort(self) -> None:
183183
def test_no_effort_for_native_model_in_headless_cmd(self) -> None:
184184
spec = CodexBackend().build_headless_cmd("test prompt", model="gpt-5.5")
185185
assert "model_reasoning_effort" not in " ".join(spec.cmd)
186+
187+
188+
class TestModelClass:
189+
def test_canonical_keys(self) -> None:
190+
from autoskillit.core import model_class
191+
192+
assert model_class("opus") == "opus"
193+
assert model_class("sonnet") == "sonnet"
194+
assert model_class("haiku") == "haiku"
195+
196+
def test_suffix_stripping(self) -> None:
197+
from autoskillit.core import model_class
198+
199+
assert model_class("opus[1m]") == "opus"
200+
assert model_class("sonnet[1m]") == "sonnet"
201+
assert model_class("haiku[1m]") == "haiku"
202+
203+
def test_codex_reverse_map(self) -> None:
204+
from autoskillit.core import model_class
205+
206+
assert model_class(CODEX_MODEL_ALIASES["opus"]) == "opus"
207+
assert model_class(CODEX_MODEL_ALIASES["sonnet"]) == "sonnet"
208+
assert model_class(CODEX_MODEL_ALIASES["haiku"]) == "haiku"
209+
210+
def test_unknown_passthrough(self) -> None:
211+
from autoskillit.core import model_class
212+
213+
assert model_class("custom-model-xyz") == "custom-model-xyz"

tests/execution/test_model_alias_registry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
pytestmark = [pytest.mark.layer("execution"), pytest.mark.small]
88

9-
VALID_CODEX_MODEL_IDS: frozenset[str] = frozenset({"gpt-5.5"})
9+
VALID_CODEX_MODEL_IDS: frozenset[str] = frozenset({"gpt-5.4", "gpt-5.4-mini", "gpt-5.5"})
1010

1111
VALID_CLAUDE_MODEL_IDS: frozenset[str] = frozenset({"sonnet", "opus", "haiku"})
1212

0 commit comments

Comments
 (0)