Skip to content

Allow subagents to use different models/providers/reasoning levels than their parent #299

Description

@kindralai

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

  • spawn_subagent tool accepts optional model and provider parameters
  • Subagent uses the specified model/provider when provided, inherits parent's config otherwise
  • Allowed-models guardrail in config prevents the agent from spawning subagents on unconfigured providers
  • API key resolves correctly for the chosen provider
  • Admin UI: Allowed models field in the Tools tab (subagent card)
  • Backward compatible — existing spawns with no model override work identically

Metadata

Metadata

Assignees

No one assigned

    Labels

    newNew additiontodoPlanned / not yet started

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions