openclaw - ✅(Solved) Fix bug(agents): SSE seq/cursor drift when NO_REPLY messages are suppressed mid-stream [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#61816Fetched 2026-04-08 02:54:08
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
cross-referenced ×2closed ×1commented ×1

When the SSE streaming layer suppresses NO_REPLY messages (or other filtered content), the sequence number and cursor used for client-side event ordering can drift out of sync. Clients that reconnect or use the cursor for resumption may miss messages or receive duplicates.

Root Cause

The SSE event emitter increments seq for every internal message but then suppresses some from the wire. The client cursor tracks the last received seq, which no longer matches the server-side counter. On reconnection with Last-Event-ID, the server resumes from the wrong offset.

Fix Action

Fixed

PR fix notes

PR #61463: fix(agents,gateway): phase-aware assistant text extraction — suppress OpenAI commentary leaks in sessions-helpers, TUI, and REST history

Description (problem / solution / changelog)

What this fixes (plain English)

Several places in the codebase that display assistant text were not aware of the phase system (commentary vs. final answer). This meant internal "thinking out loud" commentary could leak into user-visible surfaces like the TUI and HTTP/SSE session history endpoints. This PR makes those surfaces phase-aware, and hardens heartbeat session resolution against subagent key leaks.

Technical details

Follow-up to #59643 and #59150, which fixed phase separation in the core WS path. Post-merge audit found adjacent surfaces still using phase-blind extraction.

Surfaces fixed:

  • src/tui/tui-formatters.ts — assistant text extraction now uses extractAssistantVisibleText() to prefer final_answer over commentary phase blocks
  • src/infra/heartbeat-runner.ts — heartbeat session resolution now rejects subagent session keys, falling back to the main session key instead of leaking into subagent scopes
  • src/gateway/sessions-history-http.test.ts — regression test: REST history applies chat.history sanitization (strips NO_REPLY messages, preserves phase blocks)
  • src/tui/tui-formatters.test.ts — regression test: mixed commentary + final_answer blocks extract only the visible final answer

Explicitly deferred: extractAssistantTextForSilentCheck and buffered delta/final rendering — lower-confidence, more behaviorally sensitive.

Related

  • Follow-up to #59643 and #59150
  • Follow-up issues: #61474, #61475, #61476, #61477, #61478
  • Companion PRs: #61529, #61528, #61527
  • Related PRs: #61855, #61816

Test plan

  • 27/27 TUI formatter tests pass
  • Regression test for mixed commentary + final_answer in TUI extraction
  • HTTP history regression test (REST path shares chat.history sanitization, strips NO_REPLY messages)
  • SSE seq validation for NO_REPLY message stripping
  • sessions-history-http gateway integration tests have 2 pre-existing infra failures (also fail on upstream/main)

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/infra/heartbeat-runner.subagent-session-guard.test.ts (added, +72/-0)
  • src/infra/heartbeat-runner.ts (modified, +24/-17)
  • src/tui/tui-formatters.test.ts (modified, +20/-0)
  • src/tui/tui-formatters.ts (modified, +25/-0)
RAW_BUFFERClick to expand / collapse

Description

When the SSE streaming layer suppresses NO_REPLY messages (or other filtered content), the sequence number and cursor used for client-side event ordering can drift out of sync. Clients that reconnect or use the cursor for resumption may miss messages or receive duplicates.

Root cause

The SSE event emitter increments seq for every internal message but then suppresses some from the wire. The client cursor tracks the last received seq, which no longer matches the server-side counter. On reconnection with Last-Event-ID, the server resumes from the wrong offset.

Impact

  • Clients reconnecting after a suppressed NO_REPLY block may miss the next real message
  • In high-suppression scenarios (heartbeat sessions, cron runs), cursor drift accumulates
  • Affects all SSE-based consumers (Control UI, webchat, external integrations)

Proposed fix

Either:

  1. Do not increment seq for suppressed messages, or
  2. Track a separate "wire seq" that only increments for actually-sent events

Related

  • PRs #61463, #61481 (phase-separation initiative that increases suppression frequency)
  • #54736 (isSilentReplyText regex fails on doubled NO_REPLY tokens)
  • #40165 (strip NO_REPLY from prefix AND suffix positions)
  • #45909 (NO_REPLY suppression bypassed for thread-based delivery)

extent analysis

TL;DR

Implement one of the proposed fixes to prevent sequence number and cursor drift by either not incrementing the sequence number for suppressed messages or tracking a separate "wire seq" that only increments for actually-sent events.

Guidance

  • Review the proposed fixes and choose the most suitable approach for the current implementation.
  • Consider the impact of high-suppression scenarios, such as heartbeat sessions or cron runs, on the chosen fix.
  • Evaluate the effects of the fix on all SSE-based consumers, including Control UI, webchat, and external integrations.
  • Examine related PRs (#61463, #61481, #54736, #40165, #45909) to understand the context and potential interactions with the proposed fix.

Example

No code snippet is provided as the issue does not contain specific implementation details.

Notes

The chosen fix should be thoroughly tested to ensure it resolves the issue without introducing new problems, especially in high-suppression scenarios.

Recommendation

Apply a workaround by implementing one of the proposed fixes, as it directly addresses the root cause of the issue and prevents sequence number and cursor drift.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING