diff --git a/src/any_llm/providers/ollama/ollama.py b/src/any_llm/providers/ollama/ollama.py index db313d32e..88d75a085 100644 --- a/src/any_llm/providers/ollama/ollama.py +++ b/src/any_llm/providers/ollama/ollama.py @@ -1,6 +1,6 @@ import json import os -from collections.abc import AsyncIterator, Iterator +from collections.abc import AsyncIterator, Iterator, Sequence from typing import Any try: @@ -8,6 +8,7 @@ from ollama import ChatResponse as OllamaChatResponse from any_llm.providers.ollama.utils import ( + _convert_models_list, _create_chat_completion_from_ollama_response, _create_openai_chunk_from_ollama_chunk, _create_openai_embedding_response_from_ollama, @@ -21,6 +22,7 @@ from any_llm.provider import ApiConfig, Provider from any_llm.types.completion import ChatCompletion, ChatCompletionChunk, CompletionParams, CreateEmbeddingResponse +from any_llm.types.model import Model class OllamaProvider(Provider): @@ -40,7 +42,7 @@ class OllamaProvider(Provider): SUPPORTS_RESPONSES = False SUPPORTS_COMPLETION_REASONING = True SUPPORTS_EMBEDDING = True - SUPPORTS_LIST_MODELS = False + SUPPORTS_LIST_MODELS = True PACKAGES_INSTALLED = PACKAGES_INSTALLED @@ -248,3 +250,11 @@ def embedding( **kwargs, ) return _create_openai_embedding_response_from_ollama(response) + + def list_models(self, **kwargs: Any) -> Sequence[Model]: + """ + Fetch available models from the /v1/models endpoint. + """ + client = Client(host=self.url, timeout=kwargs.pop("timeout", None)) + models_list = client.list(**kwargs) + return _convert_models_list(models_list) diff --git a/src/any_llm/providers/ollama/utils.py b/src/any_llm/providers/ollama/utils.py index dcc43a440..469d0e044 100644 --- a/src/any_llm/providers/ollama/utils.py +++ b/src/any_llm/providers/ollama/utils.py @@ -5,6 +5,7 @@ from ollama import ChatResponse as OllamaChatResponse from ollama import EmbedResponse +from ollama import ListResponse as OllamaListResponse from ollama import Message as OllamaMessage from any_llm.types.completion import ( @@ -25,6 +26,7 @@ Reasoning, Usage, ) +from any_llm.types.model import Model def _create_openai_embedding_response_from_ollama( @@ -203,3 +205,16 @@ def _create_chat_completion_from_ollama_response(response: OllamaChatResponse) - choices=[choice], usage=usage, ) + + +def _convert_models_list(models_list: OllamaListResponse) -> list[Model]: + models = models_list.models + return [ + Model( + id=model.model or "Unknown", + object="model", + created=int(model.modified_at.timestamp()) if model.modified_at else 0, + owned_by="ollama", + ) + for model in models + ]