Appearance
Chat Attachments
Chat visitors can attach an image or a PDF to a message so the agent reads it directly — no OCR preprocessing, the model sees the file. Useful for intake flows ("upload your insurance policy", "send a photo of the damage") where the answer depends on document content.
Overview
| Aspect | Detail |
|---|---|
| Supported types | Images (JPEG, PNG, WebP) and PDF |
| Max size | 10 MB |
| Max PDF pages | 10 (an over-limit PDF is rejected, not truncated) |
| Attachments per message | 1 (v1) |
| Provider support | OpenAI provider only in v1 (Claude provider deferred) |
Attachments are off by default. See Enabling Attachments below.
Attaching a File
A paperclip icon appears in the composer toolbar when attachments are enabled for the agent.
- Tap/click the paperclip.
- Mobile: the OS presents its native camera/gallery/file sheet (no custom picker UI — the hidden file input's
accept="image/*,application/pdf"triggers the browser's own affordance). Desktop: the OS file picker opens directly. - Pick a file. It uploads immediately — a chip appears in the composer showing a thumbnail (images) or a document icon (PDF), the filename, and an upload progress bar.
- Once the upload finishes, the chip's progress bar is replaced by the file size and the Send button becomes available. Only one pending attachment is held at a time — picking a new file while one is pending replaces it.
- Sending the message clears the pending chip and rides the attachment along in the message; the attachment then renders inline in the sent message bubble.
Upload Errors
| Error | When | Recovery |
|---|---|---|
| Unsupported file type | File isn't JPEG/PNG/WebP/PDF (checked client-side, re-validated server-side against the real file bytes) | Choose another file |
| File is too large (max 10 MB) | File exceeds the size cap | Choose another file |
| PDF has too many pages (max 10) | PDF exceeds the page cap | Choose another file |
| Upload limit reached | Session or agent daily quota reached (HTTP 429) | Retry later — this error is retryable |
| Upload failed | Network error or unexpected server error | Retry — the chip offers a Retry action |
Validation-reject errors (wrong type, oversize, page cap) prompt "Choose another" — retrying the same file cannot succeed. Transient errors (quota, network) prompt Retry, which re-uploads the same file.
History Rendering
Once sent, an attachment renders inside its message bubble:
- Images render inline (bounded to a max width/height,
object-cover). - PDFs render as a chip with a document icon, the filename, and a download icon — clicking opens the file in a new tab via a freshly minted signed URL.
Every render — the composer preview, a message bubble in the live conversation, and a bubble loaded from session history — mints its own short-TTL signed URL (GET /api/v1/assets/{id}/url). No signed URL is ever cached or reused across renders; if minting fails (e.g. the asset was cleaned up), the chip degrades to a named, non-interactive placeholder rather than a broken image or dead link.
Agent Response Behavior
When attachments are enabled, the agent's response pattern changes automatically — no instruction authoring required:
- Read the uploaded image or PDF and pull out every value it's collecting that appears in it.
- Confirm in one message — a warm, natural recap of everything detected (e.g. "I can see your name is..., your email is..., and your company is...") and a request to confirm or correct it.
- Ask only for what's missing — once confirmed, the agent asks for the remaining required fields one at a time, applying any corrections along the way. It never re-asks for a value already visible in the upload.
This closes a bug where attachment-enabled agents ignored the uploaded file's content and re-asked for data the visitor had already provided.
The behavior is applied automatically to the assembled system prompt whenever attachments are enabled for the agent (see below) — it is runtime-injected on every chat run, not saved into the agent's own instructions. Editing or inspecting the agent's instructions in the designer will never show this section.
Enabling Attachments
Attachments is a plain per-agent capability — it does not participate in the chat theme's behavior-defaults cascade. There is no theme fallback and no create-path inheritance:
effective_attachments = agent.chat_ui.enable_attachments ?? false- New agents always start disabled. There is no agent override yet at create time, and there is no theme to inherit from — the effective state is unconditionally
falseuntil explicitly turned on. - Where to toggle it: in the agent form, open the Data Collection section — the toggle sits beside the data-extraction enable toggle, labeled "Allow File Uploads". This is NOT a Chat/theme editor setting.
- Via MCP:
gnosari_manage_data_collection(gnosari_id=<id>, enable_attachments=true|false). Passtrueto let visitors attach a photo or PDF;falseto turn uploads off. Omit the param (leave itNone) to leave the current setting unchanged.
Not implemented (out of scope for this feature): a plan/billing-tier gate on attachments. The upload endpoint and the URL-mint endpoint are the single seam a sibling initiative (
attachments-plan-gating) plugs a plan-entitlement check into later.
Wizard Guardrail
The conversational Build Wizard can write agent instructions that promise an upload affordance ("upload your document", "send me a photo of..."). If attachments are not enabled for that agent, the promised upload button never appears — a dead promise the visitor can't act on.
To prevent this, agent instructions are checked against attachments capability at two points:
| Chokepoint | Behavior |
|---|---|
Create (gnosari_create) | New agents always start with attachments disabled (see above), so if the instructions contain upload/attach/OCR-style language (e.g. "upload", "attach", "send me a photo of..."), agent creation is rejected — the error lists every problem found so one retry fixes everything |
Edit (gnosari_manage_instructions) | The same check runs before an instructions update is applied. If the agent's attachments capability is disabled and the new instructions promise an upload, the update is rejected |
The instructions are never silently rewritten or stripped — the caller must either rephrase for conversational intake (ask the visitor to type/describe the information) or enable attachments first, then retry. This guardrail closed a live incident where an agent's instructions promised document upload while attachments were off, leaving visitors with no way to comply.
Cross-References
- Assets API reference —
POST /assets,GET /assets/{id}/url, validation matrix, quota - WebSocket Chat guide — the
attachmentsfield on a chat turn - Enabling Attachments above — the agent form's Data Collection section and the
enable_attachmentsMCP param. Attachments no longer participates in the chat theme's behavior-defaults cascade; see Chat Themes → Behavior Settings for the settings that still do - Build Wizard — conversational agent creation