Skip to content

Commit d78bc27

Browse files
google-genai-botcopybara-github
authored andcommitted
fix: Exclude model thoughts when saving LLM output to state
PiperOrigin-RevId: 839890911
1 parent 2906eb5 commit d78bc27

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import com.google.errorprone.annotations.CanIgnoreReturnValue;
5454
import com.google.genai.types.Content;
5555
import com.google.genai.types.GenerateContentConfig;
56+
import com.google.genai.types.Part;
5657
import com.google.genai.types.Schema;
5758
import io.reactivex.rxjava3.core.Flowable;
5859
import io.reactivex.rxjava3.core.Maybe;
@@ -567,10 +568,11 @@ protected BaseLlmFlow determineLlmFlow() {
567568

568569
private void maybeSaveOutputToState(Event event) {
569570
if (outputKey().isPresent() && event.finalResponse() && event.content().isPresent()) {
570-
// Concatenate text from all parts.
571+
// Concatenate text from all parts, excluding thoughts.
571572
Object output;
572573
String rawResult =
573574
event.content().flatMap(Content::parts).orElse(ImmutableList.of()).stream()
575+
.filter(part -> !isThought(part))
574576
.map(part -> part.text().orElse(""))
575577
.collect(joining());
576578

@@ -602,6 +604,10 @@ private void maybeSaveOutputToState(Event event) {
602604
}
603605
}
604606

607+
private static boolean isThought(Part part) {
608+
return part.thought().isPresent() && part.thought().get();
609+
}
610+
605611
@Override
606612
protected Flowable<Event> runAsyncImpl(InvocationContext invocationContext) {
607613
return llmFlow

core/src/test/java/com/google/adk/agents/LlmAgentTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,25 @@ public void testRun_withOutputKey_savesMultiPartState() {
9696
.containsEntry("myMultiPartOutput", "Part 1. Part 2.");
9797
}
9898

99+
@Test
100+
public void testRun_withOutputKey_savesState_ignoresThoughts() {
101+
Content modelContent =
102+
Content.fromParts(
103+
Part.fromText("Saved output"),
104+
Part.fromText("Ignored thought").toBuilder().thought(true).build());
105+
TestLlm testLlm = createTestLlm(createLlmResponse(modelContent));
106+
LlmAgent agent = createTestAgentBuilder(testLlm).outputKey("myOutput").build();
107+
InvocationContext invocationContext = createInvocationContext(agent);
108+
109+
List<Event> events = agent.runAsync(invocationContext).toList().blockingGet();
110+
111+
assertThat(events).hasSize(1);
112+
assertThat(events.get(0).content()).hasValue(modelContent);
113+
assertThat(events.get(0).finalResponse()).isTrue();
114+
115+
assertThat(events.get(0).actions().stateDelta()).containsEntry("myOutput", "Saved output");
116+
}
117+
99118
@Test
100119
public void testRun_withoutOutputKey_doesNotSaveState() {
101120
Content modelContent = Content.fromParts(Part.fromText("Some output"));

0 commit comments

Comments
 (0)