fix(message): keep automatic replies out of implicit sends#88228
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed May 30, 2026, 3:41 AM ET / 07:41 UTC. Summary PR surface: Source +230, Tests +661. Total +891 across 18 files. Reproducibility: Partly. Source inspection shows current main does not consume automatic implicit message-tool sends into the internal source-reply sink and instead can infer a normal outbound current target, but I did not establish a full current-main or patched Feishu/Lark live reproduction. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land only after maintainers accept the automatic-mode source-reply sink boundary and a redacted patched Feishu/Lark run shows one streaming card with no separate normal post. Do we have a high-confidence way to reproduce the issue? Partly. Source inspection shows current main does not consume automatic implicit message-tool sends into the internal source-reply sink and instead can infer a normal outbound current target, but I did not establish a full current-main or patched Feishu/Lark live reproduction. Is this the best way to solve the issue? Unclear as a merge decision. The opt-in sink is narrow and well covered by focused tests, but maintainers still need to accept the automatic-mode delivery boundary and require patched-source real proof. AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 99ffd714ce92. Label changesLabel justifications:
Evidence reviewedPR surface: Source +230, Tests +661. Total +891 across 18 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
7bfe23b to
fd519c9
Compare
|
Updated after review and force-pushed The review-found thread-control gap is fixed:
I also tightened the PR body so it describes the current behavior accurately: embedded runs opt into the internal source-reply sink; MCP/CLI/default callers do not; explicit/structured sends are preserved. Latest local validation is listed in the PR body: format, lint, whitespace, focused infra/tool/runner tests, and @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
fd519c9 to
5b89ecf
Compare
5b89ecf to
922ca5f
Compare
43af312 to
07f0618
Compare
07f0618 to
555b261
Compare
|
Superseded by #88276. This earlier PR focused on message-tool/source-reply routing, but the original Feishu issue is better fixed in the normal Feishu streaming-card reply dispatcher path. Closing this one to keep maintainer review on the smaller, target-aligned patch. |
Summary
This PR fixes an automatic source-delivery edge case seen with OpenClaw + Feishu/Lark streaming cards + Codex:
message(action="send")calls to the current source conversation now stay on the source-reply/card path.Why this matters: previously Codex could emit the first visible answer through the shared
messagetool as a normal Feishu post while the final/footer came through the Feishu streaming card. The turn then looked split even though streaming cards were enabled.Behavior Boundary
The automatic source-reply sink is intentionally narrow. It only applies when all of these are true:
action === "send"sourceReplyDeliveryMode === "automatic"allowInternalSourceReplySink: trueNormal outbound is preserved for:
target,to,channelId, ortargetschannelmedia,mediaUrl,base64,image, paths, attachments,mediaUrls)replyTo,replyToId,threadId,threadId: null)topLevel: true,replyBroadcast: true)bestEffortwhen presentdelivery,channelData,presentation,interactiveNo-op false booleans such as
silent:false,asVoice:false,forceDocument:false,gifPlayback:false,topLevel:false, andreplyBroadcast:falseare still treated as text-only.Real behavior proof
message(action="send")tool. The first visible answer appeared as a normal Feishu message, while the final/completion footer appeared in the streaming card.27ae826) with Feishu/Lark p2p, Codex runtime,messages.visibleReplies=automatic,channels.feishu.streaming=true,channels.feishu.footer.elapsed=true, andchannels.feishu.footer.status=true.messagetool from the active embedded agent so normal assistant text was forced through the automatic source-reply dispatcher. This patch implements the same routing intent narrowly in code and verifies it with source checkout tests.messagetool removed during live mitigation, and the reply completing through the streaming card path instead of a normal Feishu post:message/sendcalls now take that same source-reply/card path, while explicit or structured sends keep normal outbound behavior.Validation
Commands run locally:
npm exec --yes [email protected] -- pnpm exec oxfmt --check ...on the 14 changed filesnpm exec --yes [email protected] -- pnpm exec oxlint ...on the 14 changed filesgit diff --checknpm exec --yes [email protected] -- pnpm exec node scripts/run-vitest.mjs run --config test/vitest/vitest.infra.config.ts src/infra/outbound/message-action-runner.send-validation.test.ts src/infra/outbound/message-action-params.test.ts src/infra/outbound/message-action-spec.test.ts— 105 testsnpm exec --yes [email protected] -- pnpm exec node scripts/run-vitest.mjs run --config test/vitest/vitest.agents-tools.config.ts src/agents/tools/message-tool.test.ts— 68 testsnpm exec --yes [email protected] -- pnpm exec node scripts/run-vitest.mjs run --config test/vitest/vitest.unit-fast.config.ts src/agents/embedded-agent-runner/run/payloads.test.ts src/agents/embedded-agent-runner/run/tool-media-payloads.test.ts— 41 testsnpm exec --yes [email protected] -- pnpm exec node scripts/run-vitest.mjs run --config test/vitest/vitest.agents-support.config.ts src/agents/embedded-agent-subscribe.handlers.messages.test.ts— 31 testsnpm exec --yes [email protected] -- pnpm exec node scripts/run-vitest.mjs run --config test/vitest/vitest.agents.config.ts src/agents/agent-tools.create-openclaw-coding-tools.test.ts— 56 testsnpm exec --yes [email protected] -- pnpm tsgo:test:srcA local Codex review found a thread-control gap (
topLevel,threadId:null,replyBroadcast, plugin send options). This update addresses it and adds regression coverage.Risk
Highest risk: accidentally capturing a legitimate current-channel send that had non-text semantics.
Mitigation:
AI-assisted