fix(chat): make attached images addressable and stop silent attachment loss - #197
Merged
Conversation
…t loss Analysis of staging conversations showed every image-editing session degrading the same way: the model receives image blocks as pixels only, so a media-library attachment's URL was invisible to it — it invented UUIDs and stock-photo URLs, or re-asked for something already provided. Meanwhile the composer had three paths that dropped an attachment with zero feedback, and Enter during streaming wiped the composer, the tray, and the pinned chips while sending nothing. Server: - validateAttachmentBlocks injects a reference line ahead of each image block: library images carry their delivery URL + storage path and a do-not-reupload directive; ephemeral images state they have no address and must never get an invented one - summary lines are now per-attachment — an attachment whose blocks were all dropped no longer inherits one, so the prompt cannot claim an image the model cannot see - fetchLinkContent accepts image URLs (pasted or dragged from another tab) and converts them to ephemeral context images - the system-prompt attachment section carries the storage path and the ephemeral warning, matching the in-message reference lines Composer: - Enter while streaming no longer falls through to a send that clears everything and delivers nothing - a failed upload now raises a toast and blocks send until the chip is removed — no more messages that silently go out without their file - clicking anywhere on the composer card focuses the textarea, and focus returns after send and after the attach menu closes, so paste lands in the input instead of vanishing on <body> - paste falls back to dataTransfer.items when files is empty - panel drops accept text/uri-list, so an image dragged from another browser tab attaches instead of navigating the page away
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.
Neden
13 Ağustos staging konuşmalarının analizi (4 konuşma, hepsi görsel değiştirme akışı) tek bir kök nedene indi: model, ekli görselin URL/path'ini göremiyor (image bloğu piksel taşır). Ajan var olmayan UUID'ler ve Unsplash URL'leri uydurdu, gerçek kütüphaneye çöp asset yükledi; kullanıcı 10 görseli elle yükleyip path yapıştırmak zorunda kaldı. Üstüne composer'da üç sessiz ek-düşürme yolu + streaming-Enter yarışı, "görseli ekledim" denilen 4 mesajın sunucuya eksiz ulaşmasına yol açtı.
Ne değişti
Server
validateAttachmentBlocksher image bloğunun önüne referans satırı enjekte ediyor: kütüphane görseli → delivery URL + storage path + "upload_media çağırma" direktifi; ephemeral görsel → "adresi yok, asla uydurma"fetchLinkContentgörsel URL'lerini kabul edip ephemeral context görseline çeviriyor (başka sekmeden sürüklenen görseller dahil)Composer
dataTransfer.itemsfallback'i; panel drop'larıtext/uri-listkabul ediyorTest
pnpm testtam süit yeşil (148 dosya / 1285 test); attachment-ingest testleri yeni sözleşmeyi pinliyor (descriptor satırları, per-attachment summary, image-URL link kanalı)🤖 Generated with Claude Code