Skip to main content

AG-UI integration for the Anthropic Claude Agent SDK, with multimodal attachment support (images and documents)

Project description

ag-ui-claude-sdk-fiqros

Implementation of the AG-UI protocol for the Anthropic Claude Agent SDK (Python), with support for user attachments — images and documents sent by the user now reach the model instead of being silently discarded.

This is a fork of integrations/claude-agent-sdk from the AG-UI project (MIT), maintained by the Fiqros team. It tracks upstream and adds the attachment fix described in Attachment support below, contributed by the Fiqros team. The import name is unchanged, so it is a drop-in replacement for the upstream package.

Installation

pip install ag-ui-claude-sdk-fiqros

Or from a checkout:

pip install -e .

Usage

The adapter manages the SDK lifecycle internally — just call adapter.run(input_data):

from ag_ui_claude_sdk import ClaudeAgentAdapter, add_claude_fastapi_endpoint

adapter = ClaudeAgentAdapter(name="my_agent", options={"model": "claude-haiku-4-5"})
add_claude_fastapi_endpoint(app=app, adapter=adapter, path="/my_agent")

Attachment support (fork changes)

Investigated, fixed and documented by the Fiqros team.

Upstream, a user message carrying an attachment never reached the model. Claude would reply "It looks like you forgot to attach the image!" — with no error and nothing in the logs.

Cause. When a user attaches a file, AG-UI sends the message content as a list of blocks rather than a plain string:

{"role": "user", "content": [
  {"type": "text",  "text": "what is in this image?"},
  {"type": "image", "source": {"type": "data", "value": "<base64>", "mime_type": "image/png"}}
]}

process_messages() walked that list looking for the first block with a .text attribute, took it, and stopped. Image, document, audio and video blocks have a .source rather than .text, so they matched nothing and fell out of the loop unreferenced. Claude was asked about an image it was never shown.

Fix. AG-UI and Anthropic describe attachments with the same structure under different field names, so the fix is a rename, not a conversion — the base64 payload is passed through untouched, with no decode/re-encode:

AG-UI      {"type": "data",   "value": "<b64>", "mime_type":  "image/png"}
Anthropic  {"type": "base64", "data":  "<b64>", "media_type": "image/png"}

Two changes implement it:

  • utils.pyconvert_content_blocks() renames every block and returns the full list. Messages with no attachment still return a plain string, so the common path is byte-for-byte unchanged.
  • session.py — content blocks require ClaudeSDKClient.query()'s streaming form (AsyncIterable[dict]), since its str form cannot carry them. A small async generator wraps the blocks in a user-message envelope.

Also fixed along the way:

  • An attachment-only message (no text) previously produced an empty prompt.
  • A message split into several text blocks lost everything after the first.
  • Unsupported or malformed blocks are now skipped with a warning instead of in silence.

Supported: images and documents, both inline base64 and URL sources. Audio and video blocks are skipped with a warning — Claude does not accept them.

Full analysis, evidence and rejected alternatives: BUG_REPORT_attachments_dropped.md.

Features

  • User attachments - Images and documents in user messages are passed through to the model
  • Full lifecycle management - Handles client pooling, message extraction, and event translation internally
  • Interrupt support - Call adapter.interrupt() to stop a running query
  • Dynamic frontend tools - Client-provided tools automatically added as MCP server with auto-granted permissions
  • Frontend tool halting - Streams pause after frontend tool calls for client-side execution (human-in-the-loop)
  • Streaming tool arguments - Real-time TOOL_CALL_ARGS emission as JSON arguments stream in
  • Bidirectional state sync - Shared state management via ag_ui_update_state tool
  • Context injection - Context and state injected into prompts for agent awareness
  • Event cleanup - Hanging events (tool calls, reasoning blocks) automatically closed on stream end
  • Custom tools via MCP - Define custom tools using Claude SDK's @tool decorator
  • Forwarded props - Per-run option overrides with security whitelist

Examples

The integration includes 5 example agents:

Route Description Features
/agentic_chat Basic conversational assistant Simple chat
/backend_tool_rendering Weather tool (backend MCP) Backend tool execution, tool rendering
/shared_state Recipe collaboration Bidirectional state sync, ag_ui_update_state
/human_in_the_loop Task planning with approval Frontend tools, step tracking, approval workflow
/tool_based_generative_ui Frontend tool rendering Dynamic frontend tools, generative UI

Running the Examples

# Install dependencies
cd integrations/claude-agent-sdk/python
pip install -e .

# Start server (port 8019)
cd examples
ANTHROPIC_API_KEY=sk-ant-xxx python server.py

# Start Dojo (in another terminal)
cd apps/dojo
pnpm dev

Visit http://localhost:3000 and select "Claude Agent SDK (Python)"

Session Persistence

Claude SDK maintains conversation state in the .claude/ directory. For production deployments:

  • Development: Sessions persist locally in .claude/{session_id}/
  • Production: Mount .claude/ as a persistent volume in your container
  • Resumption: Pass resume=<session_id> via the options dict or forwarded_props

See Claude SDK Hosting Guide for deployment patterns.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ag_ui_claude_sdk_fiqros-0.1.6.tar.gz (64.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ag_ui_claude_sdk_fiqros-0.1.6-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

File details

Details for the file ag_ui_claude_sdk_fiqros-0.1.6.tar.gz.

File metadata

  • Download URL: ag_ui_claude_sdk_fiqros-0.1.6.tar.gz
  • Upload date:
  • Size: 64.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ag_ui_claude_sdk_fiqros-0.1.6.tar.gz
Algorithm Hash digest
SHA256 8037ec37829d84e31c177246ab2933479025c769a2b30a7691bb4514fe4e4c8b
MD5 30bea781f0bda22798791e8beb699d89
BLAKE2b-256 cdc7816436816973abe129899fd453c356cf20ddde6599f1671548c31dc81984

See more details on using hashes here.

File details

Details for the file ag_ui_claude_sdk_fiqros-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: ag_ui_claude_sdk_fiqros-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 36.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ag_ui_claude_sdk_fiqros-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 4923f0d8078f4c3c98a3d5c508e564b5768b90bc4965f4d4f7c655048426aba5
MD5 5ca7a38ef7720a9abd6d667fa897d33c
BLAKE2b-256 944716230715e1e116fd98efb2ba3cca69837df68f8732c8b11249b19e88d677

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page