Compare commits

..

29 Commits

Author SHA1 Message Date
amithkoujalgi
7dd556293f [maven-release-plugin] prepare release v1.0.61 2024-03-02 15:08:57 +00:00
Amith Koujalgi
ee50131ce4 Merge remote-tracking branch 'origin/main' 2024-03-02 20:37:45 +05:30
Amith Koujalgi
2cd47dbfaa [testing] - Added release-assets upload GH action 2024-03-02 20:37:38 +05:30
amithkoujalgi
e5296c1067 [maven-release-plugin] prepare for next development iteration 2024-03-02 14:58:49 +00:00
amithkoujalgi
0f00f05e3d [maven-release-plugin] prepare release v1.0.60 2024-03-02 14:58:48 +00:00
Amith Koujalgi
976a3b82e5 [testing] - Added release-assets upload GH action 2024-03-02 20:27:37 +05:30
amithkoujalgi
ba26d620c4 [maven-release-plugin] prepare for next development iteration 2024-03-02 14:46:51 +00:00
amithkoujalgi
e45246a767 [maven-release-plugin] prepare release v1.0.59 2024-03-02 14:46:50 +00:00
Amith Koujalgi
7336668f0c [testing] - Added release-assets upload GH action 2024-03-02 20:10:04 +05:30
amithkoujalgi
11701fb222 [maven-release-plugin] prepare for next development iteration 2024-02-29 03:25:18 +00:00
amithkoujalgi
b1ec12c4e9 [maven-release-plugin] prepare release v1.0.58 2024-02-29 03:25:17 +00:00
Amith Koujalgi
d0b0a0fc97 Updated model types 2024-02-29 08:54:03 +05:30
amithkoujalgi
20774fca6b [maven-release-plugin] prepare for next development iteration 2024-02-28 12:55:28 +00:00
amithkoujalgi
9c46b510d8 [maven-release-plugin] prepare release v1.0.57 2024-02-28 12:55:26 +00:00
Amith Koujalgi
9d887b60a8 Merge pull request #30 from AgentSchmecker/feature/options_for_embedding_request
Adds options to EmbeddingsRequest
2024-02-28 18:24:10 +05:30
Markus Klenke
63d4de4e24 Adds options to EmbeddingsRequest
Additionally refactors the Embedding Models and Tests
2024-02-25 20:53:45 +00:00
amithkoujalgi
a10692e2f1 [maven-release-plugin] prepare for next development iteration 2024-02-20 03:23:40 +00:00
amithkoujalgi
b0c152a42e [maven-release-plugin] prepare release v1.0.56 2024-02-20 03:23:39 +00:00
Amith Koujalgi
f44767e023 updated docs 2024-02-20 08:52:30 +05:30
amithkoujalgi
aadef0a57c [maven-release-plugin] prepare for next development iteration 2024-02-19 05:38:03 +00:00
amithkoujalgi
777ee7ffe0 [maven-release-plugin] prepare release v1.0.55 2024-02-19 05:38:02 +00:00
Amith Koujalgi
dcf1d0bdbc Merge pull request #29 from AgentSchmecker/feature/add-streaming-to-generate-api
Adds streaming feature to generate API
2024-02-19 11:06:57 +05:30
Markus Klenke
13b7111a42 Adds toString implementation for Model and ModelMeta to be json represented 2024-02-18 22:53:34 +00:00
Markus Klenke
09442d37a3 Fixes unmarshalling exception on ModelDetail 2024-02-18 22:53:01 +00:00
Markus Klenke
1e66bdb07f Adds documentation for streamed generate API call 2024-02-18 21:41:35 +00:00
Markus Klenke
b423090db9 Merge branch 'amithkoujalgi:main' into feature/add-streaming-to-generate-api 2024-02-18 22:30:20 +01:00
amithkoujalgi
a32d94efbf [maven-release-plugin] prepare for next development iteration 2024-02-18 05:22:10 +00:00
Markus Klenke
abb76ad867 Adds streaming feature to Generate APIs 2024-02-16 17:03:15 +00:00
Markus Klenke
cf4e7a96e8 Optimizes ChatStreamObserver to use only the last message instead of parsing all messages again 2024-02-16 16:31:39 +00:00
30 changed files with 536 additions and 181 deletions

