Skip to content

feat: allow model selection for claude code chats#27155

Open
ibetitsmike wants to merge 3 commits into
mike/claude-code-chat-runtimefrom
mike/claude-code-model-selection
Open

feat: allow model selection for claude code chats#27155
ibetitsmike wants to merge 3 commits into
mike/claude-code-chat-runtimefrom
mike/claude-code-model-selection

Conversation

@ibetitsmike

Copy link
Copy Markdown
Collaborator

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

  • Selection is explicit per create/send/edit (model_config_id); an absent id means the runtime default. The server never falls back to chats.last_model_config_id on runtime chats, so the admin default stays reachable after any pick; that column remains a client restore hint.
  • The engine resolves the model from the triggering user message, so a pick queued behind older messages cannot retroactively apply to them. Resolution chain: message selection, then the admin chat_runtime_configs.model pin, then the adapter default.
  • The applied model reaches the adapter via the per-spawn ANTHROPIC_MODEL env injection (the G1 probe in claudecode/SPIKE.md verified env wins over a resumed session's stored model, so ACP session/set_config_option stays unused). ANTHROPIC_API_KEY/ANTHROPIC_BASE_URL follow the selected config's provider, with a logged fallback to another Anthropic provider's key when the selected one has none.
  • Assistant messages are stamped with the applied model_config_id for 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.
  • Non-Anthropic, disabled, or unknown config ids are rejected with 400 on create/send/edit.

Validation

  • chatd integration tests cover env resolution (pick overrides pin, disabled falls back, no pin omits env), credential routing, stamping/zero cost, and create/send/edit validation.
  • Storybook play tests cover the Default row, Anthropic-only filtering, clearing, and create-form submission payloads.
  • Dogfooded on a local dev instance: verified the Anthropic-only picker + Default row on create and chat pages, model_config_id on create/send payloads and DB rows, ANTHROPIC_MODEL=claude-sonnet-4-5 in the adapter process env for a picked turn vs claude-haiku-4-5 (admin pin) after clearing to Default, and the stamped, zero-cost assistant messages.

This PR was authored by Mux (an AI coding agent) working on Mike's behalf.

…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.
@github-actions

Copy link
Copy Markdown

Docs preview

📖 View docs preview for docs/reference/api/chats.md

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant