getsentry / getsentry/sentry-python
PydanticAI Agent.iter() not instrumented — missing tool execution and chat spans
- Lenguaje dominante
- Python
- Estrellas
- 2.2k
- Forks
- 669
- Merge medio
- 1 d 1 h
- PR fusionados (30 d)
- 213
Descripción
# Agent.iter() not instrumented — missing tool execution and chat spans
### Problem Statement
When using pydantic-ai's `Agent.iter()` to control agent execution step by step, Sentry does not create any spans. This means that tool calls, model requests, and the agent invocation itself are completely invisible in the Sentry UI.
This is a problem because `iter()` is the recommended way to drive an agent when you need fine-grained control over each execution step — for example, in real-time streaming scenarios like WebSocket consumers, where you want to process each node (tool call, model response, final result) as it arrives.
`Agent.run()` and `Agent.run_stream()` work fine and produce the expected spans. Only `iter()` is missing.
### How to reproduce
```python
import asyncio
import sentry_sdk
from sentry_sdk.integrations.pydantic_ai import PydanticAIIntegration
from pydantic_ai import Agent
sentry_sdk.init(
dsn="YOUR_DSN",
integrations=[PydanticAIIntegration()],
traces_sample_rate=1.0,
send_default_pii=True,
)
agent = Agent("openai:gpt-4.1-mini", system_prompt="You are a helpful assistant.")
@agent.tool_plain
def get_weather(city: str) -> str:
"""Get the weather for a city."""
return f"Sunny in {city}"
async def main():
# This works — creates invoke_agent, gen_ai.chat, and gen_ai.execute_tool spans:
result = await agent.run("What's the weather in Paris?")
# This does NOT create any spans (the bug):
async with agent.iter("What's the weather in London?") as agent_run:
async for node in agent_run:
pass # each node is processed but nothing shows up in Sentry
asyncio.run(main())
```
### Expected behavior
`Agent.iter()` should create an `invoke_agent` span with child `gen_ai.chat` and `gen_ai.execute_tool` spans, just like `Agent.run()` and `Agent.run_stream()` do.
### Additional context
In pydantic-ai v1.x, `Agent.run()` and `Agent.run_stream()` internally delegate to `Agent.iter()`. This means that any patch for `iter()` needs passthrough detection to avoid creating duplicate `invoke_agent` spans when `run()` or `run_stream()` are used — otherwise you'd get two nested spans for a single agent call.
pydantic-ai >= 1.0.0 is required (that's when `iter()` was introduced), as from sentry docs this is the minnimum verdsion supported.
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.