Add structured heartbeat responses and Codex tool replies#75765
Add structured heartbeat responses and Codex tool replies#75765pashpashpash merged 3 commits intomainfrom
Conversation
|
Codex review: needs maintainer review before merge. What this changes: The PR adds structured Maintainer follow-up before merge: The PR has the protected Security review: Security review cleared: No concrete security or supply-chain regression was found in the PR diff. Review detailsBest possible solution: Land this PR after maintainer approval and normal PR checks, keeping the structured heartbeat tool alongside the existing text fallback and preserving the generic harness delivery-default seam for other runtimes. Do we have a high-confidence way to reproduce the issue? Not applicable as a feature PR rather than a bug report. The high-confidence review path is diff inspection: current main lacks the structured heartbeat/Codex delivery behavior, and the PR adds focused schema, runner, and Codex tests for the new paths. Is this the best way to solve the issue? Yes. The design keeps core generic through harness delivery defaults, preserves existing heartbeat text fallback behavior, and now uses the repo's flat enum helpers for provider-portable tool schemas. What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 13c40668169f. |
a9d6285 to
e693753
Compare
|
@clawsweeper re-review |
|
🦞🦞 I asked ClawSweeper to review this item again. |
|
Addressed the remaining ClawSweeper finding in
Proof from the updated branch: focused heartbeat tool/runner tests passed, @clawsweeper re-review |
|
🦞🦞 I asked ClawSweeper to review this item again. |
Heartbeat runs have been relying on text conventions like HEARTBEAT_OK to decide whether a background check should stay quiet or notify the user. That works as a fallback, but it is a weak contract for tool-capable harnesses, especially Codex, where the model can make a deliberate structured call instead of encoding control flow in final text.
This adds a heartbeat_respond dynamic tool with explicit outcome, notify, summary, optional notification text, reason, priority, and nextCheck fields. Quiet responses now map to the same no-visible-update behavior as HEARTBEAT_OK, while notifying responses use notificationText when present and preserve the structured response through the Codex and embedded run plumbing.
The PR now also folds in #75745. Codex harness source replies default to the OpenClaw message tool when messages.visibleReplies is unset, so direct chat output in Codex mode follows the same deliberate visible-send model: the agent can finish its Codex turn privately, and it only posts to the channel when it calls message(action="send"). Explicit user config still wins, including messages.visibleReplies: "automatic" for the legacy direct-reply path.
Codex heartbeat turns get the heartbeat tool by default, and heartbeat runs under messages.visibleReplies: "message_tool" also get it through the normal tool policy path. The old text fallback remains in place for older/non-tool runs.
After pushing this branch, I restarted the local Gateway from the branch and waited for the real dev-agent Telegram heartbeat. The next heartbeat ran on Codex thread 019de4a6-f74e-7562-b37d-1601d6b1c329, run 8c21b180-fbc9-4f6f-9c44-0ad2dc0e7691. The OpenClaw trajectory shows the heartbeat prompt included the new instruction to call heartbeat_respond when available, the model then called heartbeat_respond with outcome needs_attention, notify true, priority normal, a concrete summary, and a reason that a time-sensitive travel item was worth surfacing. The tool result recorded successfully, and the model's final assistant text was only NO_REPLY, which means the Telegram notification came from the structured heartbeat response rather than final-text parsing. Pash confirmed receiving that Telegram notification during the test.
I am deliberately redacting the private itinerary and chat target from this public PR body. The local trajectory for session c96b0d01-dbdc-416b-bc4e-199caf45f4c1 has the raw prompt, tool call, tool result, and NO_REPLY completion for the observed heartbeat.