@@ -321,6 +321,34 @@ async def test_turn_span_preserves_existing_data(self):
321321 assert ended_span .data ["custom" ] == "value"
322322 assert ended_span .data ["usage" ] == {"prompt_tokens" : 3 , "completion_tokens" : 4 }
323323
324+ async def test_turn_span_warns_and_replaces_non_dict_data (self , caplog ):
325+ mock_service , module = _make_module ()
326+ started = _make_span (data = [{"item" : 1 }])
327+ mock_service .start_span .return_value = started
328+ mock_service .end_span .return_value = started
329+
330+ with patch .object (_tracing_mod , "in_temporal_workflow" , return_value = False ):
331+ async with module .turn_span (trace_id = "trace-123" , name = "turn" ) as turn :
332+ with caplog .at_level ("WARNING" ):
333+ turn .record_usage (usage = {"input_tokens" : 1 , "output_tokens" : 2 })
334+
335+ assert any ("existing data will be replaced" in message for message in caplog .messages )
336+ ended_span = mock_service .end_span .call_args .kwargs ["span" ]
337+ assert ended_span .data == {"usage" : {"input_tokens" : 1 , "output_tokens" : 2 }}
338+
339+ async def test_turn_span_dict_data_does_not_warn (self , caplog ):
340+ mock_service , module = _make_module ()
341+ started = _make_span (data = {"custom" : "value" })
342+ mock_service .start_span .return_value = started
343+ mock_service .end_span .return_value = started
344+
345+ with patch .object (_tracing_mod , "in_temporal_workflow" , return_value = False ):
346+ async with module .turn_span (trace_id = "trace-123" , name = "turn" ) as turn :
347+ with caplog .at_level ("WARNING" ):
348+ turn .record_usage (usage = {"input_tokens" : 1 })
349+
350+ assert not any ("existing data will be replaced" in message for message in caplog .messages )
351+
324352 async def test_turn_span_cost_only (self ):
325353 mock_service , module = _make_module ()
326354 started = _make_span ()
0 commit comments