Compare commits

...

48 Commits

Author SHA1 Message Date
amithkoujalgi
ef4303fbbb [maven-release-plugin] prepare release v1.0.36 2023-12-30 08:34:42 +00:00
Amith Koujalgi
2df9a9c69b Merge remote-tracking branch 'origin/main' 2023-12-30 14:03:41 +05:30
Amith Koujalgi
6bb5d9f644 Added CodeCov setup 2023-12-30 14:03:34 +05:30
amithkoujalgi
94b221248a [maven-release-plugin] prepare for next development iteration 2023-12-30 08:29:50 +00:00
amithkoujalgi
2a887f5015 [maven-release-plugin] prepare release v1.0.35 2023-12-30 08:29:49 +00:00
Amith Koujalgi
7e3dddf1bb Merge remote-tracking branch 'origin/main'
# Conflicts:
#	pom.xml
2023-12-30 13:58:38 +05:30
Amith Koujalgi
fe95a7df2a Added CodeCov setup 2023-12-30 13:56:35 +05:30
amithkoujalgi
98f6a30c6b [maven-release-plugin] prepare for next development iteration 2023-12-30 08:12:45 +00:00
amithkoujalgi
00288053bf [maven-release-plugin] prepare release v1.0.34 2023-12-30 08:12:43 +00:00
Amith Koujalgi
6a7feb98bd Added CodeCov setup 2023-12-30 13:41:33 +05:30
amithkoujalgi
770d511067 [maven-release-plugin] prepare for next development iteration 2023-12-30 06:54:50 +00:00
amithkoujalgi
b57fc1f818 [maven-release-plugin] prepare release v1.0.33 2023-12-30 06:54:48 +00:00
Amith Koujalgi
01c5a8f07f updated readme 2023-12-30 12:23:42 +05:30
amithkoujalgi
243b8a3747 [maven-release-plugin] prepare for next development iteration 2023-12-29 04:56:21 +00:00
amithkoujalgi
987fce7f07 [maven-release-plugin] prepare release v1.0.32 2023-12-29 04:56:20 +00:00
Amith Koujalgi
657593be09 Updated all APIs to use getRequestBuilderDefault() method 2023-12-29 10:25:18 +05:30
amithkoujalgi
0afba7e3e3 [maven-release-plugin] prepare for next development iteration 2023-12-29 04:03:48 +00:00
amithkoujalgi
ac00bb9029 [maven-release-plugin] prepare release v1.0.31 2023-12-29 04:03:46 +00:00
Amith Koujalgi
67cb444d82 Merge pull request #14 from omcodedthis/patch-3
Updated documentation
2023-12-29 09:32:46 +05:30
amithkoujalgi
1914a29163 [maven-release-plugin] prepare for next development iteration 2023-12-29 03:57:59 +00:00
amithkoujalgi
11201bc7c7 [maven-release-plugin] prepare release v1.0.30 2023-12-29 03:57:58 +00:00
Amith Koujalgi
3a8b5257c0 Merge pull request #12 from wyona/main
Basic Auth
2023-12-29 09:26:59 +05:30
oM
00bb4e92dc Updated documentation 2023-12-29 11:43:27 +08:00
Michael Wechner
7481c2ba0e method introduced to get request builder default settings 2023-12-27 08:42:45 +01:00
Michael Wechner
9d336e257c basic auth implemented for generate request 2023-12-26 20:49:54 +01:00
Michael Wechner
2027171cb9 version updated 2023-12-26 18:43:47 +01:00
amithkoujalgi
e06baf0d29 [maven-release-plugin] prepare for next development iteration 2023-12-26 15:01:10 +00:00
amithkoujalgi
5d6a68a5bb [maven-release-plugin] prepare release v1.0.29 2023-12-26 15:01:08 +00:00
Amith Koujalgi
41a5bb70bf Updated docs 2023-12-26 20:30:07 +05:30
amithkoujalgi
c2ec62ba08 [maven-release-plugin] prepare for next development iteration 2023-12-26 14:47:27 +00:00
amithkoujalgi
64361fc9ec [maven-release-plugin] prepare release v1.0.28 2023-12-26 14:47:25 +00:00
Amith Koujalgi
ec55024734 updated docs 2023-12-26 20:16:21 +05:30
Amith Koujalgi
df5c451a12 updated docs 2023-12-26 20:15:43 +05:30
Amith Koujalgi
16c39a0a28 updated docs 2023-12-26 19:38:15 +05:30
Amith Koujalgi
5e45b2cdd2 updated docs 2023-12-26 19:17:56 +05:30
Amith Koujalgi
39210cf0c6 updated docs 2023-12-26 19:00:11 +05:30
Amith Koujalgi
2e0e801533 updated docs 2023-12-26 17:57:51 +05:30
Amith Koujalgi
0b9785a5d4 updated docs 2023-12-26 17:54:32 +05:30
Amith Koujalgi
9070597c17 updated docs 2023-12-26 17:43:18 +05:30
Amith Koujalgi
a5f986f145 Updated docs 2023-12-26 16:13:36 +05:30
Amith Koujalgi
1911afe3ee Updated docs 2023-12-26 15:38:23 +05:30
Amith Koujalgi
8b2145913c Updated docs 2023-12-26 15:34:37 +05:30
Amith Koujalgi
e75878d248 Updated docs 2023-12-26 15:32:00 +05:30
Amith Koujalgi
154d7cca78 Updated docs 2023-12-26 14:42:59 +05:30
Amith Koujalgi
3c018295b0 Updated docs 2023-12-26 14:40:33 +05:30
Amith Koujalgi
c8b8a4df11 Updated docs 2023-12-26 14:37:04 +05:30
Amith Koujalgi
edf74dc110 Merge remote-tracking branch 'origin/main' 2023-12-26 14:32:08 +05:30
Amith Koujalgi
8d67fab958 Merge pull request #10 from amithkoujalgi/docs-build-integration
Docs build integration
2023-12-26 14:21:11 +05:30
51 changed files with 1388 additions and 1516 deletions

View File

@@ -3,14 +3,14 @@
name: Test and Publish Package
on:
release:
types: [ "created" ]
#on:
# push:
# branches: [ "main" ]
# workflow_dispatch:
# release:
# types: [ "created" ]
on:
push:
branches: [ "main" ]
workflow_dispatch:
jobs:
build:
@@ -49,6 +49,10 @@ jobs:
${{ runner.os }}-maven-
- name: Build
run: mvn -B -ntp clean install
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Publish to GitHub Packages Apache Maven
# if: >
# github.event_name != 'pull_request' &&

View File

@@ -1,5 +1,5 @@
# Simple workflow for deploying static content to GitHub Pages
name: Deploy Javadoc content to Pages
name: Deploy Docs to GH Pages
on:
# Runs on pushes targeting the default branch
@@ -30,6 +30,15 @@ jobs:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'adopt-hotspot'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v3
@@ -38,8 +47,9 @@ jobs:
- run: cd docs && npm ci
- run: cd docs && npm run build
# - name: Build with npm
# run: npm i && npm run build
- name: Build with Maven
run: mvn --file pom.xml -U clean package && cp -r ./target/apidocs/. ./docs/build/apidocs
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Upload artifact

434
README.md

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +0,0 @@
---
slug: first-blog-post
title: First Blog Post
authors:
name: Gao Wei
title: Docusaurus Core Team
url: https://github.com/wgao19
image_url: https://github.com/wgao19.png
tags: [hola, docusaurus]
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

View File

@@ -1,44 +0,0 @@
---
slug: long-blog-post
title: Long Blog Post
authors: endi
tags: [hello, docusaurus]
---
This is the summary of a very long blog post,
Use a `<!--` `truncate` `-->` comment to limit blog post size in the list view.
<!--truncate-->
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

View File

@@ -1,20 +0,0 @@
---
slug: mdx-blog-post
title: MDX Blog Post
authors: [slorber]
tags: [docusaurus]
---
Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/).
:::tip
Use the power of React to create interactive blog posts.
```js
<button onClick={() => alert('button clicked!')}>Click me!</button>
```
<button onClick={() => alert('button clicked!')}>Click me!</button>
:::

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

View File

