Skip to content

fix(delegation): honor explicit background false - #55010

Open
thestral123 wants to merge 2 commits into
NousResearch:mainfrom
thestral123:fix/delegate-background-flag
Open

fix(delegation): honor explicit background false#55010
thestral123 wants to merge 2 commits into
NousResearch:mainfrom
thestral123:fix/delegate-background-flag

Conversation

@thestral123

@thestral123 thestral123 commented Jun 29, 2026

Copy link
Copy Markdown

What does this PR do?

Restores explicit background=false handling in the model-facing delegate_task dispatch path while keeping top-level delegation asynchronous by default.

Current run_agent._dispatch_delegate_task() forces top-level model delegations to background=True, and the tool schema says the background parameter is ignored. That default is useful for interactive chats, but it removes the same-turn orchestration path needed by cron jobs and other workflows that must wait for a subagent before producing one final response.

This PR keeps the responsive async default while restoring an explicit escape hatch:

delegate_task(
    goal="Critique before finalizing",
    context="...",
    background=False,
)

Behavior after this change:

Caller No background arg background=True background=False
Top-level agent async/background async/background synchronous / same-turn
Orchestrator subagent (_delegate_depth > 0) synchronous synchronous synchronous
Direct Python caller of delegate_task() unchanged historical default unchanged unchanged

The current model-facing ACP security boundary remains intact: hidden per-task acp_command and acp_args fields are still removed before dispatch.

Related Issue

Related: #53062

That PR addresses cron-session delivery for async delegation. This PR covers the narrower API/control question: preserve async-by-default behavior while honoring explicit background=false for callers that need same-turn orchestration.

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

  • run_agent.py: keep top-level model delegation async by default, but honor explicit background=false; retain _strip_model_hidden_task_fields() and keep orchestrator/subagent delegation synchronous.
  • tools/delegate_tool.py: mirror the same background resolution in the registry fallback and update the model-facing schema description.
  • tests/tools/test_async_delegation.py: cover default async behavior, explicit background=false for single and batch calls, and forced synchronous behavior for nested/orchestrator callers.
  • website/docs/user-guide/features/delegation.md: document the async default, same-turn escape hatch, batch behavior, and process-local durability semantics.

How to Test

python3 -m pytest tests/tools/test_async_delegation.py -q -o 'addopts='
# 26 passed

python3 -m pytest tests/tools/test_delegate.py -q -o 'addopts='
# 156 passed

python3 -m py_compile run_agent.py tools/delegate_tool.py tests/tools/test_async_delegation.py
# passed

git diff --check
# passed

python3 scripts/check-windows-footguns.py --diff upstream/main
# No Windows footguns found (3 file(s) scanned).

npm --prefix website run build
# production build completed for en and zh-Hans; existing unrelated link warnings remain

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/ -q and all tests pass
    • Not run locally for this update; targeted delegation tests above pass.
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: Linux

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A: no config key added
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A: no contributor workflow change
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide
  • I've updated tool descriptions/schemas if I changed tool behavior

Screenshots / Logs

N/A — behavior is covered by unit tests and documentation updates.

@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint tool/delegate Subagent delegation P2 Medium — degraded but workaround exists labels Jun 29, 2026
@thestral123 thestral123 reopened this Jun 29, 2026
@thestral123

Copy link
Copy Markdown
Author

@teknium1 since this touches the behavior introduced around async top-level delegation, I’d appreciate your design read here.

I agree async-by-default is useful for interactive chat, but I think there’s still a legitimate same-turn orchestration use case outside cron: e.g. “before returning, ask another subagent/model to challenge this recommendation and incorporate the critique into the final answer.”

That pattern needs the parent to explicitly wait before finalizing. This draft tries to preserve the async default while restoring background=false as the explicit compatibility escape hatch. If the preferred direction is instead to solve only cron via #53062, happy to close this, but I wanted to separate the broader API/control question from the cron delivery bug.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for isolating the same-turn delegation case. The premise is verified on current main: run_agent.py:5706-5724 explicitly forces top-level model calls to background mode, and tools/delegate_tool.py:3460-3473 mirrors that behavior in the registry fallback.

Problems

  • The new docs example at website/docs/user-guide/features/delegation.md:29 passes toolsets, but current model-facing schema properties omit that field (tools/delegate_tool.py:3410-3449) and dispatch does not forward it (run_agent.py:5718-5725).

Suggested changes

  • Remove toolsets from that new example or document inherited toolsets.
  • If this behavior is adopted, port the narrow background-resolution change onto current dispatch while retaining _strip_model_hidden_task_fields at run_agent.py:5721; current main removed model-controlled ACP transport in e4dbb67bf5.

Automated hermes-sweeper review.

```python
delegate_task(
goal="Critique this provisional recommendation before I finalize",
context="...",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toolsets is not accepted by the current model-facing delegate_task schema or forwarded by its dispatcher (tools/delegate_tool.py:3410-3449, run_agent.py:5718-5725). Remove it here or explain that subagents inherit the parent's toolsets.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 15, 2026
@thestral123

Copy link
Copy Markdown
Author

Thanks — I’ve addressed both points and updated the branch against current main.

  • Removed toolsets from the new documentation example.
  • Ported only the narrow background-resolution change onto the current dispatch path.
  • Retained _strip_model_hidden_task_fields() in the live dispatch path, so model-supplied per-task acp_command and acp_args remain stripped.
  • Reconciled the delegation durability documentation with the newer upstream behavior.

Targeted verification:

  • tests/tools/test_async_delegation.py: 26 passed
  • tests/tools/test_delegate.py: 156 passed
  • Python compilation, git diff --check, and the Windows footgun check passed

The PR is now conflict-free and mergeable.

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

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state tool/delegate Subagent delegation type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants