Attach Images and Files

Pass attachments to harness agents and understand their local file lifecycle.

Pass Agno Image and File objects to run or arun, or upload multipart files through AgentOS. The configured model and native tools must support the attachment type.

from agno.media import File

# Use the database-backed agent from Run Claude or Run Codex.
result = agent.run(
    "Read the attached CSV and total its amount column.",
    files=[File(filename="sales.csv", content=b"item,amount\nA,120\nB,80\n")],
    session_id="attachment-demo",
)
print(result.status, result.content)

For Claude, enable the native Read tool and allow it through the permission configuration. For Codex, file-reading operations must be available under the selected native permissions. Disabling all file tools prevents a file attachment from being useful.

Over HTTP:

curl -N http://127.0.0.1:7777/agents/support-agent/runs \
  -F 'message=Read the attached CSV and total its amount column.' \
  -F 'session_id=attachment-demo' \
  -F 'stream=true' \
  -F 'files=@sales.csv;type=text/csv'

Use the images multipart field for images and supply the correct upload content type. For Python byte inputs, specify the image format explicitly:

from pathlib import Path
from agno.media import Image

image = Image(content=Path("chart.png").read_bytes(), format="png", mime_type="image/png")
result = agent.run("Describe this chart.", images=[image], session_id="attachment-demo")

Without a file path, format or MIME type, raw image bytes can be staged with a .bin extension that Claude's Read tool rejects. Audio and video inputs are unsupported by these adapters and are rejected.

Where attachments live

Agno stages attachment bytes under the effective cwd/.agno/uploads/<run_id>/. Claude receives paths in its prompt and opens them with native tools. Codex receives images as native image inputs; files are supplied as paths.

The run input stores the durable attachment data. It is separate from Claude's native JSONL transcript store. A URL without attachment bytes is passed as a reference; staging does not automatically download it.

Normal cleanup removes staged files after execution unless keep_uploads=True. Account for interrupted processes and staging failures in the deployment's cleanup policy; filesystem work is not a database transaction.

Follow-up turns and replicas

The adapter restores attachments from up to ten preceding runs on the active conversation branch. Restoration writes under the current workspace's .agno/uploads; historical paths are metadata, never write authority. Unsafe run IDs and symlinked staging paths are refused, and partial staging rolls back files created by that operation.

Staging locations are recorded per original attachment-owning run. Files introduced on a later replica and A → B → A moves receive path corrections in the prompt. Relocation notes can repeat because successful staging does not prove the harness consumed a previous note. Older sessions use the legacy session-root fallback; locations never recorded cannot be reconstructed exactly.

Cleanup removes a run directory created by staging, including sibling files the harness produced there. For a preexisting directory it removes only staged inputs. This attachment containment does not isolate the harness's other filesystem tools; use runtime permissions and, when available, a sandbox for that boundary.

Attachments do not restore arbitrary files created by the agent. Session sandbox allocation and workspace snapshots are separate from this feature. See Sessions and State.

The Claude media cookbook and Codex media cookbook exercise image/file inputs and cleanup.