Recipes
Send an image or PDF attachment
Upload a file via presigned URL and let the agent see it as a multimodal input.
Send an image or PDF attachment
Upload a file directly to MinIO via a presigned URL, then reference it in a chat message.
The goal
A user message that includes an image or PDF; the agent processes it as a multimodal input on a vision-capable model, or text-falls-back on a non-vision model.
Steps
Get a presigned URL.
const presigned = await platos.attachments.presigned({ filename: "invoice.pdf", mimeType: "application/pdf", conversationId, });Upload directly to MinIO.
await fetch(presigned.url, { method: "PUT", body: fileBlob, headers: { "Content-Type": "application/pdf" }, });Bytes never touch the agent runtime.
Send the message.
await platos.threads.update({ threadId, messages: [{ role: "user", content: "Summarise this invoice", attachments: [presigned.attachmentId], }], });Stream the response.
The agent receives the attachment in its turn assembly; the multimodal adapter routes it to the model.
Verify
- Postman mode shows the attachment id in the assembled message.
- The trace shows a
multimodal.adaptspan withmimeType: application/pdf. - The reply references the attachment's content.
Vision routing
When the agent's model has vision: true, image bytes (or signed URLs) are inlined. PDFs are converted to page images plus extracted text. Non-vision models receive a text fallback ("the user attached an image: platos-code-runner if image processing is needed.
Limits
- Default per-file cap: 50 MB.
- Default mime types:
image/png,image/jpeg,image/webp,image/gif,application/pdf,text/csv,text/plain,application/json. - Retention: project default (configurable, see Attachments and files).
Next steps
- Filter PII before the attachment text reaches the model.
- See
platos-code-runnerfor sandboxed PDF extraction.
