@@ -97,37 +97,47 @@ async def handle_call(
9797 call : ToolCallPart ,
9898 allow_partial : bool = False ,
9999 wrap_validation_errors : bool = True ,
100+ * ,
101+ approved : bool = False ,
100102 ) -> Any :
101103 """Handle a tool call by validating the arguments, calling the tool, and handling retries.
102104
103105 Args:
104106 call: The tool call part to handle.
105107 allow_partial: Whether to allow partial validation of the tool arguments.
106108 wrap_validation_errors: Whether to wrap validation errors in a retry prompt part.
107- usage_limits: Optional usage limits to check before executing tools .
109+ approved: Whether the tool call has been approved .
108110 """
109111 if self .tools is None or self .ctx is None :
110112 raise ValueError ('ToolManager has not been prepared for a run step yet' ) # pragma: no cover
111113
112114 if (tool := self .tools .get (call .tool_name )) and tool .tool_def .kind == 'output' :
113115 # Output tool calls are not traced and not counted
114- return await self ._call_tool (call , allow_partial , wrap_validation_errors )
116+ return await self ._call_tool (
117+ call ,
118+ allow_partial = allow_partial ,
119+ wrap_validation_errors = wrap_validation_errors ,
120+ approved = approved ,
121+ )
115122 else :
116123 return await self ._call_function_tool (
117124 call ,
118- allow_partial ,
119- wrap_validation_errors ,
120- self .ctx .tracer ,
121- self .ctx .trace_include_content ,
122- self .ctx .instrumentation_version ,
123- self .ctx .usage ,
125+ allow_partial = allow_partial ,
126+ wrap_validation_errors = wrap_validation_errors ,
127+ approved = approved ,
128+ tracer = self .ctx .tracer ,
129+ include_content = self .ctx .trace_include_content ,
130+ instrumentation_version = self .ctx .instrumentation_version ,
131+ usage = self .ctx .usage ,
124132 )
125133
126134 async def _call_tool (
127135 self ,
128136 call : ToolCallPart ,
137+ * ,
129138 allow_partial : bool ,
130139 wrap_validation_errors : bool ,
140+ approved : bool ,
131141 ) -> Any :
132142 if self .tools is None or self .ctx is None :
133143 raise ValueError ('ToolManager has not been prepared for a run step yet' ) # pragma: no cover
@@ -142,15 +152,16 @@ async def _call_tool(
142152 msg = 'No tools available.'
143153 raise ModelRetry (f'Unknown tool name: { name !r} . { msg } ' )
144154
145- if tool .tool_def .defer :
146- raise RuntimeError ('Deferred tools cannot be called' )
155+ if tool .tool_def .kind == 'external' :
156+ raise RuntimeError ('External tools cannot be called' )
147157
148158 ctx = replace (
149159 self .ctx ,
150160 tool_name = name ,
151161 tool_call_id = call .tool_call_id ,
152162 retry = self .ctx .retries .get (name , 0 ),
153163 max_retries = tool .max_retries ,
164+ tool_call_approved = approved ,
154165 partial_output = allow_partial ,
155166 )
156167
@@ -198,8 +209,10 @@ async def _call_tool(
198209 async def _call_function_tool (
199210 self ,
200211 call : ToolCallPart ,
212+ * ,
201213 allow_partial : bool ,
202214 wrap_validation_errors : bool ,
215+ approved : bool ,
203216 tracer : Tracer ,
204217 include_content : bool ,
205218 instrumentation_version : int ,
@@ -238,7 +251,12 @@ async def _call_function_tool(
238251 attributes = span_attributes ,
239252 ) as span :
240253 try :
241- tool_result = await self ._call_tool (call , allow_partial , wrap_validation_errors )
254+ tool_result = await self ._call_tool (
255+ call ,
256+ allow_partial = allow_partial ,
257+ wrap_validation_errors = wrap_validation_errors ,
258+ approved = approved ,
259+ )
242260 usage .tool_calls += 1
243261
244262 except ToolRetryError as e :
0 commit comments