@@ -1074,3 +1074,79 @@ def test_error_in_responses_api(sentry_init, capture_events):
10741074 error_event ["contexts" ]["trace" ]["trace_id" ]
10751075 == transaction_event ["contexts" ]["trace" ]["trace_id" ]
10761076 )
1077+
1078+
1079+ @pytest .mark .skipif (SKIP_RESPONSES_TESTS , reason = "Responses API not available" )
1080+ async def test_ai_client_span_responses_async_api (sentry_init , capture_events ):
1081+ sentry_init (
1082+ integrations = [OpenAIIntegration (include_prompts = True )],
1083+ traces_sample_rate = 1.0 ,
1084+ send_default_pii = True ,
1085+ )
1086+ events = capture_events ()
1087+
1088+ client = AsyncOpenAI (api_key = "z" )
1089+ client .responses ._post = mock .Mock (return_value = EXAMPLE_RESPONSE )
1090+
1091+ with start_transaction (name = "openai tx" ):
1092+ await client .responses .create (
1093+ model = "gpt-4o" ,
1094+ instructions = "You are a coding assistant that talks like a pirate." ,
1095+ input = "How do I check if a Python object is an instance of a class?" ,
1096+ )
1097+
1098+ (transaction ,) = events
1099+ spans = transaction ["spans" ]
1100+
1101+ assert len (spans ) == 1
1102+ assert spans [0 ]["op" ] == "gen_ai.responses"
1103+ assert spans [0 ]["origin" ] == "auto.ai.openai"
1104+ assert spans [0 ]["data" ] == {
1105+ "gen_ai.request.messages" : "How do I check if a Python object is an instance of a class?" ,
1106+ "gen_ai.request.model" : "gpt-4o" ,
1107+ "gen_ai.usage.input_tokens" : 20 ,
1108+ "gen_ai.usage.input_tokens.cached" : 5 ,
1109+ "gen_ai.usage.output_tokens" : 10 ,
1110+ "gen_ai.usage.output_tokens.reasoning" : 8 ,
1111+ "gen_ai.usage.total_tokens" : 30 ,
1112+ "gen_ai.response.text" : '[{"id": "message-id", "content": [{"annotations": [], "text": "the model response", "type": "output_text"}], "role": "assistant", "status": "completed", "type": "message"}]' ,
1113+ "thread.id" : mock .ANY ,
1114+ "thread.name" : mock .ANY ,
1115+ }
1116+
1117+
1118+ @pytest .mark .skipif (SKIP_RESPONSES_TESTS , reason = "Responses API not available" )
1119+ async def test_error_in_responses_async_api (sentry_init , capture_events ):
1120+ sentry_init (
1121+ integrations = [OpenAIIntegration (include_prompts = True )],
1122+ traces_sample_rate = 1.0 ,
1123+ send_default_pii = True ,
1124+ )
1125+ events = capture_events ()
1126+
1127+ client = AsyncOpenAI (api_key = "z" )
1128+ client .responses ._post = mock .Mock (
1129+ side_effect = OpenAIError ("API rate limit reached" )
1130+ )
1131+
1132+ with start_transaction (name = "openai tx" ):
1133+ with pytest .raises (OpenAIError ):
1134+ await client .responses .create (
1135+ model = "gpt-4o" ,
1136+ instructions = "You are a coding assistant that talks like a pirate." ,
1137+ input = "How do I check if a Python object is an instance of a class?" ,
1138+ )
1139+
1140+ (error_event , transaction_event ) = events
1141+
1142+ assert transaction_event ["type" ] == "transaction"
1143+ # make sure the span where the error occurred is captured
1144+ assert transaction_event ["spans" ][0 ]["op" ] == "gen_ai.responses"
1145+
1146+ assert error_event ["level" ] == "error"
1147+ assert error_event ["exception" ]["values" ][0 ]["type" ] == "OpenAIError"
1148+
1149+ assert (
1150+ error_event ["contexts" ]["trace" ]["trace_id" ]
1151+ == transaction_event ["contexts" ]["trace" ]["trace_id" ]
1152+ )
0 commit comments