Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions sentry_sdk/integrations/openai_agents/patches/agent_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ def _patch_agent_run():
original_execute_handoffs = agents._run_impl.RunImpl.execute_handoffs
original_execute_final_output = agents._run_impl.RunImpl.execute_final_output

def _start_invoke_agent_span(context_wrapper, agent):
# type: (agents.RunContextWrapper, agents.Agent) -> None
def _start_invoke_agent_span(context_wrapper, agent, kwargs):
# type: (agents.RunContextWrapper, agents.Agent, dict[str, Any]) -> None
"""Start an agent invocation span"""
# Store the agent on the context wrapper so we can access it later
context_wrapper._sentry_current_agent = agent
invoke_agent_span(context_wrapper, agent)
invoke_agent_span(context_wrapper, agent, kwargs)

def _end_invoke_agent_span(context_wrapper, agent, output=None):
# type: (agents.RunContextWrapper, agents.Agent, Optional[Any]) -> None
Expand Down Expand Up @@ -72,7 +72,7 @@ async def patched_run_single_turn(cls, *args, **kwargs):
if current_agent and current_agent != agent:
_end_invoke_agent_span(context_wrapper, current_agent)

_start_invoke_agent_span(context_wrapper, agent)
_start_invoke_agent_span(context_wrapper, agent, kwargs)

# Call original method with all the correct parameters
result = await original_run_single_turn(*args, **kwargs)
Expand Down
41 changes: 36 additions & 5 deletions sentry_sdk/integrations/openai_agents/spans/invoke_agent.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import sentry_sdk
from sentry_sdk.ai.utils import set_data_normalized
from sentry_sdk.consts import OP, SPANDATA
from sentry_sdk.scope import should_send_default_pii

from ..consts import SPAN_ORIGIN
from ..utils import _set_agent_data
Expand All @@ -11,8 +13,8 @@
from typing import Any


def invoke_agent_span(context, agent):
# type: (agents.RunContextWrapper, agents.Agent) -> sentry_sdk.tracing.Span
def invoke_agent_span(context, agent, kwargs):
# type: (agents.RunContextWrapper, agents.Agent, dict[str, Any]) -> sentry_sdk.tracing.Span
span = sentry_sdk.start_span(
op=OP.GEN_AI_INVOKE_AGENT,
name=f"invoke_agent {agent.name}",
Expand All @@ -22,13 +24,42 @@ def invoke_agent_span(context, agent):

span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "invoke_agent")

if should_send_default_pii():
messages = []
if agent.instructions:
messages.append(
{
"content": [{"text": agent.instructions, "type": "text"}],
"role": "system",
}
)

if "original_input" in kwargs and kwargs["original_input"] is not None:
messages.append(
{
"content": [{"text": kwargs["original_input"], "type": "text"}],
"role": "user",
}
)

if len(messages) > 0:
set_data_normalized(
span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages, unpack=False
)

_set_agent_data(span, agent)

return span


def update_invoke_agent_span(context, agent, output):
# type: (agents.RunContextWrapper, agents.Agent, Any) -> None
current_span = sentry_sdk.get_current_span()
if current_span:
current_span.__exit__(None, None, None)
span = sentry_sdk.get_current_span()

if span:
if should_send_default_pii():
set_data_normalized(
span, SPANDATA.GEN_AI_RESPONSE_TEXT, output, unpack=False
)

span.__exit__(None, None, None)
9 changes: 9 additions & 0 deletions tests/integrations/openai_agents/test_openai_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ async def test_agent_invocation_span(
sentry_init(
integrations=[OpenAIAgentsIntegration()],
traces_sample_rate=1.0,
send_default_pii=True,
)

events = capture_events()
Expand All @@ -134,6 +135,14 @@ async def test_agent_invocation_span(
assert transaction["contexts"]["trace"]["origin"] == "auto.ai.openai_agents"

assert invoke_agent_span["description"] == "invoke_agent test_agent"
assert (
invoke_agent_span["data"]["gen_ai.request.messages"]
== '[{"content": [{"text": "You are a helpful test assistant.", "type": "text"}], "role": "system"}, {"content": [{"text": "Test input", "type": "text"}], "role": "user"}]'
)
assert (
invoke_agent_span["data"]["gen_ai.response.text"]
== "Hello, how can I help you?"
)
assert invoke_agent_span["data"]["gen_ai.operation.name"] == "invoke_agent"
assert invoke_agent_span["data"]["gen_ai.system"] == "openai"
assert invoke_agent_span["data"]["gen_ai.agent.name"] == "test_agent"
Expand Down