@@ -1,25 +0,0 @@
---
slug: welcome
title: Welcome
authors: [slorber, yangshun]
tags: [facebook, hello, docusaurus]
---
[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog).
Simply add Markdown files (or folders) to the `blog` directory.
Regular blog authors can be added to `authors.yml`.
The blog post date can be extracted from filenames, such as:
- `2019-05-30-welcome.md`
- `2019-05-30-welcome/index.md`
A blog post folder can be convenient to co-locate blog post images:
![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg)
The blog supports tags as well!
**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config.

View File

@@ -0,0 +1,9 @@
---
slug: welcome
title: Welcome
authors: [ amith ]
tags: [ Java, AI, LLM, GenAI, GenerativeAI, Ollama, Ollama4J, OpenSource, Developers
]
---
Welcome Java Developers!

View File

@@ -0,0 +1,66 @@
---
slug: release-post
title: Release
authors: [ amith ]
tags: [ Java, AI, LLM, GenAI, GenerativeAI, Ollama, Ollama4j, OpenSource, Developers
]
---
Hey there, my fellow Java Developers! 🚀
I am glad to announce the release of Ollama4j, a library that unites Ollama (an LLM manager and runner) and your Java
applications! 🌐🚀
👉 GitHub Repository: Ollama4j on GitHub (https://github.com/amithkoujalgi/ollama4j)
🌟 Key Features:
- Easy integration with Ollama, enabling the execution of large language models locally.
- Clean and simple APIs, focused on seamless interaction with Ollama.
- Empowers Java developers to harness the full capabilities of Ollama.
- Provides APIs to perform operations such as listing, pulling, deleting models, and creating custom models.
- Provides APIs to ask questions (generate completions) to the LLMs in synchronous and asynchronous modes.
- Ability to ask questions along with image files or image URLs! 🤩
- Open-source and primed for collaborative contributions from the community!
🦙 What is Ollama?
Ollama is an advanced AI tool that allows users to easily set up and run large language models locally (in CPU and GPU
modes). With Ollama, users can leverage powerful language models such as Llama 2 and even customize and create their own
models.
For more details about Ollama, check these out:
- https://ollama.ai/
- https://www.linkedin.com/company/ollama/
👨‍💻 Why Ollama4j?
As a Java developer passionate about harnessing the latest advancements in AI, I realized the need for a simple and
efficient way to integrate Ollama into Java applications. That's why I authored Ollama4j!
🔧 How to Get Started:
Visit the GitHub repository: Ollama4j on GitHub.
Follow the easy setup instructions in the README to integrate Ollama into your Java projects.
Start unlocking the potential of large language models in your applications!
🙏 Contributions Welcome:
I invite the Java developer community to explore, use, and contribute to Ollama4j. Your feedback, suggestions, and
contributions will help this library get better.
I am excited about the possibilities that Ollama4j opens up for Java developers. Whether you're working on natural
language processing, chatbots, or any application that can benefit from advanced language models, Ollama4j is here to
elevate your projects.
I look forward to seeing the incredible applications/projects you'll build with Ollama4j! 🌟
Find the full API spec here: https://amithkoujalgi.github.io/ollama4j/
Find the Javadoc here: https://amithkoujalgi.github.io/ollama4j/apidocs/
Ollama4j Docs is powered by [Docusaurus](https://docusaurus.io).

View File

@@ -1,17 +1,5 @@
endi:
name: Endilie Yacop Sucipto
title: Maintainer of Docusaurus
url: https://github.com/endiliey
image_url: https://github.com/endiliey.png
yangshun:
name: Yangshun Tay
title: Front End Engineer @ Facebook
url: https://github.com/yangshun
image_url: https://github.com/yangshun.png
slorber:
name: Sébastien Lorber
title: Docusaurus maintainer
url: https://sebastienlorber.com
image_url: https://github.com/slorber.png
amith:
name: Amith Koujalgi
title: Maintainer of Ollama4j
url: https://github.com/amithkoujalgi
image_url: https://github.com/amithkoujalgi.png

0
docs/build.sh Normal file → Executable file
View File

View File

@@ -0,0 +1,8 @@
{
"label": "APIs - Ask",
"position": 10,
"link": {
"type": "generated-index",
"description": "Details of APIs to interact with LLMs."
}
}

View File

@@ -0,0 +1,42 @@
---
sidebar_position: 2
---
# Ask - Async
This API lets you ask questions to the LLMs in a asynchronous way.
These APIs correlate to
the [completion](https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion) APIs.
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
String prompt = "Who are you?";
OllamaAsyncResultCallback callback = ollamaAPI.askAsync(OllamaModelType.LLAMA2, prompt);
while (!callback.isComplete() || !callback.getStream().isEmpty()) {
// poll for data from the response stream
String result = callback.getStream().poll();
if (response != null) {
System.out.print(result.getResponse());
}
Thread.sleep(100);
}
}
}
```
You will get a response similar to:
> I am LLaMA, an AI assistant developed by Meta AI that can understand and respond to human input in a conversational
> manner. I am trained on a massive dataset of text from the internet and can generate human-like responses to a wide
> range of topics and questions. I can be used to create chatbots, virtual assistants, and other applications that
> require
> natural language understanding and generation capabilities.

View File

@@ -0,0 +1,44 @@
---
sidebar_position: 3
---
# Ask - With Image Files
This API lets you ask questions along with the image files to the LLMs.
These APIs correlate to
the [completion](https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion) APIs.
:::caution
Executing this on Ollama server running in CPU-mode will take longer to generate response. Hence, GPU-mode is
recommended.
:::
## Ask (Sync)
If you have this image downloaded and you pass the path to the downloaded image to the following code:
![Img](https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg)
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
ollamaAPI.setRequestTimeoutSeconds(10);
OllamaResult result = ollamaAPI.askWithImageFiles(OllamaModelType.LLAVA,
"What's in this image?",
List.of(
new File("/path/to/image")));
System.out.println(result.getResponse());
}
}
```
You will get a response similar to:
> This image features a white boat with brown cushions, where a dog is sitting on the back of the boat. The dog seems to
> be enjoying its time outdoors, perhaps on a lake.

View File

@@ -0,0 +1,44 @@
---
sidebar_position: 4
---
# Ask - With Image URLs
This API lets you ask questions along with the image files to the LLMs.
These APIs correlate to
the [completion](https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion) APIs.
:::caution
Executing this on Ollama server running in CPU-mode will take longer to generate response. Hence, GPU-mode is
recommended.
:::
## Ask (Sync)
Passing the link of this image the following code:
![Img](https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg)
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
ollamaAPI.setRequestTimeoutSeconds(10);
OllamaResult result = ollamaAPI.askWithImageURLs(OllamaModelType.LLAVA,
"What's in this image?",
List.of(
"https://t3.ftcdn.net/jpg/02/96/63/80/360_F_296638053_0gUVA4WVBKceGsIr7LNqRWSnkusi07dq.jpg"));
System.out.println(result.getResponse());
}
}
```
You will get a response similar to:
> This image features a white boat with brown cushions, where a dog is sitting on the back of the boat. The dog seems to
> be enjoying its time outdoors, perhaps on a lake.

106
docs/docs/apis-ask/ask.md Normal file
View File

@@ -0,0 +1,106 @@
---
sidebar_position: 1
---
# Ask - Sync
This API lets you ask questions to the LLMs in a synchronous way.
These APIs correlate to
the [completion](https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion) APIs.
## Try asking a question about the model.
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
OllamaResult result = ollamaAPI.ask(OllamaModelType.LLAMA2, "Who are you?");
System.out.println(result.getResponse());
}
}
```
You will get a response similar to:
> I am LLaMA, an AI assistant developed by Meta AI that can understand and respond to human input in a conversational
> manner. I am trained on a massive dataset of text from the internet and can generate human-like responses to a wide
> range of topics and questions. I can be used to create chatbots, virtual assistants, and other applications that
> require
> natural language understanding and generation capabilities.
## Try asking a question from general topics.
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
String prompt = "List all cricket world cup teams of 2019.";
OllamaResult result = ollamaAPI.ask(OllamaModelType.LLAMA2, prompt);
System.out.println(result.getResponse());
}
}
```
You'd then get a response from the model:
> The 2019 ICC Cricket World Cup was held in England and Wales from May 30 to July 14, 2019. The
> following teams
> participated in the tournament:
>
> 1. Afghanistan
> 2. Australia
> 3. Bangladesh
> 4. England
> 5. India
> 6. New Zealand
> 7. Pakistan
> 8. South Africa
> 9. Sri Lanka
> 10. West Indies
>
> These teams competed in a round-robin format, with the top four teams advancing to the
> semi-finals. The tournament was
> won by the England cricket team, who defeated New Zealand in the final.
## Try asking for a Database query for your data schema.
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
String prompt = SamplePrompts.getSampleDatabasePromptWithQuestion(
"List all customer names who have bought one or more products");
OllamaResult result = ollamaAPI.ask(OllamaModelType.SQLCODER, prompt);
System.out.println(result.getResponse());
}
}
```
_Note: Here I've used
a [sample prompt](https://github.com/amithkoujalgi/ollama4j/blob/main/src/main/resources/sample-db-prompt-template.txt)
containing a database schema from within this library for demonstration purposes._
You'd then get a response from the model:
```sql
SELECT customers.name
FROM sales
JOIN customers ON sales.customer_id = customers.customer_id
GROUP BY customers.name;
```

View File

@@ -0,0 +1,46 @@
---
sidebar_position: 5
---
# Generate Embeddings
Generate embeddings from a model.
Parameters:
- `model`: name of model to generate embeddings from
- `prompt`: text to generate embeddings for
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
List<Double> embeddings = ollamaAPI.generateEmbeddings(OllamaModelType.LLAMA2,
"Here is an article about llamas...");
embeddings.forEach(System.out::println);
}
}
```
You will get a response similar to:
```json
[
0.5670403838157654,
0.009260174818336964,
0.23178744316101074,
-0.2916173040866852,
-0.8924556970596313,
0.8785552978515625,
-0.34576427936553955,
0.5742510557174683,
-0.04222835972905159,
-0.137906014919281
]
```

View File

@@ -0,0 +1,8 @@
{
"label": "APIs - Extras",
"position": 10,
"link": {
"type": "generated-index",
"description": "Details of APIs to handle bunch of extra stuff."
}
}

View File

@@ -0,0 +1,24 @@
---
sidebar_position: 2
---
# Set Basic Authentication
This API lets you set the basic authentication for the Ollama client. This would help in scenarios where
Ollama server would be setup behind a gateway/reverse proxy with basic auth.
After configuring basic authentication, all subsequent requests will include the Basic Auth header.
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
ollamaAPI.setBasicAuth("username", "password");
}
}
```

