diff --git a/docs/docs/apis-model-management/list-library-models.md b/docs/docs/apis-model-management/list-library-models.md index b55f004..ec04efd 100644 --- a/docs/docs/apis-model-management/list-library-models.md +++ b/docs/docs/apis-model-management/list-library-models.md @@ -2,7 +2,7 @@ sidebar_position: 6 --- -# List Models from Library +# List Models from Ollama Library This API retrieves a list of models from the Ollama library. It fetches available models directly from the Ollama library page, including details such as the model's name, pull count, popular tags, tag count, and the last update time. @@ -13,7 +13,7 @@ import io.github.ollama4j.models.response.LibraryModel; import java.util.List; -public class ListModels { +public class Main { public static void main(String[] args) { @@ -32,7 +32,71 @@ The following is the sample response: ``` [ - LibraryModel(name=llama3.2-vision, description=Llama 3.2 Vision is a collection of instruction-tuned image reasoning generative models in 11B and 90B sizes., pullCount=20.6K, totalTags=9, popularTags=[vision, 11b, 90b], lastUpdated=yesterday), + LibraryModel(name=llama3.2-vision, description=Llama 3.2 Vision is a collection of instruction-tuned image reasoning generative models in 11B and 90B sizes., pullCount=21.1K, totalTags=9, popularTags=[vision, 11b, 90b], lastUpdated=yesterday), LibraryModel(name=llama3.2, description=Meta's Llama 3.2 goes small with 1B and 3B models., pullCount=2.4M, totalTags=63, popularTags=[tools, 1b, 3b], lastUpdated=6 weeks ago) ] +``` + +# Get Tags of a Library Model + +This API Fetches the tags associated with a specific model from Ollama library. + +```java title="GetLibraryModelTags.java" +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.LibraryModel; +import io.github.ollama4j.models.response.LibraryModelDetail; + +public class Main { + + public static void main(String[] args) { + + String host = "http://localhost:11434/"; + + OllamaAPI ollamaAPI = new OllamaAPI(host); + + List libraryModels = ollamaAPI.listModelsFromLibrary(); + + LibraryModelDetail libraryModelDetail = ollamaAPI.getLibraryModelDetails(libraryModels.get(0)); + + System.out.println(libraryModelDetail); + } +} +``` + +``` +LibraryModelDetail( + model=LibraryModel(name=llama3.2-vision, description=Llama 3.2 Vision is a collection of instruction-tuned image reasoning generative models in 11B and 90B sizes., pullCount=21.1K, totalTags=9, popularTags=[vision, 11b, 90b], lastUpdated=yesterday), + tags=[ + LibraryModelTag(name=llama3.2-vision, tag=latest, size=7.9GB, lastUpdated=yesterday), + LibraryModelTag(name=llama3.2-vision, tag=11b, size=7.9GB, lastUpdated=yesterday), + LibraryModelTag(name=llama3.2-vision, tag=90b, size=55GB, lastUpdated=yesterday) + ] +) +``` + +You can use this information to pull models into Ollama server. + +```java title="PullLibraryModelTags.java" +import io.github.ollama4j.OllamaAPI; +import io.github.ollama4j.models.response.LibraryModel; +import io.github.ollama4j.models.response.LibraryModelDetail; +import io.github.ollama4j.models.response.LibraryModelTag; + +public class Main { + + public static void main(String[] args) { + + String host = "http://localhost:11434/"; + + OllamaAPI ollamaAPI = new OllamaAPI(host); + + List libraryModels = ollamaAPI.listModelsFromLibrary(); + + LibraryModelDetail libraryModelDetail = ollamaAPI.getLibraryModelDetails(libraryModels.get(0)); + + LibraryModelTag libraryModelTag = libraryModelDetail.getTags().get(0); + + ollamaAPI.pullModel(libraryModelTag); + } +} ``` \ No newline at end of file diff --git a/docs/docs/apis-model-management/list-models.md b/docs/docs/apis-model-management/list-models.md index cb594ef..e55fb62 100644 --- a/docs/docs/apis-model-management/list-models.md +++ b/docs/docs/apis-model-management/list-models.md @@ -4,7 +4,7 @@ sidebar_position: 1 # List Models -This API lets you list available models on the Ollama server. +This API lets you list downloaded/available models on the Ollama server. ```java title="ListModels.java" import io.github.ollama4j.OllamaAPI; diff --git a/src/main/java/io/github/ollama4j/OllamaAPI.java b/src/main/java/io/github/ollama4j/OllamaAPI.java index f95a6f2..ea3e8b4 100644 --- a/src/main/java/io/github/ollama4j/OllamaAPI.java +++ b/src/main/java/io/github/ollama4j/OllamaAPI.java @@ -226,6 +226,67 @@ public class OllamaAPI { } } + /** + * Fetches the tags associated with a specific model from Ollama library. + * This method fetches the available model tags directly from Ollama library model page, including model tag name, size and time when model was last updated + * into a list of {@link LibraryModelTag} objects. + * + * @param libraryModel the {@link LibraryModel} object which contains the name of the library model + * for which the tags need to be fetched. + * @return a list of {@link LibraryModelTag} objects containing the extracted tags and their associated metadata. + * @throws OllamaBaseException if the HTTP response status code indicates an error (i.e., not 200 OK), + * or if there is any other issue during the request or response processing. + * @throws IOException if an input/output exception occurs during the HTTP request or response handling. + * @throws InterruptedException if the thread is interrupted while waiting for the HTTP response. + * @throws URISyntaxException if the URI format is incorrect or invalid. + */ + public LibraryModelDetail getLibraryModelDetails(LibraryModel libraryModel) throws OllamaBaseException, IOException, InterruptedException, URISyntaxException { + String url = String.format("https://ollama.com/library/%s/tags", libraryModel.getName()); + HttpClient httpClient = HttpClient.newHttpClient(); + HttpRequest httpRequest = getRequestBuilderDefault(new URI(url)).header("Accept", "application/json").header("Content-type", "application/json").GET().build(); + HttpResponse response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + int statusCode = response.statusCode(); + String responseString = response.body(); + + List libraryModelTags = new ArrayList<>(); + if (statusCode == 200) { + Document doc = Jsoup.parse(responseString); + Elements tagSections = doc.select("html > body > main > div > section > div > div > div:nth-child(n+2) > div"); + for (Element e : tagSections) { + Elements tags = e.select("div > a > div"); + Elements tagsMetas = e.select("div > span"); + + LibraryModelTag libraryModelTag = new LibraryModelTag(); + + if (tags.first() == null || tags.isEmpty()) { + // if tag cannot be extracted, skip. + continue; + } + libraryModelTag.setName(libraryModel.getName()); + Optional.ofNullable(tags.first()) + .map(Element::text) + .ifPresent(libraryModelTag::setTag); + libraryModelTag.setSize(Optional.ofNullable(tagsMetas.first()) + .map(element -> element.text().split("•")) + .filter(parts -> parts.length > 1) + .map(parts -> parts[1].trim()) + .orElse("")); + libraryModelTag.setLastUpdated(Optional.ofNullable(tagsMetas.first()) + .map(element -> element.text().split("•")) + .filter(parts -> parts.length > 1) + .map(parts -> parts[2].trim()) + .orElse("")); + libraryModelTags.add(libraryModelTag); + } + LibraryModelDetail libraryModelDetail = new LibraryModelDetail(); + libraryModelDetail.setModel(libraryModel); + libraryModelDetail.setTags(libraryModelTags); + return libraryModelDetail; + } else { + throw new OllamaBaseException(statusCode + " - " + responseString); + } + } + /** * Pull a model on the Ollama server from the list of available models. @@ -259,6 +320,23 @@ public class OllamaAPI { } } + /** + * Pulls a model using the specified Ollama library model tag. + * The model is identified by a name and a tag, which are combined into a single identifier + * in the format "name:tag" to pull the corresponding model. + * + * @param libraryModelTag the {@link LibraryModelTag} object containing the name and tag + * of the model to be pulled. + * @throws OllamaBaseException if the response indicates an error status + * @throws IOException if an I/O error occurs during the HTTP request + * @throws InterruptedException if the operation is interrupted + * @throws URISyntaxException if the URI for the request is malformed + */ + public void pullModel(LibraryModelTag libraryModelTag) throws OllamaBaseException, IOException, URISyntaxException, InterruptedException { + String tagToPull = String.format("%s:%s", libraryModelTag.getName(), libraryModelTag.getTag()); + pullModel(tagToPull); + } + /** * Gets model details from the Ollama server. * diff --git a/src/main/java/io/github/ollama4j/models/response/LibraryModelDetail.java b/src/main/java/io/github/ollama4j/models/response/LibraryModelDetail.java new file mode 100644 index 0000000..142873c --- /dev/null +++ b/src/main/java/io/github/ollama4j/models/response/LibraryModelDetail.java @@ -0,0 +1,12 @@ +package io.github.ollama4j.models.response; + +import lombok.Data; + +import java.util.List; + +@Data +public class LibraryModelDetail { + + private LibraryModel model; + private List tags; +} diff --git a/src/main/java/io/github/ollama4j/models/response/LibraryModelTag.java b/src/main/java/io/github/ollama4j/models/response/LibraryModelTag.java new file mode 100644 index 0000000..d720dd0 --- /dev/null +++ b/src/main/java/io/github/ollama4j/models/response/LibraryModelTag.java @@ -0,0 +1,13 @@ +package io.github.ollama4j.models.response; + +import lombok.Data; + +import java.util.List; + +@Data +public class LibraryModelTag { + private String name; + private String tag; + private String size; + private String lastUpdated; +}