AttachmentsSession-private files, content-addressed and idempotent, shown to the model only when asked for.

An attachment is a file that belongs to one session. It is stored beside the agent's state, addressed as attachment:<id>, and deliberately kept out of everything else until the agent asks for it.

Session-private by design

Files land in <stateDir>/session-attachments/<sessionId>/<id>.bin with a .json sidecar of metadata. The design comment is explicit that nothing is copied into cross-session memory or published to IPFS unless the agent explicitly does it — an attachment is context for one conversation, not a durable asset, until someone decides otherwise.

The id is the SHA-256 of the content, which makes uploading the same file twice idempotent: same bytes, same id, no duplicate.

Bounds: 100 MiB per attachment, 200 attachments per session, 16 referenced by any one message (see Limits). Large files arrive through a chunked upload (BeginFileUploadAppendFileUploadChunkCommitFileUpload), capped at 2 GiB with an hour-long TTL.

Reading one

read attachment:<id> behaves differently by type, and the branching is the interesting part:

    An image, under ~4.5 MB, when the model accepts image input → returned as real multimodal content: a text part plus an image part carrying base64 data and mime type.

    Text, under the tool-result cap → returned inline.

    Anything else → a summary explaining why it is not viewable inline, with the suggestion to save it to memory and work on it with execute.

A detail worth knowing: the image rides the tool result to the model only. The durable event and the UI keep just the structured output, so a transcript does not carry megabytes of base64 for every re-render, and replay does not re-send the image on every subsequent turn.

That is the same reason attachments are metadata-only in replay: a message's attachments appear as a description of what is available, and content is pulled deliberately. As the code puts it — content stays out of context until the model asks.

Moving an attachment somewhere durable

Through write, with the attachment as the source:

    write ~/memory/<path> with {fromAttachment: "<id>"} — save it into memory, where execute can reach it at /workspace.

    write ipfs:// with {fromAttachment: "<id>"} — publish it and get a CID back (requires the publish grant).

Related

Do you like what you are reading? Subscribe to receive updates.

Unsubscribe anytime