View File

@@ -0,0 +1,20 @@
---
sidebar_position: 3
---
# Ping
This API lets you check the reachability of Ollama server.
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
ollamaAPI.ping();
}
}
```

View File

@@ -0,0 +1,21 @@
---
sidebar_position: 2
---
# Set Request Timeout
This API lets you set the request timeout for the Ollama client.
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
ollamaAPI.setRequestTimeoutSeconds(10);
}
}
```

View File

@@ -0,0 +1,23 @@
---
sidebar_position: 1
---
# Set Verbosity
This API lets you set the verbosity of the Ollama client.
## Try asking a question about the model.
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
ollamaAPI.setVerbose(true);
}
}
```

View File

@@ -0,0 +1,8 @@
{
"label": "APIs - Model Management",
"position": 4,
"link": {
"type": "generated-index",
"description": "Details of APIs to manage LLMs."
}
}

View File

@@ -0,0 +1,23 @@
---
sidebar_position: 4
---
# Create Model
This API lets you create a custom model on the Ollama server.
```java title="CreateModel.java"
public class CreateModel {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
ollamaAPI.createModel("mycustommodel", "/path/to/modelfile/on/ollama-server");
}
}
```
Once created, you can see it when you use [list models](./list-models) API.

View File

@@ -0,0 +1,26 @@
---
sidebar_position: 5
---
# Delete Model
This API lets you create a delete a model from the Ollama server.
```java title="DeleteModel.java"
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
ollamaAPI.setVerbose(false);
ollamaAPI.deleteModel("mycustommodel", true);
}
}
```
Once deleted, you can verify it using [list models](./list-models) API.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,30 @@
---
sidebar_position: 1
---
# List Models
This API lets you list available models on the Ollama server.
```java title="ListModels.java"
public class ListModels {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
List<Model> models = ollamaAPI.listModels();
models.forEach(model -> System.out.println(model.getName()));
}
}
```
If you have any models already downloaded on Ollama server, you would have them listed as follows:
```bash
llama2:latest
sqlcoder:latest
```

View File

@@ -0,0 +1,23 @@
---
sidebar_position: 2
---
# Pull Model
This API lets you pull a model on the Ollama server.
```java title="PullModel.java"
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
ollamaAPI.pullModel(OllamaModelType.LLAMA2);
}
}
```
Once downloaded, you can see them when you use [list models](./list-models) API.

View File

@@ -2,46 +2,104 @@
sidebar_position: 1
---
# Tutorial Intro
# Intro
Let's discover **Docusaurus in less than 5 minutes**.
Let's get started with **Ollama4j**.
## Getting Started
Get started by **creating a new site**.
Or **try Docusaurus immediately** with **[docusaurus.new](https://docusaurus.new)**.
### What you'll need
- [Node.js](https://nodejs.org/en/download/) version 18.0 or above:
- When installing Node.js, you are recommended to check all checkboxes related to dependencies.
- **[Ollama](https://ollama.ai/download)**
- **[Oracle JDK](https://www.oracle.com/java/technologies/javase/jdk11-archive-downloads.html)** or
**[Open JDK](https://jdk.java.net/archive/)** 11.0 or above.
- **[Maven](https://maven.apache.org/download.cgi)**
## Generate a new site
### Start Ollama server
Generate a new Docusaurus site using the **classic template**.
The easiest way of getting started with Ollama server is with [Docker](https://docs.docker.com/get-started/overview/).
But if you choose to run the
Ollama server directly, **[download](https://ollama.ai/download)** the distribution of your choice
and follow the installation process.
The classic template will automatically be added to your project after you run the command:
#### With Docker
##### Run in CPU mode:
```bash
npm init docusaurus@latest my-website classic
docker run -it -v ~/ollama:/root/.ollama -p 11434:11434 ollama/ollama
```
You can type this command into Command Prompt, Powershell, Terminal, or any other integrated terminal of your code editor.
The command also installs all necessary dependencies you need to run Docusaurus.
## Start your site
Run the development server:
##### Run in GPU mode:
```bash
cd my-website
npm run start
docker run -it --gpus=all -v ~/ollama:/root/.ollama -p 11434:11434 ollama/ollama
```
The `cd` command changes the directory you're working with. In order to work with your newly created Docusaurus site, you'll need to navigate the terminal there.
You can type this command into Command Prompt, Powershell, Terminal, or any other integrated
terminal of your code editor.
The `npm run start` command builds your website locally and serves it through a development server, ready for you to view at http://localhost:3000/.
The command runs the Ollama server locally at **http://localhost:11434/**.
Open `docs/intro.md` (this page) and edit some lines: the site **reloads automatically** and displays your changes.
### Setup your project
Get started by **creating a new Maven project** on your favorite IDE.
Add the dependency to your project's `pom.xml`.
```xml
<dependency>
<groupId>io.github.amithkoujalgi</groupId>
<artifactId>ollama4j</artifactId>
<version>1.0.27</version>
</dependency>
```
Find the latest version of the library [here](https://central.sonatype.com/artifact/io.github.amithkoujalgi/ollama4j).
You might want to include an implementation of [SL4J](https://www.slf4j.org/) logger in your `pom.xml` file. For
example,
Use `slf4j-jdk14` implementation:
```xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>2.0.9</version> <!--Replace with appropriate version-->
</dependency>
```
or use `logback-classic` implementation:
```xml
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.3.11</version> <!--Replace with appropriate version-->
</dependency>
```
or use other suitable implementations.
Create a new Java class in your project and add this code.
```java
public class OllamaAPITest {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
ollamaAPI.setVerbose(true);
boolean isOllamaServerReachable = ollamaAPI.ping();
System.out.println("Is Ollama server alive: " + isOllamaServerReachable);
}
}
```

View File

@@ -1,8 +0,0 @@
{
"label": "Tutorial - Basics",
"position": 2,
"link": {
"type": "generated-index",
"description": "5 minutes to learn the most important Docusaurus concepts."
}
}

View File

@@ -1,23 +0,0 @@
---
sidebar_position: 6
---
# Congratulations!
You have just learned the **basics of Docusaurus** and made some changes to the **initial template**.
Docusaurus has **much more to offer**!
Have **5 more minutes**? Take a look at **[versioning](../tutorial-extras/manage-docs-versions.md)** and **[i18n](../tutorial-extras/translate-your-site.md)**.
Anything **unclear** or **buggy** in this tutorial? [Please report it!](https://github.com/facebook/docusaurus/discussions/4610)
## What's next?
- Read the [official documentation](https://docusaurus.io/)
- Modify your site configuration with [`docusaurus.config.js`](https://docusaurus.io/docs/api/docusaurus-config)
- Add navbar and footer items with [`themeConfig`](https://docusaurus.io/docs/api/themes/configuration)
- Add a custom [Design and Layout](https://docusaurus.io/docs/styling-layout)
- Add a [search bar](https://docusaurus.io/docs/search)
- Find inspirations in the [Docusaurus showcase](https://docusaurus.io/showcase)
- Get involved in the [Docusaurus Community](https://docusaurus.io/community/support)

View File

@@ -1,34 +0,0 @@
---
sidebar_position: 3
---
# Create a Blog Post
Docusaurus creates a **page for each blog post**, but also a **blog index page**, a **tag system**, an **RSS** feed...
## Create your first Post
Create a file at `blog/2021-02-28-greetings.md`:
```md title="blog/2021-02-28-greetings.md"
---
slug: greetings
title: Greetings!
authors:
- name: Joel Marcey
title: Co-creator of Docusaurus 1
url: https://github.com/JoelMarcey
image_url: https://github.com/JoelMarcey.png
- name: Sébastien Lorber
title: Docusaurus maintainer
url: https://sebastienlorber.com
image_url: https://github.com/slorber.png
tags: [greetings]
---
Congratulations, you have made your first post!
Feel free to play around and edit this post as much you like.
```
A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings).

View File

@@ -1,57 +0,0 @@
---
sidebar_position: 2
---
# Create a Document
Documents are **groups of pages** connected through:
- a **sidebar**
- **previous/next navigation**
- **versioning**
## Create your first Doc
Create a Markdown file at `docs/hello.md`:
```md title="docs/hello.md"
# Hello
This is my **first Docusaurus document**!
```
A new document is now available at [http://localhost:3000/docs/hello](http://localhost:3000/docs/hello).
## Configure the Sidebar
Docusaurus automatically **creates a sidebar** from the `docs` folder.
Add metadata to customize the sidebar label and position:
```md title="docs/hello.md" {1-4}
---
sidebar_label: 'Hi!'
sidebar_position: 3
---
# Hello
This is my **first Docusaurus document**!
```
It is also possible to create your sidebar explicitly in `sidebars.js`:
```js title="sidebars.js"
export default {
tutorialSidebar: [
'intro',
// highlight-next-line
'hello',
{
type: 'category',
label: 'Tutorial',
items: ['tutorial-basics/create-a-document'],
},
],
};
```

View File

@@ -1,43 +0,0 @@
---
sidebar_position: 1
---
# Create a Page
Add **Markdown or React** files to `src/pages` to create a **standalone page**:
- `src/pages/index.js``localhost:3000/`
- `src/pages/foo.md``localhost:3000/foo`
- `src/pages/foo/bar.js``localhost:3000/foo/bar`
## Create your first React Page
Create a file at `src/pages/my-react-page.js`:
```jsx title="src/pages/my-react-page.js"
import React from 'react';
import Layout from '@theme/Layout';
export default function MyReactPage() {
return (
<Layout>
<h1>My React page</h1>
<p>This is a React page</p>
</Layout>
);
}
```
A new page is now available at [http://localhost:3000/my-react-page](http://localhost:3000/my-react-page).
## Create your first Markdown Page
Create a file at `src/pages/my-markdown-page.md`:
```mdx title="src/pages/my-markdown-page.md"
# My Markdown page
This is a Markdown page
```
A new page is now available at [http://localhost:3000/my-markdown-page](http://localhost:3000/my-markdown-page).

View File

@@ -1,31 +0,0 @@
---
sidebar_position: 5
---
# Deploy your site
Docusaurus is a **static-site-generator** (also called **[Jamstack](https://jamstack.org/)**).
It builds your site as simple **static HTML, JavaScript and CSS files**.
## Build your site
Build your site **for production**:
```bash
npm run build
```
The static files are generated in the `build` folder.
## Deploy your site
Test your production build locally:
```bash
npm run serve
```
The `build` folder is now served at [http://localhost:3000/](http://localhost:3000/).
You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**).

View File

@@ -1,150 +0,0 @@
---
sidebar_position: 4
---
# Markdown Features
Docusaurus supports **[Markdown](https://daringfireball.net/projects/markdown/syntax)** and a few **additional features**.
## Front Matter
Markdown documents have metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/):
```text title="my-doc.md"
// highlight-start
---
id: my-doc-id
title: My document title
description: My document description
slug: /my-custom-url
---
// highlight-end
## Markdown heading
Markdown text with [links](./hello.md)
```
## Links
Regular Markdown links are supported, using url paths or relative file paths.
```md
Let's see how to [Create a page](/create-a-page).
```
```md
Let's see how to [Create a page](./create-a-page.md).
```
**Result:** Let's see how to [Create a page](./create-a-page.md).
## Images
Regular Markdown images are supported.
You can use absolute paths to reference images in the static directory (`static/img/docusaurus.png`):
```md
![Docusaurus logo](/img/docusaurus.png)
```
![Docusaurus logo](/img/docusaurus.png)
You can reference images relative to the current file as well. This is particularly useful to colocate images close to the Markdown files using them:
```md
![Docusaurus logo](./img/docusaurus.png)
```
## Code Blocks
Markdown code blocks are supported with Syntax highlighting.
```jsx title="src/components/HelloDocusaurus.js"
function HelloDocusaurus() {
return (
<h1>Hello, Docusaurus!</h1>
)
}
```
```jsx title="src/components/HelloDocusaurus.js"
function HelloDocusaurus() {
return <h1>Hello, Docusaurus!</h1>;
}
```
## Admonitions
Docusaurus has a special syntax to create admonitions and callouts:
:::tip My tip
Use this awesome feature option
:::
:::danger Take care
This action is dangerous
:::
:::tip My tip
Use this awesome feature option
:::
:::danger Take care
This action is dangerous
:::
## MDX and React Components
[MDX](https://mdxjs.com/) can make your documentation more **interactive** and allows using any **React components inside Markdown**:
```jsx
export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '20px',
color: '#fff',
padding: '10px',
cursor: 'pointer',
}}
onClick={() => {
alert(`You clicked the color ${color} with label ${children}`)
}}>
{children}
</span>
);
This is <Highlight color="#25c2a0">Docusaurus green</Highlight> !
This is <Highlight color="#1877F2">Facebook blue</Highlight> !
```
export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '20px',
color: '#fff',
padding: '10px',
cursor: 'pointer',
}}
onClick={() => {
alert(`You clicked the color ${color} with label ${children}`);
}}>
{children}
</span>
);
This is <Highlight color="#25c2a0">Docusaurus green</Highlight> !
This is <Highlight color="#1877F2">Facebook blue</Highlight> !

View File

@@ -1,7 +0,0 @@
{
"label": "Tutorial - Extras",
"position": 3,
"link": {
"type": "generated-index"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -1,55 +0,0 @@
---
sidebar_position: 1
---
# Manage Docs Versions
Docusaurus can manage multiple versions of your docs.
## Create a docs version
Release a version 1.0 of your project:
```bash
npm run docusaurus docs:version 1.0
```
The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created.
Your docs now have 2 versions:
- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs
- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs**
## Add a Version Dropdown
To navigate seamlessly across versions, add a version dropdown.
Modify the `docusaurus.config.js` file:
```js title="docusaurus.config.js"
export default {
themeConfig: {
navbar: {
items: [
// highlight-start
{
type: 'docsVersionDropdown',
},
// highlight-end
],
},
},
};
```
The docs version dropdown appears in your navbar:
![Docs Version Dropdown](./img/docsVersionDropdown.png)
## Update an existing version
It is possible to edit versioned docs in their respective folder:
- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello`
- `docs/hello.md` updates `http://localhost:3000/docs/next/hello`

