Skip to content

Commit b71900f

Browse files
google-genai-botcopybara-github
authored andcommitted
refactor: Use Maybe instead of Single<Optional>
PiperOrigin-RevId: 881382533
1 parent 305299f commit b71900f

2 files changed

Lines changed: 69 additions & 76 deletions

File tree

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

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import io.reactivex.rxjava3.core.Completable;
3333
import io.reactivex.rxjava3.core.Flowable;
3434
import io.reactivex.rxjava3.core.Maybe;
35-
import io.reactivex.rxjava3.core.Single;
3635
import java.util.ArrayList;
3736
import java.util.HashSet;
3837
import java.util.List;
@@ -316,30 +315,29 @@ private Flowable<Event> run(
316315
() -> {
317316
InvocationContext invocationContext = createInvocationContext(parentContext);
318317

318+
Flowable<Event> mainAndAfterEvents =
319+
Flowable.defer(() -> runImplementation.apply(invocationContext))
320+
.concatWith(
321+
Flowable.defer(
322+
() ->
323+
callCallback(
324+
afterCallbacksToFunctions(
325+
invocationContext.pluginManager(), afterAgentCallback),
326+
invocationContext)
327+
.toFlowable()));
328+
319329
return callCallback(
320330
beforeCallbacksToFunctions(
321331
invocationContext.pluginManager(), beforeAgentCallback),
322332
invocationContext)
323333
.flatMapPublisher(
324-
beforeEventOpt -> {
334+
beforeEvent -> {
325335
if (invocationContext.endInvocation()) {
326-
return Flowable.fromOptional(beforeEventOpt);
336+
return Flowable.just(beforeEvent);
327337
}
328-
329-
Flowable<Event> beforeEvents = Flowable.fromOptional(beforeEventOpt);
330-
Flowable<Event> mainEvents =
331-
Flowable.defer(() -> runImplementation.apply(invocationContext));
332-
Flowable<Event> afterEvents =
333-
Flowable.defer(
334-
() ->
335-
callCallback(
336-
afterCallbacksToFunctions(
337-
invocationContext.pluginManager(), afterAgentCallback),
338-
invocationContext)
339-
.flatMapPublisher(Flowable::fromOptional));
340-
341-
return Flowable.concat(beforeEvents, mainEvents, afterEvents);
338+
return Flowable.just(beforeEvent).concatWith(mainAndAfterEvents);
342339
})
340+
.switchIfEmpty(mainAndAfterEvents)
343341
.compose(
344342
Tracing.traceAgent(
345343
"invoke_agent " + name(), name(), description(), invocationContext));
@@ -383,13 +381,13 @@ private <T> ImmutableList<Function<CallbackContext, Maybe<Content>>> callbacksTo
383381
*
384382
* @param agentCallbacks Callback functions.
385383
* @param invocationContext Current invocation context.
386-
* @return single emitting first event, or empty if none.
384+
* @return maybe emitting first event, or empty if none.
387385
*/
388-
private Single<Optional<Event>> callCallback(
386+
private Maybe<Event> callCallback(
389387
List<Function<CallbackContext, Maybe<Content>>> agentCallbacks,
390388
InvocationContext invocationContext) {
391389
if (agentCallbacks.isEmpty()) {
392-
return Single.just(Optional.empty());
390+
return Maybe.empty();
393391
}
394392

395393
CallbackContext callbackContext =
@@ -404,21 +402,20 @@ private Single<Optional<Event>> callCallback(
404402
.map(
405403
content -> {
406404
invocationContext.setEndInvocation(true);
407-
return Optional.of(
408-
Event.builder()
409-
.id(Event.generateEventId())
410-
.invocationId(invocationContext.invocationId())
411-
.author(name())
412-
.branch(invocationContext.branch().orElse(null))
413-
.actions(callbackContext.eventActions())
414-
.content(content)
415-
.build());
405+
return Event.builder()
406+
.id(Event.generateEventId())
407+
.invocationId(invocationContext.invocationId())
408+
.author(name())
409+
.branch(invocationContext.branch().orElse(null))
410+
.actions(callbackContext.eventActions())
411+
.content(content)
412+
.build();
416413
})
417414
.toFlowable();
418415
})
419416
.firstElement()
420417
.switchIfEmpty(
421-
Single.defer(
418+
Maybe.defer(
422419
() -> {
423420
if (callbackContext.state().hasDelta()) {
424421
Event.Builder eventBuilder =
@@ -429,9 +426,9 @@ private Single<Optional<Event>> callCallback(
429426
.branch(invocationContext.branch().orElse(null))
430427
.actions(callbackContext.eventActions());
431428

432-
return Single.just(Optional.of(eventBuilder.build()));
429+
return Maybe.just(eventBuilder.build());
433430
} else {
434-
return Single.just(Optional.empty());
431+
return Maybe.empty();
435432
}
436433
}));
437434
}

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

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -170,52 +170,51 @@ private Flowable<LlmResponse> callLlm(
170170
LlmRequest.Builder llmRequestBuilder = llmRequest.toBuilder();
171171

172172
return handleBeforeModelCallback(context, llmRequestBuilder, eventForCallbackUsage)
173-
.flatMapPublisher(
174-
beforeResponse -> {
175-
if (beforeResponse.isPresent()) {
176-
return Flowable.just(beforeResponse.get());
177-
}
178-
BaseLlm llm =
179-
agent.resolvedModel().model().isPresent()
180-
? agent.resolvedModel().model().get()
181-
: LlmRegistry.getLlm(agent.resolvedModel().modelName().get());
182-
return llm.generateContent(
183-
llmRequestBuilder.build(),
184-
context.runConfig().streamingMode() == StreamingMode.SSE)
185-
.onErrorResumeNext(
186-
exception ->
187-
handleOnModelErrorCallback(
188-
context, llmRequestBuilder, eventForCallbackUsage, exception)
189-
.switchIfEmpty(Single.error(exception))
190-
.toFlowable())
191-
.doOnNext(
192-
llmResp ->
193-
Tracing.traceCallLlm(
194-
context,
195-
eventForCallbackUsage.id(),
196-
llmRequestBuilder.build(),
197-
llmResp))
198-
.doOnError(
199-
error -> {
200-
Span span = Span.current();
201-
span.setStatus(StatusCode.ERROR, error.getMessage());
202-
span.recordException(error);
203-
})
204-
.compose(Tracing.trace("call_llm"))
205-
.concatMap(
206-
llmResp ->
207-
handleAfterModelCallback(context, llmResp, eventForCallbackUsage)
208-
.toFlowable());
209-
});
173+
.toFlowable()
174+
.switchIfEmpty(
175+
Flowable.defer(
176+
() -> {
177+
BaseLlm llm =
178+
agent.resolvedModel().model().isPresent()
179+
? agent.resolvedModel().model().get()
180+
: LlmRegistry.getLlm(agent.resolvedModel().modelName().get());
181+
return llm.generateContent(
182+
llmRequestBuilder.build(),
183+
context.runConfig().streamingMode() == StreamingMode.SSE)
184+
.onErrorResumeNext(
185+
exception ->
186+
handleOnModelErrorCallback(
187+
context, llmRequestBuilder, eventForCallbackUsage, exception)
188+
.switchIfEmpty(Single.error(exception))
189+
.toFlowable())
190+
.doOnNext(
191+
llmResp ->
192+
Tracing.traceCallLlm(
193+
context,
194+
eventForCallbackUsage.id(),
195+
llmRequestBuilder.build(),
196+
llmResp))
197+
.doOnError(
198+
error -> {
199+
Span span = Span.current();
200+
span.setStatus(StatusCode.ERROR, error.getMessage());
201+
span.recordException(error);
202+
})
203+
.compose(Tracing.trace("call_llm"))
204+
.concatMap(
205+
llmResp ->
206+
handleAfterModelCallback(context, llmResp, eventForCallbackUsage)
207+
.toFlowable());
208+
}));
210209
}
211210

212211
/**
213212
* Invokes {@link BeforeModelCallback}s. If any returns a response, it's used instead of calling
214213
* the LLM.
215214
*
216-
* @return A {@link Single} with the callback result or {@link Optional#empty()}.
215+
* @return A {@link Maybe} with the callback result.
217216
*/
218-
private Single<Optional<LlmResponse>> handleBeforeModelCallback(
217+
private Maybe<LlmResponse> handleBeforeModelCallback(
219218
InvocationContext context, LlmRequest.Builder llmRequestBuilder, Event modelResponseEvent) {
220219
Event callbackEvent = modelResponseEvent.toBuilder().build();
221220
CallbackContext callbackContext =
@@ -228,7 +227,7 @@ private Single<Optional<LlmResponse>> handleBeforeModelCallback(
228227

229228
List<? extends BeforeModelCallback> callbacks = agent.canonicalBeforeModelCallbacks();
230229
if (callbacks.isEmpty()) {
231-
return pluginResult.map(Optional::of).defaultIfEmpty(Optional.empty());
230+
return pluginResult;
232231
}
233232

234233
Maybe<LlmResponse> callbackResult =
@@ -238,10 +237,7 @@ private Single<Optional<LlmResponse>> handleBeforeModelCallback(
238237
.concatMapMaybe(callback -> callback.call(callbackContext, llmRequestBuilder))
239238
.firstElement());
240239

241-
return pluginResult
242-
.switchIfEmpty(callbackResult)
243-
.map(Optional::of)
244-
.defaultIfEmpty(Optional.empty());
240+
return pluginResult.switchIfEmpty(callbackResult);
245241
}
246242

247243
/**

0 commit comments

Comments
 (0)