Skip to content

fix(agent-adapter): reconcile Claude messages on reseed - #240

Merged
AprilNEA merged 1 commit into
masterfrom
ruocheng/code-328
Jul 22, 2026
Merged

fix(agent-adapter): reconcile Claude messages on reseed#240
AprilNEA merged 1 commit into
masterfrom
ruocheng/code-328

Conversation

@Zerlight

Copy link
Copy Markdown
Member

Summary

  • Fixes CODE-328 by reconciling Claude live-stream and history messages with the stable provider message ID.
  • Prevents SWR focus/reconnect revalidation from duplicating completed responses.
  • Preserves the CODE-272 behavior that keeps unmatched in-flight content during reseeding.
  • Applies the runtime change only to the Claude adapter; other adapters and the wire protocol are unchanged.
  • Adds regression coverage for main-agent, subagent, history, and conversation-store reconciliation.

Verification

  • devenv shell -- pnpm check:ci
  • devenv shell -- pnpm test — 222 files and 1,734 tests passed.
  • Ran the desktop app with the debug protocol enabled.
  • Verified an 80-line completed response remained single after focus and online revalidation.
  • Verified a 60-line streaming response while repeatedly scrolling and triggering focus revalidation:
    • No rendered content disappeared.
    • All lines appeared exactly once.
    • No console errors were observed.

Checklist

  • pnpm check:ci and pnpm test both pass (no Rust changes)
  • I ran the affected surface and observed the change working
  • No wire message changed; WIRE_PROTOCOL_VERSION does not require a bump
  • New code and assets are my own work
  • Relevant comments were updated; no documentation changes were required

@linear-code

linear-code Bot commented Jul 22, 2026

Copy link
Copy Markdown

CODE-328

@Zerlight
Zerlight requested review from AprilNEA and lucas77778 July 22, 2026 02:36
@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown

Greptile Summary

This PR reconciles Claude live and historical messages using stable provider IDs. The main changes are:

  • Uses provider message IDs for streamed text and thought chunks.
  • Applies the same IDs to subagent messages and transcript replay.
  • Adds tests for reseeding, message grouping, subagents, and command boundaries.

Confidence Score: 5/5

The change looks mergeable after guarding deltas that arrive without a matching message start.

Provider IDs are applied consistently across the main reviewed paths.

A resumed or partial stream can assign an early delta to stale message state. The issue is limited to streams that do not begin with the expected start frame.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex ran the PR tests against the parent revision 4556ef7 and observed 3 provider-ID regressions and 69/72 tests passing.
  • T-Rex ran the PR tests against the PR source and confirmed all 72/72 tests passed across 5/5 files in 2.67s with exit code 0.
  • T-Rex validated the notable passing cases, including provider-ID convergence across SDK/history, subagent text/thinking identity, history replay identity, snapshot-covered live-chunk deduplication, and preservation of an unflushed in-flight tool call.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
packages/host/agent-adapter/src/native/claude-code.ts Switches live, subagent, thought, and history events to stable provider message IDs, but early deltas can still use a stale cursor.
packages/client/core/tests/integration/conversation-store.test.ts Adds coverage for replacing buffered live chunks with a completed history message sharing the same ID.
packages/host/agent-adapter/src/tests/message-grouping.test.ts Adds coverage for provider identity across Claude stream frames.
packages/host/agent-adapter/src/tests/claude-code-subagent.test.ts Updates subagent identity tests and verifies that subagent frames preserve the main cursor.
packages/host/agent-adapter/src/tests/normalize.test.ts Adds history replay coverage for provider-based text and thought IDs.
packages/host/agent-adapter/src/tests/claude-code-commands.test.ts Updates command tests to include provider message-start frames.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant SDK as Claude SDK
participant Adapter as Claude adapter
participant Store as Conversation store
SDK->>Adapter: message_start(provider ID)
SDK->>Adapter: content deltas
Adapter->>Store: Live chunks keyed by provider ID
SDK->>Adapter: Historical assistant row
Adapter->>Store: History chunk keyed by provider ID
Store->>Store: Reconcile history and live chunks
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant SDK as Claude SDK
participant Adapter as Claude adapter
participant Store as Conversation store
SDK->>Adapter: message_start(provider ID)
SDK->>Adapter: content deltas
Adapter->>Store: Live chunks keyed by provider ID
SDK->>Adapter: Historical assistant row
Adapter->>Store: History chunk keyed by provider ID
Store->>Store: Reconcile history and live chunks
Loading

Reviews (1): Last reviewed commit: "fix(agent-adapter): reconcile Claude mes..." | Re-trigger Greptile

Comment thread packages/host/agent-adapter/src/native/claude-code.ts
@AprilNEA
AprilNEA merged commit 54c9ac7 into master Jul 22, 2026
11 checks passed
@AprilNEA
AprilNEA deleted the ruocheng/code-328 branch July 22, 2026 06:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants