diff --git a/core/src/main/java/com/google/adk/flows/llmflows/Contents.java b/core/src/main/java/com/google/adk/flows/llmflows/Contents.java index f45461626..b5f80fbfe 100644 --- a/core/src/main/java/com/google/adk/flows/llmflows/Contents.java +++ b/core/src/main/java/com/google/adk/flows/llmflows/Contents.java @@ -406,6 +406,11 @@ private static boolean isEventBelongsToBranch(Optional invocationBranchO * @return A new list of events with the appropriate rearrangement. */ private static List rearrangeEventsForLatestFunctionResponse(List events) { + if (events.size() < 2) { + // No need to process, since there is no function_call. + return events; + } + // TODO: b/412663475 - Handle parallel function calls within the same event. Currently, this // throws an error. if (events.isEmpty() || Iterables.getLast(events).functionResponses().isEmpty()) { diff --git a/core/src/test/java/com/google/adk/flows/llmflows/ContentsTest.java b/core/src/test/java/com/google/adk/flows/llmflows/ContentsTest.java index b5df658ba..b185ad010 100644 --- a/core/src/test/java/com/google/adk/flows/llmflows/ContentsTest.java +++ b/core/src/test/java/com/google/adk/flows/llmflows/ContentsTest.java @@ -142,7 +142,9 @@ public void rearrangeLatest_multipleFRsForSameFCAsync_returnsMergedFR() { @Test public void rearrangeLatest_missingFCEvent_throwsException() { Event frEvent = createFunctionResponseEvent("fr1", "tool1", "call1"); - ImmutableList events = ImmutableList.of(createUserEvent("u1", "Query"), frEvent); + Event frEvent2 = createFunctionResponseEvent("fr2", "tool1", "call1"); + ImmutableList events = + ImmutableList.of(createUserEvent("u1", "Query"), frEvent, frEvent2); assertThrows(IllegalStateException.class, () -> runContentsProcessor(events)); } @@ -473,10 +475,12 @@ public void processRequest_includeContentsNone_asyncFRAcrossTurns_throwsExceptio Event fc1 = createFunctionCallEvent("fc1", "tool1", "call1"); Event u2 = createUserEvent("u2", "Query 2"); Event fr1 = createFunctionResponseEvent("fr1", "tool1", "call1"); // FR for fc1 + Event fr2 = createFunctionResponseEvent("fr2", "tool2", "call1"); // FR for fc2 - ImmutableList events = ImmutableList.of(u1, fc1, u2, fr1); + ImmutableList events = ImmutableList.of(u1, fc1, u2, fr1, fr2); - // The current turn starts from u2. fc1 is not in the sublist [u2, fr1], so rearrangement fails. + // The current turn starts from u2. fc1 is not in the sublist [u2, fr1, fr2], so rearrangement + // fails. IllegalStateException e = assertThrows( IllegalStateException.class, @@ -486,6 +490,18 @@ public void processRequest_includeContentsNone_asyncFRAcrossTurns_throwsExceptio .contains("No function call event found for function response IDs: [call1]"); } + @Test + public void processRequest_notEnoughEvents_returnsOriginalList() { + Event u1 = createUserEvent("u1", "Query 1"); + + ImmutableList events = ImmutableList.of(u1); + + List result = + runContentsProcessorWithIncludeContents(events, LlmAgent.IncludeContents.NONE); + assertThat(result).hasSize(1); + assertThat(result.get(0)).isEqualTo(u1.content().get()); + } + @Test public void processRequest_includeContentsNone_asyncFRWithinTurn() { Event u1 = createUserEvent("u1", "Query 1");