feat(gateway): inject isHeartbeat into agent event broadcast payload#80610
Conversation
|
Codex review: needs maintainer review before merge. Summary Reproducibility: not applicable. as a feature PR. Source inspection on current main shows the heartbeat context exists internally, while the current gateway agent payload construction does not expose a top-level Real behavior proof Next step before merge Security Review detailsBest possible solution: Land the additive gateway protocol field after normal CI and maintainer protocol review confirm the schema, generated Swift model, and focused event tests remain aligned; client-specific filtering can follow separately. Do we have a high-confidence way to reproduce the issue? Not applicable as a feature PR. Source inspection on current main shows the heartbeat context exists internally, while the current gateway agent payload construction does not expose a top-level Is this the best way to solve the issue? Yes. The proposed approach is the narrow maintainable path: expose existing What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 5a9e8a29e52e. Re-review progress:
|
There was a problem hiding this comment.
Pull request overview
This PR extends the gateway’s agent event broadcast payload to include an isHeartbeat flag derived from AgentRunContext, enabling external clients (e.g. macOS Control UI) to reliably distinguish heartbeat runs from user-initiated runs without parsing message content.
Changes:
- Injects
isHeartbeatinto the gatewayagentevent payload at broadcast/send boundaries inserver-chat.ts(omitted when undefined, preserved whenfalse). - Adds a unit test covering
isHeartbeat: true,false, and omission when absent. - Updates the gateway protocol TypeBox schema and regenerated Swift gateway models to include
isHeartbeat.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/gateway/server-chat.ts | Adds isHeartbeat enrichment to the emitted/broadcast agent event payloads (including seq-gap error payload). |
| src/gateway/server-chat.agent-events.test.ts | Adds test coverage ensuring isHeartbeat is injected (or omitted) correctly. |
| src/gateway/protocol/schema/agent.ts | Extends AgentEventSchema with optional isHeartbeat: boolean. |
| apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift | Regenerates Swift AgentEvent model to decode the new isHeartbeat field. |
a8c01fa to
5c82a18
Compare
5c82a18 to
61e5d2c
Compare
22b475e to
5b59c5e
Compare
This allows external callers to identify whether an agent event originated from a heartbeat run without polluting the core AgentEventPayload type.
5b59c5e to
cb25410
Compare
|
Merged via squash.
Thanks @medns! |
…penclaw#80610) Merged via squash. Prepared head SHA: cb25410 Co-authored-by: medns <1575008+medns@users.noreply.github.com> Co-authored-by: odysseus0 <8635094+odysseus0@users.noreply.github.com> Reviewed-by: @odysseus0
…penclaw#80610) Merged via squash. Prepared head SHA: cb25410 Co-authored-by: medns <1575008+medns@users.noreply.github.com> Co-authored-by: odysseus0 <8635094+odysseus0@users.noreply.github.com> Reviewed-by: @odysseus0
…penclaw#80610) Merged via squash. Prepared head SHA: cb25410 Co-authored-by: medns <1575008+medns@users.noreply.github.com> Co-authored-by: odysseus0 <8635094+odysseus0@users.noreply.github.com> Reviewed-by: @odysseus0
Summary
agentevent originated from a scheduled heartbeat run or a normal user chat run without parsing the payload text or guessing.HEARTBEAT_OKacks) that UIs often want to filter out or display differently. The gateway already knows this context but wasn't exposing it in the event stream.isHeartbeatfromAgentRunContextinto the gatewayagentevent broadcast payload inserver-chat.ts. Updates the TypeBox schema insrc/gateway/protocol/schema/agent.tsand regenerates the Swift models and JSON schema to match.AgentEventPayloadtype remains unchanged; the injection happens only at the broadcast boundary.Change Type (select all)
Scope (select all touched areas)
Real behavior proof (required for external PRs)
pnpm gateway:watchand macOS client.openclaw cron runand observed the WebSocket payload.Observed console output from the WebSocket stream during a heartbeat run:
{ "type": "event", "event": "agent", "payload": { "runId": "run-123", "seq": 1, "stream": "assistant", "ts": 1730000000, "isHeartbeat": true, "data": { "text": "HEARTBEAT_OK" } } }isHeartbeatflag is successfully injected into the broadcast payload only for heartbeat runs, and the Swift client decodes the payload without errors.Regression Test Plan (if applicable)
src/gateway/server-chat.agent-events.test.tsisHeartbeatis correctly injected into the broadcast payload when present in the run context, and omitted when absent.Security Impact (required)
NoNoNoNoNoEvidence
Attach at least one:
Human Verification (required)
What you personally verified (not just CI), and how:
isHeartbeatis omitted when undefined, rather than sendingisHeartbeat: null.Review Conversations
Compatibility / Migration
YesNo