feat(delegate): per-call model/provider override for subagents#3172
feat(delegate): per-call model/provider override for subagents#3172ReqX wants to merge 3 commits into
Conversation
Allow delegate_task() to accept model and provider parameters at call time, overriding config.yaml delegation settings for each invocation. Resolution priority: task-level > top-level > config > parent inherit. Changes: - Add model/provider to delegate_task() signature and schema - Add model/provider to batch task items schema - Move credential resolution into per-task loop for per-task overrides - Extend _resolve_delegation_credentials() with override params - Add 12 tests for per-call override behavior (61 total, all passing)
…patch paths
run_agent.py has two direct call sites for delegate_task that bypass
the tool registry. These were not updated in the original commit and
silently dropped per-call model/provider overrides, causing all
subagents to fall back to the parent model.
Fix: pass model/function_args.get('model') and
provider/function_args.get('provider') at both call sites:
- _execute_tool_call() (single dispatch, ~line 4957)
- _execute_tool_calls_concurrent() (concurrent dispatch, ~line 5309)
Verified: glm-5, copilot/claude-sonnet-4.6, and batch mode all
correctly route to the specified model/provider.
…work Generic template for routing subagent tasks to the right model based on cost, capability, and complexity. Includes: - Decision framework: when to delegate vs handle yourself - 4-tier escalation model: cheap → standard → expensive → frontier - Cost-effective patterns: 'many for one', 'free stack', 'scout party' - Engaged vs autonomous mode: present tradeoffs when user is present, follow ladder strictly when not - providers-example.yaml: worked example catalog showing how to define models, costs, roles, user override phrases, and delegation patterns Designed to be provider-agnostic — users fill in their own catalog. Complements the per-call model/provider override feature in this PR (NousResearch#3172) by providing the strategic 'when and why' to the technical 'how'.
|
I was going to make a PR for this exact feature! Nice to see someone already did it :) This should get merged. |
|
Happy someone else would find it useful. It works quite well for the current limited scope. Was thinking of adding pre defined personas to it (something like OMO-slim), but kept it low for easier merge at this point, and you can prompt it anyway or add some more instructions to the skill. |
|
Another user request for this: "I'd like to change models of subagent by prompting alone — 'Launch subagent to do XYZ with model ABC'." The |
The #3719 si closed in favor of #3794
|
|
I honestly like #3794, but is it exclusive? The strength path is powerfull but giving us the opp to invoke a specific model is sure valuable for power users? I can rebase/check how it could fit in if there is interest. |
What do you mean by "Exclusive"?
Most certainly, at least in my case, I would like to the coding agent to be super powrful, and different from the design one. The default chat one would be different from both and so on. |
|
Overlooked the "Per-call model/provider override" in your PR ;) That combined with the "strength-routing" is great and makes my PR most likely obsolete (didnt look at the code, on the road). |
|
Great work on this — I opened #4833 which builds on the same
Happy to consolidate if maintainers prefer a single PR. |
Three interconnected features for multi-agent model routing: 1. delegate_task() — model/provider params (like PR NousResearch#3172) - model, provider: per-call overrides for all subagents in the call - Per-task model/provider in batch tasks array - Priority: per-task > call-level > delegation config > parent inherit 2. delegate_task() — skill/skills params (new) - skill: load a single named skill into the subagent's context - skills: load multiple skills - Skill SKILL.md content is prepended to the subagent system prompt - If SKILL.md frontmatter contains model: or provider: fields, those are used as the model/provider for that subagent call (overridable by the explicit model param) 3. config.yaml — supervisor_model / execution_model aliases - delegation.supervisor_model → model.default (main agent) - delegation.execution_model → delegation.model (all subagents) - Resolved during config load; explicit model.default / delegation.model always take precedence if both are set - Allows clear intent in config: delegation: supervisor_model: anthropic/claude-opus-4-6 execution_model: google/gemini-flash-1.5 Skill frontmatter example: --- name: code-review model: anthropic/claude-opus-4-6 provider: anthropic --- Usage example (agent tool call): delegate_task(goal='review this PR', skill='code-review') delegate_task(goal='summarise docs', model='google/gemini-flash-1.5') delegate_task(tasks=[ {goal: 'fast research', model: 'google/gemini-flash-1.5'}, {goal: 'careful code', model: 'anthropic/claude-opus-4-6'}, ]) Builds on / references PR NousResearch#3172 (ReqX) for the model/provider param idea.
Three interconnected features for multi-agent model routing: 1. delegate_task() — model/provider params (like PR NousResearch#3172) - model, provider: per-call overrides for all subagents in the call - Per-task model/provider in batch tasks array - Priority: per-task > call-level > delegation config > parent inherit 2. delegate_task() — skill/skills params (new) - skill: load a single named skill into the subagent's context - skills: load multiple skills - Skill SKILL.md content is prepended to the subagent system prompt - If SKILL.md frontmatter contains model: or provider: fields, those are used as the model/provider for that subagent call (overridable by the explicit model param) 3. config.yaml — supervisor_model / execution_model aliases - delegation.supervisor_model → model.default (main agent) - delegation.execution_model → delegation.model (all subagents) - Resolved during config load; explicit model.default / delegation.model always take precedence if both are set - Allows clear intent in config: delegation: supervisor_model: anthropic/claude-opus-4-6 execution_model: google/gemini-flash-1.5 Skill frontmatter example: --- name: code-review model: anthropic/claude-opus-4-6 provider: anthropic --- Usage example (agent tool call): delegate_task(goal='review this PR', skill='code-review') delegate_task(goal='summarise docs', model='google/gemini-flash-1.5') delegate_task(tasks=[ {goal: 'fast research', model: 'google/gemini-flash-1.5'}, {goal: 'careful code', model: 'anthropic/claude-opus-4-6'}, ]) Builds on / references PR NousResearch#3172 (ReqX) for the model/provider param idea.
Three interconnected features for multi-agent model routing: 1. delegate_task() — model/provider params (like PR NousResearch#3172) - model, provider: per-call overrides for all subagents in the call - Per-task model/provider in batch tasks array - Priority: per-task > call-level > delegation config > parent inherit 2. delegate_task() — skill/skills params (new) - skill: load a single named skill into the subagent's context - skills: load multiple skills - Skill SKILL.md content is prepended to the subagent system prompt - If SKILL.md frontmatter contains model: or provider: fields, those are used as the model/provider for that subagent call (overridable by the explicit model param) 3. config.yaml — supervisor_model / execution_model aliases - delegation.supervisor_model → model.default (main agent) - delegation.execution_model → delegation.model (all subagents) - Resolved during config load; explicit model.default / delegation.model always take precedence if both are set - Allows clear intent in config: delegation: supervisor_model: anthropic/claude-opus-4-6 execution_model: google/gemini-flash-1.5 Skill frontmatter example: --- name: code-review model: anthropic/claude-opus-4-6 provider: anthropic --- Usage example (agent tool call): delegate_task(goal='review this PR', skill='code-review') delegate_task(goal='summarise docs', model='google/gemini-flash-1.5') delegate_task(tasks=[ {goal: 'fast research', model: 'google/gemini-flash-1.5'}, {goal: 'careful code', model: 'anthropic/claude-opus-4-6'}, ]) Builds on / references PR NousResearch#3172 (ReqX) for the model/provider param idea.
Three interconnected features for multi-agent model routing: 1. delegate_task() — model/provider params (like PR NousResearch#3172) - model, provider: per-call overrides for all subagents in the call - Per-task model/provider in batch tasks array - Priority: per-task > call-level > delegation config > parent inherit 2. delegate_task() — skill/skills params (new) - skill: load a single named skill into the subagent's context - skills: load multiple skills - Skill SKILL.md content is prepended to the subagent system prompt - If SKILL.md frontmatter contains model: or provider: fields, those are used as the model/provider for that subagent call (overridable by the explicit model param) 3. config.yaml — supervisor_model / execution_model aliases - delegation.supervisor_model → model.default (main agent) - delegation.execution_model → delegation.model (all subagents) - Resolved during config load; explicit model.default / delegation.model always take precedence if both are set - Allows clear intent in config: delegation: supervisor_model: anthropic/claude-opus-4-6 execution_model: google/gemini-flash-1.5 Skill frontmatter example: --- name: code-review model: anthropic/claude-opus-4-6 provider: anthropic --- Usage example (agent tool call): delegate_task(goal='review this PR', skill='code-review') delegate_task(goal='summarise docs', model='google/gemini-flash-1.5') delegate_task(tasks=[ {goal: 'fast research', model: 'google/gemini-flash-1.5'}, {goal: 'careful code', model: 'anthropic/claude-opus-4-6'}, ]) Builds on / references PR NousResearch#3172 (ReqX) for the model/provider param idea.
|
Competing PR #12794. |
PR #3172 vs #127941. Core Feature ParityFunctionally identical resolution chain: 2. Merge-ReadinessVery obvious, right ;)
4. Test Coverage
#12794 is substantially better tested, especially for the failure modes that matter in production (router resolution mismatches, TTL stash bleed). Summary
Bottom line: #12794 is the better PR on every axis except scope minimalism, this is up to maintainers. Closing here. |

Summary
Allow
delegate_task()to acceptmodelandproviderparameters at call time, overridingconfig.yamldelegation settings for each invocation.Resolution priority: task-level > top-level > config.yaml > parent agent inherit
Motivation
Previously, subagent model/provider could only be set globally via
delegation.model/delegation.providerinconfig.yaml. This PR enables the LLM (or tool callers) to dynamically route specific subagents to different models/providers per invocation — e.g., delegate cheap fast tasks to Gemini Flash while keeping the parent on Claude.Changes
tools/delegate_tool.py(+74, -15)modelandprovideroptional params todelegate_task()signaturemodel/providerto top-level and batch task item schema properties_resolve_delegation_credentials()withoverride_model/override_providerparamsrun_agent.py(+4)modelandproviderthrough both hardcodeddelegate_taskdispatch paths_execute_tool_call()— the single tool call dispatch (~line 4957)_execute_tool_calls_concurrent()— the concurrent execution path (~line 5309)_delegate_task()directly.Without this fix, per-call
model/providerwere silently dropped, causing allsubagents to fall back to the parent model regardless of override values.
tests/tools/test_delegate.py(+249)TestPerCallModelProviderOverrideclass with 12 tests covering:skills/autonomous-ai-agents/model-routing-template/(new)providers-example.yamlwith a worked multi-provider catalogTest Results
61/61 tests pass (49 existing + 12 new, zero regressions)
Live verification: Tested against running Hermes instance with:
delegate_task(provider="zai", model="glm-5")— correctly routes to glm-5delegate_task(provider="copilot", model="claude-sonnet-4.6")— correctly routes through GitHub CopilotBackward Compatibility
Fully backward compatible. All new parameters are optional with
Nonedefaults. Existing behavior (config-based delegation, parent inheritance) is unchanged when no per-call overrides are provided.