feat: add /swarm-model command for subagent model override#589
Conversation
🦋 Changeset detectedLatest commit: 5a3e3c2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f4ddc0d07
ℹ️ 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".
| } | ||
|
|
||
| try { | ||
| await host.harness.setConfig({ subAgentModel: alias }); |
There was a problem hiding this comment.
Update the active session when changing swarm model
When /swarm-model is used after a session is already active, this only persists the new value to config.toml and updates TUI state; existing Session/Agent instances keep the config object they were constructed with, and the new subagent path reads parent.kimiConfig?.subAgentModel when spawning. As a result, the command can report Swarm subagents will use <alias> while swarms in the current session still use the old/inherited model until a reload or new session. Please also update the live session/agent runtime state, or make the subagent host read the refreshed config.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 67d4ef82e5
ℹ️ 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".
| // Push the updated config to the live session so active agents pick it up | ||
| const session = host.session; | ||
| if (session !== undefined) { | ||
| await session.reloadSession(); |
There was a problem hiding this comment.
Block clearing swarm model while streaming
When /swarm-model off is entered while a turn is still running, this path is allowed by the command registry (availability: 'always') and unlike setSwarmModel it does not check streamingPhase before calling session.reloadSession(). The core reload path rejects active sessions with TURN_AGENT_BUSY, and because clearSwarmModel is launched with void clearSwarmModel(host) that rejection is not caught by the slash-command dispatcher after the config has already been written. Please apply the same idle guard/catch here so clearing the override during streaming reports a normal error instead of leaving the UI/runtime out of sync or surfacing an unhandled rejection.
Useful? React with 👍 / 👎.
| } | ||
|
|
||
| export function handleSwarmModelCommand(host: SlashCommandHost, args: string): void { | ||
| const alias = args.trim().toLowerCase(); |
There was a problem hiding this comment.
Preserve model alias casing in /swarm-model
Model aliases are case-sensitive config keys (models is a string-keyed record, and /model checks availableModels[alias] without lowercasing), but this command lowercases the user's argument before lookup and persistence. With a valid custom alias such as ClaudeSonnet, /swarm-model ClaudeSonnet looks for availableModels['claudesonnet'] and reports it as unknown, making direct selection impossible for mixed-case aliases. Keep the original trimmed alias for lookup and only compare a lowercased copy for the off subcommand.
Useful? React with 👍 / 👎.
Related Issue
No existing issue — this was requested directly as a user need.
Problem
When using swarm mode, all subagents inherit the main agent's model. Users running expensive models (e.g.,
deepseek-v4-pro) as their main model pay that cost for every parallel subagent too, even for simple sub-tasks that could run on a cheaper model (e.g.,deepseek-v4-flash). There is no way to configure a separate model for subagents.What changed
Added a
/swarm-modelslash command and asub_agent_modelconfig key that lets users set a different model for all swarm subagents.Backend (
packages/agent-core)subAgentModel: string | nullto the config schema and TOML serialization.subagent-host.ts(configureChild,resume,retry,startBtw) to readparent.kimiConfig?.subAgentModelinstead of the hardcodedparent.config.modelAlias. Falls back to the parent model when not set.TUI (
apps/kimi-code)/swarm-modelcommand with model picker support (reuses existingTabbedModelSelectorComponent)./swarm-model→ opens picker;/swarm-model <alias>→ pre-selects alias;/swarm-model off→ clears override.subAgentModelinAppStateon login, logout, and config reload.Docs
/swarm-modelto slash commands reference (en + zh).sub_agent_modelto config files reference (en + zh).Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.