diff --git a/core/src/main/java/com/google/adk/models/GeminiUtil.java b/core/src/main/java/com/google/adk/models/GeminiUtil.java index 0ef0a50fd..540d0e06e 100644 --- a/core/src/main/java/com/google/adk/models/GeminiUtil.java +++ b/core/src/main/java/com/google/adk/models/GeminiUtil.java @@ -38,6 +38,8 @@ public final class GeminiUtil { "Continue output. DO NOT look at this line. ONLY look at the content before this line and" + " system instruction."; + private static final String AF_FUNCTION_CALL_ID_PREFIX = "adk-"; + private GeminiUtil() {} /** @@ -170,12 +172,16 @@ public static LlmRequest removeClientFunctionCallId(LlmRequest llmRequest) { } private static Part removeClientFunctionCallIdFromPart(Part part) { - if (part.functionCall().isPresent() && part.functionCall().get().id().isPresent()) { + if (part.functionCall().isPresent() + && part.functionCall().get().id().isPresent() + && part.functionCall().get().id().get().startsWith(AF_FUNCTION_CALL_ID_PREFIX)) { return part.toBuilder() .functionCall(part.functionCall().get().toBuilder().clearId().build()) .build(); } - if (part.functionResponse().isPresent() && part.functionResponse().get().id().isPresent()) { + if (part.functionResponse().isPresent() + && part.functionResponse().get().id().isPresent() + && part.functionResponse().get().id().get().startsWith(AF_FUNCTION_CALL_ID_PREFIX)) { return part.toBuilder() .functionResponse(part.functionResponse().get().toBuilder().clearId().build()) .build(); diff --git a/core/src/test/java/com/google/adk/models/GeminiUtilTest.java b/core/src/test/java/com/google/adk/models/GeminiUtilTest.java index 31cbe76de..b0943aa50 100644 --- a/core/src/test/java/com/google/adk/models/GeminiUtilTest.java +++ b/core/src/test/java/com/google/adk/models/GeminiUtilTest.java @@ -460,7 +460,7 @@ public void removeClientFunctionCallId_stripsIds() { .functionCall( FunctionCall.builder() .name("foo") - .id("id1") + .id("adk-id1") .args(ImmutableMap.of("key", "value")) .build()) .build(); @@ -469,7 +469,7 @@ public void removeClientFunctionCallId_stripsIds() { .functionResponse( FunctionResponse.builder() .name("bar") - .id("id2") + .id("adk-id2") .response(ImmutableMap.of("key", "value")) .build()) .build(); @@ -490,6 +490,43 @@ public void removeClientFunctionCallId_stripsIds() { assertThat(resultPart2.functionResponse().get().name()).hasValue("bar"); } + @Test + public void removeClientFunctionCallId_preservesNonClientIds() { + Part partWithFunctionCall = + Part.builder() + .functionCall( + FunctionCall.builder() + .name("foo") + .id("call_123") + .args(ImmutableMap.of("key", "value")) + .build()) + .build(); + Part partWithFunctionResponse = + Part.builder() + .functionResponse( + FunctionResponse.builder() + .name("bar") + .id("call_456") + .response(ImmutableMap.of("key", "value")) + .build()) + .build(); + LlmRequest request = toRequest(partWithFunctionCall, partWithFunctionResponse); + + LlmRequest result = GeminiUtil.removeClientFunctionCallId(request); + + assertThat(result.contents()).hasSize(1); + assertThat(result.contents().get(0).parts()).isPresent(); + assertThat(result.contents().get(0).parts().get()).hasSize(2); + Part resultPart1 = result.contents().get(0).parts().get().get(0); + assertThat(resultPart1.functionCall()).isPresent(); + assertThat(resultPart1.functionCall().get().id()).hasValue("call_123"); + assertThat(resultPart1.functionCall().get().name()).hasValue("foo"); + Part resultPart2 = result.contents().get(0).parts().get().get(1); + assertThat(resultPart2.functionResponse()).isPresent(); + assertThat(resultPart2.functionResponse().get().id()).hasValue("call_456"); + assertThat(resultPart2.functionResponse().get().name()).hasValue("bar"); + } + private static Content toContent(Part... parts) { return Content.builder().parts(ImmutableList.copyOf(parts)).build(); }