1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15- from typing import Any , Callable , Optional , Union
16-
1715import functools
1816import inspect
17+ from typing import Any , Callable , Optional , Union
1918
19+ from google .genai .types import (
20+ ToolListUnion ,
21+ ToolListUnionDict ,
22+ ToolOrDict ,
23+ )
2024
2125from opentelemetry import trace
2226from opentelemetry .semconv ._incubating .attributes import (
2327 code_attributes ,
2428)
25- from google .genai .types import (
26- ToolOrDict ,
27- ToolListUnion ,
28- ToolListUnionDict ,
29- )
29+
3030from .custom_semconv import (
3131 CODE_MODULE ,
32- FUNCTION_TOOL_CALL_START_EVENT_ATTRS_POSITIONAL_ARGS_COUNT ,
32+ FUNCTION_TOOL_CALL_END_EVENT_BODY_RESULT ,
3333 FUNCTION_TOOL_CALL_START_EVENT_ATTRS_KEYWORD_ARGS_COUNT ,
34- FUNCTION_TOOL_CALL_START_EVENT_BODY_POSITIONAL_ARGS ,
34+ FUNCTION_TOOL_CALL_START_EVENT_ATTRS_POSITIONAL_ARGS_COUNT ,
3535 FUNCTION_TOOL_CALL_START_EVENT_BODY_KEYWORD_ARGS ,
36- FUNCTION_TOOL_CALL_END_EVENT_BODY_RESULT ,
37- TOOL_CALL_POSITIONAL_ARG_COUNT ,
36+ FUNCTION_TOOL_CALL_START_EVENT_BODY_POSITIONAL_ARGS ,
3837 TOOL_CALL_KEYWORD_ARG_COUNT ,
38+ TOOL_CALL_POSITIONAL_ARG_COUNT ,
3939)
4040from .flags import is_content_recording_enabled
4141from .otel_wrapper import OTelWrapper
4242
43-
4443ToolFunction = Callable [..., Any ]
4544
4645
@@ -50,8 +49,10 @@ def _to_otel_value(python_value):
5049 return None
5150 if isinstance (python_value , list ):
5251 return [_to_otel_value (x ) for x in python_value ]
53- if isinstance (python_value , dict ):
54- return dict ([(key , _to_otel_value (val )) for (key , val ) in python_value .items ()])
52+ if isinstance (python_value , dict ):
53+ return dict (
54+ [(key , _to_otel_value (val )) for (key , val ) in python_value .items ()]
55+ )
5556 if hasattr (python_value , "model_dump" ):
5657 return python_value .model_dump ()
5758 if hasattr (python_value , "__dict__" ):
@@ -60,16 +61,14 @@ def _to_otel_value(python_value):
6061
6162
6263def _create_function_span_name (wrapped_function ):
63- """Constructs the span name for a given local function tool call."""
64+ """Constructs the span name for a given local function tool call."""
6465 function_name = wrapped_function .__name__
6566 return f"tool_call { function_name } "
6667
6768
6869def _create_function_span_attributes (
69- wrapped_function ,
70- function_args ,
71- function_kwargs ,
72- extra_span_attributes ):
70+ wrapped_function , function_args , function_kwargs , extra_span_attributes
71+ ):
7372 """Creates the attributes for a tool call function span."""
7473 result = {}
7574 if extra_span_attributes :
@@ -82,10 +81,8 @@ def _create_function_span_attributes(
8281
8382
8483def _record_function_call_span_attributes (
85- otel_wrapper ,
86- wrapped_function ,
87- function_args ,
88- function_kwargs ):
84+ otel_wrapper , wrapped_function , function_args , function_kwargs
85+ ):
8986 """Records the details about a function invocation as span attributes."""
9087 if not is_content_recording_enabled ():
9188 return
@@ -104,49 +101,56 @@ def _record_function_call_span_attributes(
104101
105102
106103def _record_function_call_event (
107- otel_wrapper ,
108- wrapped_function ,
109- function_args ,
110- function_kwargs ):
104+ otel_wrapper , wrapped_function , function_args , function_kwargs
105+ ):
111106 """Records the details about a function invocation as a log event."""
112107 attributes = {
113- code_attributes .CODE_FUNCTION_NAME : wrapped_function .__name__ ,
114- CODE_MODULE : wrapped_function .__module__ ,
115- FUNCTION_TOOL_CALL_START_EVENT_ATTRS_POSITIONAL_ARGS_COUNT : len (function_args ),
116- FUNCTION_TOOL_CALL_START_EVENT_ATTRS_KEYWORD_ARGS_COUNT : len (function_kwargs )
108+ code_attributes .CODE_FUNCTION_NAME : wrapped_function .__name__ ,
109+ CODE_MODULE : wrapped_function .__module__ ,
110+ FUNCTION_TOOL_CALL_START_EVENT_ATTRS_POSITIONAL_ARGS_COUNT : len (
111+ function_args
112+ ),
113+ FUNCTION_TOOL_CALL_START_EVENT_ATTRS_KEYWORD_ARGS_COUNT : len (
114+ function_kwargs
115+ ),
117116 }
118117 body = {}
119118 if is_content_recording_enabled ():
120- body [FUNCTION_TOOL_CALL_START_EVENT_BODY_POSITIONAL_ARGS ] = _to_otel_value (function_args )
121- body [FUNCTION_TOOL_CALL_START_EVENT_BODY_KEYWORD_ARGS ] = _to_otel_value (function_kwargs )
119+ body [FUNCTION_TOOL_CALL_START_EVENT_BODY_POSITIONAL_ARGS ] = (
120+ _to_otel_value (function_args )
121+ )
122+ body [FUNCTION_TOOL_CALL_START_EVENT_BODY_KEYWORD_ARGS ] = (
123+ _to_otel_value (function_kwargs )
124+ )
122125 otel_wrapper .log_function_call_start (attributes , body )
123126
124127
125128def _record_function_call_arguments (
126- otel_wrapper ,
127- wrapped_function ,
128- function_args ,
129- function_kwargs ):
130- _record_function_call_span_attributes (otel_wrapper , wrapped_function , function_args , function_kwargs )
131- _record_function_call_event (otel_wrapper , wrapped_function , function_args , function_kwargs )
132-
133-
134- def _record_function_call_result_event (
135- otel_wrapper ,
136- wrapped_function ,
137- result ):
129+ otel_wrapper , wrapped_function , function_args , function_kwargs
130+ ):
131+ _record_function_call_span_attributes (
132+ otel_wrapper , wrapped_function , function_args , function_kwargs
133+ )
134+ _record_function_call_event (
135+ otel_wrapper , wrapped_function , function_args , function_kwargs
136+ )
137+
138+
139+ def _record_function_call_result_event (otel_wrapper , wrapped_function , result ):
138140 """Records the details about a function result as a log event."""
139141 attributes = {
140- code_attributes .CODE_FUNCTION_NAME : wrapped_function .__name__ ,
141- CODE_MODULE : wrapped_function .__module__ ,
142+ code_attributes .CODE_FUNCTION_NAME : wrapped_function .__name__ ,
143+ CODE_MODULE : wrapped_function .__module__ ,
142144 }
143145 body = {}
144146 if is_content_recording_enabled ():
145- body [FUNCTION_TOOL_CALL_END_EVENT_BODY_RESULT ] = _to_otel_value (result )
147+ body [FUNCTION_TOOL_CALL_END_EVENT_BODY_RESULT ] = _to_otel_value (result )
146148 otel_wrapper .log_function_call_end (attributes , body )
147149
148150
149- def _record_function_call_result_span_attributes (otel_wrapper , wrapped_function , result ):
151+ def _record_function_call_result_span_attributes (
152+ otel_wrapper , wrapped_function , result
153+ ):
150154 """Records the details about a function result as span attributes."""
151155 if not is_content_recording_enabled ():
152156 return
@@ -156,59 +160,89 @@ def _record_function_call_result_span_attributes(otel_wrapper, wrapped_function,
156160
157161def _record_function_call_result (otel_wrapper , wrapped_function , result ):
158162 _record_function_call_result_event (otel_wrapper , wrapped_function , result )
159- _record_function_call_result_span_attributes (otel_wrapper , wrapped_function , result )
163+ _record_function_call_result_span_attributes (
164+ otel_wrapper , wrapped_function , result
165+ )
160166
161167
162168def _wrap_sync_tool_function (
163169 tool_function : ToolFunction ,
164170 otel_wrapper : OTelWrapper ,
165171 extra_span_attributes : Optional [dict [str , str ]] = None ,
166- ** kwargs ):
172+ ** kwargs ,
173+ ):
167174 @functools .wraps (tool_function )
168175 def wrapped_function (* args , ** kwargs ):
169176 span_name = _create_function_span_name (tool_function )
170- attributes = _create_function_span_attributes (tool_function , args , kwargs , extra_span_attributes )
171- with otel_wrapper .start_as_current_span (span_name , attributes = attributes ):
172- _record_function_call_arguments (otel_wrapper , tool_function , args , kwargs )
177+ attributes = _create_function_span_attributes (
178+ tool_function , args , kwargs , extra_span_attributes
179+ )
180+ with otel_wrapper .start_as_current_span (
181+ span_name , attributes = attributes
182+ ):
183+ _record_function_call_arguments (
184+ otel_wrapper , tool_function , args , kwargs
185+ )
173186 result = tool_function (* args , ** kwargs )
174187 _record_function_call_result (otel_wrapper , tool_function , result )
175188 return result
189+
176190 return wrapped_function
177191
178192
179193def _wrap_async_tool_function (
180194 tool_function : ToolFunction ,
181195 otel_wrapper : OTelWrapper ,
182196 extra_span_attributes : Optional [dict [str , str ]] = None ,
183- ** kwargs ):
197+ ** kwargs ,
198+ ):
184199 @functools .wraps (tool_function )
185200 async def wrapped_function (* args , ** kwargs ):
186201 span_name = _create_function_span_name (tool_function )
187- attributes = _create_function_span_attributes (tool_function , args , kwargs , extra_span_attributes )
188- with otel_wrapper .start_as_current_span (span_name , attributes = attributes ):
189- _record_function_call_arguments (otel_wrapper , tool_function , args , kwargs )
202+ attributes = _create_function_span_attributes (
203+ tool_function , args , kwargs , extra_span_attributes
204+ )
205+ with otel_wrapper .start_as_current_span (
206+ span_name , attributes = attributes
207+ ):
208+ _record_function_call_arguments (
209+ otel_wrapper , tool_function , args , kwargs
210+ )
190211 result = await tool_function (* args , ** kwargs )
191212 _record_function_call_result (otel_wrapper , tool_function , result )
192213 return result
214+
193215 return wrapped_function
194216
195217
196- def _wrap_tool_function (tool_function : ToolFunction , otel_wrapper : OTelWrapper , ** kwargs ):
218+ def _wrap_tool_function (
219+ tool_function : ToolFunction , otel_wrapper : OTelWrapper , ** kwargs
220+ ):
197221 if inspect .iscoroutinefunction (tool_function ):
198222 return _wrap_async_tool_function (tool_function , otel_wrapper , ** kwargs )
199223 return _wrap_sync_tool_function (tool_function , otel_wrapper , ** kwargs )
200224
201225
202226def wrapped (
203- tool_or_tools : Optional [Union [ToolFunction , ToolOrDict , ToolListUnion , ToolListUnionDict ]],
227+ tool_or_tools : Optional [
228+ Union [ToolFunction , ToolOrDict , ToolListUnion , ToolListUnionDict ]
229+ ],
204230 otel_wrapper : OTelWrapper ,
205- ** kwargs ):
231+ ** kwargs ,
232+ ):
206233 if tool_or_tools is None :
207234 return None
208235 if isinstance (tool_or_tools , list ):
209- return [wrapped (item , otel_wrapper , ** kwargs ) for item in tool_or_tools ]
236+ return [
237+ wrapped (item , otel_wrapper , ** kwargs ) for item in tool_or_tools
238+ ]
210239 if isinstance (tool_or_tools , dict ):
211- return dict ([(key , wrapped (value , otel_wrapper , ** kwargs )) for (key , value ) in tool_or_tools .items ()])
240+ return dict (
241+ [
242+ (key , wrapped (value , otel_wrapper , ** kwargs ))
243+ for (key , value ) in tool_or_tools .items ()
244+ ]
245+ )
212246 if callable (tool_or_tools ):
213247 return _wrap_tool_function (tool_or_tools , otel_wrapper , ** kwargs )
214248 return tool_or_tools
0 commit comments