41
.github/workflows/release-jar.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Release JAR
on:
push:
tags:
- '**'
permissions:
contents: read
id-token: write
packages: write
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
repository-projects: write
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- name: Build with Maven
run: mvn -B clean install package --file pom.xml
- name: Release Assets
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
files: target/*.jar

View File

@@ -67,7 +67,7 @@ In your Maven project, add this dependency:
<dependency>
<groupId>io.github.amithkoujalgi</groupId>
<artifactId>ollama4j</artifactId>
<version>1.0.47</version>
<version>1.0.57</version>
</dependency>
```
@@ -125,15 +125,15 @@ Actions CI workflow.
- [x] Update request body creation with Java objects
- [ ] Async APIs for images
- [ ] Add custom headers to requests
- [ ] Add additional params for `ask` APIs such as:
- [x] Add additional params for `ask` APIs such as:
- [x] `options`: additional model parameters for the Modelfile such as `temperature` -
Supported [params](https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values).
- [ ] `system`: system prompt to (overrides what is defined in the Modelfile)
- [ ] `template`: the full prompt or prompt template (overrides what is defined in the Modelfile)
- [ ] `context`: the context parameter returned from a previous request, which can be used to keep a
- [x] `system`: system prompt to (overrides what is defined in the Modelfile)
- [x] `template`: the full prompt or prompt template (overrides what is defined in the Modelfile)
- [x] `context`: the context parameter returned from a previous request, which can be used to keep a
short
conversational memory
- [ ] `stream`: Add support for streaming responses from the model
- [x] `stream`: Add support for streaming responses from the model
- [ ] Add test cases
- [ ] Handle exceptions better (maybe throw more appropriate exceptions)

View File

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

View File

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

View File

@@ -41,6 +41,41 @@ You will get a response similar to:
> require
> natural language understanding and generation capabilities.
## Try asking a question, receiving the answer streamed
```java
public class Main {
public static void main(String[] args) {
String host = "http://localhost:11434/";
OllamaAPI ollamaAPI = new OllamaAPI(host);
// define a stream handler (Consumer<String>)
OllamaStreamHandler streamHandler = (s) -> {
System.out.println(s);
};
// Should be called using seperate thread to gain non blocking streaming effect.
OllamaResult result = ollamaAPI.generate(config.getModel(),
"What is the capital of France? And what's France's connection with Mona Lisa?",
new OptionsBuilder().build(), streamHandler);
System.out.println("Full response: " +result.getResponse());
}
}
```
You will get a response similar to:
> The
> The capital
> The capital of
> The capital of France
> The capital of France is
> The capital of France is Paris
> The capital of France is Paris.
> Full response: The capital of France is Paris.
## Try asking a question from general topics.
```java

View File

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

View File

@@ -4,7 +4,7 @@
<groupId>io.github.amithkoujalgi</groupId>
<artifactId>ollama4j</artifactId>
<version>1.0.54</version>
<version>1.0.61</version>
<name>Ollama4j</name>
<description>Java library for interacting with Ollama API.</description>
@@ -39,7 +39,7 @@
<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.54</tag>
<tag>v1.0.61</tag>
</scm>
<build>
@@ -99,7 +99,7 @@
<configuration>
<skipTests>${skipUnitTests}</skipTests>
<includes>
<include>**/unittests/*.java</include>
<include>**/unittests/**/*.java</include>
</includes>
</configuration>
</plugin>

View File

