mirror of
				https://github.com/amithkoujalgi/ollama4j.git
				synced 2025-10-31 16:40:41 +01:00 
			
		
		
		
	feat: add client-side tool handling option
This commit is contained in:
		| @@ -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); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 twosom
					twosom