@@ -650,3 +650,81 @@ def test_complex_input(input: CalculatorInput) -> CalculatorOutput:
650650 assert output ["result" ] == 54.6 # 10.5 * 5.2 = 54.6
651651 # Verify the enum is serialized as its value
652652 assert output ["operator" ] == "*"
653+
654+
655+ @pytest .mark .asyncio
656+ async def test_traced_with_pydantic_basemodel_class (setup_tracer ):
657+ """Test that Pydantic BaseModel classes can be serialized in tracing.
658+
659+ This tests the fix for the issue where passing a Pydantic BaseModel class
660+ as a parameter (like response_format=OutputFormat) would cause JSON
661+ serialization errors in tracing.
662+ """
663+ from pydantic import BaseModel
664+
665+ exporter , provider = setup_tracer
666+
667+ class OutputFormat (BaseModel ):
668+ result : str
669+ confidence : float = 0.95
670+
671+ @traced ()
672+ async def llm_chat_completions (messages : List [Any ], response_format = None ):
673+ """Simulate LLM function with BaseModel class as response_format."""
674+ if response_format :
675+ mock_content = '{"result": "hi!", "confidence": 0.95}'
676+ return {"choices" : [{"message" : {"content" : mock_content }}]}
677+ return {"choices" : [{"message" : {"content" : "hi!" }}]}
678+
679+ # Test with tuple message format and BaseModel class as parameter
680+ messages = [("human" , "repeat this: hi!" )]
681+ result = await llm_chat_completions (messages , response_format = OutputFormat )
682+
683+ assert result is not None
684+ assert "choices" in result
685+
686+ provider .shutdown () # Ensure spans are flushed
687+ spans = exporter .get_exported_spans ()
688+
689+ assert len (spans ) == 1
690+ span = spans [0 ]
691+ assert span .name == "llm_chat_completions"
692+ assert span .attributes ["span_type" ] == "function_call_async"
693+
694+ # Verify inputs are properly serialized as JSON, including BaseModel class
695+ assert "input.value" in span .attributes
696+ inputs_json = span .attributes ["input.value" ]
697+ inputs = json .loads (inputs_json )
698+
699+ # Check BaseModel class is properly serialized with schema representation
700+ assert "response_format" in inputs
701+ response_format_data = inputs ["response_format" ]
702+
703+ # Verify the BaseModel class is serialized as a schema representation
704+ assert "__class__" in response_format_data
705+ assert "__module__" in response_format_data
706+ assert "schema" in response_format_data
707+ assert response_format_data ["__class__" ] == "OutputFormat"
708+
709+ # Verify the schema contains expected structure
710+ schema = response_format_data ["schema" ]
711+ assert "properties" in schema
712+ assert "result" in schema ["properties" ]
713+ assert "confidence" in schema ["properties" ]
714+ assert schema ["properties" ]["result" ]["type" ] == "string"
715+ assert schema ["properties" ]["confidence" ]["type" ] == "number"
716+
717+ # Verify that tuple messages are also properly serialized
718+ assert "messages" in inputs
719+ messages_data = inputs ["messages" ]
720+ assert isinstance (messages_data , list )
721+ assert len (messages_data ) == 1
722+ assert messages_data [0 ] == ["human" , "repeat this: hi!" ]
723+
724+ # Verify that outputs are properly serialized as JSON
725+ assert "output.value" in span .attributes
726+ output_json = span .attributes ["output.value" ]
727+ output = json .loads (output_json )
728+
729+ assert "choices" in output
730+ assert len (output ["choices" ]) == 1
0 commit comments