Fix Gemini Tool Calling for texts returned from MethodToolCallback

Signed-off-by: nlinhvu <nlinhvu.dev@gmail.com>
This commit is contained in:
nlinhvu
2025-05-08 10:30:34 +07:00
committed by Christian Tzolov
parent 499e8baae5
commit f2df87b567
4 changed files with 54 additions and 4 deletions

View File

@@ -340,7 +340,10 @@ public class VertexAiGeminiChatModel implements ChatModel, DisposableBean {
Struct.Builder structBuilder = Struct.newBuilder();
if (rootNode.isArray()) {
if (rootNode.isTextual()) {
structBuilder.putFields("result", Value.newBuilder().setStringValue(json).build());
}
else if (rootNode.isArray()) {
// Handle JSON array
List<Value> values = new ArrayList<>();

View File

@@ -361,6 +361,38 @@ class VertexAiGeminiChatModelIT {
}
@Test
void jsonTextToolCallingTest() {
// Test for the improved jsonToStruct method that handles JSON texts in tool
// calling
ToolCallingManager toolCallingManager = ToolCallingManager.builder()
.observationRegistry(ObservationRegistry.NOOP)
.build();
VertexAiGeminiChatModel chatModelWithTools = VertexAiGeminiChatModel.builder()
.vertexAI(vertexAiApi())
.toolCallingManager(toolCallingManager)
.defaultOptions(VertexAiGeminiChatOptions.builder()
.model(VertexAiGeminiChatModel.ChatModel.GEMINI_2_0_FLASH)
.temperature(0.1)
.build())
.build();
ChatClient chatClient = ChatClient.builder(chatModelWithTools).build();
// Create a prompt that will trigger the tool call with a specific request that
// should invoke the tool
String response = chatClient.prompt()
.tools(new CurrentTimeTools())
.user("Get the current time. Make sure to use the getCurrentDateTime tool to get this information.")
.call()
.content();
assertThat(response).isNotEmpty();
assertThat(response).contains("2025-05-08T10:10:10+02:00[Europe/Berlin]");
}
/**
* Tool class that returns a JSON array to test the jsonToStruct method's ability to
* handle JSON arrays. This specifically tests the PR changes that improve the
@@ -378,6 +410,21 @@ class VertexAiGeminiChatModelIT {
}
/**
* Tool class that returns a String to test the jsonToStruct method's ability to
* handle JSON texts. This specifically tests the PR changes that improve the
* jsonToStruct method to handle JSON texts in addition to JSON objects and JSON
* arrays.
*/
public static class CurrentTimeTools {
@Tool(description = "Get the current date and time in the user's timezone")
String getCurrentDateTime() {
return "2025-05-08T10:10:10+02:00[Europe/Berlin]";
}
}
record ActorsFilmsRecord(String actor, List<String> movies) {
}

View File

@@ -45,7 +45,7 @@ public final class DefaultToolCallResultConverter implements ToolCallResultConve
public String convert(@Nullable Object result, @Nullable Type returnType) {
if (returnType == Void.TYPE) {
logger.debug("The tool has no return type. Converting to conventional response.");
return "Done";
return JsonParser.toJson("Done");
}
if (result instanceof RenderedImage) {
final var buf = new ByteArrayOutputStream(1024 * 4);

View File

@@ -50,9 +50,9 @@ class DefaultToolCallResultConverterTests {
}
@Test
void convertVoidReturnTypeShouldReturnDone() {
void convertVoidReturnTypeShouldReturnDoneJson() {
String result = this.converter.convert(null, void.class);
assertThat(result).isEqualTo("Done");
assertThat(result).isEqualTo("\"Done\"");
}
@Test