@@ -711,14 +711,16 @@ def otel_event(self, settings: InstrumentationSettings) -> Event:
711
711
def otel_message_parts (self , settings : InstrumentationSettings ) -> list [_otel_messages .MessagePart ]:
712
712
from .models .instrumented import InstrumentedModel
713
713
714
- return [
715
- _otel_messages .ToolCallResponsePart (
716
- type = 'tool_call_response' ,
717
- id = self .tool_call_id ,
718
- name = self .tool_name ,
719
- ** ({'result' : InstrumentedModel .serialize_any (self .content )} if settings .include_content else {}),
720
- )
721
- ]
714
+ part = _otel_messages .ToolCallResponsePart (
715
+ type = 'tool_call_response' ,
716
+ id = self .tool_call_id ,
717
+ name = self .tool_name ,
718
+ )
719
+
720
+ if settings .include_content and self .content is not None :
721
+ part ['result' ] = InstrumentedModel .serialize_any (self .content )
722
+
723
+ return [part ]
722
724
723
725
def has_content (self ) -> bool :
724
726
"""Return `True` if the tool return has content."""
@@ -823,14 +825,16 @@ def otel_message_parts(self, settings: InstrumentationSettings) -> list[_otel_me
823
825
if self .tool_name is None :
824
826
return [_otel_messages .TextPart (type = 'text' , content = self .model_response ())]
825
827
else :
826
- return [
827
- _otel_messages .ToolCallResponsePart (
828
- type = 'tool_call_response' ,
829
- id = self .tool_call_id ,
830
- name = self .tool_name ,
831
- ** ({'result' : self .model_response ()} if settings .include_content else {}),
832
- )
833
- ]
828
+ part = _otel_messages .ToolCallResponsePart (
829
+ type = 'tool_call_response' ,
830
+ id = self .tool_call_id ,
831
+ name = self .tool_name ,
832
+ )
833
+
834
+ if settings .include_content :
835
+ part ['result' ] = self .model_response ()
836
+
837
+ return [part ]
834
838
835
839
__repr__ = _utils .dataclasses_no_defaults_repr
836
840
@@ -1134,8 +1138,10 @@ def otel_message_parts(self, settings: InstrumentationSettings) -> list[_otel_me
1134
1138
** ({'content' : part .content } if settings .include_content else {}),
1135
1139
)
1136
1140
)
1137
- elif isinstance (part , ToolCallPart ):
1141
+ elif isinstance (part , BaseToolCallPart ):
1138
1142
call_part = _otel_messages .ToolCallPart (type = 'tool_call' , id = part .tool_call_id , name = part .tool_name )
1143
+ if isinstance (part , BuiltinToolCallPart ):
1144
+ call_part ['builtin' ] = True
1139
1145
if settings .include_content and part .args is not None :
1140
1146
from .models .instrumented import InstrumentedModel
1141
1147
@@ -1145,6 +1151,23 @@ def otel_message_parts(self, settings: InstrumentationSettings) -> list[_otel_me
1145
1151
call_part ['arguments' ] = {k : InstrumentedModel .serialize_any (v ) for k , v in part .args .items ()}
1146
1152
1147
1153
parts .append (call_part )
1154
+ elif isinstance (part , BuiltinToolReturnPart ):
1155
+ return_part = _otel_messages .ToolCallResponsePart (
1156
+ type = 'tool_call_response' ,
1157
+ id = part .tool_call_id ,
1158
+ name = part .tool_name ,
1159
+ builtin = True ,
1160
+ )
1161
+ if settings .include_content and part .content is not None : # pragma: no branch
1162
+ from .models .instrumented import InstrumentedModel
1163
+
1164
+ return_part ['result' ] = (
1165
+ part .content
1166
+ if isinstance (part .content , str )
1167
+ else {k : InstrumentedModel .serialize_any (v ) for k , v in part .content .items ()}
1168
+ )
1169
+
1170
+ parts .append (return_part )
1148
1171
return parts
1149
1172
1150
1173
@property
0 commit comments