Skip to content

feat(delegate): per-task model/provider override in delegate_task tasks array #34764

@DJNing

Description

@DJNing

Problem

When using delegate_task with a tasks array, all subagents run the same model/provider (delegation.model / delegation.provider in config.yaml). There is no way to route a specific subagent to a different model or provider for that one task.

Example use cases:

  • A research subagent that needs a reasoning model (deepseek-reasoner) alongside a coding subagent that needs a fast model (glm-5.1)
  • Routing web-scraping subagents to a cheap provider while keeping analysis subagents on the primary model

Proposed Schema

Add optional model and provider fields to each item in the tasks array of delegate_task:

tasks: [{
  "goal": str,
  "context": str?,
  "toolsets": [str]?,
  "model": str?,         # override model name only
  "provider": str?,      # override provider (re-resolves full creds)
  "role": "leaf" | "orchestrator"?,
  ...
}]

Semantics:

Override What happens
model only Sends a different model name to the existing delegation provider/endpoint
provider only Re-resolves the full credential bundle (base_url, api_key, api_mode) for that provider, uses its default model
Both Re-resolves provider creds + overrides the model name within it

Implementation sketch

In tools/delegate_tool.py:

  1. Replace the single global creds resolution (~line 1995) with per-task resolution. When t["provider"] differs from the delegation default, call _resolve_delegation_credentials() again with the overridden provider to get the full credential bundle.

  2. Feed per-task creds into _build_child_agent (~line 2061-2073). The existing override paths (override_provider, override_base_url, override_api_key, override_api_mode) already handle this — they just need the per-task values instead of a single global set.

The agent loop and AIAgent.__init__ need zero changes since _build_child_agent already resolves effective_model = model or parent_agent.model and effective_provider = override_provider or parent_agent.provider.

Edge cases

  • model without provider: only changes the model name sent to the existing endpoint — useful for swapping between models on the same provider (e.g. deepseek-chat vs deepseek-reasoner)
  • Unknown provider: _resolve_delegation_credentials raises ValueError, surfaces as a clean tool error
  • Same provider as default: no redundant re-resolution needed (compare before calling the resolver)
  • provider override auto-derives api_mode via _detect_api_mode_for_url, same as the top-level path

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havecomp/agentCore agent loop, run_agent.py, prompt buildertool/delegateSubagent delegationtype/featureNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions