Skip to content

feat: add native delegation profiles - #41998

Open
martynovdenis312 wants to merge 7 commits into
NousResearch:mainfrom
martynovdenis312:feat/delegation-profiles-20260608-124016
Open

feat: add native delegation profiles#41998
martynovdenis312 wants to merge 7 commits into
NousResearch:mainfrom
martynovdenis312:feat/delegation-profiles-20260608-124016

Conversation

@martynovdenis312

@martynovdenis312 martynovdenis312 commented Jun 8, 2026

Copy link
Copy Markdown

Summary

Refreshes PR #41998 onto current main and keeps the branch clean for the existing native delegation profiles proposal.

Adds first-class delegation profiles under delegation.profiles so delegate_task can route child agents to a named provider/model/tool policy without shell wrappers or separate spawned Hermes processes.

Key behavior:

  • Adds top-level and per-task delegation_profile support.
  • Merges named profile config over base delegation config.
  • Resolves profile provider/model/base_url/api_key/api_mode via runtime provider resolution.
  • Supports toolsets defaults and allowed_toolsets hard caps per profile.
  • Ensures hard-capped profiles cannot be widened by requested toolsets, orchestrator role, composite toolsets, or Kanban auto-add.
  • Reloads persisted delegation config before resolving child config so gateway/CLI snapshots do not keep stale delegation settings.
  • Preserves delegate_task(..., parent_agent) positional compatibility while adding delegation_profile.
  • Adds file_readonly as a read-only subagent toolset option and documents the difference from writable file.
  • Documents named delegation profiles and subagent fallback-chain inheritance.

Also preserves the existing Qwen local-relay session identity fixes already on this PR branch:

  • Stable Qwen custom/local relay session metadata.
  • No impact on native Qwen Portal routing.
  • Regression coverage for preserving chat/parent session IDs.

Tests

  • uv run --frozen --with pytest --with pytest-timeout python -m pytest tests/tools/test_delegate.py tests/tools/test_delegate_config_reload.py tests/agent/test_qwen_session_state.py tests/test_toolsets.py -q
    • 193 passed
  • python3 -m compileall -q agent tools hermes_cli run_agent.py toolsets.py
  • uv run --frozen ruff check agent/chat_completion_helpers.py agent/conversation_loop.py agent/qwen_session_state.py agent/transports/chat_completions.py hermes_cli/config.py run_agent.py tools/delegate_tool.py toolsets.py tests/agent/test_qwen_session_state.py tests/test_toolsets.py tests/tools/test_delegate.py tests/tools/test_delegate_config_reload.py
    • All checks passed
  • git diff --check origin/main...HEAD
  • Static scan of added lines for obvious hardcoded secrets / shell execution / eval / pickle / SQL string formatting
    • clean
  • PR diff artifact check
    • no .omx/ultragoal files in the submitted diff

Review

Local review passes found and fixed issues before this refresh:

  • run_agent.AIAgent._dispatch_delegate_task() initially did not forward top-level delegation_profile; fixed and covered by regression test.
  • delegate_task signature initially inserted delegation_profile before parent_agent; fixed by keeping parent_agent in its previous positional slot and adding a back-compat regression test.
  • Documentation initially described writable file as read-only; fixed to document file_readonly separately.

Latest independent pre-push review: APPROVE, 8/10, no blockers.

Notes / residual risks

  • delegation.profiles.<name>.allowed_toolsets is intentionally fail-closed and exact-name based after known composite expansion.
  • If a selected profile targets a provider without credentials, delegation returns a clear provider/key error instead of silently falling back.
  • Batch mode intentionally does not let top-level toolsets leak into each task; use per-task toolsets or profile defaults.
  • Long-lived gateway sessions may need a fresh session/restart to expose newly added tool schema fields, matching existing Hermes tool-schema behavior.

@martynovdenis312
martynovdenis312 force-pushed the feat/delegation-profiles-20260608-124016 branch from 92ee508 to fc39953 Compare June 8, 2026 10:02
@liuhao1024

Copy link
Copy Markdown
Contributor

Verified — delegation profiles PR with focus on credential isolation and toolset cap enforcement.