View File

@@ -1,88 +0,0 @@
---
sidebar_position: 2
---
# Translate your site
Let's translate `docs/intro.md` to French.
## Configure i18n
Modify `docusaurus.config.js` to add support for the `fr` locale:
```js title="docusaurus.config.js"
export default {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
};
```
## Translate a doc
Copy the `docs/intro.md` file to the `i18n/fr` folder:
```bash
mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/
cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md
```
Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French.
## Start your localized site
Start your site on the French locale:
```bash
npm run start -- --locale fr
```
Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated.
:::caution
In development, you can only use one locale at a time.
:::
## Add a Locale Dropdown
To navigate seamlessly across languages, add a locale dropdown.
Modify the `docusaurus.config.js` file:
```js title="docusaurus.config.js"
export default {
themeConfig: {
navbar: {
items: [
// highlight-start
{
type: 'localeDropdown',
},
// highlight-end
],
},
},
};
```
The locale dropdown now appears in your navbar:
![Locale Dropdown](./img/localeDropdown.png)
## Build your localized site
Build your site for a specific locale:
```bash
npm run build -- --locale fr
```
Or build your site to include all the locales at once:
```bash
npm run build
```

View File

@@ -8,131 +8,131 @@ import {themes as prismThemes} from 'prism-react-renderer';
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'Ollama4J',
tagline: 'Java library for interacting with Ollama API.',
favicon: 'img/favicon.ico',
title: 'Ollama4j',
tagline: 'Java library for interacting with Ollama.',
favicon: 'img/favicon.ico',
// Set the production url of your site here
url: 'https://your-docusaurus-site.example.com',
// Set the /<baseUrl>/ pathname under which your site is served
// For GitHub pages deployment, it is often '/<projectName>/'
baseUrl: '/ollama4j/',
// Set the production url of your site here
url: 'https://your-docusaurus-site.example.com',
// Set the /<baseUrl>/ pathname under which your site is served
// For GitHub pages deployment, it is often '/<projectName>/'
baseUrl: '/ollama4j/',
// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
organizationName: 'amithkoujalgi', // Usually your GitHub org/user name.
projectName: 'ollama4j', // Usually your repo name.
// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
organizationName: 'amithkoujalgi', // Usually your GitHub org/user name.
projectName: 'ollama4j', // Usually your repo name.
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
// Even if you don't use internationalization, you can use this field to set
// useful metadata like html lang. For example, if your site is Chinese, you
// may want to replace "en" with "zh-Hans".
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
// Even if you don't use internationalization, you can use this field to set
// useful metadata like html lang. For example, if your site is Chinese, you
// may want to replace "en" with "zh-Hans".
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
sidebarPath: './sidebars.js',
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
},
blog: {
showReadingTime: true,
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
},
theme: {
customCss: './src/css/custom.css',
},
}),
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
sidebarPath: './sidebars.js',
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
'https://github.com/amithkoujalgi/ollama4j/blob/main/docs',
},
blog: {
showReadingTime: true,
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
'https://github.com/amithkoujalgi/ollama4j/blob/main/docs',
},
theme: {
customCss: './src/css/custom.css',
},
}),
],
],
],
themeConfig:
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
// Replace with your project's social card
image: 'img/docusaurus-social-card.jpg',
navbar: {
title: 'Ollama4J',
logo: {
alt: 'Ollama4J Logo',
src: 'img/logo.svg',
},
items: [
{
type: 'docSidebar',
sidebarId: 'tutorialSidebar',
position: 'left',
label: 'Tutorial',
},
{to: '/blog', label: 'Blog', position: 'left'},
{to: 'https://github.com/amithkoujalgi/ollama4j', label: 'Javadoc', position: 'left'},
{
href: 'https://github.com/amithkoujalgi/ollama4j',
label: 'GitHub',
position: 'right',
},
],
},
footer: {
style: 'dark',
links: [
{
title: 'Docs',
items: [
{
label: 'Tutorial',
to: '/docs/intro',
},
],
},
{
title: 'Community',
items: [
{
label: 'Stack Overflow',
href: 'https://stackoverflow.com/questions/tagged/ollama4j',
},
{
label: 'Twitter',
href: 'https://twitter.com/ollama4j',
},
],
},
{
title: 'More',
items: [
{
label: 'Blog',
to: '/blog',
},
{
label: 'GitHub',
href: 'https://github.com/amithkoujalgi/ollama4j',
},
],
},
],
copyright: `Ollama4J Documentation ${new Date().getFullYear()}. Built with Docusaurus.`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
},
}),
({
// Replace with your project's social card
image: 'img/docusaurus-social-card.jpg',
navbar: {
title: 'Ollama4j',
logo: {
alt: 'Ollama4j Logo',
src: 'img/logo.svg',
},
items: [
{
type: 'docSidebar',
sidebarId: 'tutorialSidebar',
position: 'left',
label: 'Usage',
},
{to: 'https://amithkoujalgi.github.io/ollama4j/apidocs/', label: 'Javadoc', position: 'left'},
{to: '/blog', label: 'Blog', position: 'left'},
{
href: 'https://github.com/amithkoujalgi/ollama4j',
label: 'GitHub',
position: 'right',
},
],
},
footer: {
style: 'dark',
links: [
{
title: 'Docs',
items: [
{
label: 'Tutorial',
to: '/docs/intro',
},
],
},
{
title: 'Community',
items: [
{
label: 'Stack Overflow',
href: 'https://stackoverflow.com/questions/tagged/ollama4j',
},
{
label: 'Twitter',
href: 'https://twitter.com/ollama4j',
},
],
},
{
title: 'More',
items: [
{
label: 'Blog',
to: '/blog',
},
{
label: 'GitHub',
href: 'https://github.com/amithkoujalgi/ollama4j',
},
],
},
],
copyright: `Ollama4j Documentation ${new Date().getFullYear()}. Built with Docusaurus.`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
},
}),
};
export default config;

