Skip to content

feat(delegate): per-task model and provider override for delegate_task subagents#25026

Closed
ozdalva wants to merge 1 commit into
NousResearch:mainfrom
ozdalva:feat/delegate-task-per-task-model
Closed

feat(delegate): per-task model and provider override for delegate_task subagents#25026
ozdalva wants to merge 1 commit into
NousResearch:mainfrom
ozdalva:feat/delegate-task-per-task-model

Conversation

@ozdalva

@ozdalva ozdalva commented May 13, 2026

Copy link
Copy Markdown

Summary

Adds optional model and provider parameters to delegate_task — both at the top level (single-task mode) and per task item in the tasks array (batch mode). When set, these override the global delegation.model / delegation.provider for that specific subagent only. When omitted, behaviour is identical to current releases.

This enables the smart model routing pattern: use a cheap/fast model for simple tasks and an expensive/powerful model for complex reasoning, all within a single delegate_task call.

Problem

delegate_task currently assigns every subagent the same model/provider pair from delegation.* config. There is no way to route different subtasks to different models without making multiple delegation calls and manually switching config between them. This forces a trade-off: configure delegation for expensive high-quality work (wasting tokens on trivial summaries), or for cheap/fast work (getting poor results on complex analysis).

Changes

tools/delegate_tool.py (+43 lines)

  1. Signature: Added model: Optional[str] = None and provider: Optional[str] = None parameters to delegate_task().

  2. Single-task path (line ~2000): Builds the task dict with model and provider keys only when explicitly provided, so existing callers see zero diff:

    st = {"goal": goal, "context": context, "toolsets": toolsets, "role": top_role}
    if model: st["model"] = model
    if provider: st["provider"] = provider
  3. Batch loop (lines ~2048-2055): Per-task model/provider override the global delegation credentials with a simple fallback chain:

    model=t.get("model") or creds["model"],
    override_provider=t.get("provider") or creds["provider"],
  4. Schema (DELEGATE_TASK_SCHEMA): Added model and provider fields to both the top-level properties block and the tasks.items properties block, with clear descriptions that document they override delegation.model / delegation.provider.

  5. Registration: Propagates the new parameters from args to the registry.register() call.

tests/tools/test_delegate.py (+15 lines)

New test test_per_task_model_override follows the existing mocking pattern (@patch("run_agent.AIAgent") + _make_mock_parent): verifies that a task with "model": "deepseek-v4-pro" passes that model through to the child agent constructor.

Total diff: 2 files changed, 55 insertions, 5 deletions

Backward Compatibility

Fully backward compatible. Both new parameters are optional:

  • model/provider are not in the schema's required list
  • Single-task mode: when neither is provided, the task dict is built exactly as before
  • Batch mode: each task item without these keys falls through to creds["model"] / creds["provider"] as before
  • No changes to config.yaml schema, no migration needed

Use Case

delegate_task(
    tasks=[
        {"goal": "Search for relevant docs", "model": "deepseek-v4-flash"},           # cheap
        {"goal": "Analyze the architecture", "model": "deepseek-v4-pro"},             # powerful
        {"goal": "Summarize the findings", "model": "deepseek-v4-flash", "provider": "deepseek"},  # explicit provider too
    ],
    parent_agent=agent,
)

Validation

  • python -c "ast.parse(open(...))" → clean on both changed files
  • pytest tests/tools/test_delegate.py → new test follows established mocking pattern and passes alongside existing 128 tests

Related Issues

Closes #18591 — Feature: Per-task model override for delegate_task subagents
Closes #15789 — feat: per-task model/provider overrides in delegate_task
Closes #17732 — Feature: per-call model/provider override in delegate_task
Closes #23467 — delegate_task model parameter silently discarded — subagents always inherit parent model

Add optional model and provider fields to delegate_task so each
subagent task can specify its own model/provider independently,
overriding the global delegation config for that task only.

Works for single-task (goal) and batch (tasks[]) modes.
Includes schema updates and a focused test verifying per-task
model override in batch mode.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have tool/delegate Subagent delegation labels May 13, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #3172, #16163, and #17756 — all implement per-task model/provider overrides for delegate_task. See also tracking issue #15789 (dup of #14974).

@ozdalva

ozdalva commented May 13, 2026

Copy link
Copy Markdown
Author

Closing as duplicate — there are 10+ other PRs with the same feature (#6771, #7586, #12715, #16163, #17581, #17718, #20000, #20779, #23266, #23649, #23769, #12794). Thanks anyway!

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

Labels

P3 Low — cosmetic, nice to have tool/delegate Subagent delegation type/feature New feature or request

Projects

None yet

2 participants