Skip to content

Commit 335c2e3

Browse files
google-genai-botcopybara-github
authored andcommitted
refactor: Using a new InvocationContext.combinedPlugin() to simplify code
PiperOrigin-RevId: 855427656
1 parent c6c9557 commit 335c2e3

6 files changed

Lines changed: 176 additions & 168 deletions

File tree

core/src/main/java/com/google/adk/agents/BaseAgent.java

Lines changed: 29 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616

1717
package com.google.adk.agents;
1818

19-
import static com.google.common.collect.ImmutableList.toImmutableList;
20-
import static java.util.Arrays.stream;
21-
2219
import com.google.adk.Telemetry;
2320
import com.google.adk.agents.Callbacks.AfterAgentCallback;
2421
import com.google.adk.agents.Callbacks.BeforeAgentCallback;
@@ -255,9 +252,8 @@ public Flowable<Event> runAsync(InvocationContext parentContext) {
255252
spanContext,
256253
span,
257254
() ->
258-
callCallback(
259-
beforeCallbacksToFunctions(
260-
invocationContext.pluginManager(), callbackPlugin),
255+
processAgentCallbackResult(
256+
ctx -> invocationContext.combinedPlugin().beforeAgentCallback(this, ctx),
261257
invocationContext)
262258
.flatMapPublisher(
263259
beforeEventOpt -> {
@@ -271,10 +267,11 @@ public Flowable<Event> runAsync(InvocationContext parentContext) {
271267
Flowable<Event> afterEvents =
272268
Flowable.defer(
273269
() ->
274-
callCallback(
275-
afterCallbacksToFunctions(
276-
invocationContext.pluginManager(),
277-
callbackPlugin),
270+
processAgentCallbackResult(
271+
ctx ->
272+
invocationContext
273+
.combinedPlugin()
274+
.afterAgentCallback(this, ctx),
278275
invocationContext)
279276
.flatMapPublisher(Flowable::fromOptional));
280277

@@ -284,71 +281,32 @@ public Flowable<Event> runAsync(InvocationContext parentContext) {
284281
}
285282

286283
/**
287-
* Converts before-agent callbacks to functions.
284+
* Processes the result of an agent callback, creating an {@link Event} if necessary.
288285
*
289-
* @return callback functions.
286+
* @param agentCallback The callback function.
287+
* @param invocationContext The current invocation context.
288+
* @return A {@link Single} emitting an {@link Optional} containing the created {@link Event}, or
289+
* {@link Optional#empty()} if no event is produced.
290290
*/
291-
private ImmutableList<Function<CallbackContext, Maybe<Content>>> beforeCallbacksToFunctions(
292-
Plugin... plugins) {
293-
return stream(plugins)
294-
.map(
295-
p ->
296-
(Function<CallbackContext, Maybe<Content>>) ctx -> p.beforeAgentCallback(this, ctx))
297-
.collect(toImmutableList());
298-
}
299-
300-
/**
301-
* Converts after-agent callbacks to functions.
302-
*
303-
* @return callback functions.
304-
*/
305-
private ImmutableList<Function<CallbackContext, Maybe<Content>>> afterCallbacksToFunctions(
306-
Plugin... plugins) {
307-
return stream(plugins)
308-
.map(
309-
p -> (Function<CallbackContext, Maybe<Content>>) ctx -> p.afterAgentCallback(this, ctx))
310-
.collect(toImmutableList());
311-
}
312-
313-
/**
314-
* Calls agent callbacks and returns the first produced event, if any.
315-
*
316-
* @param agentCallbacks Callback functions.
317-
* @param invocationContext Current invocation context.
318-
* @return single emitting first event, or empty if none.
319-
*/
320-
private Single<Optional<Event>> callCallback(
321-
List<Function<CallbackContext, Maybe<Content>>> agentCallbacks,
291+
private Single<Optional<Event>> processAgentCallbackResult(
292+
Function<CallbackContext, Maybe<Content>> agentCallback,
322293
InvocationContext invocationContext) {
323-
if (agentCallbacks == null || agentCallbacks.isEmpty()) {
324-
return Single.just(Optional.empty());
325-
}
326-
327-
CallbackContext callbackContext =
328-
new CallbackContext(invocationContext, /* eventActions= */ null);
329-
330-
return Flowable.fromIterable(agentCallbacks)
331-
.concatMap(
332-
callback -> {
333-
Maybe<Content> maybeContent = callback.apply(callbackContext);
334-
335-
return maybeContent
336-
.map(
337-
content -> {
338-
invocationContext.setEndInvocation(true);
339-
return Optional.of(
340-
Event.builder()
341-
.id(Event.generateEventId())
342-
.invocationId(invocationContext.invocationId())
343-
.author(name())
344-
.branch(invocationContext.branch())
345-
.actions(callbackContext.eventActions())
346-
.content(content)
347-
.build());
348-
})
349-
.toFlowable();
294+
var callbackContext = new CallbackContext(invocationContext, /* eventActions= */ null);
295+
return agentCallback
296+
.apply(callbackContext)
297+
.map(
298+
content -> {
299+
invocationContext.setEndInvocation(true);
300+
return Optional.of(
301+
Event.builder()
302+
.id(Event.generateEventId())
303+
.invocationId(invocationContext.invocationId())
304+
.author(name())
305+
.branch(invocationContext.branch())
306+
.actions(callbackContext.eventActions())
307+
.content(content)
308+
.build());
350309
})
351-
.firstElement()
352310
.switchIfEmpty(
353311
Single.defer(
354312
() -> {

core/src/main/java/com/google/adk/agents/InvocationContext.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.google.adk.plugins.PluginManager;
2626
import com.google.adk.sessions.BaseSessionService;
2727
import com.google.adk.sessions.Session;
28+
import com.google.common.collect.ImmutableList;
2829
import com.google.common.collect.ImmutableSet;
2930
import com.google.errorprone.annotations.CanIgnoreReturnValue;
3031
import com.google.errorprone.annotations.InlineMe;
@@ -44,6 +45,7 @@ public class InvocationContext {
4445
private final BaseArtifactService artifactService;
4546
private final BaseMemoryService memoryService;
4647
private final Plugin pluginManager;
48+
private final Plugin combinedPlugin;
4749
private final Optional<LiveRequestQueue> liveRequestQueue;
4850
private final Map<String, ActiveStreamingTool> activeStreamingTools;
4951
private final String invocationId;
@@ -73,6 +75,13 @@ protected InvocationContext(Builder builder) {
7375
this.endInvocation = builder.endInvocation;
7476
this.resumabilityConfig = builder.resumabilityConfig;
7577
this.invocationCostManager = builder.invocationCostManager;
78+
this.combinedPlugin =
79+
Optional.ofNullable(builder.agent)
80+
.map(BaseAgent::getPlugin)
81+
.map(
82+
agentPlugin ->
83+
(Plugin) new PluginManager(ImmutableList.of(pluginManager, agentPlugin)))
84+
.orElse(pluginManager);
7685
}
7786

7887
/**
@@ -235,6 +244,10 @@ public Plugin pluginManager() {
235244
return pluginManager;
236245
}
237246

247+
public Plugin combinedPlugin() {
248+
return combinedPlugin;
249+
}
250+
238251
/** Returns a map of tool call IDs to active streaming tools for the current invocation. */
239252
public Map<String, ActiveStreamingTool> activeStreamingTools() {
240253
return activeStreamingTools;

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

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ private Flowable<LlmResponse> callLlm(
199199
.onErrorResumeNext(
200200
exception ->
201201
context
202-
.pluginManager()
202+
.combinedPlugin()
203203
.onModelErrorCallback(
204204
new CallbackContext(
205205
context, eventForCallbackUsage.actions()),
@@ -243,27 +243,9 @@ private Single<Optional<LlmResponse>> handleBeforeModelCallback(
243243
Event callbackEvent = modelResponseEvent.toBuilder().build();
244244
CallbackContext callbackContext = new CallbackContext(context, callbackEvent.actions());
245245

246-
Maybe<LlmResponse> pluginResult =
247-
context.pluginManager().beforeModelCallback(callbackContext, llmRequestBuilder);
248-
249-
LlmAgent agent = (LlmAgent) context.agent();
250-
251-
Optional<List<? extends BeforeModelCallback>> callbacksOpt = agent.beforeModelCallback();
252-
if (callbacksOpt.isEmpty() || callbacksOpt.get().isEmpty()) {
253-
return pluginResult.map(Optional::of).defaultIfEmpty(Optional.empty());
254-
}
255-
256-
List<? extends BeforeModelCallback> callbacks = callbacksOpt.get();
257-
258-
Maybe<LlmResponse> callbackResult =
259-
Maybe.defer(
260-
() ->
261-
Flowable.fromIterable(callbacks)
262-
.concatMapMaybe(callback -> callback.call(callbackContext, llmRequestBuilder))
263-
.firstElement());
264-
265-
return pluginResult
266-
.switchIfEmpty(callbackResult)
246+
return context
247+
.combinedPlugin()
248+
.beforeModelCallback(callbackContext, llmRequestBuilder)
267249
.map(Optional::of)
268250
.defaultIfEmpty(Optional.empty());
269251
}
@@ -279,24 +261,10 @@ private Single<LlmResponse> handleAfterModelCallback(
279261
Event callbackEvent = modelResponseEvent.toBuilder().build();
280262
CallbackContext callbackContext = new CallbackContext(context, callbackEvent.actions());
281263

282-
Maybe<LlmResponse> pluginResult =
283-
context.pluginManager().afterModelCallback(callbackContext, llmResponse);
284-
285-
LlmAgent agent = (LlmAgent) context.agent();
286-
Optional<List<? extends AfterModelCallback>> callbacksOpt = agent.afterModelCallback();
287-
288-
if (callbacksOpt.isEmpty() || callbacksOpt.get().isEmpty()) {
289-
return pluginResult.defaultIfEmpty(llmResponse);
290-
}
291-
292-
Maybe<LlmResponse> callbackResult =
293-
Maybe.defer(
294-
() ->
295-
Flowable.fromIterable(callbacksOpt.get())
296-
.concatMapMaybe(callback -> callback.call(callbackContext, llmResponse))
297-
.firstElement());
298-
299-
return pluginResult.switchIfEmpty(callbackResult).defaultIfEmpty(llmResponse);
264+
return context
265+
.combinedPlugin()
266+
.afterModelCallback(callbackContext, llmResponse)
267+
.defaultIfEmpty(llmResponse);
300268
}
301269

302270
/**

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

Lines changed: 5 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ private static Maybe<Event> postProcessFunctionResult(
388388
.onErrorResumeNext(
389389
t ->
390390
invocationContext
391-
.pluginManager()
391+
.combinedPlugin()
392392
.onToolErrorCallback(tool, functionArgs, toolContext, t)
393393
.map(isLive ? Optional::ofNullable : Optional::of)
394394
.switchIfEmpty(Single.error(t)))
@@ -457,30 +457,7 @@ private static Maybe<Map<String, Object>> maybeInvokeBeforeToolCall(
457457
BaseTool tool,
458458
Map<String, Object> functionArgs,
459459
ToolContext toolContext) {
460-
if (invocationContext.agent() instanceof LlmAgent) {
461-
LlmAgent agent = (LlmAgent) invocationContext.agent();
462-
463-
Maybe<Map<String, Object>> pluginResult =
464-
invocationContext.pluginManager().beforeToolCallback(tool, functionArgs, toolContext);
465-
466-
Optional<List<? extends BeforeToolCallback>> callbacksOpt = agent.beforeToolCallback();
467-
if (callbacksOpt.isEmpty() || callbacksOpt.get().isEmpty()) {
468-
return pluginResult;
469-
}
470-
List<? extends BeforeToolCallback> callbacks = callbacksOpt.get();
471-
472-
Maybe<Map<String, Object>> callbackResult =
473-
Maybe.defer(
474-
() ->
475-
Flowable.fromIterable(callbacks)
476-
.concatMapMaybe(
477-
callback ->
478-
callback.call(invocationContext, tool, functionArgs, toolContext))
479-
.firstElement());
480-
481-
return pluginResult.switchIfEmpty(callbackResult);
482-
}
483-
return Maybe.empty();
460+
return invocationContext.combinedPlugin().beforeToolCallback(tool, functionArgs, toolContext);
484461
}
485462

486463
private static Maybe<Map<String, Object>> maybeInvokeAfterToolCall(
@@ -489,37 +466,9 @@ private static Maybe<Map<String, Object>> maybeInvokeAfterToolCall(
489466
Map<String, Object> functionArgs,
490467
ToolContext toolContext,
491468
Map<String, Object> functionResult) {
492-
if (invocationContext.agent() instanceof LlmAgent) {
493-
LlmAgent agent = (LlmAgent) invocationContext.agent();
494-
495-
Maybe<Map<String, Object>> pluginResult =
496-
invocationContext
497-
.pluginManager()
498-
.afterToolCallback(tool, functionArgs, toolContext, functionResult);
499-
500-
Optional<List<? extends AfterToolCallback>> callbacksOpt = agent.afterToolCallback();
501-
if (callbacksOpt.isEmpty() || callbacksOpt.get().isEmpty()) {
502-
return pluginResult;
503-
}
504-
List<? extends AfterToolCallback> callbacks = callbacksOpt.get();
505-
506-
Maybe<Map<String, Object>> callbackResult =
507-
Maybe.defer(
508-
() ->
509-
Flowable.fromIterable(callbacks)
510-
.concatMapMaybe(
511-
callback ->
512-
callback.call(
513-
invocationContext,
514-
tool,
515-
functionArgs,
516-
toolContext,
517-
functionResult))
518-
.firstElement());
519-
520-
return pluginResult.switchIfEmpty(callbackResult);
521-
}
522-
return Maybe.empty();
469+
return invocationContext
470+
.combinedPlugin()
471+
.afterToolCallback(tool, functionArgs, toolContext, functionResult);
523472
}
524473

525474
private static Maybe<Map<String, Object>> callTool(

core/src/main/java/com/google/adk/runner/Runner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ public Flowable<Event> runAsync(
512512
updatedSession,
513513
session);
514514
return contextWithUpdatedSession
515-
.pluginManager()
515+
.combinedPlugin()
516516
.onEventCallback(
517517
contextWithUpdatedSession,
518518
registeredEvent)

0 commit comments

Comments
 (0)