maple-agent-tracing-pydantic-ai
Installation
SKILL.md
Maple agent tracing: Pydantic AI
Goal: every conversation = one Maple Agent Session. Each agent.run() = one turn (one trace) with transcript, chat spans with tokens, execute_tool spans with args/results, failed tools marked failed, sub-agents in their own lanes.
Mechanism: Pydantic AI's native OTel instrumentation (scope pydantic-ai, GenAI semconv on span attributes). No extra instrumentation package. Maple reads gen_ai.conversation.id as the session key for this framework.
Step 0: Detect
- Pydantic AI version:
python -c "import pydantic_ai; print(pydantic_ai.__version__)"(or readpyproject.toml/uv.lock/requirements*.txt).- Need 2.x (tested 2.51.0). 1.x has no
conversation_id=: tell the user to upgrade; do not work around it. ToolFailedneeds >= 2.16.
- Need 2.x (tested 2.51.0). 1.x has no
- Existing OTel setup. Search for
TracerProvider(,set_tracer_provider,logfire.configure,opentelemetry-instrument,sentry_sdk.init,instrument_all,Instrumentation(,.instrument =.- Logfire already configured → use the Logfire path (Step 2b).
- Another
TracerProviderexists → add aBatchSpanProcessor(OTLPSpanExporter())to it; do NOT create a second provider. - Nothing → Step 2a.
- Find: every
agent.run(/run_sync(/run_stream(/iter(call, where the chat/thread id lives in the request, everyAgent(construction, and every tool that calls another agent'srun(). - Other instrumentors on the same model client (
logfire.instrument_openai,OpenAIInstrumentor, OpenLLMetryTraceloop.init, a globallogfire.instrument_httpx()) → they double-trace model calls. Keep Pydantic AI's; ask before removing the others if they serve something else.logfire.instrument_httpx(client)on a non-model client (tool HTTP calls) is fine to keep.