Add message ID tracking and session registry for client deduplication#72
Merged
Add message ID tracking and session registry for client deduplication#72
Conversation
- Capture upstream message IDs from Claude (msg.message.id or msg.id) and OpenCode (part.messageID) adapters - Propagate messageId to all emitted ChatMessages (text deltas, tool calls, done messages) - Add session registry (src/sessions/registry.ts) with file locking for concurrent access safety - Sessions tracked from first message with Perry-assigned IDs, linked to agent session IDs when available - Auto-import external sessions discovered during listing - Add comprehensive test coverage (96 session-related tests) This enables clients to deduplicate messages on reconnection using messageId + content as a stable key. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Registry changes: - Remove unused functions (touchSession, getSession, findSessionByAgentId, getAllSessions, deleteSession, sessionExists) - Keep only: createSession, linkAgentSession, getSessionsForWorkspace, importExternalSession Error handling: - Fix silent error swallowing in manager.ts - createSession now properly awaited - linkAgentSession errors routed to handleAdapterError Update checker: - Skip update check for worker commands (programmatic use) - Use console.error instead of console.log (doesn't pollute stdout) Web UI: - Add messageId-based deduplication for reconnection scenarios - Track seen messages via seenMessageChunksRef - Deduplicate user messages, tool_use, tool_result by messageId/toolId Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment on lines
226
to
235
| this.emitMessage({ | ||
| type: 'done', | ||
| content: 'Response complete', | ||
| messageId: this.currentMessageId, | ||
| timestamp, | ||
| }); | ||
| this.currentMessageId = undefined; | ||
| } | ||
| } | ||
|
|
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
Fix bug where currentMessageId wasn't cleared in error or interrupt scenarios, causing subsequent messages to reuse stale IDs and break client-side deduplication. - Claude adapter: clear in handleProcessExit - OpenCode adapter: clear in catch block and interrupt method Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
msg.message.idormsg.id) and OpenCode (part.messageID) adaptersmessageIdto all emittedChatMessageobjects (text deltas, tool calls, done messages)src/sessions/registry.ts) with file locking for concurrent access safetyThis enables clients to deduplicate messages on reconnection using
messageId + contentas a stable key.Additional changes (review feedback)
Registry simplification:
Error handling:
Update checker fix:
workercommands (was breaking OpenCode session listing by polluting stdout with update messages)Web UI deduplication:
Test plan
🤖 Generated with Claude Code