0
docs/run.sh Normal file → Executable file
View File

View File

@@ -8,36 +8,33 @@ import Heading from '@theme/Heading';
import styles from './index.module.css';
function HomepageHeader() {
const {siteConfig} = useDocusaurusContext();
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<Heading as="h1" className="hero__title">
{siteConfig.title}
</Heading>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="/docs/intro">
Getting Started
</Link>
const {siteConfig} = useDocusaurusContext();
return (<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<Heading as="h1" className="hero__title">
{siteConfig.title}
</Heading>
<img src="img/logo.svg" alt="Ollama4j Logo" className={styles.logo} style={{maxWidth: '20vh'}}/>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="/docs/intro">
Getting Started
</Link>
</div>
</div>
</div>
</header>
);
</header>);
}
export default function Home() {
const {siteConfig} = useDocusaurusContext();
return (
<Layout
title={`Hello from ${siteConfig.title}`}
description="Description will go into a meta tag in <head />">
<HomepageHeader />
<main>
<HomepageFeatures />
</main>
</Layout>
);
const {siteConfig} = useDocusaurusContext();
return (<Layout
title={`Hello from ${siteConfig.title}`}
description="Description will go into a meta tag in <head />">
<HomepageHeader/>
<main>
<HomepageFeatures/>
</main>
</Layout>);
}

507
pom.xml
View File

