Skip to content

fix(agents): drop streamTo silently for non-ACP spawn requests#58686

Closed
Mintalix wants to merge 5 commits into
openclaw:mainfrom
Mintalix:fix/sessions-spawn-streamto-drop
Closed

fix(agents): drop streamTo silently for non-ACP spawn requests#58686
Mintalix wants to merge 5 commits into
openclaw:mainfrom
Mintalix:fix/sessions-spawn-streamto-drop

Conversation

@Mintalix

@Mintalix Mintalix commented Apr 1, 2026

Copy link
Copy Markdown

Summary

Problem: sessions_spawn returned { status: "error" } when streamTo: "parent" was passed with runtime: "subagent" or with runtime omitted (defaults to subagent). Callers that retain the full ACP parameter set after a runtime fallback were rejected.

Why it matters: streamTo is an output-routing hint with no effect on subagent spawns. Erroring on a no-op field breaks valid spawn flows for callers that don't strip ACP-only params before calling.

What changed: Removed the hard-error guard on streamTo for non-ACP runtime. streamTo is now resolved before the runtime branch and forwarded only when runtime === "acp"; silently dropped otherwise. Schema description updated to document the ACP-only contract.

What did NOT change (scope boundary): resumeSessionId still errors for non-ACP. All ACP spawn paths, the streamTo !== "parent" registry-tracking guard, and subagent spawn behavior are unchanged.


Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • Skills / tool execution

Linked Issue/PR


This PR fixes a bug or regression


Root Cause / Regression History (if applicable)

  • Root cause: The guard if (streamTo && runtime !== "acp") was intentionally strict but treated a harmless no-op field as a fatal input error rather than ignoring it.
  • Missing detection / guardrail: No unit test covered the path where a caller passes streamTo and runtime resolves to subagent; only the ACP forward path was tested.
  • Prior context: vincentkoc-code/pr-55483-replacement added the schema description update; this PR completes the fix by removing the error guard and adding direct test coverage.
  • Why this regressed now: N/A — the guard was always too strict; it became observable when callers started retaining the full ACP parameter set across runtime fallbacks.
  • If unknown, what was ruled out: N/A

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:

    • Unit test
  • Target test or file:
    src/agents/tools/sessions-spawn-tool.test.ts

  • Scenario the test should lock in:

    • 'ignores streamTo when runtime is explicitly "subagent"' — streamTo: "parent" + explicit subagent runtime → status: "accepted", spawnSubagentDirect called without streamTo.
    • 'ignores streamTo when runtime is omitted and defaults to "subagent"' — same with runtime omitted.
  • Why this is the smallest reliable guardrail:
    Both tests directly exercise the removed error branch and the new silent-drop path with zero infrastructure dependencies.

  • Existing test that already covers this (if any):
    Replaced 'rejects streamTo when runtime is not "acp"' (which asserted the old error behavior).

  • If no new test is added, why not:
    N/A — two tests added.


User-visible / Behavior Changes

Callers that previously received:
{ status: "error", error: "streamTo is only supported for runtime=acp; got runtime=subagent" }

Will now receive a normal:
{ status: "accepted", ... }

No change for callers that do not pass streamTo, or for ACP callers.


Diagram (if applicable)

N/A


Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS / Linux
  • Runtime/container: Node 22, local gateway
  • Model/provider: any
  • Integration/channel (if any): subagent spawn
  • Relevant config (redacted): none

Steps

  1. Call sessions_spawn with { task: "test", runtime: "subagent", streamTo: "parent" }
  2. Observe result status

Expected

{ status: "accepted", childSessionKey: "...", runId: "..." }

Actual (before fix)

{ status: "error", error: "streamTo is only supported for runtime=acp; got runtime=subagent" }

Evidence

  • Failing test/log before + passing after
    • 'rejects streamTo when runtime is not "acp"'(旧行为)
    • 替换为两个断言 status: "accepted" 且未透传 streamTo 的测试

Human Verification (required)

  • Verified scenarios:

    • explicit runtime: "subagent" + streamTo: "parent"
    • omitted runtime + streamTo: "parent"
    • streamTo absent entirely (no regression)
    • resumeSessionId error guard still fires for non-ACP
  • Edge cases checked:

    • ACP path with streamTo: "parent" — unaffected, forwarded as before.
  • What you did not verify:

    • Live ACP end-to-end session with streamTo: "parent"

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: Callers that intentionally passed streamTo on a subagent spawn expecting an error to signal misuse will no longer receive feedback.

  • Mitigation:
    streamTo is documented as an ACP-only output-routing hint in the schema description; it has no observable effect on subagent spawns. Silent drop is the correct semantic. Callers can inspect the updated schema description to understand the contract.

