diff --git a/core/src/main/java/com/google/adk/flows/llmflows/RequestConfirmationLlmRequestProcessor.java b/core/src/main/java/com/google/adk/flows/llmflows/RequestConfirmationLlmRequestProcessor.java index aa70d57b6..6d582e615 100644 --- a/core/src/main/java/com/google/adk/flows/llmflows/RequestConfirmationLlmRequestProcessor.java +++ b/core/src/main/java/com/google/adk/flows/llmflows/RequestConfirmationLlmRequestProcessor.java @@ -64,41 +64,15 @@ public Single processRequest( return Single.just(RequestProcessingResult.create(llmRequest, ImmutableList.of())); } - int confirmationEventIndex = -1; - ImmutableMap responses = ImmutableMap.of(); - // Search backwards for the most recent user event that contains request confirmation - // function responses. - for (int i = events.size() - 1; i >= 0; i--) { - Event event = events.get(i); - if (!Objects.equals(event.author(), "user") || event.functionResponses().isEmpty()) { - continue; - } - - ImmutableMap confirmationsInEvent = - event.functionResponses().stream() - .filter(functionResponse -> functionResponse.id().isPresent()) - .filter( - functionResponse -> - Objects.equals( - functionResponse.name().orElse(null), - REQUEST_CONFIRMATION_FUNCTION_CALL_NAME)) - .map(this::maybeCreateToolConfirmationEntry) - .flatMap(Optional::stream) - .collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)); - if (!confirmationsInEvent.isEmpty()) { - responses = confirmationsInEvent; - confirmationEventIndex = i; - break; - } - } - if (responses.isEmpty()) { + Optional confirmationResult = findMostRecentConfirmations(events); + if (confirmationResult.isEmpty()) { logger.trace("No request confirmation function responses found."); return Single.just(RequestProcessingResult.create(llmRequest, ImmutableList.of())); } - // Make them final to enable access from lambda expressions. - final int finalConfirmationEventIndex = confirmationEventIndex; - final ImmutableMap requestConfirmationFunctionResponses = responses; + int finalConfirmationEventIndex = confirmationResult.get().eventIndex(); + ImmutableMap requestConfirmationFunctionResponses = + confirmationResult.get().responses(); // Search backwards from the event before confirmation for the corresponding // request_confirmation function calls emitted by the model. @@ -169,6 +143,34 @@ public Single processRequest( return Single.just(RequestProcessingResult.create(llmRequest, ImmutableList.of())); } + private static Optional findMostRecentConfirmations( + ImmutableList events) { + // Search backwards for the most recent user event that contains request confirmation + // function responses. + for (int i = events.size() - 1; i >= 0; i--) { + Event event = events.get(i); + if (!Objects.equals(event.author(), "user") || event.functionResponses().isEmpty()) { + continue; + } + + ImmutableMap confirmationsInEvent = + event.functionResponses().stream() + .filter(functionResponse -> functionResponse.id().isPresent()) + .filter( + functionResponse -> + Objects.equals( + functionResponse.name().orElse(null), + REQUEST_CONFIRMATION_FUNCTION_CALL_NAME)) + .map(RequestConfirmationLlmRequestProcessor::maybeCreateToolConfirmationEntry) + .flatMap(Optional::stream) + .collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)); + if (!confirmationsInEvent.isEmpty()) { + return Optional.of(new ConfirmationResult(confirmationsInEvent, i)); + } + } + return Optional.empty(); + } + private Optional getOriginalFunctionCall(FunctionCall functionCall) { if (!functionCall.args().orElse(ImmutableMap.of()).containsKey(ORIGINAL_FUNCTION_CALL)) { return Optional.empty(); @@ -220,7 +222,7 @@ private Maybe assembleEvent( invocationContext, functionCallEvent, toolsMap, toolConfirmations)); } - private Optional> maybeCreateToolConfirmationEntry( + private static Optional> maybeCreateToolConfirmationEntry( FunctionResponse functionResponse) { Map responseMap = functionResponse.response().orElse(ImmutableMap.of()); if (responseMap.size() != 1 || !responseMap.containsKey("response")) { @@ -242,4 +244,7 @@ private Optional> maybeCreateToolConfirmatio return Optional.empty(); } + + private record ConfirmationResult( + ImmutableMap responses, int eventIndex) {} }