Problem / Motivation
Currently, a subagent always uses the same model and reasoning level as the agent that spawned it. There is no way to tell a subagent "use this cheaper/faster model for this subtask" or "use a multimodal model for this frontend task" or "turn thinking off for this simple lookup."
This limits several useful patterns:
- Lead coordinator pattern — one agent with a powerful model (e.g. Claude Opus, high thinking) delegates subtasks to subagents that use cheaper models (e.g. DeepSeek Flash, low/no thinking) to keep costs down
- Task-specific models — a frontend-coding subtask works better with a multimodal model; a simple data extraction doesn't need one
- Fast fallback — when the main model is rate-limited or slow, spawn subagents on a faster provider
Current state
The spawn_subagent tool accepts thinking_effort (off/low/medium/high) but has no model or provider parameter. The subagent always inherits its parent's LLM configuration:
"thinking_effort": {
"type": "string",
"enum": ["off", "low", "medium", "high"],
"description": "How hard the subagent reasons each step. Omit to inherit your own level."
}
There is no equivalent model or provider field.
Proposed solution
1. Add model and provider parameters to spawn_subagent
New optional fields on the tool's input schema:
"model": {
"type": "string",
"description": "Model name the subagent should use (e.g. 'deepseek-v4-flash', 'claude-sonnet-4-5'). Omit to inherit the parent's model."
}
"provider": {
"type": "string",
"description": "Provider to use (e.g. 'deepseek', 'anthropic', 'openai'). Omit to inherit the parent's provider."
}
When both provider and model are omitted, the subagent inherits the parent's config (current behaviour, backward compatible).
2. Wire model selection into subagent execution
The subagent runner (core/subagents.py or the spawn path in agent.py) currently creates an LLMClient from the agent's own config. It should accept optional overrides:
llm = LLMClient(
provider=override_provider or agent.config.agent.llm_provider,
api_key=resolve_key_for(override_provider or agent.config.agent.llm_provider),
model=override_model or agent.config.agent.model,
thinking_level=override_thinking or agent.config.agent.thinking_level,
)
3. Allowed models config in the Tools tab
A new section in the subagent tool card under the Tools tab: Allowed models for subagents.
Since the agent chooses the model at spawn time and the LLM has full control over the tool call, we need guardrails to prevent the agent from sending the subagent to an unconfigured/unkeyed provider:
| Field |
Description |
subagents.allowed_models |
A list of provider:model pairs the subagent may use (e.g. ["deepseek:deepseek-v4-flash", "anthropic:claude-sonnet-4-5"]). Empty = unrestricted (parent's model only, since no override is set). |
When allowed_models is set and the subagent requests a model not on the list, the spawn is refused with a clear error.
Alternatively, simpler: a free-text field where you list provider:model entries, one per line. The tool description tells the model which models are available.
4. Example usage
Lead coordinator (Claude Sonnet, thinking=high):
"Research the competitor landscape for product X"
→ spawn_subagent(
task="Search for competitors...",
model="deepseek-v4-flash",
thinking_effort="low"
)
→ spawn_subagent(
task="Read the top 5 results and extract pricing...",
model="deepseek-v4-flash",
thinking_effort="low"
)
→ Synthesises the final report itself with full reasoning
Open questions
- Key resolution — if a subagent uses a different provider, how does it get the API key for that provider? The parent may have multiple API keys configured, but the subagent needs to be able to use the right one.
- Model validation — should the allowed list be validated at config save time (check the model string is well-formed) or only at spawn time?
- UI — the allowed models field needs to fit in the system-level Tools tab (subagent card). Should it be a simple textarea or a structured list with add/remove?
- Backward compatibility — subagents spawned without model/provider override must behave exactly as today.
Acceptance criteria
Problem / Motivation
Currently, a subagent always uses the same model and reasoning level as the agent that spawned it. There is no way to tell a subagent "use this cheaper/faster model for this subtask" or "use a multimodal model for this frontend task" or "turn thinking off for this simple lookup."
This limits several useful patterns:
Current state
The
spawn_subagenttool acceptsthinking_effort(off/low/medium/high) but has nomodelorproviderparameter. The subagent always inherits its parent's LLM configuration:There is no equivalent
modelorproviderfield.Proposed solution
1. Add
modelandproviderparameters tospawn_subagentNew optional fields on the tool's input schema:
When both
providerandmodelare omitted, the subagent inherits the parent's config (current behaviour, backward compatible).2. Wire model selection into subagent execution
The subagent runner (
core/subagents.pyor the spawn path inagent.py) currently creates anLLMClientfrom the agent's own config. It should accept optional overrides:3. Allowed models config in the Tools tab
A new section in the subagent tool card under the Tools tab: Allowed models for subagents.
Since the agent chooses the model at spawn time and the LLM has full control over the tool call, we need guardrails to prevent the agent from sending the subagent to an unconfigured/unkeyed provider:
subagents.allowed_modelsprovider:modelpairs the subagent may use (e.g.["deepseek:deepseek-v4-flash", "anthropic:claude-sonnet-4-5"]). Empty = unrestricted (parent's model only, since no override is set).When
allowed_modelsis set and the subagent requests a model not on the list, the spawn is refused with a clear error.Alternatively, simpler: a free-text field where you list
provider:modelentries, one per line. The tool description tells the model which models are available.4. Example usage
Open questions
Acceptance criteria
spawn_subagenttool accepts optionalmodelandproviderparameters