hermes - 💡(How to fix) Fix delegate_task() lacks model and provider parameters — prevents per-call subagent routing

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

Three layers are missing:

Code Example

def delegate_task(
    goal: Optional[str] = None,
    context: Optional[str] = None,
    toolsets: Optional[List[str]] = None,
    tasks: Optional[List[Dict[str, Any]]] = None,
    max_iterations: Optional[int] = None,
    # ← No model parameter
    # ← No provider parameter
    ...
)

---

handler=lambda args, **kw: delegate_task(
    goal=args.get("goal"),
    context=args.get("context"),
    toolsets=args.get("toolsets"),
    tasks=args.get("tasks"),
    max_iterations=args.get("max_iterations"),
    acp_command=args.get("acp_command"),
    acp_args=args.get("acp_args"),
    role=args.get("role"),
    # ← No model
    # ← No provider
)

---

child = _build_child_agent(
    ...
    model=creds["model"],  # ← Always from config, never from caller or task
    ...
)

---

def delegate_task(
    ...
    model: Optional[str] = None,
    provider: Optional[str] = None,
    ...
)

---

if provider and isinstance(provider, str) and provider.strip():
    creds["provider"] = provider.strip()
if model and isinstance(model, str) and model.strip():
    creds["model"] = model.strip()

---

task_model = t.get("model")
effective_model = creds["model"]
if task_model and isinstance(task_model, str) and task_model.strip():
    effective_model = task_model.strip()
elif model and isinstance(model, str) and model.strip():
    effective_model = model.strip()
RAW_BUFFERClick to expand / collapse

delegate_task() lacks model and provider parameters — prevents per-call subagent routing

Problem

The delegate_task() function in tools/delegate_tool.py has no model or provider parameters — neither in its function signature, its OpenAI function-calling schema (DELEGATE_TASK_SCHEMA), nor its handler registration.

This makes it impossible to route a specific subagent to a different model/provider than what's configured globally in config.yaml. All delegation routing is locked to the persistent config or parent inheritance, with no per-call override.

Root Cause

Three layers are missing:

1. Function signature (line ~1918)

def delegate_task(
    goal: Optional[str] = None,
    context: Optional[str] = None,
    toolsets: Optional[List[str]] = None,
    tasks: Optional[List[Dict[str, Any]]] = None,
    max_iterations: Optional[int] = None,
    # ← No model parameter
    # ← No provider parameter
    ...
)

2. Function-calling schema (line ~2660)

DELEGATE_TASK_SCHEMA defines goal, context, toolsets, tasks, role, acp_command, acp_args — but no model or provider properties. The JSON validator strips them if the LLM emits them.

3. Handler registration (line ~2786)

handler=lambda args, **kw: delegate_task(
    goal=args.get("goal"),
    context=args.get("context"),
    toolsets=args.get("toolsets"),
    tasks=args.get("tasks"),
    max_iterations=args.get("max_iterations"),
    acp_command=args.get("acp_command"),
    acp_args=args.get("acp_args"),
    role=args.get("role"),
    # ← No model
    # ← No provider
)

4. Hardcoded model resolution (line 2066)

In the task loop:

child = _build_child_agent(
    ...
    model=creds["model"],  # ← Always from config, never from caller or task
    ...
)

The per-task schema (inside tasks array) also lacks model/provider fields, so batch-mode per-task routing is equally broken (see #17685, #17718).

Impact

  • Cost control: Cannot route simple tasks to cheap models while reserving premium models for complex reasoning
  • Capability routing: Cannot spawn a vision-capable subagent for image tasks while the parent uses a text-only model
  • A/B testing: Cannot test different models on subtasks without changing global config
  • Cross-provider: Cannot send one subtask to a different provider without reconfiguring the entire agent

Proposed Fix

1. Add parameters to function signature

def delegate_task(
    ...
    model: Optional[str] = None,
    provider: Optional[str] = None,
    ...
)

2. Wire into credential resolution

After creds = _resolve_delegation_credentials(cfg, parent_agent):

if provider and isinstance(provider, str) and provider.strip():
    creds["provider"] = provider.strip()
if model and isinstance(model, str) and model.strip():
    creds["model"] = model.strip()

3. Support per-task overrides in batch mode

task_model = t.get("model")
effective_model = creds["model"]
if task_model and isinstance(task_model, str) and task_model.strip():
    effective_model = task_model.strip()
elif model and isinstance(model, str) and model.strip():
    effective_model = model.strip()

4. Update schema

Add model and provider to both the top-level schema properties and the per-task object properties.

5. Override Priority (after fix)

  1. Per-tasktasks[i].model / tasks[i].provider (highest)
  2. Per-calldelegate_task(model=..., provider=...)
  3. Configdelegation.model / delegation.provider in config.yaml
  4. Parent inheritance — parent agent's model/provider (lowest)

Relation to Existing Issues

IssueStatusRelation
#17685Open (P3)Per-task model override in batch mode ignored
#17718Open1-line per-task model fix (t.get("model") or creds["model"])
#5012OpenFeature request for model/provider params on delegate_task
#23266OpenPer-task model + provider overrides
#32671Open (Duplicate)_load_config() bug — prerequisite for this feature to work

Impact

  • Breaking: No. Additive change with default None values — existing callers unaffected.
  • Backwards compatible: No migration required.

Willing to Contribute

I have the diagnosis, tested the gap, and can submit a PR. Please advise if you'd prefer this consolidated with existing PRs (#17718, #5012 cluster) or as a standalone contribution.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix delegate_task() lacks model and provider parameters — prevents per-call subagent routing