Ollama4j
A Java library (wrapper/binding) for Ollama server.
Loading...
Searching...
No Matches
OllamaAPI.java
Go to the documentation of this file.
1package io.github.ollama4j;
2
3import io.github.ollama4j.exceptions.OllamaBaseException;
4import io.github.ollama4j.exceptions.RoleNotFoundException;
5import io.github.ollama4j.exceptions.ToolInvocationException;
6import io.github.ollama4j.exceptions.ToolNotFoundException;
7import io.github.ollama4j.models.chat.*;
8import io.github.ollama4j.models.embeddings.OllamaEmbedRequestModel;
9import io.github.ollama4j.models.embeddings.OllamaEmbeddingResponseModel;
10import io.github.ollama4j.models.embeddings.OllamaEmbeddingsRequestModel;
11import io.github.ollama4j.models.embeddings.OllamaEmbedResponseModel;
12import io.github.ollama4j.models.generate.OllamaGenerateRequest;
13import io.github.ollama4j.models.generate.OllamaStreamHandler;
14import io.github.ollama4j.models.ps.ModelsProcessResponse;
15import io.github.ollama4j.models.request.*;
16import io.github.ollama4j.models.response.*;
17import io.github.ollama4j.tools.*;
18import io.github.ollama4j.utils.Options;
19import io.github.ollama4j.utils.Utils;
20import lombok.Setter;
21
22import java.io.*;
23import java.net.URI;
24import java.net.URISyntaxException;
25import java.net.http.HttpClient;
26import java.net.http.HttpConnectTimeoutException;
27import java.net.http.HttpRequest;
28import java.net.http.HttpResponse;
29import java.nio.charset.StandardCharsets;
30import java.nio.file.Files;
31import java.time.Duration;
32import java.util.*;
33import java.util.stream.Collectors;
34
35import org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
37import org.jsoup.Jsoup;
38import org.jsoup.nodes.Document;
39import org.jsoup.nodes.Element;
40import org.jsoup.select.Elements;
41
45@SuppressWarnings({"DuplicatedCode", "resource"})
46public class OllamaAPI {
47
48 private static final Logger logger = LoggerFactory.getLogger(OllamaAPI.class);
49 private final String host;
54 @Setter
55 private long requestTimeoutSeconds = 10;
60 @Setter
61 private boolean verbose = true;
62 private BasicAuth basicAuth;
63
64 private final ToolRegistry toolRegistry = new ToolRegistry();
65
69 public OllamaAPI() {
70 this.host = "http://localhost:11434";
71 }
72
78 public OllamaAPI(String host) {
79 if (host.endsWith("/")) {
80 this.host = host.substring(0, host.length() - 1);
81 } else {
82 this.host = host;
83 }
84 }
85
92 public void setBasicAuth(String username, String password) {
93 this.basicAuth = new BasicAuth(username, password);
94 }
95
101 public boolean ping() {
102 String url = this.host + "/api/tags";
103 HttpClient httpClient = HttpClient.newHttpClient();
104 HttpRequest httpRequest = null;
105 try {
106 httpRequest = getRequestBuilderDefault(new URI(url)).header("Accept", "application/json").header("Content-type", "application/json").GET().build();
107 } catch (URISyntaxException e) {
108 throw new RuntimeException(e);
109 }
110 HttpResponse<String> response = null;
111 try {
112 response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
113 } catch (HttpConnectTimeoutException e) {
114 return false;
115 } catch (IOException | InterruptedException e) {
116 throw new RuntimeException(e);
117 }
118 int statusCode = response.statusCode();
119 return statusCode == 200;
120 }
121
130 public ModelsProcessResponse ps() throws IOException, InterruptedException, OllamaBaseException {
131 String url = this.host + "/api/ps";
132 HttpClient httpClient = HttpClient.newHttpClient();
133 HttpRequest httpRequest = null;
134 try {
135 httpRequest = getRequestBuilderDefault(new URI(url)).header("Accept", "application/json").header("Content-type", "application/json").GET().build();
136 } catch (URISyntaxException e) {
137 throw new RuntimeException(e);
138 }
139 HttpResponse<String> response = null;
140 response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
141 int statusCode = response.statusCode();
142 String responseString = response.body();
143 if (statusCode == 200) {
144 return Utils.getObjectMapper().readValue(responseString, ModelsProcessResponse.class);
145 } else {
146 throw new OllamaBaseException(statusCode + " - " + responseString);
147 }
148 }
149
159 public List<Model> listModels() throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
160 String url = this.host + "/api/tags";
161 HttpClient httpClient = HttpClient.newHttpClient();
162 HttpRequest httpRequest = getRequestBuilderDefault(new URI(url)).header("Accept", "application/json").header("Content-type", "application/json").GET().build();
163 HttpResponse<String> response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
164 int statusCode = response.statusCode();
165 String responseString = response.body();
166 if (statusCode == 200) {
167 return Utils.getObjectMapper().readValue(responseString, ListModelsResponse.class).getModels();
168 } else {
169 throw new OllamaBaseException(statusCode + " - " + responseString);
170 }
171 }
172
183 public List<LibraryModel> listModelsFromLibrary() throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
184 String url = "https://ollama.com/library";
185 HttpClient httpClient = HttpClient.newHttpClient();
186 HttpRequest httpRequest = getRequestBuilderDefault(new URI(url)).header("Accept", "application/json").header("Content-type", "application/json").GET().build();
187 HttpResponse<String> response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
188 int statusCode = response.statusCode();
189 String responseString = response.body();
190 List<LibraryModel> models = new ArrayList<>();
191 if (statusCode == 200) {
192 Document doc = Jsoup.parse(responseString);
193 Elements modelSections = doc.selectXpath("//*[@id='repo']/ul/li/a");
194 for (Element e : modelSections) {
195 LibraryModel model = new LibraryModel();
196 Elements names = e.select("div > h2 > div > span");
197 Elements desc = e.select("div > p");
198 Elements pullCounts = e.select("div:nth-of-type(2) > p > span:first-of-type > span:first-of-type");
199 Elements popularTags = e.select("div > div > span");
200 Elements totalTags = e.select("div:nth-of-type(2) > p > span:nth-of-type(2) > span:first-of-type");
201 Elements lastUpdatedTime = e.select("div:nth-of-type(2) > p > span:nth-of-type(3) > span:nth-of-type(2)");
202
203 if (names.first() == null || names.isEmpty()) {
204 // if name cannot be extracted, skip.
205 continue;
206 }
207 Optional.ofNullable(names.first()).map(Element::text).ifPresent(model::setName);
208 model.setDescription(Optional.ofNullable(desc.first()).map(Element::text).orElse(""));
209 model.setPopularTags(Optional.of(popularTags).map(tags -> tags.stream().map(Element::text).collect(Collectors.toList())).orElse(new ArrayList<>()));
210 model.setPullCount(Optional.ofNullable(pullCounts.first()).map(Element::text).orElse(""));
211 model.setTotalTags(Optional.ofNullable(totalTags.first()).map(Element::text).map(Integer::parseInt).orElse(0));
212 model.setLastUpdated(Optional.ofNullable(lastUpdatedTime.first()).map(Element::text).orElse(""));
213
214 models.add(model);
215 }
216 return models;
217 } else {
218 throw new OllamaBaseException(statusCode + " - " + responseString);
219 }
220 }
221
236 public LibraryModelDetail getLibraryModelDetails(LibraryModel libraryModel) throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
237 String url = String.format("https://ollama.com/library/%s/tags", libraryModel.getName());
238 HttpClient httpClient = HttpClient.newHttpClient();
239 HttpRequest httpRequest = getRequestBuilderDefault(new URI(url)).header("Accept", "application/json").header("Content-type", "application/json").GET().build();
240 HttpResponse<String> response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
241 int statusCode = response.statusCode();
242 String responseString = response.body();
243
244 List<LibraryModelTag> libraryModelTags = new ArrayList<>();
245 if (statusCode == 200) {
246 Document doc = Jsoup.parse(responseString);
247 Elements tagSections = doc.select("html > body > main > div > section > div > div > div:nth-child(n+2) > div");
248 for (Element e : tagSections) {
249 Elements tags = e.select("div > a > div");
250 Elements tagsMetas = e.select("div > span");
251
252 LibraryModelTag libraryModelTag = new LibraryModelTag();
253
254 if (tags.first() == null || tags.isEmpty()) {
255 // if tag cannot be extracted, skip.
256 continue;
257 }
258 libraryModelTag.setName(libraryModel.getName());
259 Optional.ofNullable(tags.first()).map(Element::text).ifPresent(libraryModelTag::setTag);
260 libraryModelTag.setSize(Optional.ofNullable(tagsMetas.first()).map(element -> element.text().split("•")).filter(parts -> parts.length > 1).map(parts -> parts[1].trim()).orElse(""));
261 libraryModelTag.setLastUpdated(Optional.ofNullable(tagsMetas.first()).map(element -> element.text().split("•")).filter(parts -> parts.length > 1).map(parts -> parts[2].trim()).orElse(""));
262 libraryModelTags.add(libraryModelTag);
263 }
264 LibraryModelDetail libraryModelDetail = new LibraryModelDetail();
265 libraryModelDetail.setModel(libraryModel);
266 libraryModelDetail.setTags(libraryModelTags);
267 return libraryModelDetail;
268 } else {
269 throw new OllamaBaseException(statusCode + " - " + responseString);
270 }
271 }
272
289 public LibraryModelTag findModelTagFromLibrary(String modelName, String tag) throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
290 List<LibraryModel> libraryModels = this.listModelsFromLibrary();
291 LibraryModel libraryModel = libraryModels.stream().filter(model -> model.getName().equals(modelName)).findFirst().orElseThrow(() -> new NoSuchElementException(String.format("Model by name '%s' not found", modelName)));
292 LibraryModelDetail libraryModelDetail = this.getLibraryModelDetails(libraryModel);
293 LibraryModelTag libraryModelTag = libraryModelDetail.getTags().stream().filter(tagName -> tagName.getTag().equals(tag)).findFirst().orElseThrow(() -> new NoSuchElementException(String.format("Tag '%s' for model '%s' not found", tag, modelName)));
294 return libraryModelTag;
295 }
296
307 public void pullModel(String modelName) throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
308 String url = this.host + "/api/pull";
309 String jsonData = new ModelRequest(modelName).toString();
310 HttpRequest request = getRequestBuilderDefault(new URI(url)).POST(HttpRequest.BodyPublishers.ofString(jsonData)).header("Accept", "application/json").header("Content-type", "application/json").build();
311 HttpClient client = HttpClient.newHttpClient();
312 HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
313 int statusCode = response.statusCode();
314 InputStream responseBodyStream = response.body();
315 String responseString = "";
316 try (BufferedReader reader = new BufferedReader(new InputStreamReader(responseBodyStream, StandardCharsets.UTF_8))) {
317 String line;
318 while ((line = reader.readLine()) != null) {
319 ModelPullResponse modelPullResponse = Utils.getObjectMapper().readValue(line, ModelPullResponse.class);
320 if (verbose) {
321 logger.info(modelPullResponse.getStatus());
322 }
323 }
324 }
325 if (statusCode != 200) {
326 throw new OllamaBaseException(statusCode + " - " + responseString);
327 }
328 }
329
342 public void pullModel(LibraryModelTag libraryModelTag) throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
343 String tagToPull = String.format("%s:%s", libraryModelTag.getName(), libraryModelTag.getTag());
344 pullModel(tagToPull);
345 }
346
357 public ModelDetail getModelDetails(String modelName) throws IOException, OllamaBaseException, InterruptedException, URISyntaxException {
358 String url = this.host + "/api/show";
359 String jsonData = new ModelRequest(modelName).toString();
360 HttpRequest request = getRequestBuilderDefault(new URI(url)).header("Accept", "application/json").header("Content-type", "application/json").POST(HttpRequest.BodyPublishers.ofString(jsonData)).build();
361 HttpClient client = HttpClient.newHttpClient();
362 HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
363 int statusCode = response.statusCode();
364 String responseBody = response.body();
365 if (statusCode == 200) {
366 return Utils.getObjectMapper().readValue(responseBody, ModelDetail.class);
367 } else {
368 throw new OllamaBaseException(statusCode + " - " + responseBody);
369 }
370 }
371
383 public void createModelWithFilePath(String modelName, String modelFilePath) throws IOException, InterruptedException, OllamaBaseException, URISyntaxException {
384 String url = this.host + "/api/create";
385 String jsonData = new CustomModelFilePathRequest(modelName, modelFilePath).toString();
386 HttpRequest request = getRequestBuilderDefault(new URI(url)).header("Accept", "application/json").header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(jsonData, StandardCharsets.UTF_8)).build();
387 HttpClient client = HttpClient.newHttpClient();
388 HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
389 int statusCode = response.statusCode();
390 String responseString = response.body();
391 if (statusCode != 200) {
392 throw new OllamaBaseException(statusCode + " - " + responseString);
393 }
394 // FIXME: Ollama API returns HTTP status code 200 for model creation failure cases. Correct this
395 // if the issue is fixed in the Ollama API server.
396 if (responseString.contains("error")) {
397 throw new OllamaBaseException(responseString);
398 }
399 if (verbose) {
400 logger.info(responseString);
401 }
402 }
403
415 public void createModelWithModelFileContents(String modelName, String modelFileContents) throws IOException, InterruptedException, OllamaBaseException, URISyntaxException {
416 String url = this.host + "/api/create";
417 String jsonData = new CustomModelFileContentsRequest(modelName, modelFileContents).toString();
418 HttpRequest request = getRequestBuilderDefault(new URI(url)).header("Accept", "application/json").header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(jsonData, StandardCharsets.UTF_8)).build();
419 HttpClient client = HttpClient.newHttpClient();
420 HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
421 int statusCode = response.statusCode();
422 String responseString = response.body();
423 if (statusCode != 200) {
424 throw new OllamaBaseException(statusCode + " - " + responseString);
425 }
426 if (responseString.contains("error")) {
427 throw new OllamaBaseException(responseString);
428 }
429 if (verbose) {
430 logger.info(responseString);
431 }
432 }
433
444 public void deleteModel(String modelName, boolean ignoreIfNotPresent) throws IOException, InterruptedException, OllamaBaseException, URISyntaxException {
445 String url = this.host + "/api/delete";
446 String jsonData = new ModelRequest(modelName).toString();
447 HttpRequest request = getRequestBuilderDefault(new URI(url)).method("DELETE", HttpRequest.BodyPublishers.ofString(jsonData, StandardCharsets.UTF_8)).header("Accept", "application/json").header("Content-type", "application/json").build();
448 HttpClient client = HttpClient.newHttpClient();
449 HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
450 int statusCode = response.statusCode();
451 String responseBody = response.body();
452 if (statusCode == 404 && responseBody.contains("model") && responseBody.contains("not found")) {
453 return;
454 }
455 if (statusCode != 200) {
456 throw new OllamaBaseException(statusCode + " - " + responseBody);
457 }
458 }
459
471 @Deprecated
472 public List<Double> generateEmbeddings(String model, String prompt) throws IOException, InterruptedException, OllamaBaseException {
473 return generateEmbeddings(new OllamaEmbeddingsRequestModel(model, prompt));
474 }
475
486 @Deprecated
487 public List<Double> generateEmbeddings(OllamaEmbeddingsRequestModel modelRequest) throws IOException, InterruptedException, OllamaBaseException {
488 URI uri = URI.create(this.host + "/api/embeddings");
489 String jsonData = modelRequest.toString();
490 HttpClient httpClient = HttpClient.newHttpClient();
491 HttpRequest.Builder requestBuilder = getRequestBuilderDefault(uri).header("Accept", "application/json").POST(HttpRequest.BodyPublishers.ofString(jsonData));
492 HttpRequest request = requestBuilder.build();
493 HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
494 int statusCode = response.statusCode();
495 String responseBody = response.body();
496 if (statusCode == 200) {
497 OllamaEmbeddingResponseModel embeddingResponse = Utils.getObjectMapper().readValue(responseBody, OllamaEmbeddingResponseModel.class);
498 return embeddingResponse.getEmbedding();
499 } else {
500 throw new OllamaBaseException(statusCode + " - " + responseBody);
501 }
502 }
503
514 public OllamaEmbedResponseModel embed(String model, List<String> inputs) throws IOException, InterruptedException, OllamaBaseException {
515 return embed(new OllamaEmbedRequestModel(model, inputs));
516 }
517
527 public OllamaEmbedResponseModel embed(OllamaEmbedRequestModel modelRequest) throws IOException, InterruptedException, OllamaBaseException {
528 URI uri = URI.create(this.host + "/api/embed");
529 String jsonData = Utils.getObjectMapper().writeValueAsString(modelRequest);
530 HttpClient httpClient = HttpClient.newHttpClient();
531
532 HttpRequest request = HttpRequest.newBuilder(uri).header("Accept", "application/json").POST(HttpRequest.BodyPublishers.ofString(jsonData)).build();
533
534 HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
535 int statusCode = response.statusCode();
536 String responseBody = response.body();
537
538 if (statusCode == 200) {
539 return Utils.getObjectMapper().readValue(responseBody, OllamaEmbedResponseModel.class);
540 } else {
541 throw new OllamaBaseException(statusCode + " - " + responseBody);
542 }
543 }
544
560 public OllamaResult generate(String model, String prompt, boolean raw, Options options, OllamaStreamHandler streamHandler) throws OllamaBaseException, IOException, InterruptedException {
561 OllamaGenerateRequest ollamaRequestModel = new OllamaGenerateRequest(model, prompt);
562 ollamaRequestModel.setRaw(raw);
563 ollamaRequestModel.setOptions(options.getOptionsMap());
564 return generateSyncForOllamaRequestModel(ollamaRequestModel, streamHandler);
565 }
566
581 public OllamaResult generate(String model, String prompt, boolean raw, Options options) throws OllamaBaseException, IOException, InterruptedException {
582 return generate(model, prompt, raw, options, null);
583 }
584
597 public OllamaToolsResult generateWithTools(String model, String prompt, Options options) throws OllamaBaseException, IOException, InterruptedException, ToolInvocationException {
598 boolean raw = true;
599 OllamaToolsResult toolResult = new OllamaToolsResult();
600 Map<ToolFunctionCallSpec, Object> toolResults = new HashMap<>();
601
602 OllamaResult result = generate(model, prompt, raw, options, null);
603 toolResult.setModelResult(result);
604
605 String toolsResponse = result.getResponse();
606 if (toolsResponse.contains("[TOOL_CALLS]")) {
607 toolsResponse = toolsResponse.replace("[TOOL_CALLS]", "");
608 }
609
610 List<ToolFunctionCallSpec> toolFunctionCallSpecs = Utils.getObjectMapper().readValue(toolsResponse, Utils.getObjectMapper().getTypeFactory().constructCollectionType(List.class, ToolFunctionCallSpec.class));
611 for (ToolFunctionCallSpec toolFunctionCallSpec : toolFunctionCallSpecs) {
612 toolResults.put(toolFunctionCallSpec, invokeTool(toolFunctionCallSpec));
613 }
614 toolResult.setToolResults(toolResults);
615 return toolResult;
616 }
617
627 public OllamaAsyncResultStreamer generateAsync(String model, String prompt, boolean raw) {
628 OllamaGenerateRequest ollamaRequestModel = new OllamaGenerateRequest(model, prompt);
629 ollamaRequestModel.setRaw(raw);
630 URI uri = URI.create(this.host + "/api/generate");
631 OllamaAsyncResultStreamer ollamaAsyncResultStreamer = new OllamaAsyncResultStreamer(getRequestBuilderDefault(uri), ollamaRequestModel, requestTimeoutSeconds);
632 ollamaAsyncResultStreamer.start();
633 return ollamaAsyncResultStreamer;
634 }
635
652 public OllamaResult generateWithImageFiles(String model, String prompt, List<File> imageFiles, Options options, OllamaStreamHandler streamHandler) throws OllamaBaseException, IOException, InterruptedException {
653 List<String> images = new ArrayList<>();
654 for (File imageFile : imageFiles) {
655 images.add(encodeFileToBase64(imageFile));
656 }
657 OllamaGenerateRequest ollamaRequestModel = new OllamaGenerateRequest(model, prompt, images);
658 ollamaRequestModel.setOptions(options.getOptionsMap());
659 return generateSyncForOllamaRequestModel(ollamaRequestModel, streamHandler);
660 }
661
671 public OllamaResult generateWithImageFiles(String model, String prompt, List<File> imageFiles, Options options) throws OllamaBaseException, IOException, InterruptedException {
672 return generateWithImageFiles(model, prompt, imageFiles, options, null);
673 }
674
692 public OllamaResult generateWithImageURLs(String model, String prompt, List<String> imageURLs, Options options, OllamaStreamHandler streamHandler) throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
693 List<String> images = new ArrayList<>();
694 for (String imageURL : imageURLs) {
695 images.add(encodeByteArrayToBase64(Utils.loadImageBytesFromUrl(imageURL)));
696 }
697 OllamaGenerateRequest ollamaRequestModel = new OllamaGenerateRequest(model, prompt, images);
698 ollamaRequestModel.setOptions(options.getOptionsMap());
699 return generateSyncForOllamaRequestModel(ollamaRequestModel, streamHandler);
700 }
701
712 public OllamaResult generateWithImageURLs(String model, String prompt, List<String> imageURLs, Options options) throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
713 return generateWithImageURLs(model, prompt, imageURLs, options, null);
714 }
715
730 public OllamaChatResult chat(String model, List<OllamaChatMessage> messages) throws OllamaBaseException, IOException, InterruptedException {
732 return chat(builder.withMessages(messages).build());
733 }
734
749 public OllamaChatResult chat(OllamaChatRequest request) throws OllamaBaseException, IOException, InterruptedException {
750 return chat(request, null);
751 }
752
768 public OllamaChatResult chat(OllamaChatRequest request, OllamaStreamHandler streamHandler) throws OllamaBaseException, IOException, InterruptedException {
769 OllamaChatEndpointCaller requestCaller = new OllamaChatEndpointCaller(host, basicAuth, requestTimeoutSeconds, verbose);
770 OllamaResult result;
771 if (streamHandler != null) {
772 request.setStream(true);
773 result = requestCaller.call(request, streamHandler);
774 } else {
775 result = requestCaller.callSync(request);
776 }
777 return new OllamaChatResult(result.getResponse(), result.getResponseTime(), result.getHttpStatusCode(), request.getMessages());
778 }
779
780 public void registerTool(Tools.ToolSpecification toolSpecification) {
781 toolRegistry.addFunction(toolSpecification.getFunctionName(), toolSpecification.getToolDefinition());
782 }
783
790 public OllamaChatMessageRole addCustomRole(String roleName) {
791 return OllamaChatMessageRole.newCustomRole(roleName);
792 }
793
799 public List<OllamaChatMessageRole> listRoles() {
801 }
802
810 public OllamaChatMessageRole getRole(String roleName) throws RoleNotFoundException {
811 return OllamaChatMessageRole.getRole(roleName);
812 }
813
814
815 // technical private methods //
816
817 private static String encodeFileToBase64(File file) throws IOException {
818 return Base64.getEncoder().encodeToString(Files.readAllBytes(file.toPath()));
819 }
820
821 private static String encodeByteArrayToBase64(byte[] bytes) {
822 return Base64.getEncoder().encodeToString(bytes);
823 }
824
825 private OllamaResult generateSyncForOllamaRequestModel(OllamaGenerateRequest ollamaRequestModel, OllamaStreamHandler streamHandler) throws OllamaBaseException, IOException, InterruptedException {
826 OllamaGenerateEndpointCaller requestCaller = new OllamaGenerateEndpointCaller(host, basicAuth, requestTimeoutSeconds, verbose);
827 OllamaResult result;
828 if (streamHandler != null) {
829 ollamaRequestModel.setStream(true);
830 result = requestCaller.call(ollamaRequestModel, streamHandler);
831 } else {
832 result = requestCaller.callSync(ollamaRequestModel);
833 }
834 return result;
835 }
836
843 private HttpRequest.Builder getRequestBuilderDefault(URI uri) {
844 HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(uri).header("Content-Type", "application/json").timeout(Duration.ofSeconds(requestTimeoutSeconds));
845 if (isBasicAuthCredentialsSet()) {
846 requestBuilder.header("Authorization", getBasicAuthHeaderValue());
847 }
848 return requestBuilder;
849 }
850
856 private String getBasicAuthHeaderValue() {
857 String credentialsToEncode = basicAuth.getUsername() + ":" + basicAuth.getPassword();
858 return "Basic " + Base64.getEncoder().encodeToString(credentialsToEncode.getBytes());
859 }
860
866 private boolean isBasicAuthCredentialsSet() {
867 return basicAuth != null;
868 }
869
870 private Object invokeTool(ToolFunctionCallSpec toolFunctionCallSpec) throws ToolInvocationException {
871 try {
872 String methodName = toolFunctionCallSpec.getName();
873 Map<String, Object> arguments = toolFunctionCallSpec.getArguments();
874 ToolFunction function = toolRegistry.getFunction(methodName);
875 if (verbose) {
876 logger.debug("Invoking function {} with arguments {}", methodName, arguments);
877 }
878 if (function == null) {
879 throw new ToolNotFoundException("No such tool: " + methodName);
880 }
881 return function.apply(arguments);
882 } catch (Exception e) {
883 throw new ToolInvocationException("Failed to invoke tool: " + toolFunctionCallSpec.getName(), e);
884 }
885 }
886}
OllamaResult generateWithImageFiles(String model, String prompt, List< File > imageFiles, Options options, OllamaStreamHandler streamHandler)
OllamaChatResult chat(OllamaChatRequest request)
ModelDetail getModelDetails(String modelName)
List< Double > generateEmbeddings(OllamaEmbeddingsRequestModel modelRequest)
OllamaAsyncResultStreamer generateAsync(String model, String prompt, boolean raw)
OllamaChatResult chat(String model, List< OllamaChatMessage > messages)
List< Double > generateEmbeddings(String model, String prompt)
void pullModel(String modelName)
void setBasicAuth(String username, String password)
OllamaResult generate(String model, String prompt, boolean raw, Options options, OllamaStreamHandler streamHandler)
OllamaChatResult chat(OllamaChatRequest request, OllamaStreamHandler streamHandler)
void deleteModel(String modelName, boolean ignoreIfNotPresent)
void createModelWithFilePath(String modelName, String modelFilePath)
OllamaResult generate(String model, String prompt, boolean raw, Options options)
ModelsProcessResponse ps()
LibraryModelTag findModelTagFromLibrary(String modelName, String tag)
OllamaChatMessageRole getRole(String roleName)
OllamaChatMessageRole addCustomRole(String roleName)
void pullModel(LibraryModelTag libraryModelTag)
List< OllamaChatMessageRole > listRoles()
LibraryModelDetail getLibraryModelDetails(LibraryModel libraryModel)
OllamaResult generateWithImageURLs(String model, String prompt, List< String > imageURLs, Options options, OllamaStreamHandler streamHandler)
OllamaEmbedResponseModel embed(OllamaEmbedRequestModel modelRequest)
void registerTool(Tools.ToolSpecification toolSpecification)
List< LibraryModel > listModelsFromLibrary()
OllamaToolsResult generateWithTools(String model, String prompt, Options options)
OllamaResult generateWithImageURLs(String model, String prompt, List< String > imageURLs, Options options)
OllamaEmbedResponseModel embed(String model, List< String > inputs)
void createModelWithModelFileContents(String modelName, String modelFileContents)
OllamaResult generateWithImageFiles(String model, String prompt, List< File > imageFiles, Options options)
static OllamaChatMessageRole newCustomRole(String roleName)
static OllamaChatMessageRole getRole(String roleName)
OllamaChatRequestBuilder withMessages(List< OllamaChatMessage > messages)
static OllamaChatRequestBuilder getInstance(String model)
OllamaResult call(OllamaRequestBody body, OllamaStreamHandler streamHandler)
OllamaResult call(OllamaRequestBody body, OllamaStreamHandler streamHandler)
ToolFunction getFunction(String name)
void addFunction(String name, ToolFunction function)
static byte[] loadImageBytesFromUrl(String imageUrl)
Definition Utils.java:25
static ObjectMapper getObjectMapper()
Definition Utils.java:17
Object apply(Map< String, Object > arguments)