Fix heartbeat reasoning payload selection#92263
Conversation
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close because the same heartbeat reasoning leak is now covered by the open, mergeable, proof-sufficient sibling PR at #92356; this branch is useful and plausible, but it no longer has a unique implementation or test gap that should keep a second landing candidate open. Canonical path: Land one canonical heartbeat reasoning selector fix through #92356, then close the linked bug and overlapping branch. So I’m closing this here and keeping the remaining discussion on #92356. Review detailsBest possible solution: Land one canonical heartbeat reasoning selector fix through #92356, then close the linked bug and overlapping branch. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection of current main shows resolveHeartbeatReplyPayload can select a trailing reasoning payload, and the linked report plus PR proof give the concrete heartbeat payload order that leaks reasoning as the visible reply. Is this the best way to solve the issue? No for keeping this branch open as the landing path. The patch is plausible, but the cleaner current solution is the sibling PR that directly reuses the SDK classifier in the selector and runner and already has a completed proof-sufficient review. Security review: Security review cleared: The diff changes heartbeat payload-selection source and tests only; no dependency, workflow, secret, package, install, or code-execution surface change was found. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 865e4db1cd0a. |
|
ClawSweeper applied the proposed close for this PR.
|
Summary
Fixes #92260.
This fixes heartbeat main-reply selection so reasoning payloads are not delivered as the visible heartbeat reply when
includeReasoningis unset. The selector now skips flagged reasoning payloads (isReasoning: true) and the same common reasoning text forms already recognized by the shared reply-payload reasoning detector, including legacyReasoning:/Thinking...forms and blockquoted reasoning.The runner still preserves the explicit opt-in path: when
agents.defaults.heartbeat.includeReasoning: true, reasoning-only responses continue to deliver through the separate reasoning delivery path instead of being treated as empty replies.Patch-level comparison
I checked for competing open PRs before opening this: none were open for #92260 when this PR was prepared. The closest competing patch was closed PR #92262.
Compared with #92262, this branch is intentionally different in a few ways:
ResolveHeartbeatReplyPayloadOptionsexport throughsrc/plugin-sdk/reply-runtime.ts.isReasoningReplyPayload.includeReasoningsuppression on the actual heartbeat send path, not only selector unit tests.includeReasoning: truebehavior for reasoning-only responses, including the regression caught during autoreview.Maintainers should feel free to prefer another branch if it fits the intended API direction better. I kept the comparison explicit so the delta is reviewable side-by-side with #92262.
Real behavior proof (required for external PRs)
1d36bdf2ce876dc18c7644da8e308f049fa23fc8, Node 24.16.0, productionrunHeartbeatOnce, real temporaryOpenClawConfig, real session-store JSON file, real plugin registry registration, isolatedOPENCLAW_HOME/OPENCLAW_STATE_DIRunder/tmp, and a local Telegram-shaped outbound adapter that records delivery attempts without contacting Telegram.includeReasoningunset, a late blockquoted reasoning payload afterHEARTBEAT_OKproduced zero outbound sends, and a visible final heartbeat update followed by reasoning delivered only the visible final text. WithincludeReasoning: true, a reasoning-only response still delivered through the explicit reasoning path.Tests and validation
Focused commands run:
node scripts/run-vitest.mjs src/auto-reply/heartbeat-reply-payload.test.ts src/infra/heartbeat-runner.returns-default-unset.test.ts src/plugin-sdk/reply-payload.test.ts git diff --check /Users/harjothk/.cache/codex-runtimes/codex-primary-runtime/dependencies/python/bin/python3 .agents/skills/autoreview/scripts/autoreview --mode localResults:
node scripts/run-vitest.mjs ...passed 3 Vitest shards: 4 selector tests, 44 infra heartbeat runner tests, and 53 plugin-sdk reply-payload tests.git diff --checkpassed.autoreview clean: no accepted/actionable findings reported.Regression coverage added:
HEARTBEAT_OK, legacy-prefixed and blockquoted late reasoning, andincludeReasoning: truereasoning-only delivery.