mirror of
https://github.com/amithkoujalgi/ollama4j.git
synced 2025-09-16 03:39:05 +02:00
feat: add client-side tool handling option
This commit is contained in:
parent
356bd0b81f
commit
7bd3bed5e4
@ -21,7 +21,7 @@ repos:
|
||||
|
||||
# for commit message formatting
|
||||
- repo: https://github.com/commitizen-tools/commitizen
|
||||
rev: v4.8.3
|
||||
rev: v4.9.0
|
||||
hooks:
|
||||
- id: commitizen
|
||||
stages: [commit-msg]
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div align="center">
|
||||
<img src='https://raw.githubusercontent.com/ollama4j/ollama4j/65a9d526150da8fcd98e2af6a164f055572bf722/ollama4j.jpeg' width='100' alt="ollama4j-icon">
|
||||
|
||||
|
||||
### Ollama4j
|
||||
</div>
|
||||
|
||||
|
@ -93,6 +93,15 @@ public class OllamaAPI {
|
||||
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
|
||||
private int numberOfRetriesForModelPull = 0;
|
||||
|
||||
/**
|
||||
* When set to true, tools will not be automatically executed by the library.
|
||||
* Instead, tool calls will be returned to the client for manual handling.
|
||||
* <p>
|
||||
* Default is false for backward compatibility.
|
||||
*/
|
||||
@Setter
|
||||
private boolean clientHandlesTools = false;
|
||||
|
||||
/**
|
||||
* Instantiates the Ollama API with default Ollama host:
|
||||
* <a href="http://localhost:11434">http://localhost:11434</a>
|
||||
@ -1349,6 +1358,10 @@ public class OllamaAPI {
|
||||
result = requestCaller.callSync(request);
|
||||
}
|
||||
|
||||
if (clientHandlesTools) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// check if toolCallIsWanted
|
||||
List<OllamaChatToolCalls> toolCalls = result.getResponseModel().getMessage().getToolCalls();
|
||||
int toolCallTries = 0;
|
||||
|
@ -303,6 +303,8 @@ class OllamaAPIIntegrationTest {
|
||||
@Order(11)
|
||||
void testChatWithExplicitToolDefinition() throws OllamaBaseException, IOException, URISyntaxException,
|
||||
InterruptedException, ToolInvocationException {
|
||||
// Ensure default behavior (library handles tools) for baseline assertions
|
||||
api.setClientHandlesTools(false);
|
||||
String theToolModel = TOOLS_MODEL;
|
||||
api.pullModel(theToolModel);
|
||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(theToolModel);
|
||||
@ -336,10 +338,61 @@ class OllamaAPIIntegrationTest {
|
||||
assertNull(finalToolCalls, "Final tool calls in the response message should be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(13)
|
||||
void testChatWithExplicitToolDefinitionWithClientHandlesTools() throws OllamaBaseException, IOException, URISyntaxException,
|
||||
InterruptedException, ToolInvocationException {
|
||||
String theToolModel = TOOLS_MODEL;
|
||||
api.pullModel(theToolModel);
|
||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(theToolModel);
|
||||
|
||||
api.registerTool(employeeFinderTool());
|
||||
|
||||
try {
|
||||
// enable client-handled tools so the library does not auto-execute tool calls
|
||||
api.setClientHandlesTools(true);
|
||||
|
||||
OllamaChatRequest requestModel = builder
|
||||
.withMessage(OllamaChatMessageRole.USER, "Give me the ID and address of the employee Rahul Kumar.")
|
||||
.build();
|
||||
requestModel.setOptions(new OptionsBuilder().setTemperature(0.9f).build().getOptionsMap());
|
||||
|
||||
OllamaChatResult chatResult = api.chat(requestModel);
|
||||
|
||||
assertNotNull(chatResult, "chatResult should not be null");
|
||||
assertNotNull(chatResult.getResponseModel(), "Response model should not be null");
|
||||
assertNotNull(chatResult.getResponseModel().getMessage(), "Response message should not be null");
|
||||
assertEquals(
|
||||
OllamaChatMessageRole.ASSISTANT.getRoleName(),
|
||||
chatResult.getResponseModel().getMessage().getRole().getRoleName(),
|
||||
"Role of the response message should be ASSISTANT"
|
||||
);
|
||||
|
||||
// When clientHandlesTools is true, the assistant message should contain tool calls
|
||||
List<OllamaChatToolCalls> toolCalls = chatResult.getResponseModel().getMessage().getToolCalls();
|
||||
assertNotNull(toolCalls, "Assistant message should contain tool calls when clientHandlesTools is true");
|
||||
assertFalse(toolCalls.isEmpty(), "Tool calls should not be empty");
|
||||
OllamaToolCallsFunction function = toolCalls.get(0).getFunction();
|
||||
assertEquals("get-employee-details", function.getName(), "Tool function name should be 'get-employee-details'");
|
||||
Object employeeName = function.getArguments().get("employee-name");
|
||||
assertNotNull(employeeName, "Employee name argument should not be null");
|
||||
assertEquals("Rahul Kumar", employeeName, "Employee name argument should be 'Rahul Kumar'");
|
||||
|
||||
// Since tools were not auto-executed, chat history should contain only the user and assistant messages
|
||||
assertEquals(2, chatResult.getChatHistory().size(),
|
||||
"Chat history should contain only user and assistant (tool call) messages when clientHandlesTools is true");
|
||||
} finally {
|
||||
// reset to default to avoid affecting other tests
|
||||
api.setClientHandlesTools(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(14)
|
||||
void testChatWithToolsAndStream() throws OllamaBaseException, IOException, URISyntaxException,
|
||||
InterruptedException, ToolInvocationException {
|
||||
// Ensure default behavior (library handles tools) for streamed test
|
||||
api.setClientHandlesTools(false);
|
||||
String theToolModel = TOOLS_MODEL;
|
||||
api.pullModel(theToolModel);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user