Skip to content

Commit 4ca024e

Browse files
committed
fix(events): treat an error event without function calls as a final response
Matches adk-python: a complete event carrying an error code ends the turn unless the model still asked for tools, even when it holds a function response.
1 parent 4092a1f commit 4ca024e

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

‎core/src/main/java/com/google/adk/events/Event.java‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ public final boolean finalResponse() {
353353
if (actions().skipSummarization().orElse(false) || hasPendingLongRunningToolCall()) {
354354
return true;
355355
}
356+
// An error ends the turn unless the model still asked for tools; mirrors Python ADK.
357+
if (errorCode().isPresent() && !partial().orElse(false) && functionCalls().isEmpty()) {
358+
return true;
359+
}
356360
return functionCalls().isEmpty()
357361
&& functionResponses().isEmpty()
358362
&& !partial().orElse(false)

‎core/src/test/java/com/google/adk/events/EventTest.java‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,4 +330,62 @@ public void finalResponse_returnsTrueIfSkipSummarization() {
330330
.build();
331331
assertThat(event.finalResponse()).isTrue();
332332
}
333+
334+
@Test
335+
public void finalResponse_isTrueForErrorEvent() {
336+
Event event =
337+
Event.builder()
338+
.id("e1")
339+
.invocationId("i1")
340+
.author("agent")
341+
.content(Content.fromParts(Part.fromText("hello")))
342+
.errorCode(new FinishReason("SOME_ERROR"))
343+
.errorMessage("Something went wrong")
344+
.build();
345+
assertThat(event.finalResponse()).isTrue();
346+
}
347+
348+
@Test
349+
public void finalResponse_isTrueForErrorEventWithFunctionResponse() {
350+
Event event =
351+
Event.builder()
352+
.id("e1")
353+
.invocationId("i1")
354+
.author("agent")
355+
.content(
356+
Content.fromParts(Part.fromFunctionResponse("tool", ImmutableMap.of("k", "v"))))
357+
.errorCode(new FinishReason("SOME_ERROR"))
358+
.errorMessage("Something went wrong")
359+
.build();
360+
assertThat(event.finalResponse()).isTrue();
361+
}
362+
363+
@Test
364+
public void finalResponse_isFalseForErrorEventWithFunctionCall() {
365+
Event event =
366+
Event.builder()
367+
.id("e1")
368+
.invocationId("i1")
369+
.author("agent")
370+
.content(Content.fromParts(Part.fromFunctionCall("tool", ImmutableMap.of("k", "v"))))
371+
.errorCode(new FinishReason("SOME_ERROR"))
372+
.errorMessage("Something went wrong")
373+
.build();
374+
assertThat(event.finalResponse()).isFalse();
375+
}
376+
377+
@Test
378+
public void finalResponse_isFalseForPartialErrorEvent() {
379+
Event event =
380+
Event.builder()
381+
.id("e1")
382+
.invocationId("i1")
383+
.author("agent")
384+
.content(Content.fromParts(Part.fromText("hello")))
385+
.errorCode(new FinishReason("SOME_ERROR"))
386+
.errorMessage("Something went wrong")
387+
.partial(true)
388+
.build();
389+
assertThat(event.finalResponse()).isFalse();
390+
}
333391
}

0 commit comments

Comments
 (0)