Checked:

  1. Credential isolation (_resolve_delegation_profile_config): When a profile specifies provider without base_url, global base_url/api_key/api_mode are stripped from the merged config — prevents silent credential leakage from a direct-endpoint global into a named-provider profile. Correct.
  2. Toolset hard cap (_cap_toolsets_to_allowed): Fail-closed semantics — None allowed list means no cap (backward compat), but an explicit list is enforced via _expand_parent_toolsets which resolves includes recursively. A file_readonly cap correctly rejects file because file's tools (write_file, patch) are not a subset of file_readonly's tools. Sound.
  3. _normalize_toolset_list: Returns [] for non-list inputs (fail-closed). Good.
  4. Per-task profile override: delegation_profile on individual tasks overrides the top-level value, then _resolve_delegation_profile_config merges per-task. The error path (ValueError for unknown profile) is caught early before any child agent is created. Correct.
  5. _load_config priority flip: Persistent config (hermes_cli.config.load_config()) now takes precedence over CLI_CONFIG snapshot — fixes stale-config bug in long-lived gateway processes. Good change.
  6. Test coverage: 6+ new unit tests + 4+ integration tests covering profile merge, credential isolation, toolset cap, missing profile, and composite rejection. Thorough.

No issues found. Clean security model.

@alt-glitch alt-glitch added type/feature New feature or request tool/delegate Subagent delegation comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint area/config Config system, migrations, profiles P3 Low — cosmetic, nice to have labels Jun 8, 2026
Hermes Agent and others added 6 commits June 10, 2026 15:08
Keep the public delegate_task positional parent_agent slot stable while adding delegation_profile support, and cover the agent-loop dispatch path that bypasses the registry handler.\n\nTested: python -m pytest tests/tools/test_delegate.py tests/tools/test_delegate_config_reload.py -v -k 'DispatchDelegateTask or DelegationProfileConfig or DelegationProviderIntegration or config_reload or Profile'\nTested: python -m pytest tests/tools/test_delegate.py tests/tools/test_delegate_config_reload.py tests/tools/test_delegate_toolset_scope.py tests/tools/test_delegate_composite_toolsets.py tests/tools/test_delegate_subagent_timeout_diagnostic.py -q\nTested: python -m compileall -q run_agent.py tools/delegate_tool.py tests/tools/test_delegate.py tests/tools/test_delegate_config_reload.py hermes_cli/config.py\nTested: python -m ruff check run_agent.py tools/delegate_tool.py tests/tools/test_delegate.py tests/tools/test_delegate_config_reload.py hermes_cli/config.py\nTested: git diff --check
@martynovdenis312
martynovdenis312 force-pushed the feat/delegation-profiles-20260608-124016 branch from 520bb96 to 2b89947 Compare June 10, 2026 12:20
Keep subdirectory hint discovery anchored to the logical workspace path so project AGENTS.md files are loaded when users access symlinked project directories from inside the active working tree. Normalize parent traversal without resolving symlink targets, and keep direct outside paths rejected.

Tested: python -m pytest tests/agent/test_subdirectory_hints.py tests/agent/test_prompt_builder.py tests/agent/test_system_prompt.py -q -o 'addopts='

Tested: python -m py_compile agent/subdirectory_hints.py && git diff --check
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the substantial implementation and tests. There is one current-main design conflict and a scope issue.

Problems

  • Current main deliberately removed model-facing child toolset selection in ba0bc01d1 (feat(delegate): remove model-facing toolsets arg — subagents always inherit parent's). The enforced contract remains in tests/tools/test_delegate.py:68-89, and the schema at tools/delegate_tool.py:3391-3450 contains no per-call provider/model/profile selector. This PR's delegation_profile reintroduces that model-controlled routing/capability surface.
  • The branch also includes independent Qwen relay and symlinked workspace-hint changes (agent/qwen_session_state.py, agent/subdirectory_hints.py), which cannot be evaluated or salvaged independently while bundled with the delegation feature.

Suggested changes

  • Keep the current parent-inherited delegation capability model; do not add delegation_profile to the model-facing tool schema.
  • Split the Qwen relay and workspace-hint fixes into focused changes with their own reproduction evidence.

This is an automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:blast-massive Sweeper blast radius: massive — everyone, every turn (invariant surface) labels Jul 14, 2026
@teknium1 teknium1 added the area/profiles Multi-profile isolation, HERMES_HOME scoping 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 area/profiles Multi-profile isolation, HERMES_HOME scoping comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have sweeper:blast-massive Sweeper blast radius: massive — everyone, every turn (invariant surface) sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data tool/delegate Subagent delegation type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants