fix(desktop): attach non-image web uploads by path instead of failing the read - #103
Merged
Merged
Conversation
… the read The hosted web SPA (vweb) has no local filesystem. When a .md/text/pdf is dropped it is uploaded to ~/.hermes/uploads via the web shim and attached as a kind:'file' ref pointing at that server path. At submit/eager-upload time uploadComposerAttachment then re-read the file's bytes client-side via window.hermesDesktop.readFileDataUrl(serverPath). The web shim only caches data URLs for IMAGES (uploadBrowserFile gates the cache write on image/* mime), so for any non-image file the read returned '' and the code threw `Could not read <server-name>`, surfaced as the "Drop files / Could not read …md" toast — even though the upload itself had already succeeded. Images worked only because their bytes are cached. Fix: in the hosted web client, skip the client-side byte read for non-image files and attach by path only. The file already lives on the gateway (~/.hermes/uploads, made agent-readable by the upload endpoint's chown), so file.attach resolves the path directly (server.py _stage_session_file_attachment Case 2 reads the bytes and returns an @file: ref). Native Electron remote mode is unchanged — its paths live on the client disk and still upload bytes. Adds a regression test asserting the web client attaches by path with no read and no data_url. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
🔎 Lint report:
|
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.
Problem
In the hosted web rich-chat (vweb client), dropping a non-image file (
.md,.txt,.pdf, …) fails with a "Drop files / Could not read<name>" toast. Images work; other files don't. The upload itself succeeds — the file lands at~/.hermes/uploads/<date>/<name>and the chip shows that server path — but the attach then errors.Root cause
The hosted web SPA has no local filesystem. A dropped non-image file is uploaded to
~/.hermes/uploadsvia the web shim and attached as akind:'file'ref pointing at that server path. At submit/eager-upload time,uploadComposerAttachmentre-read the bytes client-side viawindow.hermesDesktop.readFileDataUrl(serverPath).But the web shim's
readFileDataUrlonly serves an in-memory cache thatuploadBrowserFilepopulates for images only (web-shim.tsgates the cache write onimage/*). So for any non-image file the read returns''→null→throw new Error('Could not read ' + label)(use-prompt-actions.ts), wherelabelis the server basename — exactly the toast in the screenshot. Images escape only because their bytes are cached at drop time.Fix
In the hosted web client, skip the client-side byte read for non-image files and attach by path only. The file already lives on the gateway (
~/.hermes/uploads, made agent-readable by the upload endpoint'schown), sofile.attachresolves the path directly —_stage_session_file_attachmentCase 2 reads the bytes and returns an@file:ref. Nodata_urlround-trip, no 16 MB cap, no double upload.window.__HERMES_WEB_CLIENT__(set bylib/web-shim.ts), matching the existing web-detection idiom._resolve_attachment_pathresolves any existing absolute file (no allowlist), so the uploads path resolves into Case 2.Test
Adds a regression test: the web client attaches a non-image file by path, with no client read and no
data_url, and returns the gateway@file:ref.Rollout
Canary-first. After merge: publish a new canary image and redeploy a canary instance to verify a real
.mddrop, then port to prod.