fix(models): per-provider discovery state, Fable 5.1 in the picker, Codex effort from the CLI - #219
fix(models): per-provider discovery state, Fable 5.1 in the picker, Codex effort from the CLI#219bbsngg wants to merge 5 commits into
Conversation
…e 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
|
Browser verification completed after the extension reconnected (dev server running from this branch against the real database):
|
- 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
|
Second commit (
Verified in the browser on this branch: Codex dropdown shows exactly the six CLI models, no duplicates; Claude dropdown shows the labels above followed by the built-ins (Fable 5.1 [1M], Fable 5.1, Opus 5, Fable 5, Opus, Opus (Plan Mode Only), Sonnet [1M], Opus 4.8/4.7/4.6), every label distinct. 173/173 tests, typecheck clean, CI green. |
…as 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
|
Third commit ( Verified in the browser: the Claude dropdown shows Default (Opus 5 with 1M context), Opus 5 with 1M context, Fable 5 [1M], Sonnet 5, Haiku 4.5, Fable 5.1 [1M] and a "Show 9 more built-in models" toggle; Codex shows its six CLI models with the retired ones folded. 173/173 tests, typecheck clean, CI green. |
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
|
Fourth commit ( |
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
Follow-up to #213 / #216 for three problems found while using the picker on
main.1. Provider switch corrupted the saved model (bug)
useHarnessModelsset its state asynchronously, so for one render after a provider switch it still held the previous provider's list whileprovideralready named the new one.ChatComposer's rescue effect then saw the Claude model "missing" from Codex's list and replaced it with Codex's default:localStorage['claude-model']ended up asgpt-5.6-sol, and every new Claude session would have failed.useChatProviderStatedrops a stored model that cannot belong to its slot (agpt-*underclaude-model, aclaude-*/alias undercodex-model) and falls back to the default, so anyone already affected recovers on next load. Verified in the browser: the corrupted value was replaced byclaude-fable-5.2. Fable 5.1 was not selectable
The Claude probe runs with
settingSources: []so no hooks fire. That also hides the model configured in~/.claude/settings.json, and that is exactly where the CLI's own/modelmenu gets Fable 5.1 from (0.3.226's base menu lists Fable 5, not 5.1). Discovery now readsmodelfrom the user settings file (honouringCLAUDE_CONFIG_DIR) andANTHROPIC_MODEL, and offers it the way the CLI does.claude-fable-5-1/claude-fable-5-1[1m]are also in the built-in list so they are available even with discovery off. Duplicate CLI display names ("Fable" for both 5 and 5.1) are disambiguated from the description.Real probe output on this machine after the change:
default,opus[1m],claude-fable-5[1m]→ Fable,sonnet,haiku,claude-fable-5-1[1m]→ Fable 5.1 [1M], then the built-ins.3. Codex reasoning-effort selector missing for discovered models
Support was a table keyed by exact model name;
gpt-5.6-sol,gpt-5.4-mini,gpt-5.3-codex-sparkfell to "default only" and the selector disappeared. Codex'smodel/listreportssupportedReasoningEffortsanddefaultReasoningEffortper model, so discovery now carries them through and the selector, its gating, and the saved-effort normalisation use that list first, with the table as fallback. Theultraeffort the CLI offers (gpt-5.6-sol/-terra) is added to the UI and en/zh-CN/ko locales.Measured:
gpt-5.6-sollow/medium/high/xhigh/max/ultra (default low),gpt-5.6-lunalow…max,gpt-5.5/5.4/5.4-mini/5.3-codex-sparklow…xhigh.useHarnessModelsmoved fromChatComposerup toChatInterfaceso composer state (normalisation) and the picker share one answer.Verification
npx vitest run: 172/172 (new tests for label disambiguation, configured-model injection,ANTHROPIC_MODEL, Codex effort mapping, discovered-effort precedence,labelForClaudeModelId).npm run typecheckclean.🤖 Generated with Claude Code
https://claude.ai/code/session_01NBqmTvJRhyysMvMvL6cp7x