Skip to content

Commit ad901e2

Browse files
google-genai-botcopybara-github
authored andcommitted
feat: Support configuring tool execution mode in RunConfig
PiperOrigin-RevId: 837140637
1 parent da81185 commit ad901e2

File tree

1 file changed

+53
-41
lines changed

1 file changed

+53
-41
lines changed

core/src/main/java/com/google/adk/flows/llmflows/Functions.java

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import io.reactivex.rxjava3.core.Maybe;
4848
import io.reactivex.rxjava3.core.Single;
4949
import io.reactivex.rxjava3.disposables.Disposable;
50+
import io.reactivex.rxjava3.functions.Function;
5051
import java.util.ArrayList;
5152
import java.util.Collections;
5253
import java.util.HashMap;
@@ -137,27 +138,28 @@ public static Maybe<Event> handleFunctionCalls(
137138
Map<String, ToolConfirmation> toolConfirmations) {
138139
ImmutableList<FunctionCall> functionCalls = functionCallEvent.functionCalls();
139140

140-
List<Maybe<Event>> functionResponseEvents = new ArrayList<>();
141-
142141
for (FunctionCall functionCall : functionCalls) {
143142
if (!tools.containsKey(functionCall.name().get())) {
144143
throw new VerifyException("Tool not found: " + functionCall.name().get());
145144
}
146-
BaseTool tool = tools.get(functionCall.name().get());
147-
ToolContext toolContext =
148-
ToolContext.builder(invocationContext)
149-
.functionCallId(functionCall.id().orElse(""))
150-
.toolConfirmation(toolConfirmations.get(functionCall.id().orElse(null)))
151-
.build();
145+
}
146+
147+
Function<FunctionCall, Maybe<Event>> functionCallMapper =
148+
functionCall -> {
149+
BaseTool tool = tools.get(functionCall.name().get());
150+
ToolContext toolContext =
151+
ToolContext.builder(invocationContext)
152+
.functionCallId(functionCall.id().orElse(""))
153+
.toolConfirmation(toolConfirmations.get(functionCall.id().orElse(null)))
154+
.build();
152155

153-
Map<String, Object> functionArgs = functionCall.args().orElse(ImmutableMap.of());
156+
Map<String, Object> functionArgs = functionCall.args().orElse(ImmutableMap.of());
154157

155-
Maybe<Map<String, Object>> maybeFunctionResult =
156-
maybeInvokeBeforeToolCall(invocationContext, tool, functionArgs, toolContext)
157-
.switchIfEmpty(Maybe.defer(() -> callTool(tool, functionArgs, toolContext)));
158+
Maybe<Map<String, Object>> maybeFunctionResult =
159+
maybeInvokeBeforeToolCall(invocationContext, tool, functionArgs, toolContext)
160+
.switchIfEmpty(Maybe.defer(() -> callTool(tool, functionArgs, toolContext)));
158161

159-
Maybe<Event> maybeFunctionResponseEvent =
160-
maybeFunctionResult
162+
return maybeFunctionResult
161163
.map(Optional::of)
162164
.defaultIfEmpty(Optional.empty())
163165
.onErrorResumeNext(
@@ -195,15 +197,15 @@ public static Maybe<Event> handleFunctionCalls(
195197
return Maybe.just(functionResponseEvent);
196198
});
197199
});
198-
199-
functionResponseEvents.add(maybeFunctionResponseEvent);
200-
}
200+
};
201201

202202
Flowable<Event> functionResponseEventsFlowable;
203203
if (invocationContext.runConfig().toolExecutionMode() == ToolExecutionMode.SEQUENTIAL) {
204-
functionResponseEventsFlowable = Maybe.concat(functionResponseEvents);
204+
functionResponseEventsFlowable =
205+
Flowable.fromIterable(functionCalls).concatMapMaybe(functionCallMapper);
205206
} else {
206-
functionResponseEventsFlowable = Maybe.merge(functionResponseEvents);
207+
functionResponseEventsFlowable =
208+
Flowable.fromIterable(functionCalls).flatMapMaybe(functionCallMapper);
207209
}
208210
return functionResponseEventsFlowable
209211
.toList()
@@ -240,29 +242,35 @@ public static Maybe<Event> handleFunctionCalls(
240242
public static Maybe<Event> handleFunctionCallsLive(
241243
InvocationContext invocationContext, Event functionCallEvent, Map<String, BaseTool> tools) {
242244
ImmutableList<FunctionCall> functionCalls = functionCallEvent.functionCalls();
243-
List<Maybe<Event>> responseEvents = new ArrayList<>();
244245

245246
for (FunctionCall functionCall : functionCalls) {
246247
if (!tools.containsKey(functionCall.name().get())) {
247248
throw new VerifyException("Tool not found: " + functionCall.name().get());
248249
}
249-
BaseTool tool = tools.get(functionCall.name().get());
250-
ToolContext toolContext =
251-
ToolContext.builder(invocationContext)
252-
.functionCallId(functionCall.id().orElse(""))
253-
.build();
254-
Map<String, Object> functionArgs = functionCall.args().orElse(new HashMap<>());
255-
256-
Maybe<Map<String, Object>> maybeFunctionResult =
257-
maybeInvokeBeforeToolCall(invocationContext, tool, functionArgs, toolContext)
258-
.switchIfEmpty(
259-
Maybe.defer(
260-
() ->
261-
processFunctionLive(
262-
invocationContext, tool, toolContext, functionCall, functionArgs)));
263-
264-
Maybe<Event> maybeFunctionResponseEvent =
265-
maybeFunctionResult
250+
}
251+
252+
Function<FunctionCall, Maybe<Event>> functionCallMapper =
253+
functionCall -> {
254+
BaseTool tool = tools.get(functionCall.name().get());
255+
ToolContext toolContext =
256+
ToolContext.builder(invocationContext)
257+
.functionCallId(functionCall.id().orElse(""))
258+
.build();
259+
Map<String, Object> functionArgs = functionCall.args().orElse(new HashMap<>());
260+
261+
Maybe<Map<String, Object>> maybeFunctionResult =
262+
maybeInvokeBeforeToolCall(invocationContext, tool, functionArgs, toolContext)
263+
.switchIfEmpty(
264+
Maybe.defer(
265+
() ->
266+
processFunctionLive(
267+
invocationContext,
268+
tool,
269+
toolContext,
270+
functionCall,
271+
functionArgs)));
272+
273+
return maybeFunctionResult
266274
.map(Optional::of)
267275
.defaultIfEmpty(Optional.empty())
268276
.onErrorResumeNext(
@@ -300,15 +308,19 @@ public static Maybe<Event> handleFunctionCallsLive(
300308
return Maybe.just(functionResponseEvent);
301309
});
302310
});
303-
responseEvents.add(maybeFunctionResponseEvent);
304-
}
311+
};
305312

306313
Flowable<Event> responseEventsFlowable;
314+
307315
if (invocationContext.runConfig().toolExecutionMode() == ToolExecutionMode.SEQUENTIAL) {
308-
responseEventsFlowable = Maybe.concat(responseEvents);
316+
responseEventsFlowable =
317+
Flowable.fromIterable(functionCalls).concatMapMaybe(functionCallMapper);
318+
309319
} else {
310-
responseEventsFlowable = Maybe.merge(responseEvents);
320+
responseEventsFlowable =
321+
Flowable.fromIterable(functionCalls).flatMapMaybe(functionCallMapper);
311322
}
323+
312324
return responseEventsFlowable
313325
.toList()
314326
.flatMapMaybe(

0 commit comments

Comments
 (0)