Skip to main content

Installation

Quick Start

What Gets Traced

The Pydantic AI integration automatically captures:
  • Agent runs — input prompt, output text (including structured Pydantic model output), model name
  • Token usage — input_tokens and output_tokens from the agent result
  • Finish reason — pydantic_ai.finish_reason captured from the last model response (e.g. "stop", "length", "tool_call")
  • Errors — error type and message captured in event properties, then re-raised to the caller
  • Async support — both run() (async) and run_sync() (sync) are instrumented
  • Double-wrap guard — calling wrap() twice on the same agent is a safe no-op

Configuration

Projects

Route events to a specific project by passing its slug as project_id:
project_id sets the X-Raindrop-Project-Id header on every event. Omit it (or pass "default") to use your org’s default Production project, which is the existing behavior. The same option is accepted by the create_raindrop_pydantic_ai(...) factory. Invalid slugs are ignored with a warning and no header is sent.

Multiple projects in one process

Available in raindrop-ai>=0.0.56. When one service runs several agents that should report to different projects, create one RaindropPydanticAI wrapper per project. Each wrapper owns its own raindrop.Raindrop client, so the two route independently — there is no shared module-level state:
Each wrapper owns its configuration and delivery pipeline, so agents handled by different wrappers route independently. To share a single client across wrappers (or with the module-level API), construct a raindrop.Raindrop yourself and pass it via client=:

Structured Output

The integration handles Pydantic AI’s structured output types — the output is serialized to JSON for telemetry:

Async Usage

The wrapper supports both sync and async agent runs:

Identifying Users

Use identify() to associate a user with traits:
Traits values must be str, int, bool, or float.

Tracking Signals

Use track_signal() to record feedback, edits, or custom signals:

Tool catalog capture (ai.prompt.tools)

raindrop-pydantic-ai ≥ 0.0.12 reads the list off each request: Pydantic AI passes every Model.request() / Model.request_stream() a ModelRequestParameters whose function_tools, output_tools and native_tools are exactly what goes into the provider request, and wrap(agent) wraps those two methods on the agent’s model (and on a Model instance or "provider:model" string passed to run(model=...)) to bind that list for the duration of the request. Every provider span started inside it records ai.prompt.tools with the JSON Schema as given; native tools such as WebSearchTool are recorded as provider-defined. Capture is exact; a request with no tools records []. A Model shared by several agents reports each agent’s own list, and a wrapped agent run from inside another wrapped agent’s tool reports its own. Model spans come from the OpenLLMetry instrumentation of the underlying provider client (the openai instrumentation for OpenAIChatModel), which only runs with disable_auto_instrument=False; with the default True there is no model span at all, and Pydantic AI’s own instrument=True spans are not model spans in this sense. The instrumentation writes the same list to gen_ai.tool.definitions (OpenLLMetry ≥ 0.62 no longer emits llm.request.functions.*), which raindrop-ai ≥ 0.0.72 also rebuilds from; the wrapper does not depend on that, and its bound list takes precedence when both are present. Pass tools= on RaindropPydanticAI(...) / create_raindrop_pydantic_ai(...) as the default for every run, or wrap(agent, tools=[...]) for one agent; the per-wrap value replaces the default, either replaces the request’s list, and tools=[] records an empty catalog. Follows TRACELOOP_TRACE_CONTENT; needs raindrop-ai ≥ 0.0.70. See Tool catalog capture for the attribute format, the absent / [] semantics and the override shapes accepted.

Flushing and Shutdown

Always call flush() before your process exits to ensure all telemetry is shipped:

Factory Function (Legacy)

The create_raindrop_pydantic_ai() factory is available for backwards compatibility:

Application Git metadata (Python)

RaindropPydanticAI(...) and create_raindrop_pydantic_ai(...) accept the keyword-only app_git option. It defaults to True: explicit Raindrop Git environment or deployment context is applied immediately, and the base SDK may perform one bounded background local-Git lookup from the process working directory. Event capture, flush, and shutdown never wait for that lookup. Pass False to disable enrichment, or pass an AppGitOptions mapping with commit_sha, commit_dirty, branch, source_directory, detect_branch, and/or auto_detect. Automatic branch discovery remains opt-in through detect_branch=True (or RAINDROP_GIT_DETECT_BRANCH=true). For an ordinary in-process application, the process working directory is treated as the application-under-test checkout. A remote, coding, workflow, or observer process must not rely on its own checkout: pass app_git=False, provide explicit revision values, or set source_directory to the actual application checkout. Canonical per-operation properties remain authoritative. When supplying client=, configure app_git while constructing that Raindrop client; the supplied client is authoritative and the wrapper’s app_git argument does not reconfigure it. Release order is deliberate: first publish the base SDK feature, then publish the wrapper feature release with its minimum dependency coordinated to that base release. The existing raindrop-ai lower bound remains compatible, but application Git metadata is unavailable on an older core and must not be claimed complete until the base is upgraded. Until coordination assigns a released version, the wrapper checks for an explicit base app_git parameter and omits the option when unsupported. Explicit non-default configuration is debug-logged and omitted. Unsupported app_git is determined by signature inspection before construction, not by retrying initialization after a TypeError; Git configuration adds no initialization attempts and does not change any existing framework-specific initialization fallback.

Known Limitations

  • run_stream() is not instrumented — only run() and run_sync() are captured. Streaming runs produce no telemetry.
  • Multi-step agent runs: In agents with multiple LLM calls (e.g., tool use loops), only the final result’s data is captured. Intermediate LLM calls are not tracked individually.