@@ -6,10 +6,11 @@ import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatMessage;
import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestBuilder;
import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestModel;
import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatResult;
import io.github.amithkoujalgi.ollama4j.core.models.embeddings.OllamaEmbeddingResponseModel;
import io.github.amithkoujalgi.ollama4j.core.models.embeddings.OllamaEmbeddingsRequestModel;
import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateRequestModel;
import io.github.amithkoujalgi.ollama4j.core.models.request.CustomModelFileContentsRequest;
import io.github.amithkoujalgi.ollama4j.core.models.request.CustomModelFilePathRequest;
import io.github.amithkoujalgi.ollama4j.core.models.request.ModelEmbeddingsRequest;
import io.github.amithkoujalgi.ollama4j.core.models.request.ModelRequest;
import io.github.amithkoujalgi.ollama4j.core.models.request.OllamaChatEndpointCaller;
import io.github.amithkoujalgi.ollama4j.core.models.request.OllamaGenerateEndpointCaller;
@@ -313,8 +314,18 @@ public class OllamaAPI {
*/
public List<Double> generateEmbeddings(String model, String prompt)
throws IOException, InterruptedException, OllamaBaseException {
return generateEmbeddings(new OllamaEmbeddingsRequestModel(model, prompt));
}
/**
* Generate embeddings using a {@link OllamaEmbeddingsRequestModel}.
*
* @param modelRequest request for '/api/embeddings' endpoint
* @return embeddings
*/
public List<Double> generateEmbeddings(OllamaEmbeddingsRequestModel modelRequest) throws IOException, InterruptedException, OllamaBaseException{
URI uri = URI.create(this.host + "/api/embeddings");
String jsonData = new ModelEmbeddingsRequest(model, prompt).toString();
String jsonData = modelRequest.toString();
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest.Builder requestBuilder =
getRequestBuilderDefault(uri)
@@ -325,8 +336,8 @@ public class OllamaAPI {
int statusCode = response.statusCode();
String responseBody = response.body();
if (statusCode == 200) {
EmbeddingResponse embeddingResponse =
Utils.getObjectMapper().readValue(responseBody, EmbeddingResponse.class);
OllamaEmbeddingResponseModel embeddingResponse =
Utils.getObjectMapper().readValue(responseBody, OllamaEmbeddingResponseModel.class);
return embeddingResponse.getEmbedding();
} else {
throw new OllamaBaseException(statusCode + " - " + responseBody);
@@ -342,13 +353,24 @@ public class OllamaAPI {
* @param options the Options object - <a
* href="https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values">More
* details on the options</a>
* @param streamHandler optional callback consumer that will be applied every time a streamed response is received. If not set, the stream parameter of the request is set to false.
* @return OllamaResult that includes response text and time taken for response
*/
public OllamaResult generate(String model, String prompt, Options options)
public OllamaResult generate(String model, String prompt, Options options, OllamaStreamHandler streamHandler)
throws OllamaBaseException, IOException, InterruptedException {
OllamaGenerateRequestModel ollamaRequestModel = new OllamaGenerateRequestModel(model, prompt);
ollamaRequestModel.setOptions(options.getOptionsMap());
return generateSyncForOllamaRequestModel(ollamaRequestModel);
return generateSyncForOllamaRequestModel(ollamaRequestModel,streamHandler);
}
/**
* Convenience method to call Ollama API without streaming responses.
*
* Uses {@link #generate(String, String, Options, OllamaStreamHandler)}
*/
public OllamaResult generate(String model, String prompt, Options options)
throws OllamaBaseException, IOException, InterruptedException {
return generate(model, prompt, options,null);
}
/**
@@ -381,10 +403,11 @@ public class OllamaAPI {
* @param options the Options object - <a
* href="https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values">More
* details on the options</a>
* @param streamHandler optional callback consumer that will be applied every time a streamed response is received. If not set, the stream parameter of the request is set to false.
* @return OllamaResult that includes response text and time taken for response
*/
public OllamaResult generateWithImageFiles(
String model, String prompt, List<File> imageFiles, Options options)
String model, String prompt, List<File> imageFiles, Options options, OllamaStreamHandler streamHandler)
throws OllamaBaseException, IOException, InterruptedException {
List<String> images = new ArrayList<>();
for (File imageFile : imageFiles) {
@@ -392,9 +415,20 @@ public class OllamaAPI {
}
OllamaGenerateRequestModel ollamaRequestModel = new OllamaGenerateRequestModel(model, prompt, images);
ollamaRequestModel.setOptions(options.getOptionsMap());
return generateSyncForOllamaRequestModel(ollamaRequestModel);
return generateSyncForOllamaRequestModel(ollamaRequestModel,streamHandler);
}
/**
* Convenience method to call Ollama API without streaming responses.
*
* Uses {@link #generateWithImageFiles(String, String, List, Options, OllamaStreamHandler)}
*/
public OllamaResult generateWithImageFiles(
String model, String prompt, List<File> imageFiles, Options options)
throws OllamaBaseException, IOException, InterruptedException{
return generateWithImageFiles(model, prompt, imageFiles, options, null);
}
/**
* With one or more image URLs, ask a question to a model running on Ollama server. This is a
* sync/blocking call.
@@ -405,10 +439,11 @@ public class OllamaAPI {
* @param options the Options object - <a
* href="https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values">More
* details on the options</a>
* @param streamHandler optional callback consumer that will be applied every time a streamed response is received. If not set, the stream parameter of the request is set to false.
* @return OllamaResult that includes response text and time taken for response
*/
public OllamaResult generateWithImageURLs(
String model, String prompt, List<String> imageURLs, Options options)
String model, String prompt, List<String> imageURLs, Options options, OllamaStreamHandler streamHandler)
throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
List<String> images = new ArrayList<>();
for (String imageURL : imageURLs) {
@@ -416,7 +451,18 @@ public class OllamaAPI {
}
OllamaGenerateRequestModel ollamaRequestModel = new OllamaGenerateRequestModel(model, prompt, images);
ollamaRequestModel.setOptions(options.getOptionsMap());
return generateSyncForOllamaRequestModel(ollamaRequestModel);
return generateSyncForOllamaRequestModel(ollamaRequestModel,streamHandler);
}
/**
* Convenience method to call Ollama API without streaming responses.
*
* Uses {@link #generateWithImageURLs(String, String, List, Options, OllamaStreamHandler)}
*/
public OllamaResult generateWithImageURLs(String model, String prompt, List<String> imageURLs,
Options options)
throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
return generateWithImageURLs(model, prompt, imageURLs, options, null);
}
@@ -487,10 +533,19 @@ public class OllamaAPI {
return Base64.getEncoder().encodeToString(bytes);
}
private OllamaResult generateSyncForOllamaRequestModel(OllamaGenerateRequestModel ollamaRequestModel)
private OllamaResult generateSyncForOllamaRequestModel(
OllamaGenerateRequestModel ollamaRequestModel, OllamaStreamHandler streamHandler)
throws OllamaBaseException, IOException, InterruptedException {
OllamaGenerateEndpointCaller requestCaller = new OllamaGenerateEndpointCaller(host, basicAuth, requestTimeoutSeconds, verbose);
return requestCaller.callSync(ollamaRequestModel);
OllamaGenerateEndpointCaller requestCaller =
new OllamaGenerateEndpointCaller(host, basicAuth, requestTimeoutSeconds, verbose);
OllamaResult result;
if (streamHandler != null) {
ollamaRequestModel.setStream(true);
result = requestCaller.call(ollamaRequestModel, streamHandler);
} else {
result = requestCaller.callSync(ollamaRequestModel);
}
return result;
}
/**

View File

@@ -1,6 +1,8 @@
package io.github.amithkoujalgi.ollama4j.core.models;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.github.amithkoujalgi.ollama4j.core.utils.Utils;
import lombok.Data;
@Data
@@ -34,4 +36,13 @@ public class Model {
return name.split(":")[1];
}
@Override
public String toString() {
try {
return Utils.getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -2,7 +2,8 @@ package io.github.amithkoujalgi.ollama4j.core.models;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.github.amithkoujalgi.ollama4j.core.utils.Utils;
import lombok.Data;
@Data
@@ -16,5 +17,14 @@ public class ModelDetail {
private String parameters;
private String template;
private String system;
private Map<String, String> details;
private ModelMeta details;
@Override
public String toString() {
try {
return Utils.getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -2,6 +2,8 @@ package io.github.amithkoujalgi.ollama4j.core.models;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.github.amithkoujalgi.ollama4j.core.utils.Utils;
import lombok.Data;
@Data
@@ -21,4 +23,13 @@ public class ModelMeta {
@JsonProperty("quantization_level")
private String quantizationLevel;
@Override
public String toString() {
try {
return Utils.getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -2,10 +2,8 @@ package io.github.amithkoujalgi.ollama4j.core.models.chat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import io.github.amithkoujalgi.ollama4j.core.OllamaStreamHandler;
import lombok.NonNull;
public class OllamaChatStreamObserver {
@@ -13,7 +11,7 @@ public class OllamaChatStreamObserver {
private List<OllamaChatResponseModel> responseParts = new ArrayList<>();
private String message;
private String message = "";
public OllamaChatStreamObserver(OllamaStreamHandler streamHandler) {
this.streamHandler = streamHandler;
@@ -25,8 +23,7 @@ public class OllamaChatStreamObserver {
}
protected void handleCurrentResponsePart(OllamaChatResponseModel currentResponsePart){
List<@NonNull String> allResponsePartsByNow = responseParts.stream().map(r -> r.getMessage().getContent()).collect(Collectors.toList());
message = String.join("", allResponsePartsByNow);
message = message + currentResponsePart.getMessage().getContent();
streamHandler.accept(message);
}

View File

@@ -1,4 +1,4 @@
package io.github.amithkoujalgi.ollama4j.core.models;
package io.github.amithkoujalgi.ollama4j.core.models.embeddings;
import com.fasterxml.jackson.annotation.JsonProperty;
@@ -7,7 +7,7 @@ import lombok.Data;
@SuppressWarnings("unused")
@Data
public class EmbeddingResponse {
public class OllamaEmbeddingResponseModel {
@JsonProperty("embedding")
private List<Double> embedding;
}

View File

@@ -0,0 +1,31 @@
package io.github.amithkoujalgi.ollama4j.core.models.embeddings;
import io.github.amithkoujalgi.ollama4j.core.utils.Options;
public class OllamaEmbeddingsRequestBuilder {
private OllamaEmbeddingsRequestBuilder(String model, String prompt){
request = new OllamaEmbeddingsRequestModel(model, prompt);
}
private OllamaEmbeddingsRequestModel request;
public static OllamaEmbeddingsRequestBuilder getInstance(String model, String prompt){
return new OllamaEmbeddingsRequestBuilder(model, prompt);
}
public OllamaEmbeddingsRequestModel build(){
return request;
}
public OllamaEmbeddingsRequestBuilder withOptions(Options options){
this.request.setOptions(options.getOptionsMap());
return this;
}
public OllamaEmbeddingsRequestBuilder withKeepAlive(String keepAlive){
this.request.setKeepAlive(keepAlive);
return this;
}
}

View File

@@ -0,0 +1,33 @@
package io.github.amithkoujalgi.ollama4j.core.models.embeddings;
import static io.github.amithkoujalgi.ollama4j.core.utils.Utils.getObjectMapper;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@Data
@RequiredArgsConstructor
@NoArgsConstructor
public class OllamaEmbeddingsRequestModel {
@NonNull
private String model;
@NonNull
private String prompt;
protected Map<String, Object> options;
@JsonProperty(value = "keep_alive")
private String keepAlive;
@Override
public String toString() {
try {
return getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,31 @@
package io.github.amithkoujalgi.ollama4j.core.models.generate;
import java.util.ArrayList;
import java.util.List;
import io.github.amithkoujalgi.ollama4j.core.OllamaStreamHandler;
public class OllamaGenerateStreamObserver {
private OllamaStreamHandler streamHandler;
private List<OllamaGenerateResponseModel> responseParts = new ArrayList<>();
private String message = "";
public OllamaGenerateStreamObserver(OllamaStreamHandler streamHandler) {
this.streamHandler = streamHandler;
}
public void notify(OllamaGenerateResponseModel currentResponsePart){
responseParts.add(currentResponsePart);
handleCurrentResponsePart(currentResponsePart);
}
protected void handleCurrentResponsePart(OllamaGenerateResponseModel currentResponsePart){
message = message + currentResponsePart.getResponse();
streamHandler.accept(message);
}
}

View File

@@ -1,23 +0,0 @@
package io.github.amithkoujalgi.ollama4j.core.models.request;
import static io.github.amithkoujalgi.ollama4j.core.utils.Utils.getObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ModelEmbeddingsRequest {
private String model;
private String prompt;
@Override
public String toString() {
try {
return getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,18 +1,25 @@
package io.github.amithkoujalgi.ollama4j.core.models.request;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.github.amithkoujalgi.ollama4j.core.OllamaStreamHandler;
import io.github.amithkoujalgi.ollama4j.core.exceptions.OllamaBaseException;
import io.github.amithkoujalgi.ollama4j.core.models.BasicAuth;
import io.github.amithkoujalgi.ollama4j.core.models.OllamaResult;
import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateResponseModel;
import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateStreamObserver;
import io.github.amithkoujalgi.ollama4j.core.utils.OllamaRequestBody;
import io.github.amithkoujalgi.ollama4j.core.utils.Utils;
public class OllamaGenerateEndpointCaller extends OllamaEndpointCaller{
private static final Logger LOG = LoggerFactory.getLogger(OllamaGenerateEndpointCaller.class);
private OllamaGenerateStreamObserver streamObserver;
public OllamaGenerateEndpointCaller(String host, BasicAuth basicAuth, long requestTimeoutSeconds, boolean verbose) {
super(host, basicAuth, requestTimeoutSeconds, verbose);
}
@@ -27,6 +34,9 @@ public class OllamaGenerateEndpointCaller extends OllamaEndpointCaller{
try {
OllamaGenerateResponseModel ollamaResponseModel = Utils.getObjectMapper().readValue(line, OllamaGenerateResponseModel.class);
responseBuffer.append(ollamaResponseModel.getResponse());
if(streamObserver != null) {
streamObserver.notify(ollamaResponseModel);
}
return ollamaResponseModel.isDone();
} catch (JsonProcessingException e) {
LOG.error("Error parsing the Ollama chat response!",e);
@@ -34,7 +44,11 @@ public class OllamaGenerateEndpointCaller extends OllamaEndpointCaller{
}
}
public OllamaResult call(OllamaRequestBody body, OllamaStreamHandler streamHandler)
throws OllamaBaseException, IOException, InterruptedException {
streamObserver = new OllamaGenerateStreamObserver(streamHandler);
return super.callSync(body);
}
}

View File

@@ -8,57 +8,72 @@ package io.github.amithkoujalgi.ollama4j.core.types;
*/
@SuppressWarnings("ALL")
public class OllamaModelType {
public static final String GEMMA = "gemma";
public static final String LLAMA2 = "llama2";
public static final String MISTRAL = "mistral";
public static final String LLAVA = "llava";
public static final String MIXTRAL = "mixtral";
public static final String STARLING_LM = "starling-lm";
public static final String LLAVA = "llava";
public static final String NEURAL_CHAT = "neural-chat";
public static final String CODELLAMA = "codellama";
public static final String LLAMA2_UNCENSORED = "llama2-uncensored";
public static final String DOLPHIN_MIXTRAL = "dolphin-mixtral";
public static final String MISTRAL_OPENORCA = "mistral-openorca";
public static final String LLAMA2_UNCENSORED = "llama2-uncensored";
public static final String PHI = "phi";
public static final String ORCA_MINI = "orca-mini";
public static final String DEEPSEEK_CODER = "deepseek-coder";
public static final String DOLPHIN_MISTRAL = "dolphin-mistral";
public static final String VICUNA = "vicuna";
public static final String WIZARD_VICUNA_UNCENSORED = "wizard-vicuna-uncensored";
public static final String PHIND_CODELLAMA = "phind-codellama";
public static final String PHI = "phi";
public static final String ZEPHYR = "zephyr";
public static final String OPENHERMES = "openhermes";
public static final String QWEN = "qwen";
public static final String WIZARDCODER = "wizardcoder";
public static final String MISTRAL_OPENORCA = "mistral-openorca";
public static final String NOUS_HERMES = "nous-hermes";
public static final String DEEPSEEK_CODER = "deepseek-coder";
public static final String WIZARD_MATH = "wizard-math";
public static final String LLAMA2_CHINESE = "llama2-chinese";
public static final String FALCON = "falcon";
public static final String ORCA2 = "orca2";
public static final String STABLE_BELUGA = "stable-beluga";
public static final String CODEUP = "codeup";
public static final String EVERYTHINGLM = "everythinglm";
public static final String MEDLLAMA2 = "medllama2";
public static final String WIZARDLM_UNCENSORED = "wizardlm-uncensored";
public static final String STARCODER = "starcoder";
public static final String DOLPHIN22_MISTRAL = "dolphin2.2-mistral";
public static final String TINYLLAMA = "tinyllama";
public static final String PHIND_CODELLAMA = "phind-codellama";
public static final String OPENCHAT = "openchat";
public static final String WIZARD_VICUNA = "wizard-vicuna";
public static final String OPENHERMES25_MISTRAL = "openhermes2.5-mistral";
public static final String OPEN_ORCA_PLATYPUS2 = "open-orca-platypus2";
public static final String ORCA2 = "orca2";
public static final String FALCON = "falcon";
public static final String WIZARD_MATH = "wizard-math";
public static final String TINYDOLPHIN = "tinydolphin";
public static final String NOUS_HERMES = "nous-hermes";
public static final String YI = "yi";
public static final String YARN_MISTRAL = "yarn-mistral";
public static final String SAMANTHA_MISTRAL = "samantha-mistral";
public static final String SQLCODER = "sqlcoder";
public static final String YARN_LLAMA2 = "yarn-llama2";
public static final String MEDITRON = "meditron";
public static final String STABLELM_ZEPHYR = "stablelm-zephyr";
public static final String OPENHERMES2_MISTRAL = "openhermes2-mistral";
public static final String DEEPSEEK_LLM = "deepseek-llm";
public static final String MISTRALLITE = "mistrallite";
public static final String DOLPHIN21_MISTRAL = "dolphin2.1-mistral";
public static final String WIZARDLM = "wizardlm";
public static final String CODEBOOGA = "codebooga";
public static final String MAGICODER = "magicoder";
public static final String GOLIATH = "goliath";
public static final String NEXUSRAVEN = "nexusraven";
public static final String ALFRED = "alfred";
public static final String XWINLM = "xwinlm";
public static final String DOLPHIN_PHI = "dolphin-phi";
public static final String STARLING_LM = "starling-lm";
public static final String STARCODER = "starcoder";
public static final String CODEUP = "codeup";
public static final String MEDLLAMA2 = "medllama2";
public static final String STABLE_CODE = "stable-code";
public static final String WIZARDLM_UNCENSORED = "wizardlm-uncensored";
public static final String BAKLLAVA = "bakllava";
public static final String EVERYTHINGLM = "everythinglm";
public static final String SOLAR = "solar";
public static final String STABLE_BELUGA = "stable-beluga";
public static final String SQLCODER = "sqlcoder";
public static final String YARN_MISTRAL = "yarn-mistral";
public static final String NOUS_HERMES2_MIXTRAL = "nous-hermes2-mixtral";
public static final String SAMANTHA_MISTRAL = "samantha-mistral";
public static final String STABLELM_ZEPHYR = "stablelm-zephyr";
public static final String MEDITRON = "meditron";
public static final String WIZARD_VICUNA = "wizard-vicuna";
public static final String STABLELM2 = "stablelm2";
public static final String MAGICODER = "magicoder";
public static final String YARN_LLAMA2 = "yarn-llama2";
public static final String NOUS_HERMES2 = "nous-hermes2";
public static final String DEEPSEEK_LLM = "deepseek-llm";
public static final String LLAMA_PRO = "llama-pro";
public static final String OPEN_ORCA_PLATYPUS2 = "open-orca-platypus2";
public static final String CODEBOOGA = "codebooga";
public static final String MISTRALLITE = "mistrallite";
public static final String NEXUSRAVEN = "nexusraven";
public static final String GOLIATH = "goliath";
public static final String NOMIC_EMBED_TEXT = "nomic-embed-text";
public static final String NOTUX = "notux";
public static final String ALFRED = "alfred";
public static final String MEGADOLPHIN = "megadolphin";
public static final String WIZARDLM = "wizardlm";
public static final String XWINLM = "xwinlm";
public static final String NOTUS = "notus";
public static final String DUCKDB_NSQL = "duckdb-nsql";
public static final String ALL_MINILM = "all-minilm";
}

View File

@@ -4,11 +4,14 @@ 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.ModelDetail;
import io.github.amithkoujalgi.ollama4j.core.models.OllamaResult;
import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatMessageRole;
import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestBuilder;
import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestModel;
import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatResult;
import io.github.amithkoujalgi.ollama4j.core.models.embeddings.OllamaEmbeddingsRequestModel;
import io.github.amithkoujalgi.ollama4j.core.models.embeddings.OllamaEmbeddingsRequestBuilder;
import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder;
import java.io.File;
import java.io.IOException;
@@ -60,7 +63,7 @@ class TestRealAPIs {
} catch (HttpConnectTimeoutException e) {
fail(e.getMessage());
} catch (Exception e) {
throw new RuntimeException(e);
fail(e);
}
}
@@ -72,7 +75,7 @@ class TestRealAPIs {
assertNotNull(ollamaAPI.listModels());
ollamaAPI.listModels().forEach(System.out::println);
} catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
throw new RuntimeException(e);
fail(e);
}
}
@@ -87,7 +90,20 @@ class TestRealAPIs {
.anyMatch(model -> model.getModel().equalsIgnoreCase(config.getModel()));
assertTrue(found);
} catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
throw new RuntimeException(e);
fail(e);
}
}
@Test
@Order(3)
void testListDtails() {
testEndpointReachability();
try {
ModelDetail modelDetails = ollamaAPI.getModelDetails(config.getModel());
assertNotNull(modelDetails);
System.out.println(modelDetails);
} catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
fail(e);
}
}
@@ -105,7 +121,33 @@ class TestRealAPIs {
assertNotNull(result.getResponse());
assertFalse(result.getResponse().isEmpty());
} catch (IOException | OllamaBaseException | InterruptedException e) {
throw new RuntimeException(e);
fail(e);
}
}
@Test
@Order(3)
void testAskModelWithDefaultOptionsStreamed() {
testEndpointReachability();
try {
StringBuffer sb = new StringBuffer("");
OllamaResult result = ollamaAPI.generate(config.getModel(),
"What is the capital of France? And what's France's connection with Mona Lisa?",
new OptionsBuilder().build(), (s) -> {
LOG.info(s);
String substring = s.substring(sb.toString().length(), s.length());
LOG.info(substring);
sb.append(substring);
});
assertNotNull(result);
assertNotNull(result.getResponse());
assertFalse(result.getResponse().isEmpty());
assertEquals(sb.toString().trim(), result.getResponse().trim());
} catch (IOException | OllamaBaseException | InterruptedException e) {
fail(e);
}
}
@@ -123,7 +165,7 @@ class TestRealAPIs {
assertNotNull(result.getResponse());
assertFalse(result.getResponse().isEmpty());
} catch (IOException | OllamaBaseException | InterruptedException e) {
throw new RuntimeException(e);
fail(e);
}
}
@@ -143,7 +185,7 @@ class TestRealAPIs {
assertFalse(chatResult.getResponse().isBlank());
assertEquals(4,chatResult.getChatHistory().size());
} catch (IOException | OllamaBaseException | InterruptedException e) {
throw new RuntimeException(e);
fail(e);
}
}
@@ -165,7 +207,7 @@ class TestRealAPIs {
assertTrue(chatResult.getResponse().startsWith("NI"));
assertEquals(3, chatResult.getChatHistory().size());
} catch (IOException | OllamaBaseException | InterruptedException e) {
throw new RuntimeException(e);
fail(e);
}
}
@@ -183,14 +225,14 @@ class TestRealAPIs {
OllamaChatResult chatResult = ollamaAPI.chat(requestModel,(s) -> {
LOG.info(s);
String substring = s.substring(sb.toString().length(), s.length()-1);
String substring = s.substring(sb.toString().length(), s.length());
LOG.info(substring);
sb.append(substring);
});
assertNotNull(chatResult);
assertEquals(sb.toString().trim(), chatResult.getResponse().trim());
} catch (IOException | OllamaBaseException | InterruptedException e) {
throw new RuntimeException(e);
fail(e);
}
}
@@ -221,7 +263,7 @@ class TestRealAPIs {
} catch (IOException | OllamaBaseException | InterruptedException e) {
throw new RuntimeException(e);
fail(e);
}
}
@@ -238,7 +280,7 @@ class TestRealAPIs {
OllamaChatResult chatResult = ollamaAPI.chat(requestModel);
assertNotNull(chatResult);
} catch (IOException | OllamaBaseException | InterruptedException e) {
throw new RuntimeException(e);
fail(e);
}
}
@@ -258,7 +300,31 @@ class TestRealAPIs {
assertNotNull(result.getResponse());
assertFalse(result.getResponse().isEmpty());
} catch (IOException | OllamaBaseException | InterruptedException e) {
throw new RuntimeException(e);
fail(e);
}
}
@Test
@Order(3)
void testAskModelWithOptionsAndImageFilesStreamed() {
testEndpointReachability();
File imageFile = getImageFileFromClasspath("dog-on-a-boat.jpg");
try {
StringBuffer sb = new StringBuffer("");
OllamaResult result = ollamaAPI.generateWithImageFiles(config.getImageModel(),
"What is in this image?", List.of(imageFile), new OptionsBuilder().build(), (s) -> {
LOG.info(s);
String substring = s.substring(sb.toString().length(), s.length());
LOG.info(substring);
sb.append(substring);
});
assertNotNull(result);
assertNotNull(result.getResponse());
assertFalse(result.getResponse().isEmpty());
assertEquals(sb.toString().trim(), result.getResponse().trim());
} catch (IOException | OllamaBaseException | InterruptedException e) {
fail(e);
}
}
@@ -278,7 +344,24 @@ class TestRealAPIs {
assertNotNull(result.getResponse());
assertFalse(result.getResponse().isEmpty());
} catch (IOException | OllamaBaseException | InterruptedException | URISyntaxException e) {
throw new RuntimeException(e);
fail(e);
}
}
@Test
@Order(3)
public void testEmbedding() {
testEndpointReachability();
try {
OllamaEmbeddingsRequestModel request = OllamaEmbeddingsRequestBuilder
.getInstance(config.getModel(), "What is the capital of France?").build();
List<Double> embeddings = ollamaAPI.generateEmbeddings(request);
assertNotNull(embeddings);
assertFalse(embeddings.isEmpty());
} catch (IOException | OllamaBaseException | InterruptedException e) {
fail(e);
}
}
}

