From e59549113996cedb5525ec8f5eda136864cd0d4e Mon Sep 17 00:00:00 2001 From: Simon Hellmayr Date: Thu, 6 Nov 2025 11:33:55 +0100 Subject: [PATCH] fix(openai-agents): add input messages to errored spans as well --- .../openai_agents/spans/ai_client.py | 2 +- .../openai_agents/test_openai_agents.py | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/openai_agents/spans/ai_client.py b/sentry_sdk/integrations/openai_agents/spans/ai_client.py index 88b403ba85..e424e93888 100644 --- a/sentry_sdk/integrations/openai_agents/spans/ai_client.py +++ b/sentry_sdk/integrations/openai_agents/spans/ai_client.py @@ -30,6 +30,7 @@ def ai_client_span(agent, get_response_kwargs): span.set_data(SPANDATA.GEN_AI_OPERATION_NAME, "chat") _set_agent_data(span, agent) + _set_input_data(span, get_response_kwargs) return span @@ -37,6 +38,5 @@ def ai_client_span(agent, get_response_kwargs): def update_ai_client_span(span, agent, get_response_kwargs, result): # type: (sentry_sdk.tracing.Span, Agent, dict[str, Any], Any) -> None _set_usage_data(span, result.usage) - _set_input_data(span, get_response_kwargs) _set_output_data(span, result) _create_mcp_execute_tool_spans(span, result) diff --git a/tests/integrations/openai_agents/test_openai_agents.py b/tests/integrations/openai_agents/test_openai_agents.py index bc1de4e95b..113f95df12 100644 --- a/tests/integrations/openai_agents/test_openai_agents.py +++ b/tests/integrations/openai_agents/test_openai_agents.py @@ -664,6 +664,60 @@ async def test_error_handling(sentry_init, capture_events, test_agent): assert ai_client_span["tags"]["status"] == "internal_error" +@pytest.mark.asyncio +async def test_error_captures_input_data(sentry_init, capture_events, test_agent): + """ + Test that input data is captured even when the API call raises an exception. + This verifies that _set_input_data is called before the API call. + """ + with patch.dict(os.environ, {"OPENAI_API_KEY": "test-key"}): + with patch( + "agents.models.openai_responses.OpenAIResponsesModel.get_response" + ) as mock_get_response: + mock_get_response.side_effect = Exception("API Error") + + sentry_init( + integrations=[OpenAIAgentsIntegration()], + traces_sample_rate=1.0, + send_default_pii=True, + ) + + events = capture_events() + + with pytest.raises(Exception, match="API Error"): + await agents.Runner.run( + test_agent, "Test input", run_config=test_run_config + ) + + ( + error_event, + transaction, + ) = events + + assert error_event["exception"]["values"][0]["type"] == "Exception" + assert error_event["exception"]["values"][0]["value"] == "API Error" + + spans = transaction["spans"] + ai_client_span = [s for s in spans if s["op"] == "gen_ai.chat"][0] + + assert ai_client_span["description"] == "chat gpt-4" + assert ai_client_span["tags"]["status"] == "internal_error" + + assert "gen_ai.request.messages" in ai_client_span["data"] + request_messages = safe_serialize( + [ + { + "role": "system", + "content": [ + {"type": "text", "text": "You are a helpful test assistant."} + ], + }, + {"role": "user", "content": [{"type": "text", "text": "Test input"}]}, + ] + ) + assert ai_client_span["data"]["gen_ai.request.messages"] == request_messages + + @pytest.mark.asyncio async def test_span_status_error(sentry_init, capture_events, test_agent): with patch.dict(os.environ, {"OPENAI_API_KEY": "test-key"}):