@@ -4,20 +4,20 @@
<groupId>io.github.amithkoujalgi</groupId>
<artifactId>ollama4j</artifactId>
<version>1.0.28-SNAPSHOT</version>
<version>1.0.36</version>
<name>Ollama4j</name>
<description>Java library for interacting with Ollama API.</description>
<url>https://github.com/amithkoujalgi/ollama4j</url>
<name>Ollama4j</name>
<description>Java library for interacting with Ollama API.</description>
<url>https://github.com/amithkoujalgi/ollama4j</url>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
<maven-failsafe-plugin.version>3.0.0-M5</maven-failsafe-plugin.version>
<lombok.version>1.18.30</lombok.version>
</properties>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
<maven-failsafe-plugin.version>3.0.0-M5</maven-failsafe-plugin.version>
<lombok.version>1.18.30</lombok.version>
</properties>
<developers>
<developer>
@@ -28,230 +28,273 @@
</developer>
</developers>
<licenses>
<license>
<name>MIT License</name>
<url>https://raw.githubusercontent.com/amithkoujalgi/ollama4j/main/LICENSE</url>
</license>
</licenses>
<licenses>
<license>
<name>MIT License</name>
<url>https://raw.githubusercontent.com/amithkoujalgi/ollama4j/main/LICENSE</url>
</license>
</licenses>
<scm>
<connection>scm:git:git@github.com:amithkoujalgi/ollama4j.git</connection>
<developerConnection>scm:git:https://github.com/amithkoujalgi/ollama4j.git</developerConnection>
<url>https://github.com/amithkoujalgi/ollama4j</url>
<tag>v1.0.16</tag>
</scm>
<scm>
<connection>scm:git:git@github.com:amithkoujalgi/ollama4j.git</connection>
<developerConnection>scm:git:https://github.com/amithkoujalgi/ollama4j.git</developerConnection>
<url>https://github.com/amithkoujalgi/ollama4j</url>
<tag>v1.0.36</tag>
</scm>
<build>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-gpg-plugin</artifactId>-->
<!-- <version>1.5</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>sign-artifacts</id>-->
<!-- <phase>verify</phase>-->
<!-- <goals>-->
<!-- <goal>sign</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- &lt;!&ndash; This is necessary for gpg to not try to use the pinentry programs &ndash;&gt;-->
<!-- <gpgArguments>-->
<!-- <arg>&#45;&#45;pinentry-mode</arg>-->
<!-- <arg>loopback</arg>-->
<!-- </gpgArguments>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- Surefire Plugin for Unit Tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<skipTests>${skipUnitTests}</skipTests>
<includes>
<include>**/unittests/*.java</include>
</includes>
</configuration>
</plugin>
<!-- Failsafe Plugin for Integration Tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
<configuration>
<includes>
<include>**/integrationtests/*.java</include>
</includes>
<excludes>
<exclude>**/unittests/*.java</exclude>
</excludes>
<skipTests>${skipIntegrationTests}</skipTests>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<!-- <goals>install</goals>-->
<tagNameFormat>v@{project.version}</tagNameFormat>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2</url>
</repository>
</distributionManagement>
<profiles>
<profile>
<id>unit-tests</id>
<properties>
<test.env>unit</test.env>
<skipUnitTests>false</skipUnitTests>
<skipIntegrationTests>true</skipIntegrationTests>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-gpg-plugin</artifactId>-->
<!-- <version>1.5</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>sign-artifacts</id>-->
<!-- <phase>verify</phase>-->
<!-- <goals>-->
<!-- <goal>sign</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- &lt;!&ndash; This is necessary for gpg to not try to use the pinentry programs &ndash;&gt;-->
<!-- <gpgArguments>-->
<!-- <arg>&#45;&#45;pinentry-mode</arg>-->
<!-- <arg>loopback</arg>-->
<!-- </gpgArguments>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- Surefire Plugin for Unit Tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<skipTests>${skipUnitTests}</skipTests>
<includes>
<include>**/unittests/*.java</include>
</includes>
</configuration>
</plugin>
<!-- Failsafe Plugin for Integration Tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
<configuration>
<includes>
<include>**/integrationtests/*.java</include>
</includes>
<excludes>
<exclude>**/unittests/*.java</exclude>
</excludes>
<skipTests>${skipIntegrationTests}</skipTests>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<!-- <goals>install</goals>-->
<tagNameFormat>v@{project.version}</tagNameFormat>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</build>
</profile>
<profile>
<id>integration-tests</id>
<properties>
<test.env>integration</test.env>
<skipUnitTests>true</skipUnitTests>
<skipIntegrationTests>false</skipIntegrationTests>
</properties>
</profile>
<profile>
<id>ci-cd</id>
<properties>
<test.env>unit</test.env>
<skipUnitTests>true</skipUnitTests>
<skipIntegrationTests>true</skipIntegrationTests>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<!-- Prevent gpg from using pinentry programs. Fixes:
gpg: signing failed: Inappropriate ioctl for device -->
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.13</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.3.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2</url>
</repository>
</distributionManagement>
<profiles>
<profile>
<id>unit-tests</id>
<properties>
<test.env>unit</test.env>
<skipUnitTests>false</skipUnitTests>
<skipIntegrationTests>true</skipIntegrationTests>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>integration-tests</id>
<properties>
<test.env>integration</test.env>
<skipUnitTests>true</skipUnitTests>
<skipIntegrationTests>false</skipIntegrationTests>
</properties>
</profile>
<profile>
<id>ci-cd</id>
<properties>
<test.env>unit</test.env>
<skipUnitTests>true</skipUnitTests>
<skipIntegrationTests>true</skipIntegrationTests>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<!-- Prevent gpg from using pinentry programs. Fixes:
gpg: signing failed: Inappropriate ioctl for device -->
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.13</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -17,6 +17,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpConnectTimeoutException;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
@@ -36,6 +37,7 @@ public class OllamaAPI {
private final String host;
private long requestTimeoutSeconds = 3;
private boolean verbose = true;
private BasicAuth basicAuth;
/**
* Instantiates the Ollama API.
@@ -50,6 +52,11 @@ public class OllamaAPI {
}
}
/**
* Set request timeout in seconds. Default is 3 seconds.
*
* @param requestTimeoutSeconds the request timeout in seconds
*/
public void setRequestTimeoutSeconds(long requestTimeoutSeconds) {
this.requestTimeoutSeconds = requestTimeoutSeconds;
}
@@ -63,6 +70,47 @@ public class OllamaAPI {
this.verbose = verbose;
}
/**
* Set basic authentication for accessing Ollama server that's behind a reverse-proxy/gateway.
*
* @param username the username
* @param password the password
*/
public void setBasicAuth(String username, String password) {
this.basicAuth = new BasicAuth(username, password);
}
/**
* API to check the reachability of Ollama server.
*
* @return true if the server is reachable, false otherwise.
*/
public boolean ping() {
String url = this.host + "/api/tags";
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpRequest = null;
try {
httpRequest =
getRequestBuilderDefault(new URI(url))
.header("Accept", "application/json")
.header("Content-type", "application/json")
.GET()
.build();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
HttpResponse<String> response = null;
try {
response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
} catch (HttpConnectTimeoutException e) {
return false;
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
int statusCode = response.statusCode();
return statusCode == 200;
}
/**
* List available models from Ollama server.
*
@@ -73,11 +121,9 @@ public class OllamaAPI {
String url = this.host + "/api/tags";
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpRequest =
HttpRequest.newBuilder()
.uri(new URI(url))
getRequestBuilderDefault(new URI(url))
.header("Accept", "application/json")
.header("Content-type", "application/json")
.timeout(Duration.ofSeconds(requestTimeoutSeconds))
.GET()
.build();
HttpResponse<String> response =
@@ -104,12 +150,10 @@ public class OllamaAPI {
String url = this.host + "/api/pull";
String jsonData = new ModelRequest(modelName).toString();
HttpRequest request =
HttpRequest.newBuilder()
.uri(new URI(url))
getRequestBuilderDefault(new URI(url))
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.header("Accept", "application/json")
.header("Content-type", "application/json")
.timeout(Duration.ofSeconds(requestTimeoutSeconds))
.build();
HttpClient client = HttpClient.newHttpClient();
HttpResponse<InputStream> response =
@@ -140,15 +184,13 @@ public class OllamaAPI {
* @return the model details
*/
public ModelDetail getModelDetails(String modelName)
throws IOException, OllamaBaseException, InterruptedException {
throws IOException, OllamaBaseException, InterruptedException, URISyntaxException {
String url = this.host + "/api/show";
String jsonData = new ModelRequest(modelName).toString();
HttpRequest request =
HttpRequest.newBuilder()
.uri(URI.create(url))
getRequestBuilderDefault(new URI(url))
.header("Accept", "application/json")
.header("Content-type", "application/json")
.timeout(Duration.ofSeconds(requestTimeoutSeconds))
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
HttpClient client = HttpClient.newHttpClient();
@@ -170,15 +212,13 @@ public class OllamaAPI {
* @param modelFilePath the path to model file that exists on the Ollama server.
*/
public void createModelWithFilePath(String modelName, String modelFilePath)
throws IOException, InterruptedException, OllamaBaseException {
throws IOException, InterruptedException, OllamaBaseException, URISyntaxException {
String url = this.host + "/api/create";
String jsonData = new CustomModelFilePathRequest(modelName, modelFilePath).toString();
HttpRequest request =
HttpRequest.newBuilder()
.uri(URI.create(url))
getRequestBuilderDefault(new URI(url))
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.timeout(Duration.ofSeconds(requestTimeoutSeconds))
.POST(HttpRequest.BodyPublishers.ofString(jsonData, StandardCharsets.UTF_8))
.build();
HttpClient client = HttpClient.newHttpClient();
@@ -206,15 +246,13 @@ public class OllamaAPI {
* @param modelFileContents the path to model file that exists on the Ollama server.
*/
public void createModelWithModelFileContents(String modelName, String modelFileContents)
throws IOException, InterruptedException, OllamaBaseException {
throws IOException, InterruptedException, OllamaBaseException, URISyntaxException {
String url = this.host + "/api/create";
String jsonData = new CustomModelFileContentsRequest(modelName, modelFileContents).toString();
HttpRequest request =
HttpRequest.newBuilder()
.uri(URI.create(url))
getRequestBuilderDefault(new URI(url))
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.timeout(Duration.ofSeconds(requestTimeoutSeconds))
.POST(HttpRequest.BodyPublishers.ofString(jsonData, StandardCharsets.UTF_8))
.build();
HttpClient client = HttpClient.newHttpClient();
@@ -236,20 +274,17 @@ public class OllamaAPI {
* Delete a model from Ollama server.
*
* @param modelName the name of the model to be deleted.
* @param ignoreIfNotPresent - ignore errors if the specified model is not present on Ollama
* server.
* @param ignoreIfNotPresent ignore errors if the specified model is not present on Ollama server.
*/
public void deleteModel(String modelName, boolean ignoreIfNotPresent)
throws IOException, InterruptedException, OllamaBaseException {
throws IOException, InterruptedException, OllamaBaseException, URISyntaxException {
String url = this.host + "/api/delete";
String jsonData = new ModelRequest(modelName).toString();
HttpRequest request =
HttpRequest.newBuilder()
.uri(URI.create(url))
getRequestBuilderDefault(new URI(url))
.method("DELETE", HttpRequest.BodyPublishers.ofString(jsonData, StandardCharsets.UTF_8))
.header("Accept", "application/json")
.header("Content-type", "application/json")
.timeout(Duration.ofSeconds(requestTimeoutSeconds))
.build();
HttpClient client = HttpClient.newHttpClient();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
@@ -272,17 +307,14 @@ public class OllamaAPI {
*/
public List<Double> generateEmbeddings(String model, String prompt)
throws IOException, InterruptedException, OllamaBaseException {
String url = this.host + "/api/embeddings";
URI uri = URI.create(this.host + "/api/embeddings");
String jsonData = new ModelEmbeddingsRequest(model, prompt).toString();
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request =
HttpRequest.newBuilder()
.uri(URI.create(url))
HttpRequest.Builder requestBuilder =
getRequestBuilderDefault(uri)
.header("Accept", "application/json")
.header("Content-type", "application/json")
.timeout(Duration.ofSeconds(requestTimeoutSeconds))
.POST(HttpRequest.BodyPublishers.ofString(jsonData))
.build();
.POST(HttpRequest.BodyPublishers.ofString(jsonData));
HttpRequest request = requestBuilder.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
int statusCode = response.statusCode();
String responseBody = response.body();
@@ -299,12 +331,12 @@ public class OllamaAPI {
* Ask a question to a model running on Ollama server. This is a sync/blocking call.
*
* @param model the ollama model to ask the question to
* @param promptText the prompt/question text
* @return OllamaResult - that includes response text and time taken for response
* @param prompt the prompt/question text
* @return OllamaResult that includes response text and time taken for response
*/
public OllamaResult ask(String model, String promptText)
public OllamaResult ask(String model, String prompt)
throws OllamaBaseException, IOException, InterruptedException {
OllamaRequestModel ollamaRequestModel = new OllamaRequestModel(model, promptText);
OllamaRequestModel ollamaRequestModel = new OllamaRequestModel(model, prompt);
return askSync(ollamaRequestModel);
}
@@ -314,15 +346,16 @@ public class OllamaAPI {
* async/non-blocking call.
*
* @param model the ollama model to ask the question to
* @param promptText the prompt/question text
* @param prompt the prompt/question text
* @return the ollama async result callback handle
*/
public OllamaAsyncResultCallback askAsync(String model, String promptText) {
OllamaRequestModel ollamaRequestModel = new OllamaRequestModel(model, promptText);
HttpClient httpClient = HttpClient.newHttpClient();
public OllamaAsyncResultCallback askAsync(String model, String prompt) {
OllamaRequestModel ollamaRequestModel = new OllamaRequestModel(model, prompt);
URI uri = URI.create(this.host + "/api/generate");
OllamaAsyncResultCallback ollamaAsyncResultCallback =
new OllamaAsyncResultCallback(httpClient, uri, ollamaRequestModel, requestTimeoutSeconds);
new OllamaAsyncResultCallback(
getRequestBuilderDefault(uri), ollamaRequestModel, requestTimeoutSeconds);
ollamaAsyncResultCallback.start();
return ollamaAsyncResultCallback;
}
@@ -332,17 +365,17 @@ public class OllamaAPI {
* sync/blocking call.
*
* @param model the ollama model to ask the question to
* @param promptText the prompt/question text
* @param prompt the prompt/question text
* @param imageFiles the list of image files to use for the question
* @return OllamaResult - that includes response text and time taken for response
* @return OllamaResult that includes response text and time taken for response
*/
public OllamaResult askWithImageFiles(String model, String promptText, List<File> imageFiles)
public OllamaResult askWithImageFiles(String model, String prompt, List<File> imageFiles)
throws OllamaBaseException, IOException, InterruptedException {
List<String> images = new ArrayList<>();
for (File imageFile : imageFiles) {
images.add(encodeFileToBase64(imageFile));
}
OllamaRequestModel ollamaRequestModel = new OllamaRequestModel(model, promptText, images);
OllamaRequestModel ollamaRequestModel = new OllamaRequestModel(model, prompt, images);
return askSync(ollamaRequestModel);
}
@@ -351,17 +384,17 @@ public class OllamaAPI {
* sync/blocking call.
*
* @param model the ollama model to ask the question to
* @param promptText the prompt/question text
* @param prompt the prompt/question text
* @param imageURLs the list of image URLs to use for the question
* @return OllamaResult - that includes response text and time taken for response
* @return OllamaResult that includes response text and time taken for response
*/
public OllamaResult askWithImageURLs(String model, String promptText, List<String> imageURLs)
public OllamaResult askWithImageURLs(String model, String prompt, List<String> imageURLs)
throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
List<String> images = new ArrayList<>();
for (String imageURL : imageURLs) {
images.add(encodeByteArrayToBase64(loadImageBytesFromUrl(imageURL)));
}
OllamaRequestModel ollamaRequestModel = new OllamaRequestModel(model, promptText, images);
OllamaRequestModel ollamaRequestModel = new OllamaRequestModel(model, prompt, images);
return askSync(ollamaRequestModel);
}
@@ -392,14 +425,13 @@ public class OllamaAPI {
long startTime = System.currentTimeMillis();
HttpClient httpClient = HttpClient.newHttpClient();
URI uri = URI.create(this.host + "/api/generate");
HttpRequest request =
HttpRequest.newBuilder(uri)
HttpRequest.Builder requestBuilder =
getRequestBuilderDefault(uri)
.POST(
HttpRequest.BodyPublishers.ofString(
Utils.getObjectMapper().writeValueAsString(ollamaRequestModel)))
.header("Content-Type", "application/json")
.timeout(Duration.ofSeconds(requestTimeoutSeconds))
.build();
Utils.getObjectMapper().writeValueAsString(ollamaRequestModel)));
HttpRequest request = requestBuilder.build();
logger.debug("Ask model '" + ollamaRequestModel + "' ...");
HttpResponse<InputStream> response =
httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
int statusCode = response.statusCode();
@@ -410,9 +442,16 @@ public class OllamaAPI {
String line;
while ((line = reader.readLine()) != null) {
if (statusCode == 404) {
logger.warn("Status code: 404 (Not Found)");
OllamaErrorResponseModel ollamaResponseModel =
Utils.getObjectMapper().readValue(line, OllamaErrorResponseModel.class);
responseBuffer.append(ollamaResponseModel.getError());
} else if (statusCode == 401) {
logger.warn("Status code: 401 (Unauthorized)");
OllamaErrorResponseModel ollamaResponseModel =
Utils.getObjectMapper()
.readValue("{\"error\":\"Unauthorized\"}", OllamaErrorResponseModel.class);
responseBuffer.append(ollamaResponseModel.getError());
} else {
OllamaResponseModel ollamaResponseModel =
Utils.getObjectMapper().readValue(line, OllamaResponseModel.class);
@@ -423,10 +462,47 @@ public class OllamaAPI {
}
}
if (statusCode != 200) {
logger.error("Status code " + statusCode);
throw new OllamaBaseException(responseBuffer.toString());
} else {
long endTime = System.currentTimeMillis();
return new OllamaResult(responseBuffer.toString().trim(), endTime - startTime, statusCode);
}
}
/**
* Get default request builder.
*
* @param uri URI to get a HttpRequest.Builder
* @return HttpRequest.Builder
*/
private HttpRequest.Builder getRequestBuilderDefault(URI uri) {
HttpRequest.Builder requestBuilder =
HttpRequest.newBuilder(uri)
.header("Content-Type", "application/json")
.timeout(Duration.ofSeconds(requestTimeoutSeconds));
if (isBasicAuthCredentialsSet()) {
requestBuilder.header("Authorization", getBasicAuthHeaderValue());
}
return requestBuilder;
}
/**
* Get basic authentication header value.
*
* @return basic authentication header value (encoded credentials)
*/
private String getBasicAuthHeaderValue() {
String credentialsToEncode = basicAuth.getUsername() + ":" + basicAuth.getPassword();
return "Basic " + Base64.getEncoder().encodeToString(credentialsToEncode.getBytes());
}
/**
* Check if Basic Auth credentials set.
*
* @return true when Basic Auth credentials set
*/
private boolean isBasicAuthCredentialsSet() {
return basicAuth != null;
}
}

View File

@@ -0,0 +1,13 @@
package io.github.amithkoujalgi.ollama4j.core.models;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BasicAuth {
private String username;
private String password;
}

View File

@@ -6,7 +6,6 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
@@ -14,30 +13,44 @@ import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.LinkedList;
import java.util.Queue;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@Data
@EqualsAndHashCode(callSuper = true)
@SuppressWarnings("unused")
public class OllamaAsyncResultCallback extends Thread {
private final HttpClient client;
private final URI uri;
private final HttpRequest.Builder requestBuilder;
private final OllamaRequestModel ollamaRequestModel;
private final Queue<String> queue = new LinkedList<>();
private String result;
private boolean isDone;
private boolean succeeded;
/**
* -- GETTER -- Returns the status of the request. Indicates if the request was successful or a
* failure. If the request was a failure, the `getResponse()` method will return the error
* message.
*/
@Getter private boolean succeeded;
private long requestTimeoutSeconds;
private int httpStatusCode;
private long responseTime = 0;
/**
* -- GETTER -- Returns the HTTP response status code for the request that was made to Ollama
* server.
*/
@Getter private int httpStatusCode;
/** -- GETTER -- Returns the response time in milliseconds. */
@Getter private long responseTime = 0;
public OllamaAsyncResultCallback(
HttpClient client,
URI uri,
HttpRequest.Builder requestBuilder,
OllamaRequestModel ollamaRequestModel,
long requestTimeoutSeconds) {
this.client = client;
this.requestBuilder = requestBuilder;
this.ollamaRequestModel = ollamaRequestModel;
this.uri = uri;
this.isDone = false;
this.result = "";
this.queue.add("");
@@ -46,10 +59,11 @@ public class OllamaAsyncResultCallback extends Thread {
@Override
public void run() {
HttpClient httpClient = HttpClient.newHttpClient();
try {
long startTime = System.currentTimeMillis();
HttpRequest request =
HttpRequest.newBuilder(uri)
requestBuilder
.POST(
HttpRequest.BodyPublishers.ofString(
Utils.getObjectMapper().writeValueAsString(ollamaRequestModel)))
@@ -57,7 +71,7 @@ public class OllamaAsyncResultCallback extends Thread {
.timeout(Duration.ofSeconds(requestTimeoutSeconds))
.build();
HttpResponse<InputStream> response =
client.send(request, HttpResponse.BodyHandlers.ofInputStream());
httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
int statusCode = response.statusCode();
this.httpStatusCode = statusCode;
@@ -108,25 +122,6 @@ public class OllamaAsyncResultCallback extends Thread {
return isDone;
}
/**
* Returns the HTTP response status code for the request that was made to Ollama server.
*
* @return int - the status code for the request
*/
public int getHttpStatusCode() {
return httpStatusCode;
}
/**
* Returns the status of the request. Indicates if the request was successful or a failure. If the
* request was a failure, the `getResponse()` method will return the error message.
*
* @return boolean - status
*/
public boolean isSucceeded() {
return succeeded;
}
/**
* Returns the final response when the execution completes. Does not return intermediate results.
*
@@ -140,15 +135,6 @@ public class OllamaAsyncResultCallback extends Thread {
return queue;
}
/**
* Returns the response time in milliseconds.
*
* @return long - response time in milliseconds.
*/
public long getResponseTime() {
return responseTime;
}
public void setRequestTimeoutSeconds(long requestTimeoutSeconds) {
this.requestTimeoutSeconds = requestTimeoutSeconds;
}

View File

@@ -3,7 +3,7 @@ package io.github.amithkoujalgi.ollama4j.core.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Utils {
public static ObjectMapper getObjectMapper() {
return new ObjectMapper();
}
public static ObjectMapper getObjectMapper() {
return new ObjectMapper();
}
}

View File

@@ -11,12 +11,13 @@ import io.github.amithkoujalgi.ollama4j.core.types.OllamaModelType;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
class TestMockedAPIs {
@Test
void testMockPullModel() {
void testPullModel() {
OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class);
String model = OllamaModelType.LLAMA2;
try {
@@ -49,7 +50,7 @@ class TestMockedAPIs {
doNothing().when(ollamaAPI).createModelWithModelFileContents(model, modelFilePath);
ollamaAPI.createModelWithModelFileContents(model, modelFilePath);
verify(ollamaAPI, times(1)).createModelWithModelFileContents(model, modelFilePath);
} catch (IOException | OllamaBaseException | InterruptedException e) {
} catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
@@ -62,7 +63,7 @@ class TestMockedAPIs {
doNothing().when(ollamaAPI).deleteModel(model, true);
ollamaAPI.deleteModel(model, true);
verify(ollamaAPI, times(1)).deleteModel(model, true);
} catch (IOException | OllamaBaseException | InterruptedException e) {
} catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
@@ -75,7 +76,7 @@ class TestMockedAPIs {
when(ollamaAPI.getModelDetails(model)).thenReturn(new ModelDetail());
ollamaAPI.getModelDetails(model);
verify(ollamaAPI, times(1)).getModelDetails(model);
} catch (IOException | OllamaBaseException | InterruptedException e) {
} catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
@@ -108,13 +109,43 @@ class TestMockedAPIs {
}
}
@Test
void testAskWithImageFiles() {
OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class);
String model = OllamaModelType.LLAMA2;
String prompt = "some prompt text";
try {
when(ollamaAPI.askWithImageFiles(model, prompt, Collections.emptyList()))
.thenReturn(new OllamaResult("", 0, 200));
ollamaAPI.askWithImageFiles(model, prompt, Collections.emptyList());
verify(ollamaAPI, times(1)).askWithImageFiles(model, prompt, Collections.emptyList());
} catch (IOException | OllamaBaseException | InterruptedException e) {
throw new RuntimeException(e);
}
}
@Test
void testAskWithImageURLs() {
OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class);
String model = OllamaModelType.LLAMA2;
String prompt = "some prompt text";
try {
when(ollamaAPI.askWithImageURLs(model, prompt, Collections.emptyList()))
.thenReturn(new OllamaResult("", 0, 200));
ollamaAPI.askWithImageURLs(model, prompt, Collections.emptyList());
verify(ollamaAPI, times(1)).askWithImageURLs(model, prompt, Collections.emptyList());
} catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
@Test
void testAskAsync() {
OllamaAPI ollamaAPI = Mockito.mock(OllamaAPI.class);
String model = OllamaModelType.LLAMA2;
String prompt = "some prompt text";
when(ollamaAPI.askAsync(model, prompt))
.thenReturn(new OllamaAsyncResultCallback(null, null, null, 3));
.thenReturn(new OllamaAsyncResultCallback(null, null, 3));
ollamaAPI.askAsync(model, prompt);
verify(ollamaAPI, times(1)).askAsync(model, prompt);
}