|
30 | 30 | import com.google.adk.events.EventActions; |
31 | 31 | import com.google.adk.tools.BaseTool; |
32 | 32 | import com.google.adk.tools.FunctionTool; |
| 33 | +import com.google.adk.tools.MissingToolResolutionStrategy; |
33 | 34 | import com.google.adk.tools.ToolConfirmation; |
34 | 35 | import com.google.adk.tools.ToolContext; |
35 | | -import com.google.common.base.VerifyException; |
36 | 36 | import com.google.common.collect.ImmutableList; |
37 | 37 | import com.google.common.collect.ImmutableMap; |
38 | 38 | import com.google.genai.types.Content; |
@@ -137,10 +137,16 @@ public static Maybe<Event> handleFunctionCalls( |
137 | 137 | Map<String, BaseTool> tools, |
138 | 138 | Map<String, ToolConfirmation> toolConfirmations) { |
139 | 139 | ImmutableList<FunctionCall> functionCalls = functionCallEvent.functionCalls(); |
140 | | - |
| 140 | + MissingToolResolutionStrategy missingToolResolutionStrategy = |
| 141 | + invocationContext.runConfig().missingToolResolutionStrategy(); |
| 142 | + ImmutableList.Builder<Maybe<Event>> missingTools = ImmutableList.builder(); |
| 143 | + ImmutableList.Builder<FunctionCall> validCalls = ImmutableList.builder(); |
141 | 144 | for (FunctionCall functionCall : functionCalls) { |
142 | 145 | if (!tools.containsKey(functionCall.name().get())) { |
143 | | - throw new VerifyException("Tool not found: " + functionCall.name().get()); |
| 146 | + missingTools.add( |
| 147 | + missingToolResolutionStrategy.onMissingTool(invocationContext, functionCall)); |
| 148 | + } else { |
| 149 | + validCalls.add(functionCall); |
144 | 150 | } |
145 | 151 | } |
146 | 152 |
|
@@ -202,12 +208,16 @@ public static Maybe<Event> handleFunctionCalls( |
202 | 208 | Flowable<Event> functionResponseEventsFlowable; |
203 | 209 | if (invocationContext.runConfig().toolExecutionMode() == ToolExecutionMode.SEQUENTIAL) { |
204 | 210 | functionResponseEventsFlowable = |
205 | | - Flowable.fromIterable(functionCalls).concatMapMaybe(functionCallMapper); |
| 211 | + Flowable.fromIterable(validCalls.build()).concatMapMaybe(functionCallMapper); |
206 | 212 | } else { |
207 | 213 | functionResponseEventsFlowable = |
208 | | - Flowable.fromIterable(functionCalls).flatMapMaybe(functionCallMapper); |
| 214 | + Flowable.fromIterable(validCalls.build()).flatMapMaybe(functionCallMapper); |
209 | 215 | } |
210 | | - return functionResponseEventsFlowable |
| 216 | + Flowable<Event> missingToolsFlowable = |
| 217 | + Flowable.fromIterable(missingTools.build()).concatMapMaybe(maybe -> maybe); |
| 218 | + Flowable<Event> allEventsFlowable = |
| 219 | + Flowable.concat(missingToolsFlowable, functionResponseEventsFlowable); |
| 220 | + return allEventsFlowable |
211 | 221 | .toList() |
212 | 222 | .flatMapMaybe( |
213 | 223 | events -> { |
@@ -242,13 +252,19 @@ public static Maybe<Event> handleFunctionCalls( |
242 | 252 | public static Maybe<Event> handleFunctionCallsLive( |
243 | 253 | InvocationContext invocationContext, Event functionCallEvent, Map<String, BaseTool> tools) { |
244 | 254 | ImmutableList<FunctionCall> functionCalls = functionCallEvent.functionCalls(); |
| 255 | + MissingToolResolutionStrategy missingToolResolutionStrategy = |
| 256 | + invocationContext.runConfig().missingToolResolutionStrategy(); |
245 | 257 |
|
| 258 | + ImmutableList.Builder<Maybe<Event>> missingTools = ImmutableList.builder(); |
| 259 | + ImmutableList.Builder<FunctionCall> validCalls = ImmutableList.builder(); |
246 | 260 | for (FunctionCall functionCall : functionCalls) { |
247 | 261 | if (!tools.containsKey(functionCall.name().get())) { |
248 | | - throw new VerifyException("Tool not found: " + functionCall.name().get()); |
| 262 | + missingTools.add( |
| 263 | + missingToolResolutionStrategy.onMissingTool(invocationContext, functionCall)); |
| 264 | + } else { |
| 265 | + validCalls.add(functionCall); |
249 | 266 | } |
250 | 267 | } |
251 | | - |
252 | 268 | Function<FunctionCall, Maybe<Event>> functionCallMapper = |
253 | 269 | functionCall -> { |
254 | 270 | BaseTool tool = tools.get(functionCall.name().get()); |
@@ -311,17 +327,20 @@ public static Maybe<Event> handleFunctionCallsLive( |
311 | 327 | }; |
312 | 328 |
|
313 | 329 | Flowable<Event> responseEventsFlowable; |
314 | | - |
315 | 330 | if (invocationContext.runConfig().toolExecutionMode() == ToolExecutionMode.SEQUENTIAL) { |
316 | 331 | responseEventsFlowable = |
317 | | - Flowable.fromIterable(functionCalls).concatMapMaybe(functionCallMapper); |
| 332 | + Flowable.fromIterable(validCalls.build()).concatMapMaybe(functionCallMapper); |
318 | 333 |
|
319 | 334 | } else { |
320 | 335 | responseEventsFlowable = |
321 | | - Flowable.fromIterable(functionCalls).flatMapMaybe(functionCallMapper); |
| 336 | + Flowable.fromIterable(validCalls.build()).flatMapMaybe(functionCallMapper); |
322 | 337 | } |
| 338 | + Flowable<Event> missingToolsFlowable = |
| 339 | + Flowable.fromIterable(missingTools.build()).concatMapMaybe(maybe -> maybe); |
| 340 | + Flowable<Event> allEventsFlowable = |
| 341 | + Flowable.concat(missingToolsFlowable, responseEventsFlowable); |
323 | 342 |
|
324 | | - return responseEventsFlowable |
| 343 | + return allEventsFlowable |
325 | 344 | .toList() |
326 | 345 | .flatMapMaybe( |
327 | 346 | events -> { |
|
0 commit comments