Feat/opus5 support - #216
Conversation
With #213 merged, Codex and OpenRouter ask their harness for a live model list, but Claude still shipped a hand-maintained table, which is why Opus 5 needed a patch at all. Add a Claude discoverer that opens an Agent SDK session in streaming-input mode and reads supportedModels() from the control channel: the list then tracks whatever the bundled CLI serves (the 0.3.226 CLI in this PR lists Opus 5 and Fable 5.1). The probe consumes no turn, disables settings sources so no hooks fire, and closes the session on every path including timeout. Claude Code accepts model ids it does not advertise, so the provider is flagged acceptsUnlisted: built-in entries are kept without a deprecated marker and the configured default stands, which also keeps the picker's auto-rescue from firing on Claude. Also treat any `[1m]` alias as a 1M-context model in both token-usage tables, since the discovered menu is made of such aliases, and add the Fable 5.1 entries. The /model command caps the Claude probe at 3s like Codex. Docs updated; tests cover the happy path, timeout, and SDK errors. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBqmTvJRhyysMvMvL6cp7x
|
Rebuilt this branch on top of What the new commit does The Codex/OpenRouter discovery from #213 did not cover Claude, so the picker still depended on the hand-maintained table. The Agent SDK exposes the CLI's own menu via Measured with the SDK from this PR (0.3.226), the CLI serves: Because the CLI also runs ids it does not list ( Tests: 31/31 in the discovery + route suites, typecheck clean, real end-to-end probe through the module works. |
6301e12 to
d1c0044
Compare
bbsngg
left a comment
There was a problem hiding this comment.
Approving: rebased onto main (single Opus 5 commit, SDK 0.3.226, 1M context) plus the Claude discoverer commit. CI green; 31/31 discovery + route tests and typecheck clean locally; real end-to-end probe verified.
* fix(models): keep discovery per-provider, surface Fable 5.1, and drive Codex effort from the CLI Three problems reported after #213/#216 landed, all in the model picker. 1. Switching provider could write one provider's model into another's slot. useHarnessModels updated its state asynchronously, so for one render after a switch it still held the previous provider's list while `provider` already named the new one. ChatComposer's rescue effect then saw a Claude model "missing" from Codex's list and replaced it with Codex's default, persisting `claude-model` = `gpt-5.6-sol`. The hook now tags every answer with the provider it was fetched for and only ever exposes an answer for the current provider. useChatProviderState also discards a stored model that cannot belong to its slot, so users already hit by this get their default back instead of a failing session. 2. Fable 5.1 was not selectable. The Claude probe disables settings sources (so no hooks fire), which also hid the model the user configured in ~/.claude/settings.json; that is where the CLI's own /model menu gets Fable 5.1 from. Discovery now reads `model` from the user settings file (honouring CLAUDE_CONFIG_DIR) and ANTHROPIC_MODEL and offers it, and Fable 5.1 is in the built-in list too so it is there even when discovery is unavailable. Duplicate CLI display names ("Fable" for both Fable 5 and Fable 5.1) are disambiguated from the description. 3. No reasoning-effort selector for discovered Codex models. Support was a table keyed by exact model name, so `gpt-5.6-sol` and friends fell to "default only". Codex's model/list reports supportedReasoningEfforts and defaultReasoningEffort per model; discovery now carries them through and the selector, its gating, and the saved-effort normalisation prefer that list over the table. The `ultra` effort the CLI offers is added to the UI and locales. useHarnessModels moved up to ChatInterface so composer state and the picker share one answer. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBqmTvJRhyysMvMvL6cp7x * fix(models): stop the picker showing one model under two names - Codex built-in list uses the ids codex-cli actually serves: the retired `gpt-5.6` (labelled "GPT-5.6 (Sol)") is replaced by `gpt-5.6-sol`, and `gpt-5.4-mini` / `gpt-5.3-codex-spark` are added; default follows. - The picker no longer lists a built-in entry the harness has retired unless it is the selected value. The API still returns such entries flagged deprecated, and the picker labels a selected one "not in CLI list", so a saved preference is neither hidden nor mistaken for a live model. - Claude menu labels are expanded from the CLI's description so they stand apart from the built-in entries: "Fable" becomes "Fable 5 [1M]", "Sonnet" becomes "Sonnet 5", "Default (recommended)" becomes "Default (Opus 5 with 1M context)". Descriptions show as tooltips. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBqmTvJRhyysMvMvL6cp7x * fix(models): fold built-in entries behind a toggle once the harness has answered With the CLI menu and the compiled-in table shown side by side, the same Claude model appeared twice ("Fable 5 [1M]" from the CLI next to "Fable 5" from the table, likewise Fable 5.1). Mark table entries builtIn in the discovery payload and have the picker show, like Claude Code's own /model menu, only what the harness reports plus the configured and selected models; the rest sit behind a "show N more built-in models" row so an explicit version such as Opus 4.6 is still one click away. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBqmTvJRhyysMvMvL6cp7x * fix(models): show only the harness's list once it has answered The built-in table is a fallback for when discovery is unavailable, not a second list to browse: drop the "show more built-in models" toggle and list only what the harness reported, plus the currently selected value so a saved preference never vanishes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBqmTvJRhyysMvMvL6cp7x * fix(models): close the model picker on Escape An open picker that ignores Escape stays in the way of the next click, which is how a stray selection can land on the wrong row. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBqmTvJRhyysMvMvL6cp7x --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Summary
claude-opus-5to the Claude model selector