fix(web-ui): keep image attachments when editing a user message - #3167
Merged
Merged
Conversation
An edit-rerun is a rollback plus a fresh submission. The rerun only carried the text the edit composer owns, so the attachments stayed out of the new turn while the rollback had already deleted the turn that held them, and the images were gone for good. Rebuild the message's image contexts the way rollback and the failed-message refill already do, and pass them to the rerun as imageContexts/imageDisplayData. Drop canEditUserMessage and message.editDisabledImages with it. That gate forbade editing any message that carried images and had no caller; images stay uneditable, but they are carried through an edit.
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
Editing a user message that carried image attachments and rerunning it dropped the images. An edit-rerun is a rollback plus a fresh submission: the rerun callback forwarded only
sessionMutationLeaseId, so the new Turn was created without attachments while the rollback had already deleted the Turn whoseuserMessage.metadata.imagesheld them. The rerun now rebuilds the message's image contexts and passes them throughimageContexts/imageDisplayData, the same way rollback and the failed-message refill path already restore attachments.Type and Areas
Type: Bug fix
Areas: Web UI (FlowChat message list, message edit service, locales)
Motivation / Impact
Problem. With an image message, the edit path lost the attachments permanently — not just for the new Turn, since the rolled-back Turn was the only place their metadata lived. The edit composer is a text-only surface: images are composer-owned
imageContextsthat render outside the editor and never entercomposerPresentation, and the normal submission path inuseMessageSenderis the piece that turns them into a payload. The edit rerun skipped that step.What changes for users. Editing a message that has images keeps them and resubmits them unchanged alongside the edited text. Images stay non-editable: the compact editor still owns text only, and the thumbnails remain outside it — the layout already pinned by
UserMessageItemActions.test.ts. The rerun now matches what that layout implies.Removed dead code that contradicted this behavior.
canEditUserMessage()inUserMessageEditServicereturned false for any message withhasImagesand had no caller;UserMessageItemreimplemented the availability check and omitted the image condition, which is what let an image message reach the editor at all.message.editDisabledImagesinen-US/zh-CN/zh-TWwas the copy written for that gate, and it is removed with it.Scope. No Rust, protocol, or remote-scenario surface is touched. Editing is already disabled for remote and dispatch sessions (
canEditBase), androllback_session_to_turnis declaredUnsupportedfor remote workspaces, so this adds no new remote exposure.Verification
Results: 3 test files / 43 tests passed;
tsc --noEmitexit 0; eslint 0 errors;i18n:auditpassed with 0 warnings;i18n:contract:test37/37 passed. The design-system build is listed first because@openbitfun/uitype output must exist fortscto resolve it; it is not a change in this PR.New tests in
UserMessageItem.test.tsx:resubmits the original image attachments when editing a messageasserts the restoredImageContextreachesbuildImagePayload(id, image name, host path,isLocal: true) and thatflowChatManager.sendMessagereceives the resultingimageContexts/imageDisplayDatatogether with the edit'ssessionMutationLeaseId;reruns an edit without attachments when the message has no imagesis the control case asserting the send options stay exactly{ sessionMutationLeaseId }.Manual checks: not performed. Please confirm in-app: send a message with an image, edit the text, save, then verify the reran Turn renders the original thumbnails and the model receives the image.
Reviewer Notes
restoreImageContextsFromPayload(already used by rollback and the failed-message "fill to input" path) and handed to the send path throughbuildImagePayload, the same call normal submission uses.data_urlnor a still-readable hostimage_path, the rerun can only carry its name — exactly how the existing failed-message refill path degrades.Checklist