List models supported by provider

This commit is contained in:
Nicolas Mowen 2026-04-03 15:40:48 -06:00
parent 78b22d722e
commit 9046890a37
7 changed files with 65 additions and 0 deletions

View File

@ -329,6 +329,13 @@ Guidelines:
""" """
return True return True
def list_models(self) -> list[str]:
"""Return the list of model names available from this provider.
Providers should override this to query their backend.
"""
return []
def get_context_size(self) -> int: def get_context_size(self) -> int:
"""Get the context window size for this provider in tokens.""" """Get the context window size for this provider in tokens."""
return 4096 return 4096

View File

@ -82,6 +82,14 @@ class OpenAIClient(GenAIClient):
return str(result.choices[0].message.content.strip()) return str(result.choices[0].message.content.strip())
return None return None
def list_models(self) -> list[str]:
"""Return available model IDs from Azure OpenAI."""
try:
return sorted(m.id for m in self.provider.models.list().data)
except Exception as e:
logger.warning("Failed to list Azure OpenAI models: %s", e)
return []
def get_context_size(self) -> int: def get_context_size(self) -> int:
"""Get the context window size for Azure OpenAI.""" """Get the context window size for Azure OpenAI."""
return 128000 return 128000

View File

@ -87,6 +87,14 @@ class GeminiClient(GenAIClient):
return None return None
return description return description
def list_models(self) -> list[str]:
"""Return available model names from Gemini."""
try:
return sorted(m.name for m in self.provider.models.list())
except Exception as e:
logger.warning("Failed to list Gemini models: %s", e)
return []
def get_context_size(self) -> int: def get_context_size(self) -> int:
"""Get the context window size for Gemini.""" """Get the context window size for Gemini."""
# Gemini Pro Vision has a 1M token context window # Gemini Pro Vision has a 1M token context window

View File

@ -236,6 +236,23 @@ class LlamaCppClient(GenAIClient):
"""Whether the loaded model supports tool/function calling.""" """Whether the loaded model supports tool/function calling."""
return self._supports_tools return self._supports_tools
def list_models(self) -> list[str]:
"""Return available model IDs from the llama.cpp server."""
if self.provider is None:
return []
try:
response = requests.get(f"{self.provider}/v1/models", timeout=10)
response.raise_for_status()
models = []
for m in response.json().get("data", []):
models.append(m.get("id", "unknown"))
for alias in m.get("aliases", []):
models.append(alias)
return sorted(models)
except Exception as e:
logger.warning("Failed to list llama.cpp models: %s", e)
return []
def get_context_size(self) -> int: def get_context_size(self) -> int:
"""Get the context window size for llama.cpp. """Get the context window size for llama.cpp.

View File

@ -24,6 +24,7 @@ class GenAIClientManager:
self._chat_client: Optional[GenAIClient] = None self._chat_client: Optional[GenAIClient] = None
self._description_client: Optional[GenAIClient] = None self._description_client: Optional[GenAIClient] = None
self._embeddings_client: Optional[GenAIClient] = None self._embeddings_client: Optional[GenAIClient] = None
self._clients: dict[str, "GenAIClient"] = {}
self.update_config(config) self.update_config(config)
def update_config(self, config: FrigateConfig) -> None: def update_config(self, config: FrigateConfig) -> None:
@ -38,6 +39,7 @@ class GenAIClientManager:
self._chat_client = None self._chat_client = None
self._description_client = None self._description_client = None
self._embeddings_client = None self._embeddings_client = None
self._clients = {}
if not config.genai: if not config.genai:
return return
@ -64,6 +66,8 @@ class GenAIClientManager:
) )
continue continue
self._clients[_name] = client
for role in genai_cfg.roles: for role in genai_cfg.roles:
if role == GenAIRoleEnum.chat: if role == GenAIRoleEnum.chat:
self._chat_client = client self._chat_client = client
@ -86,3 +90,7 @@ class GenAIClientManager:
def embeddings_client(self) -> "Optional[GenAIClient]": def embeddings_client(self) -> "Optional[GenAIClient]":
"""Client configured for the embeddings role.""" """Client configured for the embeddings role."""
return self._embeddings_client return self._embeddings_client
def list_models(self) -> dict[str, list[str]]:
"""Return available models keyed by config entry name."""
return {name: client.list_models() for name, client in self._clients.items()}

View File

@ -132,6 +132,15 @@ class OllamaClient(GenAIClient):
logger.warning("Ollama returned an error: %s", str(e)) logger.warning("Ollama returned an error: %s", str(e))
return None return None
def list_models(self) -> list[str]:
"""Return available model names from the Ollama server."""
try:
response = self.provider.list()
return sorted(m.get("name", m.get("model", "")) for m in response.get("models", []))
except Exception as e:
logger.warning("Failed to list Ollama models: %s", e)
return []
def get_context_size(self) -> int: def get_context_size(self) -> int:
"""Get the context window size for Ollama.""" """Get the context window size for Ollama."""
return int( return int(

View File

@ -86,6 +86,14 @@ class OpenAIClient(GenAIClient):
logger.warning("OpenAI returned an error: %s", str(e)) logger.warning("OpenAI returned an error: %s", str(e))
return None return None
def list_models(self) -> list[str]:
"""Return available model IDs from the OpenAI-compatible API."""
try:
return sorted(m.id for m in self.provider.models.list().data)
except Exception as e:
logger.warning("Failed to list OpenAI models: %s", e)
return []
def get_context_size(self) -> int: def get_context_size(self) -> int:
"""Get the context window size for OpenAI.""" """Get the context window size for OpenAI."""
if self.context_size is not None: if self.context_size is not None: