Attachments — images and files in a message
Shipped
View as MarkdownAn attachment is an image or a text file you send alongside your message. The model reads it as part of the turn — describing a screenshot, reviewing a log, answering questions about a config file. What you can attach depends on the model you brought: the app only offers what the model advertises it can read.
Why it matters
A prompt is text, but the thing you actually want help with often isn't. An attachment lets you hand the model the artifact itself — a photo, an error log, a CSV — instead of retyping or describing it. And because the attach options are driven by the model's advertised capabilities, the app never lets you send an image to a model that would reject the whole turn for it.
What you can attach
- Images, when the model advertises image input (vision): PNG, JPEG, GIF, WebP, BMP, AVIF, and SVG.
- Text files, when the model advertises file input: plain text and log files, source code in many languages, Markdown, JSON / JSONL, CSV / TSV, XML, YAML, HTML, and CSS.
Source-code files of every kind are read as plain text; the model still sees the real filename, so it knows it's looking at, say, a Dart file rather than a Python one.
Attaching one
The composer's attach button opens a short menu. Which entries appear depends on what the model accepts:
- Add image… / Add file… — pick from your device.
- Take a photo — capture with the camera. Phones only; desktop has no camera to reach for.
- Paste from clipboard — drop in an image you copied elsewhere. You can also insert an image straight from a keyboard that supports it.
Each attachment shows in the composer before you send — an image as a thumbnail, a file as a document chip — and you can remove any of them before sending. The attach button itself is hidden entirely when the model accepts neither images nor files, so it's never a dead control.
How the model receives it
- An image goes to the model inline with your message.
- A file goes as a native file part where the backend accepts one, and is otherwise folded into the message text so its contents still reach the model — either way the model reads the file.
If you switch a conversation to a model that can't read an image already in it, the turn still runs: the image is left out of the request and the app shows a warning saying so, rather than failing the send. The point is that a model swap never silently breaks a turn.
Where attachments live
Attachment bytes are stored encrypted on your device, in a blob store separate from the conversation database, and are cleaned up when you delete the message or conversation that referenced them. This is the same local-first, encrypted-at-rest handling the rest of your data gets — see Local-first & private by design.
What it doesn't do yet
- Images and text files only. There's no PDF, audio, or video attachment path today — a PDF is not among the pickable file types.
- The model must advertise the capability. If a provider doesn't report a model's input modalities, the app can't know it accepts images or files, so the attach options for those stay hidden even if the model would in fact accept them. Bring a provider that advertises what its models can read.