Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import io.agentscope.core.message.ToolUseBlock;
import io.agentscope.core.model.ChatResponse;
import io.agentscope.core.model.ChatUsage;
import io.agentscope.core.util.JsonUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -66,10 +67,16 @@ public ChatResponse parseResponse(OllamaResponse response) {
// AgentScope requirement.
String callId = UUID.randomUUID().toString();

// Convert input to JSON string for validation in ToolExecutor
// For tools with no parameters, input will be null or an empty map {}
String argumentsJson;
if (input == null || input.isEmpty()) {
argumentsJson = "{}";
} else {
argumentsJson = JsonUtils.getJsonCodec().toJson(input);
}
contentBlocks.add(
new ToolUseBlock(
callId, fn.getName(), input, null // raw content
));
new ToolUseBlock(callId, fn.getName(), input, argumentsJson, null));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,46 @@ void testFallbackFinishReason() {
// Assert
assertEquals("stop", chatResponse.getFinishReason());
}

@Test
@DisplayName("Should parse tool call with no parameters (empty arguments map)")
void testParseToolCallWithNoParameters() {
// Arrange - This reproduces the bug from issue #569
// Ollama returns empty map {} for tools with no parameters
OllamaResponse response = new OllamaResponse();
response.setModel("test-model");

OllamaMessage message = new OllamaMessage("assistant", "");

OllamaToolCall toolCall = new OllamaToolCall();
OllamaFunction function = new OllamaFunction();
function.setName("getTime");
function.setArguments(Map.of()); // Empty map for no parameters
toolCall.setFunction(function);

message.setToolCalls(Arrays.asList(toolCall));
response.setMessage(message);

// Act
ChatResponse chatResponse = parser.parseResponse(response);

// Assert
assertNotNull(chatResponse);
List<ContentBlock> content = chatResponse.getContent();
assertEquals(1, content.size());
assertTrue(content.get(0) instanceof ToolUseBlock);

ToolUseBlock toolBlock = (ToolUseBlock) content.get(0);
assertEquals("getTime", toolBlock.getName());
assertTrue(toolBlock.getInput().isEmpty(), "Input should be empty map");

// Verify that getContent() returns "{}" (not null) for no-parameter tools
assertNotNull(
toolBlock.getContent(),
"ToolUseBlock content should not be null for validation in ToolExecutor");
assertEquals(
"{}",
toolBlock.getContent(),
"ToolUseBlock content should be empty JSON object string for no-parameter tools");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,21 @@ void testNullSchema() {
assertNull(result);
}

@Test
@DisplayName("Should pass when input is empty object with empty schema")
void testEmptyInputWithEmptySchema() {
// This simulates a tool with no parameters (like getTime())
Map<String, Object> schema =
Map.of(
"type",
"object",
"properties",
Map.of()); // Empty properties = no parameters

String result = ToolValidator.validateInput("{}", schema);
assertNull(result, "Empty object {} should pass validation with empty schema");
}

@Test
@DisplayName("Should pass when schema is empty")
void testEmptySchema() {
Expand Down
Loading