✨ feat: Preview PDF Code-Interpreter Attachments Instead of Downloading - #16282
Open
TomasPalsson wants to merge 18 commits into
Open
TomasPalsson wants to merge 18 commits into
TomasPalsson wants to merge 18 commits into
Conversation
Clicking a code-execution PDF attachment force-downloaded it. Route previewable attachments (PDF, text) through the existing file preview dialog instead, fetching code-interpreter output bytes through the same session-scoped download path the chip's own download button already uses.
Contributor
|
👋 Thanks for the contribution! LibreChat merges all changes into Nothing is needed from you; your commits, reviews and discussion are unchanged. If the diff now shows files you did not touch, rebase onto git remote add upstream https://github.com/LibreChat-AI/LibreChat.git
git fetch upstream dev
git rebase upstream/dev
git push --force-with-leaseMaintainers: apply the |
Contributor
Author
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The prior commit's code-output check (`fileSource === 'execute_code'`) never fires: persisted code outputs carry a real storage source + file_id (already handled by the owner path) and download-fallback outputs (no storage strategy, or oversized) carry neither, only a session-scoped filePath. The dialog's fileId-gated effect/download guards then left the fallback case opening to a dead, empty dialog. Add `isCodeOutputAttachment`, mirroring LogLink's own download-routing discriminator, and use it both to pick the dialog's fetch path and to decide up front whether an attachment is fetchable at all before routing its click to the dialog instead of a direct download.
TomasPalsson
marked this pull request as ready for review
September 24, 2026 10:17
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.
Summary
Clicking a PDF (or text) attachment produced by code execution force-downloads it instead of previewing it.
FilePreviewDialogalready fetches an authed blob and renders it in an<iframe>for persisted PDF and text files, but the attachment chip inAttachment.tsxalways calledhandleDownloadon click and never opened the dialog. The dialog also only fetched persistedTFilerecords through the owner/share file-ACL path, not code-interpreter outputs served from/api/files/code/download/:session_id/:fileId, so a download-fallback code-output attachment (no persisted file record) would have opened on a dead, empty dialog even if a click had routed to it.FileAttachmentnow opensFilePreviewDialogon click whenevergetPreviewKind(...)says the file is previewable and its bytes are actually fetchable — either a persisted file (file_idplus a locally-storedsource, checked directly) or a code-interpreter download-fallback attachment (a session-scopedfilePath, nofile_id/source, matched by the newisCodeOutputAttachmenthelper inLogLink.tsx). The dialog picks its preview/download hook pair off that same check:useCodeOutputPreviewBlob/useCodeOutputDownloadfor a code-output attachment, or the existing owner/share hooks otherwise. Non-previewable files (zip, …) and attachments backed by an absolute http(s) URL still download directly on click, and the dialog's own download button keeps working either way.How it works
No server changes: the code-output route still sends
Content-Disposition: attachment, and fetching it as a blob sidesteps that the same way the existing owner/share preview path already does. The preview renders through an<iframe>, not<object>/<embed>, so it stays compatible with the CSP'sobject-src 'none'.Type of change
Testing
Tested environments/configuration:
Verified with the automated tests below; no manual browser run is recorded here yet.
Automated tests:
Parts/__tests__/Attachment.test.tsx: a persisted PDF and a download-fallback PDF (nofile_id/source) each open the preview dialog instead of downloading, and a non-previewable download-fallback file (zip) still downloads.Parts/__tests__/ArtifactRouting.test.tsxandParts/__tests__/TextAttachment.test.tsx: mock updates only, keepingLogLink's pure helpers (isLocallyStoredSource,isCodeOutputAttachment) real instead of mocking them away.__tests__/FilePreviewDialog.lifecycle.test.tsx: added a case for a download-fallback code-output attachment (nofileId/fileSource/fileType) previewing and downloading throughfilePath.npx jest src/components/Chat/Messages/Content/ src/data-provider/Files→ 80 suites, 1198 tests pass.npx tsc --noEmit(client) passes.Screenshots / recordings
Screenshots not attached yet.
Risk / compatibility
Client-only change, no server, schema, or config changes. This changes click behavior for any previewable persisted attachment (PDF, text), not just code-interpreter output: clicking now opens the preview dialog instead of downloading directly, though the dialog's own download button still downloads the same bytes. Non-previewable files and http(s)-sourced attachments keep the original direct-download click.
Checklist