Repository navigation
Keep an attached file as a file after a Bot on a harness answers - #1499
Open
davidmckayv wants to merge 2 commits into
Open
davidmckayv wants to merge 2 commits into
davidmckayv wants to merge 2 commits into
Conversation
A Bot on an endpoint (the LangGraph harness Desktop runs, among others) ends its run with a MESSAGES_SNAPSHOT of the thread as it was sent to it. The server inlines a file's contents on the way to the endpoint, so the snapshot carried the file's text, or an image's base64, where the person's reference to the file was. The browser applied it and Intelligence stored it: a text file became one giant block of its own contents when the answer finished, an image's thumbnail vanished, and a reload showed the same. The remote middleware now puts each person's message that carried a file back as they sent it in every snapshot the endpoint emits. The model is still sent the file's contents.
davidmckayv
requested review from
MikeRyanDev,
dustywusty,
guidovizoso,
mxmzb,
samjulien and
tylerslaton
as code owners
November 11, 2026 17:54
This branch has not been deployed
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.
What this changes
On a Bot OpenBot runs in a harness (the Personal Assistant on Desktop's LangChain harness, and any remote AG-UI Bot whose integration ends its run with a
MESSAGES_SNAPSHOT), a file a person attached turned into the file's raw contents the moment the answer finished: a text file became one giant block of text, an image's thumbnail disappeared, and a reload showed the same.Cause: the remote middleware in
server/src/copilot.tsinlines each attachment's contents on the way to the endpoint (inlineAttachments). ag-ui-langgraph ends every run with aMESSAGES_SNAPSHOTof the thread as it was sent to it, so the person's message came back holdingAttached file "x.txt": ...(or an image's base64) instead of the/api/attachments/<id>reference. The browser replaced its messages with that snapshot, and Intelligence stored it as the thread.Fix: the remote middleware keeps each person's message that carried a file, as sent, and puts it back by id in every
MESSAGES_SNAPSHOTthe endpoint emits (withAttachmentsAsSent, applied last over every step's stream). The model is still sent the file's contents, and later turns inline it again from the reference as they already do for history. Built-in Bots never emit a snapshot and were not affected (checked in the browser).Messages already stored as text in an existing conversation stay as they are.
Where it runs
Boundary and audit
Changelog
CHANGELOG.mdunderUnreleased, Conversations.Proof
server/tests/attachment-snapshot.test.ts: a remote Bot built throughbuildAgents, dialling a real local AG-UI endpoint over HTTP that ends its run with a snapshot of the messages it was sent, as ag-ui-langgraph does. It checks the model still receives the text file's contents and the image's bytes, and that the emitted snapshot, and the messages the client holds after applying it, keep the person's message exactly as sent (text file, image, files earlier in the thread, plain messages untouched). Onorigin/main: 3 fail, 1 pass. With the fix: 4 pass.server/tests/copilot.test.ts,attachment-parts,attachment-routes,headless-tools,learning-remote,bot-knows-its-model: all pass.tsc --noEmit(server),typecheck:testsand biome clean.agent-langgraph-agui) as the Personal Assistant, the way Desktop runs it. Headless Chromium attached a text file and an image, watched the message during and after the answer, then reloaded. Before: the text message became the file's contents after the answer and after reload, and the image vanished. After: both stay as file tiles during, after and after reload, in light and dark, including a second file later in the same conversation; the stored thread holds the/api/attachments/<id>references and the Bot's answer shows it read the whole file. A PDF is still refused by the composer, unchanged.