Skip to content

feat(delegate): per-task model routing — model/provider/base_url/api_…#26736

Open
wuwuzhijing wants to merge 1 commit into
NousResearch:mainfrom
wuwuzhijing:hermes/hermes-f9c12b5b
Open

feat(delegate): per-task model routing — model/provider/base_url/api_…#26736
wuwuzhijing wants to merge 1 commit into
NousResearch:mainfrom
wuwuzhijing:hermes/hermes-f9c12b5b

Conversation

@wuwuzhijing

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds per-task model routing to delegate_task: top-level and per-task model / provider / base_url / api_key parameters. Each sub-agent can independently resolve full credentials (base_url, api_key, api_mode) by provider name, enabling a single delegate_task call to route different sub-agents to different models (e.g., DeepSeek reviewer + GLM reviewer + KIMI reviewer running in parallel).

  • delegate_task now accepts model, provider, base_url, api_key at both top-level and per-task level
  • Each task with a provider override calls _resolve_delegation_credentials to resolve full credentials independently
  • Top-level params serve as defaults for all tasks; per-task params override top-level
  • Updated DELEGATE_TASK_SCHEMA with new field definitions (top-level + tasks.items.properties)
  • Added 3 unit tests covering batch mode, single-task mode, and provider-only resolution

Related Issue

N/A

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • tools/delegate_tool.py — Extended function signature (+4 params), per-task credential resolution logic, DELEGATE_TASK_SCHEMA field definitions, registry.register param forwarding
    • Added: model, provider, base_url, api_key parameters (all optional, backward compatible)
    • Added: per-task credential resolution via _resolve_delegation_credentials when a task specifies its own provider
    • Added: 4 new field definitions in DELEGATE_TASK_SCHEMA at both top-level and tasks.items.properties
  • tests/tools/test_delegate.py — Added 3 test cases + schema field validation
    • test_per_task_model_routing_overrides_global_config — batch mode: 2 tasks with different providers/models
    • test_toplevel_model_routing_overrides_global_config — single-task mode: top-level routing overrides global config
    • test_per_task_provider_resolved_when_only_provider_and_model_given — provider name alone triggers full credential resolution (base_url/api_key/api_mode/acp_command)
    • test_schema_has_routing_keys — validates schema fields at both top-level and per-task level

How to Test

1. Unit Tests

cd hermes-agent
source venv/bin/activate
pytest tests/tools/test_delegate.py -x -q

Result: 130 passed in 38.07s, zero regressions.

All 3 new per-task routing tests pass:

tests/tools/test_delegate.py::TestDelegationProviderIntegration::test_per_task_model_routing_overrides_global_config PASSED
tests/tools/test_delegate.py::TestDelegationProviderIntegration::test_toplevel_model_routing_overrides_global_config PASSED
tests/tools/test_delegate.py::TestDelegationProviderIntegration::test_per_task_provider_resolved_when_only_provider_and_model_given PASSED

2. End-to-End Validation (CLI with real multi-model routing)

PYTHONPATH=. hermes-agent/venv/bin/python -m hermes_cli.main chat -q '
You must call delegate_task to create 3 sub-tasks at once:
1. DeepSeek task: provider=deepseek, model=deepseek-chat, goal="Reply only: I am DeepSeek"
2. GLM task: provider=zai, model=glm-4.5, goal="Reply only: I am GLM"
3. KIMI task: provider=Kimi / Moonshot China (Moonshot CN direct API), model=kimi-k2.6, goal="Reply only: I am KIMI"
Do nothing else. Summarize the results of all three tasks at the end.
'

Result:

✓ [1/3] Reply only: I am DeepSeek  (1.26s)  — tokens: in=13033, out=7
✓ [3/3] Reply only: I am KIMI      (2.6s)   — tokens: in=11375, out=10
✓ [2/3] Reply only: I am GLM       (3.9s)   — tokens: in=12984, out=120
┊ 🔀 delegate 3 parallel tasks  10.1s

All three sub-tasks correctly returned their respective model identities. Per-task model routing works as expected.

3. Credential Resolution Validation (no token consumption)

PYTHONPATH=. hermes-agent/venv/bin/python - <<'PY'
from tools.delegate_tool import _resolve_delegation_credentials
for cfg in [
    {"provider": "deepseek", "model": "deepseek-chat"},
    {"provider": "zai", "model": "glm-4.5"},
    {"provider": "moonshot", "model": "kimi-k2-0905-preview"},
]:
    creds = _resolve_delegation_credentials(cfg, parent_agent=None)
    print(f"{cfg['provider']:12s} | model={creds['model']:20s} | base_url={creds['base_url']} | api_key_present={bool(creds.get('api_key'))}")
PY

Result: All three providers correctly resolved to their respective base_url, api_key, and api_mode.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/tools/test_delegate.py -x -q and all 130 tests pass
  • I've added tests for my changes (3 new test cases + schema validation)
  • I've tested on my platform: Ubuntu 24.04, Python 3.11.15

Documentation & Housekeeping

  • I've updated relevant documentation — N/A (tool schema descriptions are inline in DELEGATE_TASK_SCHEMA)
  • I've updated cli-config.yaml.example — N/A (no new config keys)
  • I've updated CONTRIBUTING.md or AGENTS.md — N/A (no architecture changes)
  • I've considered cross-platform impact — N/A (pure Python, no platform-specific code)
  • I've updated tool descriptions/schemas — DELEGATE_TASK_SCHEMA updated with new fields at both top-level and per-task level

@wuwuzhijing wuwuzhijing force-pushed the hermes/hermes-f9c12b5b branch 2 times, most recently from 1c5b6c4 to fac0ed1 Compare May 16, 2026 04:02
…key overrides

- delegate_task 顶层和 per-task 均支持 model/provider/base_url/api_key 参数
- 每个子任务可按 provider 名称解析完整凭证(base_url、api_key、api_mode)
- 顶层参数作为所有子任务的默认值,per-task 参数覆盖顶层
- 新增 DELEGATE_TASK_SCHEMA 字段定义
- 新增 3 个单元测试覆盖 batch mode / single-task / provider-only resolution
- 在 scripts/release.py AUTHOR_MAP 中注册 wuyefeima9@gmail.com
@wuwuzhijing wuwuzhijing force-pushed the hermes/hermes-f9c12b5b branch from fac0ed1 to 4a7f494 Compare May 16, 2026 04:04
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/agent Core agent loop, run_agent.py, prompt builder tool/delegate Subagent delegation labels May 16, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This competes with at least 6 open PRs implementing the same per-task model routing feature: #20000, #25530, #17756, #23649, #3172, #7201. Tracking issue: #14974. Also related: #15789.

@wuwuzhijing

Copy link
Copy Markdown
Contributor Author

This competes with at least 6 open PRs implementing the same per-task model routing feature: #20000, #25530, #17756, #23649, #3172, #7201. Tracking issue: #14974. Also related: #15789.

got it

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

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P3 Low — cosmetic, nice to have tool/delegate Subagent delegation type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants