Upload a file in an agent chat¶
In an App's agent chat you can attach a file — a PDF, an image, a spreadsheet — with the paperclip in the message box. The file is stored in one of the App's memories, checked by the platform's scanner, and kept there after the chat.
What this doesn't do today
- The agent doesn't ask you for files. There is no upload request from the agent and no upload card in the chat; you attach files yourself.
- An attached file isn't sent to the agent with your chat message. The message the agent receives carries your text only. The file is stored, but the agent isn't told about it as part of that message.
For the limits, scan lifecycle and API in full, see the asset upload reference. For why files and references are separate things, see Assets vs. References.
Before you start¶
- An App with a working agent chat — App → Chats → Agent chat. See Chatting with an agent.
- A memory the file can go into. The App's agent needs at least one memory attached with read-write access. Without one, there's no paperclip.
- Write access to that memory — the first read-write one by name (see Where the file goes) — and the memory must accept uploads. It does by default, and the portal has no setting to change that yet.
Attach a file¶
- Open the App → Chats → Agent chat, and open a chat or start one with + New chat. The paperclip is greyed out until a chat is open, and while a message is sending.
- Click the paperclip (Attach a file) and pick a file.
- A progress bar shows while it uploads. The bytes go straight from your browser to storage; the portal doesn't relay them.
- A chip appears above the message box with the file's name and size.
The chip also shows the scan result, in words only when it isn't clean:
| The chip shows | Meaning |
|---|---|
| nothing after the size | Clean: scanned and available. |
| Scanning (amber) | Not scanned yet. The file is stored; downloads wait for the scan. |
| Blocked (red), with the scanner's signature | Flagged by the scanner. The bytes are deleted and the file can't be downloaded. |
Remove a chip with its ×. That only clears it from the message box; it doesn't delete the stored file.
Where the file goes¶
Into one fixed memory: the first, by name, of the memories attached to
the App's agent with read-write access. The portal doesn't look for one
you can write to. If you can't write to that memory, the upload is refused
with PERMISSION_DENIED, even if you could write to another of the agent's
memories. It is not a private, per-user place: anyone who can read that
memory can see the file there. To find it later, open that memory and its
Files tab.
What happens to the chip¶
The chip lives only in your message box. Sending a message doesn't attach the file to it, and reloading the page clears the chip. The stored file stays in the memory either way.
Limits¶
- 25 MB per file. A platform cap, the same for everyone; it can't be raised per App or per agent.
- These types only: PDF, PNG, JPEG, WebP, plain text, Markdown, CSV,
JSON, and Word, Excel and PowerPoint (
.docx,.xlsx,.pptx). GIF is not allowed. - The content must match the type. For types with a recognisable signature — PDF, images, Office files — the server checks the start of the file against the type it was uploaded as, and refuses a mismatch. Text, CSV and JSON have no signature to check.
Scanning and downloads¶
A file is downloadable only once its scan is clean. While it's
Scanning, a download is refused with SCAN_PENDING — try again later.
A Blocked file is refused with SCAN_BLOCKED, for good; upload a clean
copy instead. If the scanner flags a file while it's being uploaded, the
upload itself fails with MALWARE_BLOCKED.
On a self-hosted deployment with no scanner configured, a file stays Scanning unless the operator has set the server to mark files clean automatically — see the reference.
Download links are short-lived: 5 minutes by default, at most 1 hour.
A server can also offer public links: a link to a clean file in a memory
that isn't encrypted, which anyone holding it can open without signing in.
They are off unless the server's operator turns them on
(ASSET_PUBLIC_HOTLINK_ENABLED, with BASE_URL set) — see
Downloading in the reference.
When an upload is refused¶
The paperclip shows the reason under it.
| Refusal | Why | What to do |
|---|---|---|
| No paperclip | The App's agent has no read-write memory. | Attach one to the agent with read-write access. |
| Paperclip greyed out | No chat is open, or a message is sending. | Open or start a chat. |
SIZE_EXCEEDED |
Over 25 MB. | Send a smaller file. |
MIME_NOT_ALLOWED |
Not one of the allowed types. | Convert it — for example a GIF to PNG. |
INVALID_INPUT |
The file's content doesn't match its type (a renamed file, for example). | Upload the file in its real format. |
MEMORY_NOT_ACCEPTING_UPLOADS |
The destination memory is set not to accept uploads. | Ask the memory's owner. The portal can't change this setting yet. |
PERMISSION_DENIED |
You can't write to the destination memory — the first read-write one by name, whichever others you could write to. | Ask for write access to that memory. |
MALWARE_BLOCKED |
The scanner flagged the file during the upload. The bytes are deleted; a record is kept for audit. | Upload a clean copy. |
For builders¶
The portal uses the memory-addressed upload flow: beginAssetUploadV2
returns a presigned URL, the browser PUTs the bytes to it, and
completeAssetUpload checks and records the file. memoryAssets(memoryId)
lists a memory's files. The full contract — including the older
agent-addressed operations — is in the
asset upload reference and the
GraphQL schema.
Related¶
- Asset upload reference — limits, lifecycle, encryption and the API.
- Assets vs. References — why files and references are separate primitives.
- Chatting with an agent — where the agent chat is, and what it needs.
- Portal chat testing — broader manual-test checklist for agent chat.