View File

@@ -0,0 +1,35 @@
package io.github.amithkoujalgi.ollama4j.unittests.jackson;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.amithkoujalgi.ollama4j.core.utils.Utils;
public abstract class AbstractRequestSerializationTest<T> {
protected ObjectMapper mapper = Utils.getObjectMapper();
protected String serializeRequest(T req) {
try {
return mapper.writeValueAsString(req);
} catch (JsonProcessingException e) {
fail("Could not serialize request!", e);
return null;
}
}
protected T deserializeRequest(String jsonRequest, Class<T> requestClass) {
try {
return mapper.readValue(jsonRequest, requestClass);
} catch (JsonProcessingException e) {
fail("Could not deserialize jsonRequest!", e);
return null;
}
}
protected void assertEqualsAfterUnmarshalling(T unmarshalledRequest,
T req) {
assertEquals(req, unmarshalledRequest);
}
}

View File

@@ -1,7 +1,6 @@
package io.github.amithkoujalgi.ollama4j.unittests.jackson;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.File;
import java.util.List;
@@ -10,21 +9,15 @@ import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatMessageRole;
import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestBuilder;
import io.github.amithkoujalgi.ollama4j.core.models.chat.OllamaChatRequestModel;
import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder;
import io.github.amithkoujalgi.ollama4j.core.utils.Utils;
public class TestChatRequestSerialization {
public class TestChatRequestSerialization extends AbstractRequestSerializationTest<OllamaChatRequestModel>{
private OllamaChatRequestBuilder builder;
private ObjectMapper mapper = Utils.getObjectMapper();
@BeforeEach
public void init() {
builder = OllamaChatRequestBuilder.getInstance("DummyModel");
@@ -32,10 +25,9 @@ public class TestChatRequestSerialization {
@Test
public void testRequestOnlyMandatoryFields() {
OllamaChatRequestModel req = builder.withMessage(OllamaChatMessageRole.USER, "Some prompt",
List.of(new File("src/test/resources/dog-on-a-boat.jpg"))).build();
OllamaChatRequestModel req = builder.withMessage(OllamaChatMessageRole.USER, "Some prompt").build();
String jsonRequest = serializeRequest(req);
assertEqualsAfterUnmarshalling(deserializeRequest(jsonRequest), req);
assertEqualsAfterUnmarshalling(deserializeRequest(jsonRequest,OllamaChatRequestModel.class), req);
}
@Test
@@ -44,7 +36,7 @@ public class TestChatRequestSerialization {
.withMessage(OllamaChatMessageRole.USER, "Some prompt")
.build();
String jsonRequest = serializeRequest(req);
assertEqualsAfterUnmarshalling(deserializeRequest(jsonRequest), req);
assertEqualsAfterUnmarshalling(deserializeRequest(jsonRequest,OllamaChatRequestModel.class), req);
}
@Test
@@ -52,7 +44,7 @@ public class TestChatRequestSerialization {
OllamaChatRequestModel req = builder.withMessage(OllamaChatMessageRole.USER, "Some prompt",
List.of(new File("src/test/resources/dog-on-a-boat.jpg"))).build();
String jsonRequest = serializeRequest(req);
assertEqualsAfterUnmarshalling(deserializeRequest(jsonRequest), req);
assertEqualsAfterUnmarshalling(deserializeRequest(jsonRequest,OllamaChatRequestModel.class), req);
}
@Test
@@ -62,7 +54,7 @@ public class TestChatRequestSerialization {
.withOptions(b.setMirostat(1).build()).build();
String jsonRequest = serializeRequest(req);
OllamaChatRequestModel deserializeRequest = deserializeRequest(jsonRequest);
OllamaChatRequestModel deserializeRequest = deserializeRequest(jsonRequest,OllamaChatRequestModel.class);
assertEqualsAfterUnmarshalling(deserializeRequest, req);
assertEquals(1, deserializeRequest.getOptions().get("mirostat"));
}
@@ -79,28 +71,4 @@ public class TestChatRequestSerialization {
String requestFormatProperty = jsonObject.getString("format");
assertEquals("json", requestFormatProperty);
}
private String serializeRequest(OllamaChatRequestModel req) {
try {
return mapper.writeValueAsString(req);
} catch (JsonProcessingException e) {
fail("Could not serialize request!", e);
return null;
}
}
private OllamaChatRequestModel deserializeRequest(String jsonRequest) {
try {
return mapper.readValue(jsonRequest, OllamaChatRequestModel.class);
} catch (JsonProcessingException e) {
fail("Could not deserialize jsonRequest!", e);
return null;
}
}
private void assertEqualsAfterUnmarshalling(OllamaChatRequestModel unmarshalledRequest,
OllamaChatRequestModel req) {
assertEquals(req, unmarshalledRequest);
}
}

View File

@@ -0,0 +1,37 @@
package io.github.amithkoujalgi.ollama4j.unittests.jackson;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import io.github.amithkoujalgi.ollama4j.core.models.embeddings.OllamaEmbeddingsRequestModel;
import io.github.amithkoujalgi.ollama4j.core.models.embeddings.OllamaEmbeddingsRequestBuilder;
import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder;
public class TestEmbeddingsRequestSerialization extends AbstractRequestSerializationTest<OllamaEmbeddingsRequestModel>{
private OllamaEmbeddingsRequestBuilder builder;
@BeforeEach
public void init() {
builder = OllamaEmbeddingsRequestBuilder.getInstance("DummyModel","DummyPrompt");
}
@Test
public void testRequestOnlyMandatoryFields() {
OllamaEmbeddingsRequestModel req = builder.build();
String jsonRequest = serializeRequest(req);
assertEqualsAfterUnmarshalling(deserializeRequest(jsonRequest,OllamaEmbeddingsRequestModel.class), req);
}
@Test
public void testRequestWithOptions() {
OptionsBuilder b = new OptionsBuilder();
OllamaEmbeddingsRequestModel req = builder
.withOptions(b.setMirostat(1).build()).build();
String jsonRequest = serializeRequest(req);
OllamaEmbeddingsRequestModel deserializeRequest = deserializeRequest(jsonRequest,OllamaEmbeddingsRequestModel.class);
assertEqualsAfterUnmarshalling(deserializeRequest, req);
assertEquals(1, deserializeRequest.getOptions().get("mirostat"));
}
}

View File

@@ -1,26 +1,20 @@
package io.github.amithkoujalgi.ollama4j.unittests.jackson;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateRequestBuilder;
import io.github.amithkoujalgi.ollama4j.core.models.generate.OllamaGenerateRequestModel;
import io.github.amithkoujalgi.ollama4j.core.utils.OptionsBuilder;
import io.github.amithkoujalgi.ollama4j.core.utils.Utils;
public class TestGenerateRequestSerialization {
public class TestGenerateRequestSerialization extends AbstractRequestSerializationTest<OllamaGenerateRequestModel>{
private OllamaGenerateRequestBuilder builder;
private ObjectMapper mapper = Utils.getObjectMapper();
@BeforeEach
public void init() {
builder = OllamaGenerateRequestBuilder.getInstance("DummyModel");
@@ -31,7 +25,7 @@ public class TestGenerateRequestSerialization {
OllamaGenerateRequestModel req = builder.withPrompt("Some prompt").build();
String jsonRequest = serializeRequest(req);
assertEqualsAfterUnmarshalling(deserializeRequest(jsonRequest), req);
assertEqualsAfterUnmarshalling(deserializeRequest(jsonRequest, OllamaGenerateRequestModel.class), req);
}
@Test
@@ -41,7 +35,7 @@ public class TestGenerateRequestSerialization {
builder.withPrompt("Some prompt").withOptions(b.setMirostat(1).build()).build();
String jsonRequest = serializeRequest(req);
OllamaGenerateRequestModel deserializeRequest = deserializeRequest(jsonRequest);
OllamaGenerateRequestModel deserializeRequest = deserializeRequest(jsonRequest, OllamaGenerateRequestModel.class);
assertEqualsAfterUnmarshalling(deserializeRequest, req);
assertEquals(1, deserializeRequest.getOptions().get("mirostat"));
}
@@ -59,27 +53,4 @@ public class TestGenerateRequestSerialization {
assertEquals("json", requestFormatProperty);
}
private String serializeRequest(OllamaGenerateRequestModel req) {
try {
return mapper.writeValueAsString(req);
} catch (JsonProcessingException e) {
fail("Could not serialize request!", e);
return null;
}
}
private OllamaGenerateRequestModel deserializeRequest(String jsonRequest) {
try {
return mapper.readValue(jsonRequest, OllamaGenerateRequestModel.class);
} catch (JsonProcessingException e) {
fail("Could not deserialize jsonRequest!", e);
return null;
}
}
private void assertEqualsAfterUnmarshalling(OllamaGenerateRequestModel unmarshalledRequest,
OllamaGenerateRequestModel req) {
assertEquals(req, unmarshalledRequest);
}
}