Framework integrationsAgent frameworks
Pydantic AI
Connect Pydantic AI agents to Radicas — native OpenTelemetry following the GenAI semantic conventions.
Status: experimental — implemented, not yet fixture-verified. Pydantic AI is the most
promising non-ADK case: it ships native OpenTelemetry following the GenAI semantic
conventions, so it may land close to the canonical contract with no shim. The deep-dive will
capture a fixture and diff span names/attributes before a registry card is written.
Install
pip install "radicas[pydantic-ai]" # = radicas + pydantic-aiUse
import radicas
radicas.init(service="pricing-agent", feature="flight-pricing")
# instrument="auto" detects pydantic_ai and calls Agent.instrument_all()
# (guarded: on older versions a warning tells you to pass instrument=True per Agent).
from pydantic_ai import Agent
agent = Agent("anthropic:claude-sonnet-4-5")
result = agent.run_sync(prompt)
radicas.shutdown()Explicit selection: radicas.init(instrument=["pydantic-ai"]).
What it emits
- Scope name:
pydantic-ai— expected, pending fixture. - Namespace:
gen_ai.*(native, per Pydantic AI's docs) — how close the span names are toinvoke_agent / generate_content / execute_toolis exactly what the deep-dive must answer. - Coverage: no registry card yet — all fields expected, pending fixture (model and token usage are documented by Pydantic AI as emitted; cache tokens unverified).
Shim behavior
- Client-side adapter: none yet — no registry card, so the exporter passes spans through
untouched (no
radicas.source_frameworkstamp until the card exists). - Server-side OTTL: none yet — the ClickHouse COALESCE safety net still catches known
gen_ai.*aliases.
Known limitations
- Not fixture-verified; treat dashboards populated from this source as best-effort until the card lands.
Agent.instrument_all()availability varies by version — the SDK degrades to a warning, and you can always passinstrument=Trueto individual agents.- Logfire (Pydantic's hosted backend) is NOT required — the same instrumentation exports to Radicas over plain OTLP.
Verify it works
SELECT model, input_tokens, output_tokens, estimated_cost_usd
FROM otel.llm_call ORDER BY ts DESC LIMIT 5;
-- inspect what it actually emitted (deep-dive helper):
SELECT DISTINCT ScopeName, SpanName FROM otel_traces ORDER BY 1, 2;Bench example (agent runnable, telemetry pending): agents/pydantic-ai/python in
radicas-integrations.