Skip to content

fix(acp): implicit streamToParent for mode=run without thread#42404

Merged
osolmaz merged 3 commits intoopenclaw:mainfrom
davidguttman:fix/acp-spawn-no-discord-delivery-without-thread
Mar 10, 2026
Merged

fix(acp): implicit streamToParent for mode=run without thread#42404
osolmaz merged 3 commits intoopenclaw:mainfrom
davidguttman:fix/acp-spawn-no-discord-delivery-without-thread

Conversation

@davidguttman
Copy link
Copy Markdown
Contributor

Problem

When spawning ACP sessions with mode=run and thread=false (or no thread param), output still posts to Discord because hasDeliveryTarget is true when called from a Discord context.

This breaks agent-to-agent supervision patterns where the spawning agent wants to receive results programmatically, not via Discord chat messages.

Solution

When mode=run and thread=false and there's a parent session, automatically enable streamToParent behavior. This routes output to the parent session instead of posting to the channel.

Testing

Tested locally by comparing behavior:

  • Production: mode=run without thread posts output to Discord thread
  • With fix: Output stays internal, routed to parent session only

AI Disclosure

This PR was AI-assisted (Claude). Tested manually end-to-end.

@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling size: XS labels Mar 10, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bc2fc473de

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 10, 2026

Greptile Summary

This PR fixes a bug where child ACP sessions spawned with mode="run" (without a thread binding) would still post output to Discord because hasDeliveryTarget was true in a Discord context. The fix introduces an implicitStreamToParent flag that automatically activates streamTo="parent" routing when mode="run", thread is not requested, and there is an active parent session — routing output to the parent session instead of the channel.

The core logic is sound and the three streamToParentRequestedeffectiveStreamToParent substitutions are consistent. However, there is a coverage gap: the implicit activation checks params.mode === "run" (the raw param), but resolveSpawnMode already defaults to "run" when mode is omitted and thread is not requested. Callers that rely on the default mode will not receive the fix.

Confidence Score: 4/5

  • The fix is sound and addresses the stated problem, but has a functional gap for callers that omit the mode parameter.
  • The PR correctly implements implicit parent-stream routing for explicit mode="run" cases. The change is well-reasoned and the three substitution sites are consistent. The score is 4/5 rather than 5 because of a verified coverage gap: callers that omit mode entirely (relying on the default) will not receive the implicit routing fix, even though their resolved behavior is identical to explicit mode="run".
  • src/agents/acp-spawn.ts — the implicitStreamToParent condition at line 335 should consider using the resolved spawnMode rather than the raw params.mode to cover all callers that expect "run" behavior.

Last reviewed commit: bc2fc47

@osolmaz osolmaz self-assigned this Mar 10, 2026
@aerelune
Copy link
Copy Markdown
Contributor

🟡 需要小修改

问题:

覆盖不全 - 修复只在明确设置 mode="run" 时生效,依赖默认模式解析时不生效

建议:

335 行应该使用解析后的 spawnMode 而不是原始的 params.mode

这样可以确保无论是显式设置还是默认值都能正确处理。

osolmaz added a commit to davidguttman/clawdbot that referenced this pull request Mar 10, 2026
@osolmaz osolmaz force-pushed the fix/acp-spawn-no-discord-delivery-without-thread branch from 78a4694 to b7d69dc Compare March 10, 2026 20:20
davidguttman and others added 3 commits March 10, 2026 21:21
When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.
Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.
@osolmaz osolmaz force-pushed the fix/acp-spawn-no-discord-delivery-without-thread branch from b7d69dc to 626c85d Compare March 10, 2026 20:42
@osolmaz osolmaz merged commit 9f5dee3 into openclaw:main Mar 10, 2026
9 checks passed
@osolmaz
Copy link
Copy Markdown
Contributor

osolmaz commented Mar 10, 2026

Landed via squash ✅

Validation run:

  • pnpm lint
  • pnpm build
  • pnpm test

Changelog updated under Unreleased → Fixes for #42404.

Thanks @davidguttman!

mrosmarin added a commit to mrosmarin/openclaw that referenced this pull request Mar 10, 2026
* main: (42 commits)
  test: share runtime group policy fallback cases
  refactor: share windows command shim resolution
  refactor: share approval gateway client setup
  refactor: share telegram payload send flow
  refactor: share passive account lifecycle helpers
  refactor: share channel config schema fragments
  refactor: share channel config security scaffolding
  refactor: share onboarding secret prompt flows
  refactor: share scoped account config patching
  feat(discord): add autoArchiveDuration config option (openclaw#35065)
  fix(gateway): harden token fallback/reconnect behavior and docs (openclaw#42507)
  fix(acp): strip provider auth env for child ACP processes (openclaw#42250)
  fix(browser): surface 429 rate limit errors with actionable hints (openclaw#40491)
  fix(acp): scope cancellation and event routing by runId (openclaw#41331)
  docs: require codex review in contributing guide (openclaw#42503)
  Fix stale runtime model reuse on session reset (openclaw#41173)
  docs: document r: spam auto-close label
  fix(ci): auto-close and lock r: spam items
  fix(acp): implicit streamToParent for mode=run without thread (openclaw#42404)
  test: extract sendpayload outbound contract suite
  ...
frankekn pushed a commit to MoerAI/openclaw that referenced this pull request Mar 11, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
frankekn pushed a commit to Effet/openclaw that referenced this pull request Mar 11, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
frankekn pushed a commit to ImLukeF/openclaw that referenced this pull request Mar 11, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
Treedy2020 pushed a commit to Treedy2020/openclaw that referenced this pull request Mar 11, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
dhoman pushed a commit to dhoman/chrono-claw that referenced this pull request Mar 11, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
ahelpercn pushed a commit to ahelpercn/openclaw that referenced this pull request Mar 12, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
Ruijie-Ysp pushed a commit to Ruijie-Ysp/clawdbot that referenced this pull request Mar 12, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
leozhengliu-pixel pushed a commit to leozhengliu-pixel/openclaw that referenced this pull request Mar 13, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
senw-developers pushed a commit to senw-developers/va-openclaw that referenced this pull request Mar 17, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 23, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
(cherry picked from commit 9f5dee3)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 25, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
(cherry picked from commit 9f5dee3)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 25, 2026
…aw#42404)

* fix(acp): implicit streamToParent for mode=run without thread

When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.

The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.

Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.

* fix: use resolved spawnMode instead of params.mode

Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.

This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.

* fix: tighten implicit ACP parent relay gating (openclaw#42404) (thanks @davidguttman)

---------

Co-authored-by: Onur Solmaz <[email protected]>
(cherry picked from commit 9f5dee3)
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: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants