Skip to content

Commit c0302b6

Browse files
Poggeccicopybara-github
authored andcommitted
fix: IncludeContents.None not including user message in request
PiperOrigin-RevId: 794155407
1 parent 4fcb1cc commit c0302b6

File tree

2 files changed

+103
-2
lines changed

2 files changed

+103
-2
lines changed

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,12 @@ public Single<RequestProcessor.RequestProcessingResult> processRequest(
5656
if (llmAgent.includeContents() == LlmAgent.IncludeContents.NONE) {
5757
return Single.just(
5858
RequestProcessor.RequestProcessingResult.create(
59-
request.toBuilder().contents(ImmutableList.of()).build(), ImmutableList.of()));
59+
request.toBuilder()
60+
.contents(
61+
getCurrentTurnContents(
62+
context.branch(), context.session().events(), context.agent().name()))
63+
.build(),
64+
ImmutableList.of()));
6065
}
6166

6267
ImmutableList<Content> contents =
@@ -67,6 +72,19 @@ public Single<RequestProcessor.RequestProcessingResult> processRequest(
6772
request.toBuilder().contents(contents).build(), ImmutableList.of()));
6873
}
6974

75+
/** Gets contents for the current turn only (no conversation history). */
76+
private ImmutableList<Content> getCurrentTurnContents(
77+
Optional<String> currentBranch, List<Event> events, String agentName) {
78+
// Find the latest event that starts the current turn and process from there.
79+
for (int i = events.size() - 1; i >= 0; i--) {
80+
Event event = events.get(i);
81+
if (event.author().equals("user") || isOtherAgentReply(agentName, event)) {
82+
return getContents(currentBranch, events.subList(i, events.size()), agentName);
83+
}
84+
}
85+
return ImmutableList.of();
86+
}
87+
7088
private ImmutableList<Content> getContents(
7189
Optional<String> currentBranch, List<Event> events, String agentName) {
7290
List<Event> filteredEvents = new ArrayList<>();

core/src/test/java/com/google/adk/flows/llmflows/ContentsTest.java

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,84 @@ public void convertForeignEvent_eventsFromOtherAgents_returnsContextualOnlyEvent
367367
.inOrder();
368368
}
369369

370+
@Test
371+
public void processRequest_includeContentsNone_lastEventIsUser() {
372+
ImmutableList<Event> events =
373+
ImmutableList.of(
374+
createUserEvent("u1", "Turn 1"),
375+
createAgentEvent("a1", "Reply 1"),
376+
createUserEvent("u2", "Turn 2"));
377+
List<Content> result =
378+
runContentsProcessorWithIncludeContents(events, LlmAgent.IncludeContents.NONE);
379+
assertThat(result).containsExactly(events.get(2).content().get());
380+
}
381+
382+
@Test
383+
public void processRequest_includeContentsNone_lastEventIsOtherAgent() {
384+
ImmutableList<Event> events =
385+
ImmutableList.of(
386+
createUserEvent("u1", "Turn 1"),
387+
createAgentEvent("a1", "Reply 1"),
388+
createAgentEvent(OTHER_AGENT, "oa1", "Other Agent Turn"));
389+
List<Content> result =
390+
runContentsProcessorWithIncludeContents(events, LlmAgent.IncludeContents.NONE);
391+
assertThat(result)
392+
.containsExactly(
393+
Content.fromParts(
394+
Part.fromText("For context:"),
395+
Part.fromText("[other_agent] said: Other Agent Turn")));
396+
}
397+
398+
@Test
399+
public void processRequest_includeContentsNone_noUserMessage() {
400+
ImmutableList<Event> events =
401+
ImmutableList.of(
402+
createAgentEvent("a1", "Reply 1"),
403+
createFunctionCallEvent("fc1", "tool1", "call1"),
404+
createFunctionResponseEvent("fr1", "tool1", "call1"));
405+
List<Content> result =
406+
runContentsProcessorWithIncludeContents(events, LlmAgent.IncludeContents.NONE);
407+
assertThat(result).isEmpty();
408+
}
409+
410+
@Test
411+
public void processRequest_includeContentsNone_asyncFRAcrossTurns_throwsException() {
412+
Event u1 = createUserEvent("u1", "Query 1");
413+
Event fc1 = createFunctionCallEvent("fc1", "tool1", "call1");
414+
Event u2 = createUserEvent("u2", "Query 2");
415+
Event fr1 = createFunctionResponseEvent("fr1", "tool1", "call1"); // FR for fc1
416+
417+
ImmutableList<Event> events = ImmutableList.of(u1, fc1, u2, fr1);
418+
419+
// The current turn starts from u2. fc1 is not in the sublist [u2, fr1], so rearrangement fails.
420+
IllegalStateException e =
421+
assertThrows(
422+
IllegalStateException.class,
423+
() -> runContentsProcessorWithIncludeContents(events, LlmAgent.IncludeContents.NONE));
424+
assertThat(e)
425+
.hasMessageThat()
426+
.contains("No function call event found for function response IDs: [call1]");
427+
}
428+
429+
@Test
430+
public void processRequest_includeContentsNone_asyncFRWithinTurn() {
431+
Event u1 = createUserEvent("u1", "Query 1");
432+
Event fc1 = createFunctionCallEvent("fc1", "tool1", "call1");
433+
Event a1 = createAgentEvent("a1", "Agent thinking");
434+
Event fr1 = createFunctionResponseEvent("fr1", "tool1", "call1");
435+
436+
ImmutableList<Event> events = ImmutableList.of(u1, fc1, a1, fr1);
437+
// Current turn starts with u1. The list passed to getContents is [u1, fc1, a1, fr1].
438+
List<Content> result =
439+
runContentsProcessorWithIncludeContents(events, LlmAgent.IncludeContents.NONE);
440+
assertThat(result)
441+
.containsExactly(
442+
events.get(0).content().get(), // u1
443+
events.get(1).content().get(), // fc1
444+
events.get(3).content().get()) // fr1 (merged)
445+
.inOrder();
446+
}
447+
370448
private static Event createUserEvent(String id, String text) {
371449
return Event.builder()
372450
.id(id)
@@ -503,7 +581,12 @@ private static Event createFunctionResponseEvent(
503581
}
504582

505583
private List<Content> runContentsProcessor(List<Event> events) {
506-
LlmAgent agent = LlmAgent.builder().name(AGENT).build();
584+
return runContentsProcessorWithIncludeContents(events, LlmAgent.IncludeContents.DEFAULT);
585+
}
586+
587+
private List<Content> runContentsProcessorWithIncludeContents(
588+
List<Event> events, LlmAgent.IncludeContents includeContents) {
589+
LlmAgent agent = LlmAgent.builder().name(AGENT).includeContents(includeContents).build();
507590
Session session =
508591
Session.builder("test-session")
509592
.appName("test-app")

0 commit comments

Comments
 (0)