@@ -83,13 +83,14 @@ def handle_chat_attributes(
8383 # Tool calls
8484 if "tool_calls" in msg :
8585 tool_calls = msg ["tool_calls" ]
86- for j , tool_call in enumerate (tool_calls ):
87- if is_openai_v1 () and hasattr (tool_call , "__dict__" ):
88- tool_call = model_as_dict (tool_call )
89- function = tool_call .get ("function" , {})
90- attributes [f"{ prefix } .tool_calls.{ j } .id" ] = tool_call .get ("id" )
91- attributes [f"{ prefix } .tool_calls.{ j } .name" ] = function .get ("name" )
92- attributes [f"{ prefix } .tool_calls.{ j } .arguments" ] = function .get ("arguments" )
86+ if tool_calls : # Check if tool_calls is not None
87+ for j , tool_call in enumerate (tool_calls ):
88+ if is_openai_v1 () and hasattr (tool_call , "__dict__" ):
89+ tool_call = model_as_dict (tool_call )
90+ function = tool_call .get ("function" , {})
91+ attributes [f"{ prefix } .tool_calls.{ j } .id" ] = tool_call .get ("id" )
92+ attributes [f"{ prefix } .tool_calls.{ j } .name" ] = function .get ("name" )
93+ attributes [f"{ prefix } .tool_calls.{ j } .arguments" ] = function .get ("arguments" )
9394
9495 # Functions
9596 if "functions" in kwargs :
@@ -121,6 +122,14 @@ def handle_chat_attributes(
121122 response_dict = model_as_dict (return_value )
122123 elif isinstance (return_value , dict ):
123124 response_dict = return_value
125+ elif hasattr (return_value , "model_dump" ):
126+ # Handle Pydantic models directly
127+ response_dict = return_value .model_dump ()
128+ elif hasattr (return_value , "__dict__" ):
129+ # Try to use model_as_dict even if it has __iter__(fallback)
130+ response_dict = model_as_dict (return_value )
131+
132+ logger .debug (f"[OPENAI DEBUG] response_dict keys: { list (response_dict .keys ()) if response_dict else 'empty' } " )
124133
125134 # Basic response attributes
126135 if "id" in response_dict :
@@ -174,17 +183,19 @@ def handle_chat_attributes(
174183 # Function call
175184 if "function_call" in message :
176185 function_call = message ["function_call" ]
177- attributes [f"{ prefix } .tool_calls.0.name" ] = function_call .get ("name" )
178- attributes [f"{ prefix } .tool_calls.0.arguments" ] = function_call .get ("arguments" )
186+ if function_call : # Check if function_call is not None
187+ attributes [f"{ prefix } .tool_calls.0.name" ] = function_call .get ("name" )
188+ attributes [f"{ prefix } .tool_calls.0.arguments" ] = function_call .get ("arguments" )
179189
180190 # Tool calls
181191 if "tool_calls" in message :
182192 tool_calls = message ["tool_calls" ]
183- for i , tool_call in enumerate (tool_calls ):
184- function = tool_call .get ("function" , {})
185- attributes [f"{ prefix } .tool_calls.{ i } .id" ] = tool_call .get ("id" )
186- attributes [f"{ prefix } .tool_calls.{ i } .name" ] = function .get ("name" )
187- attributes [f"{ prefix } .tool_calls.{ i } .arguments" ] = function .get ("arguments" )
193+ if tool_calls : # Check if tool_calls is not None
194+ for i , tool_call in enumerate (tool_calls ):
195+ function = tool_call .get ("function" , {})
196+ attributes [f"{ prefix } .tool_calls.{ i } .id" ] = tool_call .get ("id" )
197+ attributes [f"{ prefix } .tool_calls.{ i } .name" ] = function .get ("name" )
198+ attributes [f"{ prefix } .tool_calls.{ i } .arguments" ] = function .get ("arguments" )
188199
189200 # Prompt filter results
190201 if "prompt_filter_results" in response_dict :
0 commit comments