AAEP integration for agents built directly on the Anthropic Python SDK
Project description
Python Anthropic SDK Producer Example
AAEP integration with the official Anthropic Python SDK. This example demonstrates how to emit AAEP events from agents built directly on anthropic.Anthropic() and client.messages.stream(), without any agent framework.
If you're building Claude-powered agents using the Anthropic SDK and want AAEP support, this is the example to copy.
What this example demonstrates
- Direct integration with
client.messages.stream()andclient.messages.create() - Native handling of Anthropic's streaming event format (content_block_delta, content_block_start, etc.)
- Tool use translation: Anthropic's
tool_usecontent blocks → AAEPagent.tool.invoked - Multi-turn conversation handling
- Proper Claude model version reporting in
producer.model - Streaming output with sentence-boundary coalescing
- All 12 core AAEP event types in realistic Anthropic-API-driven usage
This example reuses the AAEPEmitter from python-minimal — same machinery, different integration. The Anthropic-specific code is just the adapter between Anthropic's API and the emitter.
When to use this pattern vs others
Pick this pattern when:
- You use the Anthropic Python SDK directly
- You want to leverage Anthropic's native tool use, prompt caching, or extended thinking
- You don't need (or don't want) a framework abstraction
Pick python-langchain when: you already use LangChain (regardless of LLM provider).
Pick python-minimal when: you're building everything from scratch, including your own LLM client.
Installation
cd examples/producers/python-anthropic-sdk
pip install -e .
You'll need an Anthropic API key in your environment:
export ANTHROPIC_API_KEY="sk-ant-..."
Requires Python 3.10 or newer.
Quick start
import anthropic
from aaep_anthropic_sdk import AnthropicAAEPAdapter
# Step 1: Set up your Anthropic client normally
client = anthropic.Anthropic()
# Step 2: Wrap it with the AAEP adapter
def my_transport(event):
"""Send the event to subscribers (HTTP/SSE, WebSocket, etc.)"""
print(event) # in production: serialize and send
adapter = AnthropicAAEPAdapter(send_event=my_transport, model="claude-opus-4-7")
# Step 3: Run a session through the adapter
session_id = await adapter.run_session(
user_message="Tell me about retirement planning.",
tools=[
{
"name": "fetch_balance",
"description": "Look up an account balance",
"input_schema": {
"type": "object",
"properties": {"account": {"type": "string"}},
},
},
],
tool_handlers={
"fetch_balance": lambda account: f"Balance for {account}: $3,247.18",
},
)
That's all. The adapter calls Claude, processes the streaming response, executes any tool_use blocks (with confirmation for irreversible tools), and emits AAEP events throughout.
Running the included demo
python -m aaep_anthropic_sdk.example_agent
This runs three example sessions (basic query, tool use, multi-turn) against Claude and prints every emitted AAEP event.
Note: the demo requires ANTHROPIC_API_KEY to be set. If not set, it falls back to a mock mode that doesn't call the real API.
Running the conformance suite against it
# Terminal 1: start the server (uses mock mode by default for portability)
python -m aaep_anthropic_sdk.server --port 8082
# Terminal 2: run conformance
aaep-conformance producer --endpoint http://localhost:8082 --level 2
The conformance suite drives the adapter with synthetic user prompts and verifies the resulting AAEP event streams.
Project layout
python-anthropic-sdk/
├── README.md
├── pyproject.toml
├── aaep_anthropic_sdk/
│ ├── __init__.py
│ ├── adapter.py # AnthropicAAEPAdapter
│ ├── example_agent.py # Runnable demo with real Anthropic API
│ └── server.py # HTTP/SSE wrapper for conformance testing
└── tests/
├── __init__.py
└── test_adapter.py
Key design decisions
1. The adapter directly consumes Anthropic's streaming events
Anthropic's client.messages.stream() returns a structured event stream:
message_start— model begins respondingcontent_block_start— new content block (text, tool_use, etc.)content_block_delta— incremental update (text_delta, input_json_delta)content_block_stop— content block donemessage_delta— usage stats, stop_reasonmessage_stop— full message done
The adapter translates each into the appropriate AAEP event. Text deltas feed the StreamCoalescer; tool_use blocks become tool.invoked/tool.completed pairs; stop_reason informs the terminal event.
2. Tool use safety enforced before execution
When Claude emits a tool_use content block, the adapter:
- Emits
agent.tool.invokedBEFORE calling the handler - For irreversible or high-risk tools: emits
agent.awaiting.confirmationand blocks on the reply - Only executes the tool handler on
decision: "accept" - Emits
agent.tool.completedwith the result
This means an unsafe action (e.g., send_email) cannot execute without explicit user consent — regardless of what the model "wants" to do.
3. Model version included in producer
The adapter reports the exact Claude model version in producer.model, so subscribers know which model is responding (different models may need different verbosity treatment for accessibility). When using claude-opus-4-7, you'll see "model": "claude-opus-4-7" in every emitted event.
4. Same emitter as python-minimal
The adapter imports AAEPEmitter, StreamCoalescer, and make_id from the python-minimal package. Bug fixes propagate; safety guarantees are uniform across all examples.
See also
../python-minimal/— manual loop pattern with the same emitter../python-langchain/— callback pattern with LangChain- Implementer's Guide §3.4 — Anthropic SDK specifics
- Anthropic SDK documentation — upstream reference
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aaep_anthropic_sdk_producer-1.0.0.tar.gz.
File metadata
- Download URL: aaep_anthropic_sdk_producer-1.0.0.tar.gz
- Upload date:
- Size: 19.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aea37d126f3a8d449ead25cdf1c49dbf593e17ff4e8e006025ee75959d91152a
|
|
| MD5 |
2e2373864f66fbff8b47eb7ef8b295a5
|
|
| BLAKE2b-256 |
278bb7bcb0ed61598deda0e4cc6de0129f324d3936ca10cbc4d71b6b200362cf
|
File details
Details for the file aaep_anthropic_sdk_producer-1.0.0-py3-none-any.whl.
File metadata
- Download URL: aaep_anthropic_sdk_producer-1.0.0-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cbe13f336dd6a8b7d6f87578e82d45160d40202d5b8c3b55dd301a776bd46372
|
|
| MD5 |
1cd9c7e6c3e95c9c91989bd86f31498d
|
|
| BLAKE2b-256 |
1a6555f9118c9d3b73a72656b9ae60db5c557fed32aafe5db80a08d887f29f4d
|