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.
fix(client-core): preserve conversation identity across history reseeds #483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Uh oh!
There was an error while loading. Please reload this page.
fix(client-core): preserve conversation identity across history reseeds #483
Changes from all commits
57a2b5d9abe462d9bd53dFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dropping the image-stripped fallback means every attachment prompt renders twice after a reseed — and this is structural, not a race.
textHistoryEventatpackages/host/agent-adapter/src/history-util.ts:84emitscontent: [textBlock(text)], and every adapter (claude-code, codex, pi, opencode) routes its history user rows through it. So a provider history user row is text-only by construction. An echo carrying an image block can therefore never exact-match its seed row viatakeSeedPrompt'sJSON.stringifykey, and always falls through to this line as its own live item — landing after the agent reply that answered it, with its own Edit button (packages/presentation/ui/src/chat/user-message.tsx:66gatescanEditonbranchCursor !== undefined).The PR's own test encodes this outcome: the expected message count went from 2 to 3.
Technical details
Required outcome: an attachment prompt appears exactly once in the transcript after a reseed, in its original position, with its image intact.
Why the old fallback wasn't the bug: the pre-PR code already kept the seed row's own
branchCursoron a stripped match — it never let the echo's cursor overwrite the row's. The cursor-corruption vector this PR is fixing was the unconditional exact-content bind granting shared identity, not the stripped-content enrichment. Those are separable.Suggested approach: restore the stripped-content match as a dedupe-only bind (
trusted: false), so the echo consumes its row and is not re-folded, but gains none of the trusted powers. Optionally require the stripped match to be unambiguous (exactly one candidate row) so it can't mis-bind across repeated text.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This forward scan is a real fix on a destructive code path, but it ships with zero coverage — I reverted it to the backward scan (
findLastIndex-style) and all 110packages/client/coretests still pass. Nothing in the suite distinguishes the two directions.Repro that does distinguish them
No seed. Feed the buffer:
user-messagehost-m1, text'old prompt'host-m1carrying abranchCursor(the in-place update that appends the secondentriesrow with the same id)agent-messageagent-r1conversation-rewindcitinghost-m1user-messagehost-m2, text'rewritten prompt'Forward scan →
['rewritten prompt']. Backward scan →['old prompt', 'rewritten prompt']— the rewound prompt survives the cut and the transcript shows both.Given this governs a destructive truncation, I'd want that case pinned before merge — otherwise the next person refactoring the scan has no signal.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.