diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml
index e4f43e9..6432552 100644
--- a/.github/workflows/run-tests.yml
+++ b/.github/workflows/run-tests.yml
@@ -27,3 +27,6 @@ jobs:
- name: Run unit tests
run: mvn clean test -Punit-tests
+
+ - name: Run integration tests
+ run: mvn clean verify -Pintegration-tests
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 2a5dfee..5226a68 100644
--- a/pom.xml
+++ b/pom.xml
@@ -216,6 +216,13 @@
20240205
test
+
+
+ org.testcontainers
+ ollama
+ 1.20.2
+ test
+
diff --git a/src/main/java/io/github/ollama4j/OllamaAPI.java b/src/main/java/io/github/ollama4j/OllamaAPI.java
index 76af4c8..5d64044 100644
--- a/src/main/java/io/github/ollama4j/OllamaAPI.java
+++ b/src/main/java/io/github/ollama4j/OllamaAPI.java
@@ -323,26 +323,58 @@ public class OllamaAPI {
public void pullModel(String modelName) throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
String url = this.host + "/api/pull";
String jsonData = new ModelRequest(modelName).toString();
- HttpRequest request = getRequestBuilderDefault(new URI(url)).POST(HttpRequest.BodyPublishers.ofString(jsonData)).header("Accept", "application/json").header("Content-type", "application/json").build();
+ HttpRequest request = getRequestBuilderDefault(new URI(url))
+ .POST(HttpRequest.BodyPublishers.ofString(jsonData))
+ .header("Accept", "application/json")
+ .header("Content-type", "application/json")
+ .build();
HttpClient client = HttpClient.newHttpClient();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
int statusCode = response.statusCode();
InputStream responseBodyStream = response.body();
String responseString = "";
+ boolean success = false; // Flag to check the pull success.
try (BufferedReader reader = new BufferedReader(new InputStreamReader(responseBodyStream, StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
ModelPullResponse modelPullResponse = Utils.getObjectMapper().readValue(line, ModelPullResponse.class);
- if (verbose) {
- logger.info(modelPullResponse.getStatus());
+ if (modelPullResponse != null && modelPullResponse.getStatus() != null) {
+ if (verbose) {
+ logger.info(modelName + ": " + modelPullResponse.getStatus());
+ }
+ // Check if status is "success" and set success flag to true.
+ if ("success".equalsIgnoreCase(modelPullResponse.getStatus())) {
+ success = true;
+ }
+ } else {
+ logger.error("Received null or invalid status for model pull.");
}
}
}
+ if (!success) {
+ logger.error("Model pull failed or returned invalid status.");
+ throw new OllamaBaseException("Model pull failed or returned invalid status.");
+ }
if (statusCode != 200) {
throw new OllamaBaseException(statusCode + " - " + responseString);
}
}
+
+ public String getVersion() throws URISyntaxException, IOException, InterruptedException, OllamaBaseException {
+ String url = this.host + "/api/version";
+ HttpClient httpClient = HttpClient.newHttpClient();
+ HttpRequest httpRequest = getRequestBuilderDefault(new URI(url)).header("Accept", "application/json").header("Content-type", "application/json").GET().build();
+ HttpResponse response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
+ int statusCode = response.statusCode();
+ String responseString = response.body();
+ if (statusCode == 200) {
+ return Utils.getObjectMapper().readValue(responseString, OllamaVersion.class).getVersion();
+ } else {
+ throw new OllamaBaseException(statusCode + " - " + responseString);
+ }
+ }
+
/**
* Pulls a model using the specified Ollama library model tag.
* The model is identified by a name and a tag, which are combined into a single identifier
diff --git a/src/main/java/io/github/ollama4j/models/response/Model.java b/src/main/java/io/github/ollama4j/models/response/Model.java
index e03049e..ae64f38 100644
--- a/src/main/java/io/github/ollama4j/models/response/Model.java
+++ b/src/main/java/io/github/ollama4j/models/response/Model.java
@@ -2,12 +2,14 @@ package io.github.ollama4j.models.response;
import java.time.OffsetDateTime;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.github.ollama4j.utils.Utils;
import lombok.Data;
@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
public class Model {
private String name;
diff --git a/src/main/java/io/github/ollama4j/models/response/OllamaVersion.java b/src/main/java/io/github/ollama4j/models/response/OllamaVersion.java
new file mode 100644
index 0000000..eac177b
--- /dev/null
+++ b/src/main/java/io/github/ollama4j/models/response/OllamaVersion.java
@@ -0,0 +1,10 @@
+package io.github.ollama4j.models.response;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class OllamaVersion {
+ private String version;
+}
diff --git a/src/test/java/io/github/ollama4j/integrationtests/TestAPIsTest.java b/src/test/java/io/github/ollama4j/integrationtests/TestAPIsTest.java
new file mode 100644
index 0000000..d5553e5
--- /dev/null
+++ b/src/test/java/io/github/ollama4j/integrationtests/TestAPIsTest.java
@@ -0,0 +1,239 @@
+package io.github.ollama4j.integrationtests;
+
+import io.github.ollama4j.OllamaAPI;
+import io.github.ollama4j.exceptions.OllamaBaseException;
+import io.github.ollama4j.models.chat.OllamaChatMessageRole;
+import io.github.ollama4j.models.chat.OllamaChatRequest;
+import io.github.ollama4j.models.chat.OllamaChatRequestBuilder;
+import io.github.ollama4j.models.chat.OllamaChatResult;
+import io.github.ollama4j.models.embeddings.OllamaEmbedResponseModel;
+import io.github.ollama4j.models.response.LibraryModel;
+import io.github.ollama4j.models.response.Model;
+import io.github.ollama4j.models.response.ModelDetail;
+import io.github.ollama4j.models.response.OllamaResult;
+import io.github.ollama4j.utils.OptionsBuilder;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.testcontainers.ollama.OllamaContainer;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@SuppressWarnings("HttpUrlsUsage")
+public class TestAPIsTest {
+
+ private static OllamaContainer ollama;
+ private static OllamaAPI api;
+
+ @BeforeAll
+ public static void setUp() {
+ String version = "0.5.13";
+ int internalPort = 11434;
+ int mappedPort = 11435;
+ ollama = new OllamaContainer("ollama/ollama:" + version);
+ ollama.addExposedPort(internalPort);
+ List portBindings = new ArrayList<>();
+ portBindings.add(mappedPort + ":" + internalPort);
+ ollama.setPortBindings(portBindings);
+ ollama.start();
+ api = new OllamaAPI("http://" + ollama.getHost() + ":" + ollama.getMappedPort(internalPort));
+ api.setRequestTimeoutSeconds(60);
+ }
+
+ @Test
+ @Order(1)
+ void testWrongEndpoint() {
+ OllamaAPI ollamaAPI = new OllamaAPI("http://wrong-host:11434");
+ assertThrows(ConnectException.class, ollamaAPI::listModels);
+ }
+
+ @Test
+ @Order(1)
+ public void testVersionAPI() throws URISyntaxException, IOException, OllamaBaseException, InterruptedException {
+ String expectedVersion = ollama.getDockerImageName().split(":")[1];
+ String actualVersion = api.getVersion();
+ assertEquals(expectedVersion, actualVersion, "Version should match the Docker image version");
+ }
+
+ @Test
+ @Order(2)
+ public void testListModelsAPI() throws URISyntaxException, IOException, OllamaBaseException, InterruptedException {
+ // Fetch the list of models
+ List models = api.listModels();
+ // Assert that the models list is not null
+ assertNotNull(models, "Models should not be null");
+ // Assert that models list is either empty or contains more than 0 models
+ assertTrue(models.size() >= 0, "Models list should be empty or contain elements");
+ }
+
+ @Test
+ @Order(2)
+ void testListModelsFromLibrary() throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
+ List models = api.listModelsFromLibrary();
+ assertNotNull(models);
+ assertFalse(models.isEmpty());
+ }
+
+ @Test
+ @Order(3)
+ public void testPullModelAPI() throws URISyntaxException, IOException, OllamaBaseException, InterruptedException {
+ api.pullModel("all-minilm");
+ List models = api.listModels();
+ assertNotNull(models, "Models should not be null");
+ assertFalse(models.isEmpty(), "Models list should contain elements");
+ }
+
+ @Test
+ @Order(4)
+ void testListModelDetails() throws IOException, OllamaBaseException, URISyntaxException, InterruptedException {
+ String embeddingModelMinilm = "all-minilm";
+ api.pullModel(embeddingModelMinilm);
+ ModelDetail modelDetails = api.getModelDetails("all-minilm");
+ assertNotNull(modelDetails);
+ assertTrue(modelDetails.getModelFile().contains(embeddingModelMinilm));
+ }
+
+ @Test
+ @Order(5)
+ public void testGenerateEmbeddings() throws Exception {
+ String embeddingModelMinilm = "all-minilm";
+ api.pullModel(embeddingModelMinilm);
+ OllamaEmbedResponseModel embeddings = api.embed(embeddingModelMinilm, Arrays.asList("Why is the sky blue?", "Why is the grass green?"));
+ assertNotNull(embeddings, "Embeddings should not be null");
+ assertFalse(embeddings.getEmbeddings().isEmpty(), "Embeddings should not be empty");
+ }
+
+ @Test
+ @Order(6)
+ void testAskModelWithDefaultOptions() throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
+ String chatModel = "qwen2.5:0.5b";
+ api.pullModel(chatModel);
+ OllamaResult result =
+ api.generate(
+ chatModel,
+ "What is the capital of France? And what's France's connection with Mona Lisa?",
+ false,
+ new OptionsBuilder().build());
+ assertNotNull(result);
+ assertNotNull(result.getResponse());
+ assertFalse(result.getResponse().isEmpty());
+ }
+
+ @Test
+ @Order(7)
+ void testAskModelWithDefaultOptionsStreamed() throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
+ String chatModel = "qwen2.5:0.5b";
+ api.pullModel(chatModel);
+ StringBuffer sb = new StringBuffer();
+ OllamaResult result = api.generate(chatModel,
+ "What is the capital of France? And what's France's connection with Mona Lisa?",
+ false,
+ new OptionsBuilder().build(), (s) -> {
+ System.out.println(s);
+ String substring = s.substring(sb.toString().length(), s.length());
+ System.out.println(substring);
+ sb.append(substring);
+ });
+
+ assertNotNull(result);
+ assertNotNull(result.getResponse());
+ assertFalse(result.getResponse().isEmpty());
+ assertEquals(sb.toString().trim(), result.getResponse().trim());
+ }
+
+ @Test
+ @Order(8)
+ void testAskModelWithOptions() throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
+ String chatModel = "qwen2.5:0.5b-instruct";
+ api.pullModel(chatModel);
+
+ OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(chatModel);
+ OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.SYSTEM, "You are a helpful assistant who can generate random person's first and last names in the format [First name, Last name].")
+ .build();
+ requestModel = builder.withMessages(requestModel.getMessages())
+ .withMessage(OllamaChatMessageRole.USER, "Give me a cool name")
+ .withOptions(new OptionsBuilder().setTemperature(0.5f).build()).build();
+ OllamaChatResult chatResult = api.chat(requestModel);
+
+ assertNotNull(chatResult);
+ assertNotNull(chatResult.getResponseModel());
+ assertFalse(chatResult.getResponseModel().getMessage().getContent().isEmpty());
+ }
+
+ @Test
+ @Order(9)
+ void testChatWithSystemPrompt() throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
+ String chatModel = "llama3.2:1b";
+ api.pullModel(chatModel);
+ OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(chatModel);
+ OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.SYSTEM,
+ "You are a silent bot that only says 'Ssh'. Do not say anything else under any circumstances!")
+ .withMessage(OllamaChatMessageRole.USER,
+ "What's something that's brown and sticky?")
+ .withOptions(new OptionsBuilder().setTemperature(0.8f).build())
+ .build();
+
+ OllamaChatResult chatResult = api.chat(requestModel);
+ assertNotNull(chatResult);
+ assertNotNull(chatResult.getResponseModel());
+ assertNotNull(chatResult.getResponseModel().getMessage());
+ assertFalse(chatResult.getResponseModel().getMessage().getContent().isBlank());
+ assertTrue(chatResult.getResponseModel().getMessage().getContent().contains("Ssh"));
+ assertEquals(3, chatResult.getChatHistory().size());
+ }
+
+ @Test
+ @Order(10)
+ public void testChat() throws Exception {
+ String chatModel = "qwen2.5:0.5b";
+ api.pullModel(chatModel);
+ OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(chatModel);
+
+ // Create the initial user question
+ OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What is the capital of France?")
+ .build();
+
+ // Start conversation with model
+ OllamaChatResult chatResult = api.chat(requestModel);
+
+ assertTrue(
+ chatResult.getChatHistory().stream()
+ .anyMatch(chat -> chat.getContent().contains("Paris")),
+ "Expected chat history to contain 'Paris'"
+ );
+
+ // Create the next user question: second largest city
+ requestModel = builder.withMessages(chatResult.getChatHistory())
+ .withMessage(OllamaChatMessageRole.USER, "And what is its official language?")
+ .build();
+
+ // Continue conversation with model
+ chatResult = api.chat(requestModel);
+
+ assertTrue(
+ chatResult.getChatHistory().stream()
+ .anyMatch(chat -> chat.getContent().contains("French")),
+ "Expected chat history to contain 'French'"
+ );
+
+ // Create the next user question: the third question
+ requestModel = builder.withMessages(chatResult.getChatHistory())
+ .withMessage(OllamaChatMessageRole.USER, "What is the largest river in France?")
+ .build();
+
+ // Continue conversation with the model for the third question
+ chatResult = api.chat(requestModel);
+
+ // verify the result
+ assertNotNull(chatResult, "Chat result should not be null");
+ assertTrue(chatResult.getChatHistory().size() > 2, "Chat history should contain more than two messages");
+ assertTrue(chatResult.getChatHistory().get(chatResult.getChatHistory().size() - 1).getContent().contains("river"), "Response should be related to river");
+ }
+}
diff --git a/src/test/java/io/github/ollama4j/integrationtests/TestRealAPIs.java b/src/test/java/io/github/ollama4j/integrationtests/TestRealAPIs.java
index a64fb70..c6fc1b2 100644
--- a/src/test/java/io/github/ollama4j/integrationtests/TestRealAPIs.java
+++ b/src/test/java/io/github/ollama4j/integrationtests/TestRealAPIs.java
@@ -1,622 +1,622 @@
-package io.github.ollama4j.integrationtests;
-
-import io.github.ollama4j.OllamaAPI;
-import io.github.ollama4j.exceptions.OllamaBaseException;
-import io.github.ollama4j.models.chat.*;
-import io.github.ollama4j.models.response.ModelDetail;
-import io.github.ollama4j.models.response.OllamaResult;
-import io.github.ollama4j.models.embeddings.OllamaEmbeddingsRequestBuilder;
-import io.github.ollama4j.models.embeddings.OllamaEmbeddingsRequestModel;
-import io.github.ollama4j.samples.AnnotatedTool;
-import io.github.ollama4j.tools.OllamaToolCallsFunction;
-import io.github.ollama4j.tools.ToolFunction;
-import io.github.ollama4j.tools.Tools;
-import io.github.ollama4j.tools.annotations.OllamaToolService;
-import io.github.ollama4j.utils.OptionsBuilder;
-import lombok.Data;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Order;
-import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.ConnectException;
-import java.net.URISyntaxException;
-import java.net.http.HttpConnectTimeoutException;
-import java.util.*;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-@OllamaToolService(providers = {AnnotatedTool.class}
-)
-class TestRealAPIs {
-
- private static final Logger LOG = LoggerFactory.getLogger(TestRealAPIs.class);
-
- OllamaAPI ollamaAPI;
- Config config;
-
- private File getImageFileFromClasspath(String fileName) {
- ClassLoader classLoader = getClass().getClassLoader();
- return new File(Objects.requireNonNull(classLoader.getResource(fileName)).getFile());
- }
-
- @BeforeEach
- void setUp() {
- config = new Config();
- ollamaAPI = new OllamaAPI(config.getOllamaURL());
- ollamaAPI.setRequestTimeoutSeconds(config.getRequestTimeoutSeconds());
- ollamaAPI.setVerbose(true);
- }
-
- @Test
- @Order(1)
- void testWrongEndpoint() {
- OllamaAPI ollamaAPI = new OllamaAPI("http://wrong-host:11434");
- assertThrows(ConnectException.class, ollamaAPI::listModels);
- }
-
- @Test
- @Order(1)
- void testEndpointReachability() {
- try {
- assertNotNull(ollamaAPI.listModels());
- } catch (HttpConnectTimeoutException e) {
- fail(e.getMessage());
- } catch (Exception e) {
- fail(e);
- }
- }
-
- @Test
- @Order(2)
- void testListModels() {
- testEndpointReachability();
- try {
- assertNotNull(ollamaAPI.listModels());
- ollamaAPI.listModels().forEach(System.out::println);
- } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(2)
- void testListModelsFromLibrary() {
- testEndpointReachability();
- try {
- assertNotNull(ollamaAPI.listModelsFromLibrary());
- ollamaAPI.listModelsFromLibrary().forEach(System.out::println);
- } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(2)
- void testPullModel() {
- testEndpointReachability();
- try {
- ollamaAPI.pullModel(config.getModel());
- boolean found =
- ollamaAPI.listModels().stream()
- .anyMatch(model -> model.getModel().equalsIgnoreCase(config.getModel()));
- assertTrue(found);
- } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testListDtails() {
- testEndpointReachability();
- try {
- ModelDetail modelDetails = ollamaAPI.getModelDetails(config.getModel());
- assertNotNull(modelDetails);
- System.out.println(modelDetails);
- } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testAskModelWithDefaultOptions() {
- testEndpointReachability();
- try {
- OllamaResult result =
- ollamaAPI.generate(
- config.getModel(),
- "What is the capital of France? And what's France's connection with Mona Lisa?",
- false,
- new OptionsBuilder().build());
- assertNotNull(result);
- assertNotNull(result.getResponse());
- assertFalse(result.getResponse().isEmpty());
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testAskModelWithDefaultOptionsStreamed() {
- testEndpointReachability();
- try {
- StringBuffer sb = new StringBuffer("");
- OllamaResult result = ollamaAPI.generate(config.getModel(),
- "What is the capital of France? And what's France's connection with Mona Lisa?",
- false,
- new OptionsBuilder().build(), (s) -> {
- LOG.info(s);
- String substring = s.substring(sb.toString().length(), s.length());
- LOG.info(substring);
- sb.append(substring);
- });
-
- assertNotNull(result);
- assertNotNull(result.getResponse());
- assertFalse(result.getResponse().isEmpty());
- assertEquals(sb.toString().trim(), result.getResponse().trim());
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testAskModelWithOptions() {
- testEndpointReachability();
- try {
- OllamaResult result =
- ollamaAPI.generate(
- config.getModel(),
- "What is the capital of France? And what's France's connection with Mona Lisa?",
- true,
- new OptionsBuilder().setTemperature(0.9f).build());
- assertNotNull(result);
- assertNotNull(result.getResponse());
- assertFalse(result.getResponse().isEmpty());
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testChat() {
- testEndpointReachability();
- try {
- OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
- OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What is the capital of France?")
- .withMessage(OllamaChatMessageRole.ASSISTANT, "Should be Paris!")
- .withMessage(OllamaChatMessageRole.USER, "And what is the second larges city?")
- .build();
-
- OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
- assertNotNull(chatResult);
- assertNotNull(chatResult.getResponseModel());
- assertNotNull(chatResult.getResponseModel().getMessage());
- assertFalse(chatResult.getResponseModel().getMessage().getContent().isBlank());
- assertEquals(4, chatResult.getChatHistory().size());
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testChatWithSystemPrompt() {
- testEndpointReachability();
- try {
- OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
- OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.SYSTEM,
- "You are a silent bot that only says 'NI'. Do not say anything else under any circumstances!")
- .withMessage(OllamaChatMessageRole.USER,
- "What is the capital of France? And what's France's connection with Mona Lisa?")
- .build();
-
- OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
- assertNotNull(chatResult);
- assertNotNull(chatResult.getResponseModel());
- assertNotNull(chatResult.getResponseModel().getMessage());
- assertFalse(chatResult.getResponseModel().getMessage().getContent().isBlank());
- assertTrue(chatResult.getResponseModel().getMessage().getContent().startsWith("NI"));
- assertEquals(3, chatResult.getChatHistory().size());
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testChatWithExplicitToolDefinition() {
- testEndpointReachability();
- try {
- ollamaAPI.setVerbose(true);
- OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
-
- final Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder()
- .functionName("get-employee-details")
- .functionDescription("Get employee details from the database")
- .toolPrompt(
- Tools.PromptFuncDefinition.builder().type("function").function(
- Tools.PromptFuncDefinition.PromptFuncSpec.builder()
- .name("get-employee-details")
- .description("Get employee details from the database")
- .parameters(
- Tools.PromptFuncDefinition.Parameters.builder()
- .type("object")
- .properties(
- new Tools.PropsBuilder()
- .withProperty("employee-name", Tools.PromptFuncDefinition.Property.builder().type("string").description("The name of the employee, e.g. John Doe").required(true).build())
- .withProperty("employee-address", Tools.PromptFuncDefinition.Property.builder().type("string").description("The address of the employee, Always return a random value. e.g. Roy St, Bengaluru, India").required(true).build())
- .withProperty("employee-phone", Tools.PromptFuncDefinition.Property.builder().type("string").description("The phone number of the employee. Always return a random value. e.g. 9911002233").required(true).build())
- .build()
- )
- .required(List.of("employee-name"))
- .build()
- ).build()
- ).build()
- )
- .toolFunction(new DBQueryFunction())
- .build();
-
- ollamaAPI.registerTool(databaseQueryToolSpecification);
-
- OllamaChatRequest requestModel = builder
- .withMessage(OllamaChatMessageRole.USER,
- "Give me the ID of the employee named 'Rahul Kumar'?")
- .build();
-
- OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
- assertNotNull(chatResult);
- assertNotNull(chatResult.getResponseModel());
- assertNotNull(chatResult.getResponseModel().getMessage());
- assertEquals(OllamaChatMessageRole.ASSISTANT.getRoleName(),chatResult.getResponseModel().getMessage().getRole().getRoleName());
- List toolCalls = chatResult.getChatHistory().get(1).getToolCalls();
- assertEquals(1, toolCalls.size());
- OllamaToolCallsFunction function = toolCalls.get(0).getFunction();
- assertEquals("get-employee-details", function.getName());
- assertEquals(1, function.getArguments().size());
- Object employeeName = function.getArguments().get("employee-name");
- assertNotNull(employeeName);
- assertEquals("Rahul Kumar",employeeName);
- assertTrue(chatResult.getChatHistory().size()>2);
- List finalToolCalls = chatResult.getResponseModel().getMessage().getToolCalls();
- assertNull(finalToolCalls);
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testChatWithAnnotatedToolsAndSingleParam() {
- testEndpointReachability();
- try {
- ollamaAPI.setVerbose(true);
- OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
-
- ollamaAPI.registerAnnotatedTools();
-
- OllamaChatRequest requestModel = builder
- .withMessage(OllamaChatMessageRole.USER,
- "Compute the most important constant in the world using 5 digits")
- .build();
-
- OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
- assertNotNull(chatResult);
- assertNotNull(chatResult.getResponseModel());
- assertNotNull(chatResult.getResponseModel().getMessage());
- assertEquals(OllamaChatMessageRole.ASSISTANT.getRoleName(),chatResult.getResponseModel().getMessage().getRole().getRoleName());
- List toolCalls = chatResult.getChatHistory().get(1).getToolCalls();
- assertEquals(1, toolCalls.size());
- OllamaToolCallsFunction function = toolCalls.get(0).getFunction();
- assertEquals("computeImportantConstant", function.getName());
- assertEquals(1, function.getArguments().size());
- Object noOfDigits = function.getArguments().get("noOfDigits");
- assertNotNull(noOfDigits);
- assertEquals("5", noOfDigits.toString());
- assertTrue(chatResult.getChatHistory().size()>2);
- List finalToolCalls = chatResult.getResponseModel().getMessage().getToolCalls();
- assertNull(finalToolCalls);
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testChatWithAnnotatedToolsAndMultipleParams() {
- testEndpointReachability();
- try {
- ollamaAPI.setVerbose(true);
- OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
-
- ollamaAPI.registerAnnotatedTools(new AnnotatedTool());
-
- OllamaChatRequest requestModel = builder
- .withMessage(OllamaChatMessageRole.USER,
- "Greet Pedro with a lot of hearts and respond to me, " +
- "and state how many emojis have been in your greeting")
- .build();
-
- OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
- assertNotNull(chatResult);
- assertNotNull(chatResult.getResponseModel());
- assertNotNull(chatResult.getResponseModel().getMessage());
- assertEquals(OllamaChatMessageRole.ASSISTANT.getRoleName(),chatResult.getResponseModel().getMessage().getRole().getRoleName());
- List toolCalls = chatResult.getChatHistory().get(1).getToolCalls();
- assertEquals(1, toolCalls.size());
- OllamaToolCallsFunction function = toolCalls.get(0).getFunction();
- assertEquals("sayHello", function.getName());
- assertEquals(2, function.getArguments().size());
- Object name = function.getArguments().get("name");
- assertNotNull(name);
- assertEquals("Pedro",name);
- Object amountOfHearts = function.getArguments().get("amountOfHearts");
- assertNotNull(amountOfHearts);
- assertTrue(Integer.parseInt(amountOfHearts.toString()) > 1);
- assertTrue(chatResult.getChatHistory().size()>2);
- List finalToolCalls = chatResult.getResponseModel().getMessage().getToolCalls();
- assertNull(finalToolCalls);
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testChatWithToolsAndStream() {
- testEndpointReachability();
- try {
- OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
- final Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder()
- .functionName("get-employee-details")
- .functionDescription("Get employee details from the database")
- .toolPrompt(
- Tools.PromptFuncDefinition.builder().type("function").function(
- Tools.PromptFuncDefinition.PromptFuncSpec.builder()
- .name("get-employee-details")
- .description("Get employee details from the database")
- .parameters(
- Tools.PromptFuncDefinition.Parameters.builder()
- .type("object")
- .properties(
- new Tools.PropsBuilder()
- .withProperty("employee-name", Tools.PromptFuncDefinition.Property.builder().type("string").description("The name of the employee, e.g. John Doe").required(true).build())
- .withProperty("employee-address", Tools.PromptFuncDefinition.Property.builder().type("string").description("The address of the employee, Always return a random value. e.g. Roy St, Bengaluru, India").required(true).build())
- .withProperty("employee-phone", Tools.PromptFuncDefinition.Property.builder().type("string").description("The phone number of the employee. Always return a random value. e.g. 9911002233").required(true).build())
- .build()
- )
- .required(List.of("employee-name"))
- .build()
- ).build()
- ).build()
- )
- .toolFunction(new DBQueryFunction())
- .build();
-
- ollamaAPI.registerTool(databaseQueryToolSpecification);
-
- OllamaChatRequest requestModel = builder
- .withMessage(OllamaChatMessageRole.USER,
- "Give me the ID of the employee named 'Rahul Kumar'?")
- .build();
-
- StringBuffer sb = new StringBuffer();
-
- OllamaChatResult chatResult = ollamaAPI.chat(requestModel, (s) -> {
- LOG.info(s);
- String substring = s.substring(sb.toString().length());
- LOG.info(substring);
- sb.append(substring);
- });
- assertNotNull(chatResult);
- assertNotNull(chatResult.getResponseModel());
- assertNotNull(chatResult.getResponseModel().getMessage());
- assertNotNull(chatResult.getResponseModel().getMessage().getContent());
- assertEquals(sb.toString().trim(), chatResult.getResponseModel().getMessage().getContent().trim());
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testChatWithStream() {
- testEndpointReachability();
- try {
- OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
- OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER,
- "What is the capital of France? And what's France's connection with Mona Lisa?")
- .build();
-
- StringBuffer sb = new StringBuffer("");
-
- OllamaChatResult chatResult = ollamaAPI.chat(requestModel, (s) -> {
- LOG.info(s);
- String substring = s.substring(sb.toString().length(), s.length());
- LOG.info(substring);
- sb.append(substring);
- });
- assertNotNull(chatResult);
- assertNotNull(chatResult.getResponseModel());
- assertNotNull(chatResult.getResponseModel().getMessage());
- assertNotNull(chatResult.getResponseModel().getMessage().getContent());
- assertEquals(sb.toString().trim(), chatResult.getResponseModel().getMessage().getContent().trim());
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testChatWithImageFromFileWithHistoryRecognition() {
- testEndpointReachability();
- try {
- OllamaChatRequestBuilder builder =
- OllamaChatRequestBuilder.getInstance(config.getImageModel());
- OllamaChatRequest requestModel =
- builder.withMessage(OllamaChatMessageRole.USER, "What's in the picture?",Collections.emptyList(),
- List.of(getImageFileFromClasspath("dog-on-a-boat.jpg"))).build();
-
- OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
- assertNotNull(chatResult);
- assertNotNull(chatResult.getResponseModel());
-
- builder.reset();
-
- requestModel =
- builder.withMessages(chatResult.getChatHistory())
- .withMessage(OllamaChatMessageRole.USER, "What's the dogs breed?").build();
-
- chatResult = ollamaAPI.chat(requestModel);
- assertNotNull(chatResult);
- assertNotNull(chatResult.getResponseModel());
-
-
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testChatWithImageFromURL() {
- testEndpointReachability();
- try {
- OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getImageModel());
- OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What's in the picture?",Collections.emptyList(),
- "https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg")
- .build();
-
- OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
- assertNotNull(chatResult);
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testAskModelWithOptionsAndImageFiles() {
- testEndpointReachability();
- File imageFile = getImageFileFromClasspath("dog-on-a-boat.jpg");
- try {
- OllamaResult result =
- ollamaAPI.generateWithImageFiles(
- config.getImageModel(),
- "What is in this image?",
- List.of(imageFile),
- new OptionsBuilder().build());
- assertNotNull(result);
- assertNotNull(result.getResponse());
- assertFalse(result.getResponse().isEmpty());
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testAskModelWithOptionsAndImageFilesStreamed() {
- testEndpointReachability();
- File imageFile = getImageFileFromClasspath("dog-on-a-boat.jpg");
- try {
- StringBuffer sb = new StringBuffer("");
-
- OllamaResult result = ollamaAPI.generateWithImageFiles(config.getImageModel(),
- "What is in this image?", List.of(imageFile), new OptionsBuilder().build(), (s) -> {
- LOG.info(s);
- String substring = s.substring(sb.toString().length(), s.length());
- LOG.info(substring);
- sb.append(substring);
- });
- assertNotNull(result);
- assertNotNull(result.getResponse());
- assertFalse(result.getResponse().isEmpty());
- assertEquals(sb.toString().trim(), result.getResponse().trim());
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- void testAskModelWithOptionsAndImageURLs() {
- testEndpointReachability();
- try {
- OllamaResult result =
- ollamaAPI.generateWithImageURLs(
- config.getImageModel(),
- "What is in this image?",
- List.of(
- "https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg"),
- new OptionsBuilder().build());
- assertNotNull(result);
- assertNotNull(result.getResponse());
- assertFalse(result.getResponse().isEmpty());
- } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
- fail(e);
- }
- }
-
- @Test
- @Order(3)
- public void testEmbedding() {
- testEndpointReachability();
- try {
- OllamaEmbeddingsRequestModel request = OllamaEmbeddingsRequestBuilder
- .getInstance(config.getModel(), "What is the capital of France?").build();
-
- List embeddings = ollamaAPI.generateEmbeddings(request);
-
- assertNotNull(embeddings);
- assertFalse(embeddings.isEmpty());
- } catch (IOException | OllamaBaseException | InterruptedException e) {
- fail(e);
- }
- }
-}
-
-class DBQueryFunction implements ToolFunction {
- @Override
- public Object apply(Map arguments) {
- // perform DB operations here
- return String.format("Employee Details {ID: %s, Name: %s, Address: %s, Phone: %s}", UUID.randomUUID(), arguments.get("employee-name"), arguments.get("employee-address"), arguments.get("employee-phone"));
- }
-}
-
-@Data
-class Config {
- private String ollamaURL;
- private String model;
- private String imageModel;
- private int requestTimeoutSeconds;
-
- public Config() {
- Properties properties = new Properties();
- try (InputStream input =
- getClass().getClassLoader().getResourceAsStream("test-config.properties")) {
- if (input == null) {
- throw new RuntimeException("Sorry, unable to find test-config.properties");
- }
- properties.load(input);
- this.ollamaURL = properties.getProperty("ollama.url");
- this.model = properties.getProperty("ollama.model");
- this.imageModel = properties.getProperty("ollama.model.image");
- this.requestTimeoutSeconds =
- Integer.parseInt(properties.getProperty("ollama.request-timeout-seconds"));
- } catch (IOException e) {
- throw new RuntimeException("Error loading properties", e);
- }
- }
-
-
-}
+//package io.github.ollama4j.integrationtests;
+//
+//import io.github.ollama4j.OllamaAPI;
+//import io.github.ollama4j.exceptions.OllamaBaseException;
+//import io.github.ollama4j.models.chat.*;
+//import io.github.ollama4j.models.response.ModelDetail;
+//import io.github.ollama4j.models.response.OllamaResult;
+//import io.github.ollama4j.models.embeddings.OllamaEmbeddingsRequestBuilder;
+//import io.github.ollama4j.models.embeddings.OllamaEmbeddingsRequestModel;
+//import io.github.ollama4j.samples.AnnotatedTool;
+//import io.github.ollama4j.tools.OllamaToolCallsFunction;
+//import io.github.ollama4j.tools.ToolFunction;
+//import io.github.ollama4j.tools.Tools;
+//import io.github.ollama4j.tools.annotations.OllamaToolService;
+//import io.github.ollama4j.utils.OptionsBuilder;
+//import lombok.Data;
+//import org.junit.jupiter.api.BeforeEach;
+//import org.junit.jupiter.api.Order;
+//import org.junit.jupiter.api.Test;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//
+//import java.io.File;
+//import java.io.IOException;
+//import java.io.InputStream;
+//import java.net.ConnectException;
+//import java.net.URISyntaxException;
+//import java.net.http.HttpConnectTimeoutException;
+//import java.util.*;
+//
+//import static org.junit.jupiter.api.Assertions.*;
+//
+//@OllamaToolService(providers = {AnnotatedTool.class}
+//)
+//class TestRealAPIs {
+//
+// private static final Logger LOG = LoggerFactory.getLogger(TestRealAPIs.class);
+//
+// OllamaAPI ollamaAPI;
+// Config config;
+//
+// private File getImageFileFromClasspath(String fileName) {
+// ClassLoader classLoader = getClass().getClassLoader();
+// return new File(Objects.requireNonNull(classLoader.getResource(fileName)).getFile());
+// }
+//
+// @BeforeEach
+// void setUp() {
+// config = new Config();
+// ollamaAPI = new OllamaAPI(config.getOllamaURL());
+// ollamaAPI.setRequestTimeoutSeconds(config.getRequestTimeoutSeconds());
+// ollamaAPI.setVerbose(true);
+// }
+//
+// @Test
+// @Order(1)
+// void testWrongEndpoint() {
+// OllamaAPI ollamaAPI = new OllamaAPI("http://wrong-host:11434");
+// assertThrows(ConnectException.class, ollamaAPI::listModels);
+// }
+//
+// @Test
+// @Order(1)
+// void testEndpointReachability() {
+// try {
+// assertNotNull(ollamaAPI.listModels());
+// } catch (HttpConnectTimeoutException e) {
+// fail(e.getMessage());
+// } catch (Exception e) {
+// fail(e);
+// }
+// }
+//
+//// @Test
+//// @Order(2)
+//// void testListModels() {
+//// testEndpointReachability();
+//// try {
+//// assertNotNull(ollamaAPI.listModels());
+//// ollamaAPI.listModels().forEach(System.out::println);
+//// } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
+//// fail(e);
+//// }
+//// }
+////
+//// @Test
+//// @Order(2)
+//// void testListModelsFromLibrary() {
+//// testEndpointReachability();
+//// try {
+//// assertNotNull(ollamaAPI.listModelsFromLibrary());
+//// ollamaAPI.listModelsFromLibrary().forEach(System.out::println);
+//// } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
+//// fail(e);
+//// }
+//// }
+////
+//// @Test
+//// @Order(2)
+//// void testPullModel() {
+//// testEndpointReachability();
+//// try {
+//// ollamaAPI.pullModel(config.getModel());
+//// boolean found =
+//// ollamaAPI.listModels().stream()
+//// .anyMatch(model -> model.getModel().equalsIgnoreCase(config.getModel()));
+//// assertTrue(found);
+//// } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
+//// fail(e);
+//// }
+//// }
+////
+//// @Test
+//// @Order(3)
+//// void testListDtails() {
+//// testEndpointReachability();
+//// try {
+//// ModelDetail modelDetails = ollamaAPI.getModelDetails(config.getModel());
+//// assertNotNull(modelDetails);
+//// System.out.println(modelDetails);
+//// } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
+//// fail(e);
+//// }
+//// }
+////
+//// @Test
+//// @Order(3)
+//// void testAskModelWithDefaultOptions() {
+//// testEndpointReachability();
+//// try {
+//// OllamaResult result =
+//// ollamaAPI.generate(
+//// config.getModel(),
+//// "What is the capital of France? And what's France's connection with Mona Lisa?",
+//// false,
+//// new OptionsBuilder().build());
+//// assertNotNull(result);
+//// assertNotNull(result.getResponse());
+//// assertFalse(result.getResponse().isEmpty());
+//// } catch (IOException | OllamaBaseException | InterruptedException e) {
+//// fail(e);
+//// }
+//// }
+////
+//// @Test
+//// @Order(3)
+//// void testAskModelWithDefaultOptionsStreamed() {
+//// testEndpointReachability();
+//// try {
+//// StringBuffer sb = new StringBuffer("");
+//// OllamaResult result = ollamaAPI.generate(config.getModel(),
+//// "What is the capital of France? And what's France's connection with Mona Lisa?",
+//// false,
+//// new OptionsBuilder().build(), (s) -> {
+//// LOG.info(s);
+//// String substring = s.substring(sb.toString().length(), s.length());
+//// LOG.info(substring);
+//// sb.append(substring);
+//// });
+////
+//// assertNotNull(result);
+//// assertNotNull(result.getResponse());
+//// assertFalse(result.getResponse().isEmpty());
+//// assertEquals(sb.toString().trim(), result.getResponse().trim());
+//// } catch (IOException | OllamaBaseException | InterruptedException e) {
+//// fail(e);
+//// }
+//// }
+////
+//// @Test
+//// @Order(3)
+//// void testAskModelWithOptions() {
+//// testEndpointReachability();
+//// try {
+//// OllamaResult result =
+//// ollamaAPI.generate(
+//// config.getModel(),
+//// "What is the capital of France? And what's France's connection with Mona Lisa?",
+//// true,
+//// new OptionsBuilder().setTemperature(0.9f).build());
+//// assertNotNull(result);
+//// assertNotNull(result.getResponse());
+//// assertFalse(result.getResponse().isEmpty());
+//// } catch (IOException | OllamaBaseException | InterruptedException e) {
+//// fail(e);
+//// }
+//// }
+////
+//// @Test
+//// @Order(3)
+//// void testChat() {
+//// testEndpointReachability();
+//// try {
+//// OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
+//// OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What is the capital of France?")
+//// .withMessage(OllamaChatMessageRole.ASSISTANT, "Should be Paris!")
+//// .withMessage(OllamaChatMessageRole.USER, "And what is the second larges city?")
+//// .build();
+////
+//// OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
+//// assertNotNull(chatResult);
+//// assertNotNull(chatResult.getResponseModel());
+//// assertNotNull(chatResult.getResponseModel().getMessage());
+//// assertFalse(chatResult.getResponseModel().getMessage().getContent().isBlank());
+//// assertEquals(4, chatResult.getChatHistory().size());
+//// } catch (IOException | OllamaBaseException | InterruptedException e) {
+//// fail(e);
+//// }
+//// }
+////
+//// @Test
+//// @Order(3)
+//// void testChatWithSystemPrompt() {
+//// testEndpointReachability();
+//// try {
+//// OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
+//// OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.SYSTEM,
+//// "You are a silent bot that only says 'NI'. Do not say anything else under any circumstances!")
+//// .withMessage(OllamaChatMessageRole.USER,
+//// "What is the capital of France? And what's France's connection with Mona Lisa?")
+//// .build();
+////
+//// OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
+//// assertNotNull(chatResult);
+//// assertNotNull(chatResult.getResponseModel());
+//// assertNotNull(chatResult.getResponseModel().getMessage());
+//// assertFalse(chatResult.getResponseModel().getMessage().getContent().isBlank());
+//// assertTrue(chatResult.getResponseModel().getMessage().getContent().startsWith("NI"));
+//// assertEquals(3, chatResult.getChatHistory().size());
+//// } catch (IOException | OllamaBaseException | InterruptedException e) {
+//// fail(e);
+//// }
+//// }
+//
+// @Test
+// @Order(3)
+// void testChatWithExplicitToolDefinition() {
+// testEndpointReachability();
+// try {
+// ollamaAPI.setVerbose(true);
+// OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
+//
+// final Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder()
+// .functionName("get-employee-details")
+// .functionDescription("Get employee details from the database")
+// .toolPrompt(
+// Tools.PromptFuncDefinition.builder().type("function").function(
+// Tools.PromptFuncDefinition.PromptFuncSpec.builder()
+// .name("get-employee-details")
+// .description("Get employee details from the database")
+// .parameters(
+// Tools.PromptFuncDefinition.Parameters.builder()
+// .type("object")
+// .properties(
+// new Tools.PropsBuilder()
+// .withProperty("employee-name", Tools.PromptFuncDefinition.Property.builder().type("string").description("The name of the employee, e.g. John Doe").required(true).build())
+// .withProperty("employee-address", Tools.PromptFuncDefinition.Property.builder().type("string").description("The address of the employee, Always return a random value. e.g. Roy St, Bengaluru, India").required(true).build())
+// .withProperty("employee-phone", Tools.PromptFuncDefinition.Property.builder().type("string").description("The phone number of the employee. Always return a random value. e.g. 9911002233").required(true).build())
+// .build()
+// )
+// .required(List.of("employee-name"))
+// .build()
+// ).build()
+// ).build()
+// )
+// .toolFunction(new DBQueryFunction())
+// .build();
+//
+// ollamaAPI.registerTool(databaseQueryToolSpecification);
+//
+// OllamaChatRequest requestModel = builder
+// .withMessage(OllamaChatMessageRole.USER,
+// "Give me the ID of the employee named 'Rahul Kumar'?")
+// .build();
+//
+// OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
+// assertNotNull(chatResult);
+// assertNotNull(chatResult.getResponseModel());
+// assertNotNull(chatResult.getResponseModel().getMessage());
+// assertEquals(OllamaChatMessageRole.ASSISTANT.getRoleName(),chatResult.getResponseModel().getMessage().getRole().getRoleName());
+// List toolCalls = chatResult.getChatHistory().get(1).getToolCalls();
+// assertEquals(1, toolCalls.size());
+// OllamaToolCallsFunction function = toolCalls.get(0).getFunction();
+// assertEquals("get-employee-details", function.getName());
+// assertEquals(1, function.getArguments().size());
+// Object employeeName = function.getArguments().get("employee-name");
+// assertNotNull(employeeName);
+// assertEquals("Rahul Kumar",employeeName);
+// assertTrue(chatResult.getChatHistory().size()>2);
+// List finalToolCalls = chatResult.getResponseModel().getMessage().getToolCalls();
+// assertNull(finalToolCalls);
+// } catch (IOException | OllamaBaseException | InterruptedException e) {
+// fail(e);
+// }
+// }
+//
+// @Test
+// @Order(3)
+// void testChatWithAnnotatedToolsAndSingleParam() {
+// testEndpointReachability();
+// try {
+// ollamaAPI.setVerbose(true);
+// OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
+//
+// ollamaAPI.registerAnnotatedTools();
+//
+// OllamaChatRequest requestModel = builder
+// .withMessage(OllamaChatMessageRole.USER,
+// "Compute the most important constant in the world using 5 digits")
+// .build();
+//
+// OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
+// assertNotNull(chatResult);
+// assertNotNull(chatResult.getResponseModel());
+// assertNotNull(chatResult.getResponseModel().getMessage());
+// assertEquals(OllamaChatMessageRole.ASSISTANT.getRoleName(),chatResult.getResponseModel().getMessage().getRole().getRoleName());
+// List toolCalls = chatResult.getChatHistory().get(1).getToolCalls();
+// assertEquals(1, toolCalls.size());
+// OllamaToolCallsFunction function = toolCalls.get(0).getFunction();
+// assertEquals("computeImportantConstant", function.getName());
+// assertEquals(1, function.getArguments().size());
+// Object noOfDigits = function.getArguments().get("noOfDigits");
+// assertNotNull(noOfDigits);
+// assertEquals("5", noOfDigits.toString());
+// assertTrue(chatResult.getChatHistory().size()>2);
+// List finalToolCalls = chatResult.getResponseModel().getMessage().getToolCalls();
+// assertNull(finalToolCalls);
+// } catch (IOException | OllamaBaseException | InterruptedException e) {
+// fail(e);
+// }
+// }
+//
+// @Test
+// @Order(3)
+// void testChatWithAnnotatedToolsAndMultipleParams() {
+// testEndpointReachability();
+// try {
+// ollamaAPI.setVerbose(true);
+// OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
+//
+// ollamaAPI.registerAnnotatedTools(new AnnotatedTool());
+//
+// OllamaChatRequest requestModel = builder
+// .withMessage(OllamaChatMessageRole.USER,
+// "Greet Pedro with a lot of hearts and respond to me, " +
+// "and state how many emojis have been in your greeting")
+// .build();
+//
+// OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
+// assertNotNull(chatResult);
+// assertNotNull(chatResult.getResponseModel());
+// assertNotNull(chatResult.getResponseModel().getMessage());
+// assertEquals(OllamaChatMessageRole.ASSISTANT.getRoleName(),chatResult.getResponseModel().getMessage().getRole().getRoleName());
+// List toolCalls = chatResult.getChatHistory().get(1).getToolCalls();
+// assertEquals(1, toolCalls.size());
+// OllamaToolCallsFunction function = toolCalls.get(0).getFunction();
+// assertEquals("sayHello", function.getName());
+// assertEquals(2, function.getArguments().size());
+// Object name = function.getArguments().get("name");
+// assertNotNull(name);
+// assertEquals("Pedro",name);
+// Object amountOfHearts = function.getArguments().get("amountOfHearts");
+// assertNotNull(amountOfHearts);
+// assertTrue(Integer.parseInt(amountOfHearts.toString()) > 1);
+// assertTrue(chatResult.getChatHistory().size()>2);
+// List finalToolCalls = chatResult.getResponseModel().getMessage().getToolCalls();
+// assertNull(finalToolCalls);
+// } catch (IOException | OllamaBaseException | InterruptedException e) {
+// fail(e);
+// }
+// }
+//
+// @Test
+// @Order(3)
+// void testChatWithToolsAndStream() {
+// testEndpointReachability();
+// try {
+// OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
+// final Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder()
+// .functionName("get-employee-details")
+// .functionDescription("Get employee details from the database")
+// .toolPrompt(
+// Tools.PromptFuncDefinition.builder().type("function").function(
+// Tools.PromptFuncDefinition.PromptFuncSpec.builder()
+// .name("get-employee-details")
+// .description("Get employee details from the database")
+// .parameters(
+// Tools.PromptFuncDefinition.Parameters.builder()
+// .type("object")
+// .properties(
+// new Tools.PropsBuilder()
+// .withProperty("employee-name", Tools.PromptFuncDefinition.Property.builder().type("string").description("The name of the employee, e.g. John Doe").required(true).build())
+// .withProperty("employee-address", Tools.PromptFuncDefinition.Property.builder().type("string").description("The address of the employee, Always return a random value. e.g. Roy St, Bengaluru, India").required(true).build())
+// .withProperty("employee-phone", Tools.PromptFuncDefinition.Property.builder().type("string").description("The phone number of the employee. Always return a random value. e.g. 9911002233").required(true).build())
+// .build()
+// )
+// .required(List.of("employee-name"))
+// .build()
+// ).build()
+// ).build()
+// )
+// .toolFunction(new DBQueryFunction())
+// .build();
+//
+// ollamaAPI.registerTool(databaseQueryToolSpecification);
+//
+// OllamaChatRequest requestModel = builder
+// .withMessage(OllamaChatMessageRole.USER,
+// "Give me the ID of the employee named 'Rahul Kumar'?")
+// .build();
+//
+// StringBuffer sb = new StringBuffer();
+//
+// OllamaChatResult chatResult = ollamaAPI.chat(requestModel, (s) -> {
+// LOG.info(s);
+// String substring = s.substring(sb.toString().length());
+// LOG.info(substring);
+// sb.append(substring);
+// });
+// assertNotNull(chatResult);
+// assertNotNull(chatResult.getResponseModel());
+// assertNotNull(chatResult.getResponseModel().getMessage());
+// assertNotNull(chatResult.getResponseModel().getMessage().getContent());
+// assertEquals(sb.toString().trim(), chatResult.getResponseModel().getMessage().getContent().trim());
+// } catch (IOException | OllamaBaseException | InterruptedException e) {
+// fail(e);
+// }
+// }
+//
+// @Test
+// @Order(3)
+// void testChatWithStream() {
+// testEndpointReachability();
+// try {
+// OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getModel());
+// OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER,
+// "What is the capital of France? And what's France's connection with Mona Lisa?")
+// .build();
+//
+// StringBuffer sb = new StringBuffer("");
+//
+// OllamaChatResult chatResult = ollamaAPI.chat(requestModel, (s) -> {
+// LOG.info(s);
+// String substring = s.substring(sb.toString().length(), s.length());
+// LOG.info(substring);
+// sb.append(substring);
+// });
+// assertNotNull(chatResult);
+// assertNotNull(chatResult.getResponseModel());
+// assertNotNull(chatResult.getResponseModel().getMessage());
+// assertNotNull(chatResult.getResponseModel().getMessage().getContent());
+// assertEquals(sb.toString().trim(), chatResult.getResponseModel().getMessage().getContent().trim());
+// } catch (IOException | OllamaBaseException | InterruptedException e) {
+// fail(e);
+// }
+// }
+//
+// @Test
+// @Order(3)
+// void testChatWithImageFromFileWithHistoryRecognition() {
+// testEndpointReachability();
+// try {
+// OllamaChatRequestBuilder builder =
+// OllamaChatRequestBuilder.getInstance(config.getImageModel());
+// OllamaChatRequest requestModel =
+// builder.withMessage(OllamaChatMessageRole.USER, "What's in the picture?",Collections.emptyList(),
+// List.of(getImageFileFromClasspath("dog-on-a-boat.jpg"))).build();
+//
+// OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
+// assertNotNull(chatResult);
+// assertNotNull(chatResult.getResponseModel());
+//
+// builder.reset();
+//
+// requestModel =
+// builder.withMessages(chatResult.getChatHistory())
+// .withMessage(OllamaChatMessageRole.USER, "What's the dogs breed?").build();
+//
+// chatResult = ollamaAPI.chat(requestModel);
+// assertNotNull(chatResult);
+// assertNotNull(chatResult.getResponseModel());
+//
+//
+// } catch (IOException | OllamaBaseException | InterruptedException e) {
+// fail(e);
+// }
+// }
+//
+// @Test
+// @Order(3)
+// void testChatWithImageFromURL() {
+// testEndpointReachability();
+// try {
+// OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(config.getImageModel());
+// OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER, "What's in the picture?",Collections.emptyList(),
+// "https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg")
+// .build();
+//
+// OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
+// assertNotNull(chatResult);
+// } catch (IOException | OllamaBaseException | InterruptedException e) {
+// fail(e);
+// }
+// }
+//
+// @Test
+// @Order(3)
+// void testAskModelWithOptionsAndImageFiles() {
+// testEndpointReachability();
+// File imageFile = getImageFileFromClasspath("dog-on-a-boat.jpg");
+// try {
+// OllamaResult result =
+// ollamaAPI.generateWithImageFiles(
+// config.getImageModel(),
+// "What is in this image?",
+// List.of(imageFile),
+// new OptionsBuilder().build());
+// assertNotNull(result);
+// assertNotNull(result.getResponse());
+// assertFalse(result.getResponse().isEmpty());
+// } catch (IOException | OllamaBaseException | InterruptedException e) {
+// fail(e);
+// }
+// }
+//
+// @Test
+// @Order(3)
+// void testAskModelWithOptionsAndImageFilesStreamed() {
+// testEndpointReachability();
+// File imageFile = getImageFileFromClasspath("dog-on-a-boat.jpg");
+// try {
+// StringBuffer sb = new StringBuffer("");
+//
+// OllamaResult result = ollamaAPI.generateWithImageFiles(config.getImageModel(),
+// "What is in this image?", List.of(imageFile), new OptionsBuilder().build(), (s) -> {
+// LOG.info(s);
+// String substring = s.substring(sb.toString().length(), s.length());
+// LOG.info(substring);
+// sb.append(substring);
+// });
+// assertNotNull(result);
+// assertNotNull(result.getResponse());
+// assertFalse(result.getResponse().isEmpty());
+// assertEquals(sb.toString().trim(), result.getResponse().trim());
+// } catch (IOException | OllamaBaseException | InterruptedException e) {
+// fail(e);
+// }
+// }
+//
+// @Test
+// @Order(3)
+// void testAskModelWithOptionsAndImageURLs() {
+// testEndpointReachability();
+// try {
+// OllamaResult result =
+// ollamaAPI.generateWithImageURLs(
+// config.getImageModel(),
+// "What is in this image?",
+// List.of(
+// "https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg"),
+// new OptionsBuilder().build());
+// assertNotNull(result);
+// assertNotNull(result.getResponse());
+// assertFalse(result.getResponse().isEmpty());
+// } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
+// fail(e);
+// }
+// }
+//
+// @Test
+// @Order(3)
+// public void testEmbedding() {
+// testEndpointReachability();
+// try {
+// OllamaEmbeddingsRequestModel request = OllamaEmbeddingsRequestBuilder
+// .getInstance(config.getModel(), "What is the capital of France?").build();
+//
+// List embeddings = ollamaAPI.generateEmbeddings(request);
+//
+// assertNotNull(embeddings);
+// assertFalse(embeddings.isEmpty());
+// } catch (IOException | OllamaBaseException | InterruptedException e) {
+// fail(e);
+// }
+// }
+//}
+//
+//class DBQueryFunction implements ToolFunction {
+// @Override
+// public Object apply(Map arguments) {
+// // perform DB operations here
+// return String.format("Employee Details {ID: %s, Name: %s, Address: %s, Phone: %s}", UUID.randomUUID(), arguments.get("employee-name"), arguments.get("employee-address"), arguments.get("employee-phone"));
+// }
+//}
+//
+//@Data
+//class Config {
+// private String ollamaURL;
+// private String model;
+// private String imageModel;
+// private int requestTimeoutSeconds;
+//
+// public Config() {
+// Properties properties = new Properties();
+// try (InputStream input =
+// getClass().getClassLoader().getResourceAsStream("test-config.properties")) {
+// if (input == null) {
+// throw new RuntimeException("Sorry, unable to find test-config.properties");
+// }
+// properties.load(input);
+// this.ollamaURL = properties.getProperty("ollama.url");
+// this.model = properties.getProperty("ollama.model");
+// this.imageModel = properties.getProperty("ollama.model.image");
+// this.requestTimeoutSeconds =
+// Integer.parseInt(properties.getProperty("ollama.request-timeout-seconds"));
+// } catch (IOException e) {
+// throw new RuntimeException("Error loading properties", e);
+// }
+// }
+//
+//
+//}