Skip to content

feat(delegation): dynamic provider-aware subagent model router (default OFF) - #67346

Closed
loes5050 wants to merge 2 commits into
NousResearch:mainfrom
loes5050:feat/phase03-model-router
Closed

loes5050 wants to merge 2 commits into
NousResearch:mainfrom
loes5050:feat/phase03-model-router

Conversation

@loes5050

Copy link
Copy Markdown
Contributor

Summary

Adds an optional, provider-aware dynamic model router for subagent delegation (default OFF), plus two reliability fixes on the same path:

  1. failed explicit tasks[].provider/model no longer falls back to parent auth with a mismatched model (401),
  2. safe upper caps on max_concurrent_children / max_spawn_depth (default ON, byte-stable for normal configs).

Root cause

delegate_task could only inherit the parent model or honor an explicit override — no availability/capability-aware choice and no per-task fallback chain. Separately, a failed explicit override merged the model onto parent credentials (wrong provider auth → 401), and concurrency/depth knobs had no hard ceiling against exponential fan-out.

Fix

  • agent/model_router.py: deterministic, stdlib-only router; enabled default false; scores from injected inventory/catalog/pricing/credential gates — no network at import, no fixed model brand names.
  • tools/delegate_tool.py: (creds, fallback_chain) with precedence explicit → forced delegation.provider/base_url → router → inherit; schema exposes tasks[].model + tasks[].provider; override_fallback_chain into _build_child_agent.
  • 401 fix: explicit provider resolve failure → ValueErrortool_error (model-only override still inherits parent auth).
  • Safe caps: delegation.enforce_safe_caps (default true) clamps concurrent children (hard cap 16) and spawn depth (hard cap 3); opt-out via false or higher *_hard_cap.
  • hermes_cli/config.py: delegation.model_router block default OFF + cap knobs documented in cli-config.yaml.example.

Footprint

Focused on delegation routing/reliability. Feature off by default for the router; caps only clamp absurd values under default config.

Validation

pytest tests/agent/test_model_router.py \
       tests/tools/test_delegate_model_router_integration.py \
       tests/tools/test_delegate.py -o addopts=
→ 205 passed
Includes REAL end-to-end router test (unmocked select_delegation_model) + 401/caps regressions.
Zero live API calls (inventory/catalog/pricing/bundle mocked at the boundary).

Tests

Unit router suite + integration (schema, override, forced provider, fallback chain, E2E unmocked select) + full test_delegate*.py regression.

loes5050 added 2 commits July 19, 2026 10:04
…lt OFF)

- Add agent/model_router.py: deterministic, stdlib-only provider/model router (default OFF)
- Replace fixed-name delegation.task_routing with delegation.model_router config
- Precedence: explicit tasks[].model/provider > forced delegation.provider/base_url > router > inherit
- Add tasks[].provider to delegate schema; explicit overrides bypass the router
- Wire per-task fallback chain into _build_child_agent (override_fallback_chain)
- Tests: 15 integration incl. REAL end-to-end router test (unmocked select_delegation_model)
- No live API calls; no fixed model brand names in production path
…an-out caps

Two reliability fixes in delegate_tool:

1) 401 fix: an explicit tasks[].provider/model that fails to resolve no longer merges the model onto the PARENT's credentials (which ran a foreign model against the wrong provider's auth -> 401). It now raises ValueError -> tool_error. Legitimate model-only override still inherits parent auth.

2) Safe caps: delegation.enforce_safe_caps (default true) clamps max_concurrent_children (hard cap 16) and max_spawn_depth (hard cap 3), one-shot warnings, byte-stable for normal config (3-10 / depth 1-3). enforce_safe_caps:false restores unbounded legacy.

Regression tests in tests/tools/test_delegate.py + test_delegate_model_router_integration.py.
@alt-glitch alt-glitch added type/feature New feature or request comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard tool/delegate Subagent delegation area/config Config system, migrations, profiles P3 Low — cosmetic, nice to have needs-decision Awaiting maintainer decision before any implementation sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Jul 19, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

This was generated by AI during triage.

Related to the closed #66613 resubmission and the earlier delegation-routing cluster. This is the active branch, not a duplicate of closed predecessors; its routing policy and default cap changes need a maintainer decision.

@teknium1

Copy link
Copy Markdown
Collaborator

Thanks for the careful opt-in implementation and the focused test coverage.

This automated hermes-sweeper review is closing this under the standing delegation-model-routing policy.

  • Current main deliberately keeps individual delegate_task calls from selecting subagent models; the live tool contract directs users to delegation.provider / delegation.model in config.yaml (tools/delegate_tool.py:3325).
  • The supported configuration-level provider/model resolution is already implemented in tools/delegate_tool.py:3056-3181.
  • This PR's tasks[].model / tasks[].provider API and automatic provider-aware router (7592d53babe5) are the policy-prohibited direction, even when default-off.
  • The default safe-cap change also reverses the deliberate no-ceiling design adopted in d41427504 (feat(delegation): uncap max_spawn_depth).
  • The related resubmission feat(delegation): dynamic provider-aware subagent model router (default OFF) #66613 was closed on the same policy, following the maintainer decision on feat(delegate_task): per-subagent model/provider overrides + model observability plugin #12794.

For globally pinning subagent routing, please use delegation.provider and delegation.model in config.yaml.


Closed as not-planned per standing maintainer policy (delegation-model-routing). This is a design-direction decision, not a code-quality judgment.


Closed as not-planned per standing maintainer policy (delegation-model-routing). This is a design-direction decision, not a code-quality judgment — see the Contribution Rubric in AGENTS.md for what the project is looking for. If you believe this policy was misapplied to your change, comment here and a maintainer will take a look.

@teknium1 teknium1 closed this Jul 19, 2026
@teknium1 teknium1 added the sweeper:not-planned Sweeper: closed per standing maintainer policy (design direction) label Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have sweeper:not-planned Sweeper: closed per standing maintainer policy (design direction) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades tool/delegate Subagent delegation type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants