Skip to content

Commit a0cba25

Browse files
google-genai-botcopybara-github
authored andcommitted
fix: Fixed issue where events were marked empty if the first part had an empty text; now checks all parts for meaningful content
PiperOrigin-RevId: 878371150
1 parent 6e30af3 commit a0cba25

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,36 @@ private boolean isEmptyContent(Event event) {
169169
|| content.role().get().isEmpty()
170170
|| content.parts().isEmpty()
171171
|| content.parts().get().isEmpty()
172-
|| content.parts().get().get(0).text().map(String::isEmpty).orElse(false));
172+
|| content.parts().get().stream().allMatch(this::isPartInvisible));
173+
}
174+
175+
/**
176+
* Returns whether a part is invisible for LLM context.
177+
*
178+
* <p>A part is invisible if:
179+
*
180+
* <ul>
181+
* <li>It has no meaningful content (text, inline_data, file_data, function_call,
182+
* function_response, executable_code, or code_execution_result), OR
183+
* <li>It is marked as a thought AND does not contain function_call or function_response
184+
* </ul>
185+
*
186+
* <p>Function calls and responses are never invisible, even if marked as thought, because they
187+
* represent actions that need to be executed or results that need to be processed.
188+
*
189+
* @param part the part to check.
190+
* @return {@code true} if the part is invisible, {@code false} otherwise.
191+
*/
192+
private boolean isPartInvisible(Part part) {
193+
if (part.functionCall().isPresent() || part.functionResponse().isPresent()) {
194+
return false;
195+
}
196+
return part.thought().orElse(false)
197+
|| !(part.text().isPresent()
198+
|| part.inlineData().isPresent()
199+
|| part.fileData().isPresent()
200+
|| part.codeExecutionResult().isPresent()
201+
|| part.executableCode().isPresent());
173202
}
174203

175204
/**

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,32 @@ public void processRequest_slidingWindow_preservesOverlappingCompactions() {
754754
.containsExactly("C1", "C2", "E4", "E5");
755755
}
756756

757+
@Test
758+
public void processRequest_notEmptyContent() {
759+
Event e =
760+
Event.builder()
761+
.id("e1")
762+
.author(AGENT)
763+
.content(
764+
Content.builder()
765+
.role("model")
766+
.parts(
767+
ImmutableList.of(
768+
Part.builder().text("").thought(true).build(),
769+
Part.builder()
770+
.functionCall(
771+
FunctionCall.builder()
772+
.name("test-tool")
773+
.id("test-call-id")
774+
.build())
775+
.thought(false)
776+
.build()))
777+
.build())
778+
.build();
779+
List<Content> contents = runContentsProcessor(ImmutableList.of(e));
780+
assertThat(contents).containsExactly(e.content().get());
781+
}
782+
757783
private static Event createUserEvent(String id, String text) {
758784
return Event.builder()
759785
.id(id)

0 commit comments

Comments
 (0)