Skip to main content
Let your tools hand back screenshots, charts, or rendered pages — the agent sees the picture, not a description of it.
The user asks a visual question; tools return images the vision model reads on the next turn.

Quick Start

1

Screenshot tool returning an image

A @tool-decorated function captures a screenshot and hands the PNG bytes back to the agent. The vision model sees the actual image on the next turn.
The user asks for a screenshot summary; the tool returns multimodal content the model can read.
2

Remote image via URL

No downloading needed — pass url= directly and the model fetches it.
3

Bare list (lightweight shape)

Skip the helper — return a plain list of part-dicts. The runtime normalises it automatically.
---Let your tools hand back screenshots, charts, or rendered pages — the agent sees the picture, not a description of it.
The user asks a visual question; the tool returns image bytes the vision model reads on the next turn. The runtime emits two messages automatically:
  1. A tool message satisfying the tool_call_id contract (containing a short text fallback).
  2. A follow-up user message carrying the image_url parts.
This two-step delivery is required because most providers reject image_url parts inside tool-role messages. You don’t need to do anything — it’s automatic. When an assistant turn contains multiple tool calls, all tool replies stay consecutive and the media user message is appended only after the full batch flushes.

Choosing the Return Shape

All four shapes are auto-detected by the runtime — pick whichever feels natural:

Configuration Options

There is no separate config class. Import the helpers from praisonaiagents.tools:
image_part accepts any of:
  • Raw bytes
  • Base64 str
  • A data: URI string
  • A remote url= keyword argument

Common Patterns

Screenshot tool

Chart renderer (matplotlib → PNG)

MCP image passthrough

MCP servers often return image blocks with a mimeType key. Return the block as-is — the runtime normalises mimeTypemime automatically.

Best Practices

The runtime enforces a 5 MB cap per image part (MULTIMODAL_IMAGE_BYTE_LIMIT = 5_000_000). Images over this limit are silently dropped with a warning — the model only sees the text fallback.Resize before returning:
Image parts are only perceived by models that support vision. Use:
  • gpt-4o / gpt-4o-mini (OpenAI)
  • claude-3-5-sonnet-20241022 or any Claude 3+ model (Anthropic)
  • gemini-1.5-pro / gemini-1.5-flash (Google)
Plain text models only see the text fallback string — they do not raise an error.
A caption improves grounding and is the only signal a non-vision model gets. Always pair image_part with text_part:
This also helps when the image is dropped due to the 5 MB cap — the agent still gets useful context.
file_part is currently surfaced to the model as a text annotation [file: name (mime)]. Most LLM providers cannot ingest arbitrary binary files inline.For PDFs or other documents you want the model to see, rasterise to images first:

Security

Text parts returned by external or untrusted tools are automatically wrapped in a prompt-injection fence — the same protection used for text-only tool output. You don’t need to do anything, but know that if you mark a tool as external, its text parts will be fenced before the model sees them.

Multimodal Agents

Send images to the agent via Task(images=[...]) or agent.chat(attachments=[...]) — the symmetric direction.

Image Generation

Generate new images with AI models and use them in agent workflows.