Skip to content
Changelog

ClaudeAgent hands images and PDFs to Claude Code inside the message

October 16, 20261 min read

Agno's ClaudeAgent still stages each attachment under .agno/uploads/<run_id>/, then sends the Claude Agent SDK one streamed user message holding the prompt text followed by an image or document block for every image and PDF. Claude sees the picture directly and has no reason to open the file.

Earlier releases listed the paths and left Claude to open them with Read. For an image, Read returns the whole file as base64 inside a tool result, and a PNG of a few hundred KB overflowed the SDK's 1 MiB message buffer or the sandbox's 256 KiB event frame. In the PR's live test, a 467 KB PNG uploaded through AgentOS to a Docker-sandboxed Claude agent used to fail on the SDK buffer, and with this change it completed in 7.5 s with no tool calls.

We ran ClaudeAgent.arun() with a PNG, a real PDF and a memo.pdf that holds HTML, against a stand-in SDK client that records what it receives.

# real output, earlier release: what the SDK client received (stand-in Claude SDK)
SDK received: str
What does the chart show?
Attached files. Read them before answering; images and PDFs can be opened with the file tools:
- <cwd>/.agno/uploads/<run_id>/image-1.png (image/png, 74 bytes)
- <cwd>/.agno/uploads/<run_id>/report.pdf (application/pdf, 45 bytes)
- <cwd>/.agno/uploads/<run_id>/memo.pdf (application/pdf, 22 bytes)
# real output, this release: same run, same stand-in
SDK received: streamed user message
What does the chart show?
Attached files:
- <cwd>/.agno/uploads/<run_id>/image-1.png (image/png, 74 bytes; already included in this message, do not read it, the file is on disk for programs)
- <cwd>/.agno/uploads/<run_id>/report.pdf (application/pdf, 45 bytes; already included in this message, do not read it, the file is on disk for programs)
- <cwd>/.agno/uploads/<run_id>/memo.pdf (application/pdf, 22 bytes; read it with the file tools before answering)
block: {"type": "image", "media_type": "image/png", "base64_chars": 100}
block: {"type": "document", "media_type": "application/pdf", "base64_chars": 60}

Agno reads each file's signature to choose what goes inline, so memo.pdf keeps its label in the prompt and stays a file for the Read tool. Text, CSV and other files, plus any image or PDF over 4 MiB, keep the Read path too. Every file still lands on disk, so a program Claude writes can open it. Sandboxed agents pick this up once you rebuild the runtime image with build_image.py, or redeploy it on AgentCore.

See the cookbook, and learn more about where attachments live in the documentation.

Frequently asked questions

PNG, JPEG, GIF and WEBP images and PDFs of up to 4 MiB each. Text, CSV and other files, and larger images or PDFs, stay on disk for Claude's Read tool.

Claude opened the image with its Read tool, which returns the whole file as base64 in a tool result. An image of a few hundred KB pushed that result past the Agent SDK's 1 MiB message buffer or the sandbox's 256 KiB event frame.

Agno checks the bytes, finds no PDF signature, and leaves the file on disk with a prompt line asking Claude to read it with the file tools.

Yes. Runtime images built before this release keep the old behaviour, so rebuild the Docker image with build_image.py or redeploy the AgentCore runtime.

Shipped around the same time