@@ -242,6 +242,7 @@ def original_compile(self, *args, **kwargs):
242242 assert "calculator" in tools_data
243243
244244
245+ @pytest .mark .parametrize ("stream_gen_ai_spans" , [True , False ])
245246@pytest .mark .parametrize (
246247 "send_default_pii, include_prompts" ,
247248 [
@@ -251,14 +252,21 @@ def original_compile(self, *args, **kwargs):
251252 (False , False ),
252253 ],
253254)
254- def test_pregel_invoke (sentry_init , capture_events , send_default_pii , include_prompts ):
255+ def test_pregel_invoke (
256+ sentry_init ,
257+ capture_events ,
258+ capture_items ,
259+ send_default_pii ,
260+ include_prompts ,
261+ stream_gen_ai_spans ,
262+ ):
255263 """Test Pregel.invoke() wrapper creates proper invoke_agent span."""
256264 sentry_init (
257265 integrations = [LanggraphIntegration (include_prompts = include_prompts )],
258266 traces_sample_rate = 1.0 ,
259267 send_default_pii = send_default_pii ,
268+ stream_gen_ai_spans = stream_gen_ai_spans ,
260269 )
261- events = capture_events ()
262270
263271 test_state = {
264272 "messages" : [
@@ -289,57 +297,135 @@ def original_invoke(self, *args, **kwargs):
289297 ]
290298 return {"messages" : new_messages }
291299
292- with start_transaction ():
293- wrapped_invoke = _wrap_pregel_invoke (original_invoke )
294- result = wrapped_invoke (pregel , test_state )
300+ if stream_gen_ai_spans :
301+ items = capture_items ("transaction" , "span" )
295302
296- assert result is not None
303+ with start_transaction ():
304+ wrapped_invoke = _wrap_pregel_invoke (original_invoke )
305+ result = wrapped_invoke (pregel , test_state )
297306
298- tx = events [0 ]
299- assert tx ["type" ] == "transaction"
307+ assert result is not None
300308
301- invoke_spans = [
302- span for span in tx ["spans" ] if span ["op" ] == OP .GEN_AI_INVOKE_AGENT
303- ]
304- assert len (invoke_spans ) == 1
309+ spans = [item .payload for item in items if item .type == "span" ]
310+ invoke_spans = [
311+ span
312+ for span in spans
313+ if span ["attributes" ]["sentry.op" ] == OP .GEN_AI_INVOKE_AGENT
314+ ]
305315
306- invoke_span = invoke_spans [0 ]
307- assert invoke_span ["description" ] == "invoke_agent test_graph"
308- assert invoke_span ["origin" ] == "auto.ai.langgraph"
309- assert invoke_span ["data" ][SPANDATA .GEN_AI_OPERATION_NAME ] == "invoke_agent"
310- assert invoke_span ["data" ][SPANDATA .GEN_AI_PIPELINE_NAME ] == "test_graph"
311- assert invoke_span ["data" ][SPANDATA .GEN_AI_AGENT_NAME ] == "test_graph"
312-
313- if send_default_pii and include_prompts :
314- assert SPANDATA .GEN_AI_REQUEST_MESSAGES in invoke_span ["data" ]
315- assert SPANDATA .GEN_AI_RESPONSE_TEXT in invoke_span ["data" ]
316+ assert len (invoke_spans ) == 1
316317
317- request_messages = invoke_span [ "data" ][ SPANDATA . GEN_AI_REQUEST_MESSAGES ]
318+ invoke_span = invoke_spans [ 0 ]
318319
319- if isinstance (request_messages , str ):
320- import json
320+ assert invoke_span ["name" ] == "invoke_agent test_graph"
321+ assert invoke_span ["attributes" ]["sentry.origin" ] == "auto.ai.langgraph"
322+ assert (
323+ invoke_span ["attributes" ][SPANDATA .GEN_AI_OPERATION_NAME ] == "invoke_agent"
324+ )
325+ assert invoke_span ["attributes" ][SPANDATA .GEN_AI_PIPELINE_NAME ] == "test_graph"
326+ assert invoke_span ["attributes" ][SPANDATA .GEN_AI_AGENT_NAME ] == "test_graph"
321327
322- request_messages = json . loads ( request_messages )
323- assert len ( request_messages ) == 1
324- assert request_messages [ 0 ][ "content" ] == "Of course! How can I assist you?"
328+ if send_default_pii and include_prompts :
329+ assert SPANDATA . GEN_AI_REQUEST_MESSAGES in invoke_span [ "attributes" ]
330+ assert SPANDATA . GEN_AI_RESPONSE_TEXT in invoke_span [ "attributes" ]
325331
326- response_text = invoke_span ["data" ][SPANDATA .GEN_AI_RESPONSE_TEXT ]
327- assert response_text == expected_assistant_response
332+ request_messages = invoke_span ["attributes" ][
333+ SPANDATA .GEN_AI_REQUEST_MESSAGES
334+ ]
328335
329- assert SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS in invoke_span ["data" ]
330- tool_calls_data = invoke_span ["data" ][SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS ]
331- if isinstance (tool_calls_data , str ):
332- import json
336+ if isinstance (request_messages , str ):
337+ import json
338+
339+ request_messages = json .loads (request_messages )
340+ assert len (request_messages ) == 1
341+ assert request_messages [0 ]["content" ] == "Hello, can you help me?"
342+ assert request_messages [1 ]["content" ] == "Of course! How can I assist you?"
343+
344+ response_text = invoke_span ["attributes" ][SPANDATA .GEN_AI_RESPONSE_TEXT ]
345+ assert response_text == expected_assistant_response
346+
347+ assert SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS in invoke_span ["attributes" ]
348+ tool_calls_data = invoke_span ["attributes" ][
349+ SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS
350+ ]
351+
352+ if isinstance (tool_calls_data , str ):
353+ import json
333354
334- tool_calls_data = json .loads (tool_calls_data )
355+ tool_calls_data = json .loads (tool_calls_data )
335356
336- assert len (tool_calls_data ) == 1
337- assert tool_calls_data [0 ]["id" ] == "call_test_123"
338- assert tool_calls_data [0 ]["function" ]["name" ] == "search_tool"
357+ assert len (tool_calls_data ) == 1
358+ assert tool_calls_data [0 ]["id" ] == "call_test_123"
359+ assert tool_calls_data [0 ]["function" ]["name" ] == "search_tool"
360+ else :
361+ assert SPANDATA .GEN_AI_REQUEST_MESSAGES not in invoke_span .get (
362+ "attributes" , {}
363+ )
364+ assert SPANDATA .GEN_AI_RESPONSE_TEXT not in invoke_span .get (
365+ "attributes" , {}
366+ )
367+ assert SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS not in invoke_span .get (
368+ "attributes" , {}
369+ )
339370 else :
340- assert SPANDATA .GEN_AI_REQUEST_MESSAGES not in invoke_span .get ("data" , {})
341- assert SPANDATA .GEN_AI_RESPONSE_TEXT not in invoke_span .get ("data" , {})
342- assert SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS not in invoke_span .get ("data" , {})
371+ events = capture_events ()
372+
373+ with start_transaction ():
374+ wrapped_invoke = _wrap_pregel_invoke (original_invoke )
375+ result = wrapped_invoke (pregel , test_state )
376+
377+ assert result is not None
378+
379+ tx = events [0 ]
380+ assert tx ["type" ] == "transaction"
381+
382+ invoke_spans = [
383+ span for span in tx ["spans" ] if span ["op" ] == OP .GEN_AI_INVOKE_AGENT
384+ ]
385+
386+ assert len (invoke_spans ) == 1
387+
388+ invoke_span = invoke_spans [0 ]
389+
390+ assert invoke_span ["description" ] == "invoke_agent test_graph"
391+ assert invoke_span ["origin" ] == "auto.ai.langgraph"
392+ assert invoke_span ["data" ][SPANDATA .GEN_AI_OPERATION_NAME ] == "invoke_agent"
393+ assert invoke_span ["data" ][SPANDATA .GEN_AI_PIPELINE_NAME ] == "test_graph"
394+ assert invoke_span ["data" ][SPANDATA .GEN_AI_AGENT_NAME ] == "test_graph"
395+
396+ if send_default_pii and include_prompts :
397+ assert SPANDATA .GEN_AI_REQUEST_MESSAGES in invoke_span ["data" ]
398+ assert SPANDATA .GEN_AI_RESPONSE_TEXT in invoke_span ["data" ]
399+
400+ request_messages = invoke_span ["data" ][SPANDATA .GEN_AI_REQUEST_MESSAGES ]
401+
402+ if isinstance (request_messages , str ):
403+ import json
404+
405+ request_messages = json .loads (request_messages )
406+ assert len (request_messages ) == 1
407+ assert request_messages [0 ]["content" ] == "Of course! How can I assist you?"
408+
409+ response_text = invoke_span ["data" ][SPANDATA .GEN_AI_RESPONSE_TEXT ]
410+ assert response_text == expected_assistant_response
411+
412+ assert SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS in invoke_span ["data" ]
413+ tool_calls_data = invoke_span ["data" ][SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS ]
414+
415+ if isinstance (tool_calls_data , str ):
416+ import json
417+
418+ tool_calls_data = json .loads (tool_calls_data )
419+
420+ assert len (tool_calls_data ) == 1
421+ assert tool_calls_data [0 ]["id" ] == "call_test_123"
422+ assert tool_calls_data [0 ]["function" ]["name" ] == "search_tool"
423+ else :
424+ assert SPANDATA .GEN_AI_REQUEST_MESSAGES not in invoke_span .get ("data" , {})
425+ assert SPANDATA .GEN_AI_RESPONSE_TEXT not in invoke_span .get ("data" , {})
426+ assert SPANDATA .GEN_AI_RESPONSE_TOOL_CALLS not in invoke_span .get (
427+ "data" , {}
428+ )
343429
344430
345431@pytest .mark .parametrize ("stream_gen_ai_spans" , [True , False ])
0 commit comments