feat: allow model selection for claude code chats#27155
Conversation
…upe frontend option plumbing - EditMessage reuses resolveSendMessageModelConfigID instead of reimplementing runtime-specific model config validation. - AgentChatPage derives selectableModelOptions once instead of repeating the isClaudeCodeChat ternary at four call sites. - ModelSelector computes the trigger label once for aria-label and the visible text. - filterAnthropicModelOptions compares against a typed AIProviderType constant. - AgentCreateForm handleSend comment updated to reflect the optional model pick on runtime chats.
Docs preview📖 View docs preview for |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: da4f6eef62
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| model_config_id: isClaudeCodeChat | ||
| ? undefined | ||
| : editSelectedModelConfigID, | ||
| model_config_id: editSelectedModelConfigID, |
There was a problem hiding this comment.
Preserve the Default choice when editing Claude Code messages
When editing a Claude Code message that already has a model_config_id, choosing the new Default row makes effectiveSelectedModel empty, so editSelectedModelConfigID becomes undefined and this request omits model_config_id. The edit path interprets an omitted model as “preserve the original,” so the user-visible Default selection cannot actually clear the per-message model and the regenerated turn still uses the old model. This needs an explicit clear signal or equivalent handling for Claude Code edits.
Useful? React with 👍 / 👎.
Let users pick a model per message on Claude Code chats. The composer reuses the existing model picker, filtered to enabled Anthropic model configs, with an explicit "Default" row that clears the pick.
How it works
model_config_id); an absent id means the runtime default. The server never falls back tochats.last_model_config_idon runtime chats, so the admin default stays reachable after any pick; that column remains a client restore hint.chat_runtime_configs.modelpin, then the adapter default.ANTHROPIC_MODELenv injection (the G1 probe inclaudecode/SPIKE.mdverified env wins over a resumed session's stored model, so ACPsession/set_config_optionstays unused).ANTHROPIC_API_KEY/ANTHROPIC_BASE_URLfollow the selected config's provider, with a logged fallback to another Anthropic provider's key when the selected one has none.model_config_idfor per-model token analytics; their cost intentionally stays zero. A selection that became disabled/deleted by turn time falls back to the admin pin, unstamped, with a warning log.Validation
chatdintegration tests cover env resolution (pick overrides pin, disabled falls back, no pin omits env), credential routing, stamping/zero cost, and create/send/edit validation.model_config_idon create/send payloads and DB rows,ANTHROPIC_MODEL=claude-sonnet-4-5in the adapter process env for a picked turn vsclaude-haiku-4-5(admin pin) after clearing to Default, and the stamped, zero-cost assistant messages.