diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 2bc6a4c..f1d6e94 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -6,25 +6,35 @@ /* You can override the default Infima variables here. */ :root { - --ifm-color-primary: #2e8555; - --ifm-color-primary-dark: #29784c; - --ifm-color-primary-darker: #277148; - --ifm-color-primary-darkest: #205d3b; - --ifm-color-primary-light: #33925d; - --ifm-color-primary-lighter: #359962; - --ifm-color-primary-lightest: #3cad6e; - --ifm-code-font-size: 95%; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); + --ifm-color-primary: #2e8555; + --ifm-color-primary-dark: #29784c; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205d3b; + --ifm-color-primary-light: #33925d; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-lightest: #3cad6e; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); } /* For readability concerns, you should choose a lighter palette in dark mode. */ [data-theme='dark'] { - --ifm-color-primary: #25c2a0; - --ifm-color-primary-dark: #21af90; - --ifm-color-primary-darker: #1fa588; - --ifm-color-primary-darkest: #1a8870; - --ifm-color-primary-light: #29d5b0; - --ifm-color-primary-lighter: #32d8b4; - --ifm-color-primary-lightest: #4fddbf; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); + --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: #21af90; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #1a8870; + --ifm-color-primary-light: #29d5b0; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); } + +article > header > h1 { + font-size: 2rem !important; +} + +div > h1, +header > h1, +h2 > a { + font-size: 2rem !important; +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index d0e25e7..69dd190 100644 --- a/pom.xml +++ b/pom.xml @@ -1,23 +1,24 @@ - + 4.0.0 io.github.amithkoujalgi ollama4j 1.0.43-SNAPSHOT - Ollama4j - Java library for interacting with Ollama API. - https://github.com/amithkoujalgi/ollama4j + Ollama4j + Java library for interacting with Ollama API. + https://github.com/amithkoujalgi/ollama4j - - 11 - 11 - UTF-8 - 3.0.0-M5 - 3.0.0-M5 - 1.18.30 - + + 11 + 11 + UTF-8 + 3.0.0-M5 + 3.0.0-M5 + 1.18.30 + @@ -28,273 +29,273 @@ - - - MIT License - https://raw.githubusercontent.com/amithkoujalgi/ollama4j/main/LICENSE - - + + + MIT License + https://raw.githubusercontent.com/amithkoujalgi/ollama4j/main/LICENSE + + - - scm:git:git@github.com:amithkoujalgi/ollama4j.git - scm:git:https://github.com/amithkoujalgi/ollama4j.git - https://github.com/amithkoujalgi/ollama4j - v1.0.16 - + + scm:git:git@github.com:amithkoujalgi/ollama4j.git + scm:git:https://github.com/amithkoujalgi/ollama4j.git + https://github.com/amithkoujalgi/ollama4j + v1.0.16 + - - - - org.apache.maven.plugins - maven-source-plugin - 3.3.0 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.5.0 - - - attach-javadocs - - jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - ${skipUnitTests} - - **/unittests/*.java - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - ${maven-failsafe-plugin.version} - - - **/integrationtests/*.java - - - **/unittests/*.java - - ${skipIntegrationTests} - - - - - integration-test - verify - - - - - - org.apache.maven.plugins - maven-release-plugin - 3.0.1 - - - v@{project.version} - - - - - - - - org.projectlombok - lombok - ${lombok.version} - provided - - - com.fasterxml.jackson.core - jackson-databind - 2.15.3 - - - ch.qos.logback - logback-classic - 1.4.12 - test - - - org.slf4j - slf4j-api - 2.0.9 - - - org.junit.jupiter - junit-jupiter-api - 5.10.0 - test - - - org.mockito - mockito-core - 4.1.0 - test - - - - - - ossrh - https://s01.oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://s01.oss.sonatype.org/service/local/staging/deploy/maven2 - - - - - - unit-tests - - unit - false - true - - - true - - + - - org.jacoco - jacoco-maven-plugin - 0.8.7 - - - - prepare-agent - - - - report - test - - report - - - - - - - - - integration-tests - - integration - true - false - - - - ci-cd - - unit - true - true - - - - - org.apache.maven.plugins - maven-gpg-plugin - 3.1.0 - - - sign-artifacts - verify - - sign - + + org.apache.maven.plugins + maven-source-plugin + 3.3.0 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + + attach-javadocs + + jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} - - - --pinentry-mode - loopback - + ${skipUnitTests} + + **/unittests/*.java + - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.13 - true - - ossrh - https://s01.oss.sonatype.org/ - true - - + - - org.jacoco - jacoco-maven-plugin - 0.8.7 - - - - prepare-agent - - - - report - test - - report - - - - + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + **/integrationtests/*.java + + + **/unittests/*.java + + ${skipIntegrationTests} + + + + + integration-test + verify + + + + + + org.apache.maven.plugins + maven-release-plugin + 3.0.1 + + + v@{project.version} + + - - - + + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + com.fasterxml.jackson.core + jackson-databind + 2.15.3 + + + ch.qos.logback + logback-classic + 1.4.12 + test + + + org.slf4j + slf4j-api + 2.0.9 + + + org.junit.jupiter + junit-jupiter-api + 5.10.0 + test + + + org.mockito + mockito-core + 4.1.0 + test + + + + + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2 + + + + + + unit-tests + + unit + false + true + + + true + + + + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + + prepare-agent + + + + report + test + + report + + + + + + + + + integration-tests + + integration + true + false + + + + ci-cd + + unit + true + true + + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.1.0 + + + sign-artifacts + verify + + sign + + + + + --pinentry-mode + loopback + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true + + ossrh + https://s01.oss.sonatype.org/ + true + + + + + org.jacoco + jacoco-maven-plugin + 0.8.7 + + + + prepare-agent + + + + report + test + + report + + + + + + + + \ No newline at end of file diff --git a/src/main/java/io/github/amithkoujalgi/ollama4j/core/OllamaAPI.java b/src/main/java/io/github/amithkoujalgi/ollama4j/core/OllamaAPI.java index c61c55f..19cfb26 100644 --- a/src/main/java/io/github/amithkoujalgi/ollama4j/core/OllamaAPI.java +++ b/src/main/java/io/github/amithkoujalgi/ollama4j/core/OllamaAPI.java @@ -372,15 +372,20 @@ public class OllamaAPI { * @param model the ollama model to ask the question to * @param prompt the prompt/question text * @param imageFiles the list of image files to use for the question + * @param options the Options object - More + * details on the options * @return OllamaResult that includes response text and time taken for response */ - public OllamaResult askWithImageFiles(String model, String prompt, List imageFiles) + public OllamaResult askWithImageFiles( + String model, String prompt, List imageFiles, Options options) throws OllamaBaseException, IOException, InterruptedException { List images = new ArrayList<>(); for (File imageFile : imageFiles) { images.add(encodeFileToBase64(imageFile)); } OllamaRequestModel ollamaRequestModel = new OllamaRequestModel(model, prompt, images); + ollamaRequestModel.setOptions(options.getOptionsMap()); return askSync(ollamaRequestModel); } @@ -391,15 +396,20 @@ public class OllamaAPI { * @param model the ollama model to ask the question to * @param prompt the prompt/question text * @param imageURLs the list of image URLs to use for the question + * @param options the Options object - More + * details on the options * @return OllamaResult that includes response text and time taken for response */ - public OllamaResult askWithImageURLs(String model, String prompt, List imageURLs) + public OllamaResult askWithImageURLs( + String model, String prompt, List imageURLs, Options options) throws OllamaBaseException, IOException, InterruptedException, URISyntaxException { List images = new ArrayList<>(); for (String imageURL : imageURLs) { images.add(encodeByteArrayToBase64(loadImageBytesFromUrl(imageURL))); } OllamaRequestModel ollamaRequestModel = new OllamaRequestModel(model, prompt, images); + ollamaRequestModel.setOptions(options.getOptionsMap()); return askSync(ollamaRequestModel); } @@ -436,7 +446,7 @@ public class OllamaAPI { HttpRequest.BodyPublishers.ofString( Utils.getObjectMapper().writeValueAsString(ollamaRequestModel))); HttpRequest request = requestBuilder.build(); - logger.debug("Ask model '" + ollamaRequestModel + "' ..."); + if (verbose) logger.info("Asking model: " + ollamaRequestModel); HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream()); int statusCode = response.statusCode(); @@ -471,7 +481,10 @@ public class OllamaAPI { throw new OllamaBaseException(responseBuffer.toString()); } else { long endTime = System.currentTimeMillis(); - return new OllamaResult(responseBuffer.toString().trim(), endTime - startTime, statusCode); + OllamaResult ollamaResult = + new OllamaResult(responseBuffer.toString().trim(), endTime - startTime, statusCode); + if (verbose) logger.info("Model response: " + ollamaResult); + return ollamaResult; } } diff --git a/src/test/java/io/github/amithkoujalgi/ollama4j/integrationtests/TestRealAPIs.java b/src/test/java/io/github/amithkoujalgi/ollama4j/integrationtests/TestRealAPIs.java index 271f980..ed55323 100644 --- a/src/test/java/io/github/amithkoujalgi/ollama4j/integrationtests/TestRealAPIs.java +++ b/src/test/java/io/github/amithkoujalgi/ollama4j/integrationtests/TestRealAPIs.java @@ -4,12 +4,17 @@ import static org.junit.jupiter.api.Assertions.*; import io.github.amithkoujalgi.ollama4j.core.OllamaAPI; import io.github.amithkoujalgi.ollama4j.core.exceptions.OllamaBaseException; +import io.github.amithkoujalgi.ollama4j.core.models.OllamaResult; import io.github.amithkoujalgi.ollama4j.core.types.OllamaModelType; +import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder; +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.List; +import java.util.Objects; import java.util.Properties; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Order; @@ -32,10 +37,16 @@ class TestRealAPIs { } } + private File getImageFileFromClasspath(String fileName) { + ClassLoader classLoader = getClass().getClassLoader(); + return new File(Objects.requireNonNull(classLoader.getResource(fileName)).getFile()); + } + @BeforeEach void setUp() { Properties properties = loadProperties(); ollamaAPI = new OllamaAPI(properties.getProperty("ollama.api.url")); + ollamaAPI.setRequestTimeoutSeconds(20); } @Test @@ -83,4 +94,80 @@ class TestRealAPIs { throw new RuntimeException(e); } } + + @Test + @Order(3) + void testAskModelWithDefaultOptions() { + testEndpointReachability(); + try { + OllamaResult result = + ollamaAPI.ask( + OllamaModelType.LLAMA2, + "What is the capital of France? And what's France's connection with Mona Lisa?", + new OptionsBuilder().build()); + assertNotNull(result); + assertNotNull(result.getResponse()); + assertFalse(result.getResponse().isEmpty()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + @Test + @Order(3) + void testAskModelWithOptions() { + testEndpointReachability(); + try { + OllamaResult result = + ollamaAPI.ask( + OllamaModelType.LLAMA2, + "What is the capital of France? And what's France's connection with Mona Lisa?", + new OptionsBuilder().setTemperature(0.9f).build()); + assertNotNull(result); + assertNotNull(result.getResponse()); + assertFalse(result.getResponse().isEmpty()); + } catch (IOException | OllamaBaseException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + @Test + @Order(3) + void testAskModelWithOptionsAndImageFiles() { + testEndpointReachability(); + File imageFile = getImageFileFromClasspath("dog-on-a-boat.jpg"); + try { + OllamaResult result = + ollamaAPI.askWithImageFiles( + OllamaModelType.LLAVA, + "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) { + throw new RuntimeException(e); + } + } + + @Test + @Order(3) + void testAskModelWithOptionsAndImageURLs() { + testEndpointReachability(); + try { + OllamaResult result = + ollamaAPI.askWithImageURLs( + OllamaModelType.LLAVA, + "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) { + throw new RuntimeException(e); + } + } } diff --git a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/TestMockedAPIs.java b/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/TestMockedAPIs.java index 49b9eee..0003d09 100644 --- a/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/TestMockedAPIs.java +++ b/src/test/java/io/github/amithkoujalgi/ollama4j/unittests/TestMockedAPIs.java @@ -118,10 +118,13 @@ class TestMockedAPIs { String model = OllamaModelType.LLAMA2; String prompt = "some prompt text"; try { - when(ollamaAPI.askWithImageFiles(model, prompt, Collections.emptyList())) + when(ollamaAPI.askWithImageFiles( + model, prompt, Collections.emptyList(), new OptionsBuilder().build())) .thenReturn(new OllamaResult("", 0, 200)); - ollamaAPI.askWithImageFiles(model, prompt, Collections.emptyList()); - verify(ollamaAPI, times(1)).askWithImageFiles(model, prompt, Collections.emptyList()); + ollamaAPI.askWithImageFiles( + model, prompt, Collections.emptyList(), new OptionsBuilder().build()); + verify(ollamaAPI, times(1)) + .askWithImageFiles(model, prompt, Collections.emptyList(), new OptionsBuilder().build()); } catch (IOException | OllamaBaseException | InterruptedException e) { throw new RuntimeException(e); } @@ -133,10 +136,13 @@ class TestMockedAPIs { String model = OllamaModelType.LLAMA2; String prompt = "some prompt text"; try { - when(ollamaAPI.askWithImageURLs(model, prompt, Collections.emptyList())) + when(ollamaAPI.askWithImageURLs( + model, prompt, Collections.emptyList(), new OptionsBuilder().build())) .thenReturn(new OllamaResult("", 0, 200)); - ollamaAPI.askWithImageURLs(model, prompt, Collections.emptyList()); - verify(ollamaAPI, times(1)).askWithImageURLs(model, prompt, Collections.emptyList()); + ollamaAPI.askWithImageURLs( + model, prompt, Collections.emptyList(), new OptionsBuilder().build()); + verify(ollamaAPI, times(1)) + .askWithImageURLs(model, prompt, Collections.emptyList(), new OptionsBuilder().build()); } catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) { throw new RuntimeException(e); } diff --git a/src/test/resources/dog-on-a-boat.jpg b/src/test/resources/dog-on-a-boat.jpg new file mode 100644 index 0000000..1a17143 Binary files /dev/null and b/src/test/resources/dog-on-a-boat.jpg differ diff --git a/src/test/resources/test-config.properties b/src/test/resources/test-config.properties index 6c2a862..1d5d55e 100644 --- a/src/test/resources/test-config.properties +++ b/src/test/resources/test-config.properties @@ -1 +1,2 @@ -ollama.api.url=http://192.168.29.223:11434 \ No newline at end of file +ollama.api.url=http://192.168.29.223:11434 +ollama.model=llava \ No newline at end of file