Some callers retain ACP-only fields when falling back from ACP to
subagent runtime. Previously the tool returned an error; now streamTo
is silently dropped for subagent requests and forwarded only for
runtime=acp. Schema description updated to document the ACP-only
contract.
Copilot AI review requested due to automatic review settings April 1, 2026 02:48
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Apr 1, 2026
@greptile-apps

greptile-apps Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR removes an overly strict error guard that rejected streamTo: "parent" on subagent spawn requests. Instead of returning { status: "error" }, streamTo is now silently dropped when runtime !== "acp", which is the correct semantic since it's an ACP-only output-routing hint. The schema description is also updated to document this contract.

Key changes:

  • sessions-spawn-tool.ts: streamTo is now resolved in two steps — requestedStreamTo captures the raw value, and streamTo is set to requestedStreamTo only when runtime === "acp", otherwise undefined. The hard-error guard if (streamTo && runtime !== "acp") is removed.
  • sessions-spawn-tool.test.ts: The old test that asserted the error response is replaced by two new tests covering (1) explicit runtime: "subagent" + streamTo and (2) omitted runtime (defaults to subagent) + streamTo. Both verify status: "accepted" and that spawnSubagentDirect is called without streamTo.
  • The resumeSessionId error guard for non-ACP runtimes remains intact and is unaffected.

The implementation is correct and consistent — streamTo was never included in the spawnSubagentDirect call parameters even before this PR, so the subagent execution path is unchanged. The ACP path (including the streamTo !== "parent" registry-tracking guard) is also unchanged.

Confidence Score: 5/5

Safe to merge — the fix is minimal, well-scoped, and fully covered by new tests.

No P0 or P1 issues found. The logic change is correct: streamTo was never forwarded to spawnSubagentDirect before this PR either, so subagent behavior is unchanged. The ACP path including the registry-tracking guard is untouched. The two new tests directly cover both removed-error-branch scenarios, and the existing ACP test continues to verify that streamTo is still forwarded on ACP spawns.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(agents): drop streamTo silently for ..." | Re-trigger Greptile

Copilot AI 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.

Pull request overview

Fixes sessions_spawn to treat streamTo as an ACP-only hint by forwarding it only for runtime="acp" and silently ignoring it for subagent spawns, preventing otherwise-valid subagent spawn requests from being rejected.

Changes:

  • Update sessions_spawn tool behavior to drop streamTo for non-ACP runtimes instead of returning an error.
  • Update the streamTo schema description to document the ACP-only contract.
  • Replace the prior rejection test with regression tests asserting streamTo is ignored for explicit/implicit subagent runtime.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/agents/tools/sessions-spawn-tool.ts Drops streamTo for subagent runtime; updates schema docs to clarify ACP-only semantics.
src/agents/tools/sessions-spawn-tool.test.ts Adds/updates unit tests to lock in “ignore streamTo on subagent” behavior.

Comment thread src/agents/tools/sessions-spawn-tool.test.ts Outdated
Comment thread src/agents/tools/sessions-spawn-tool.test.ts Outdated

@bshelby88 bshelby88 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM! The logic is correct:

  • streamTo = runtime === "acp" ? requestedStreamTo : undefined correctly drops the param for non-ACP requests
  • Test coverage is good — both explicit runtime="subagent" and omitted runtime (defaulting to subagent) are tested
  • expect.not.objectContaining correctly verifies streamTo is NOT passed to the spawn function
  • Schema description update documents the ACP-only behavior

Silently dropping is the right call here — more graceful than erroring when callers fall back from ACP to subagent with leftover ACP-specific fields.

Copilot AI 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.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@Mintalix

Mintalix commented Apr 3, 2026

Copy link
Copy Markdown
Author

@vincentkoc Friendly ping on this one. Since #55483 was closed as dirty and #56906 has been quiet, I opened #58686 on a clean branch with the full fix and regression tests. When you have a chance, could you take a look and let me know if we should continue here and close #56906? Thanks.

@vincentkoc

Copy link
Copy Markdown
Member

Thanks @Mintalix for the focused fix and regression coverage in this PR.

ProjectClownfish is closing this as superseded by #72614. #72614 carries the same narrow sessions_spawn ACP-only field tolerance forward on the ProjectClownfish replacement branch, includes source PR credit for #58686, and will own final validation and merge. The branch here has stale failing checks and unresolved formatting review comments, so the credited replacement path is the safer canonical path.

If #72614 misses a behavior covered here, please reply and we can reopen or split the gap back out.

@vincentkoc vincentkoc closed this Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: streamTo in sessions_spawn breaks subagent runtime

4 participants