mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-15 00:11:15 +03:00
Improve model loading
This commit is contained in:
parent
8e4f2cc5f8
commit
3a79f3952e
@ -1,15 +1,15 @@
|
|||||||
"""GenAI client manager for Frigate.
|
"""GenAI client manager for Frigate.
|
||||||
|
|
||||||
Manages GenAI provider clients from Frigate config. Configuration is read only
|
Manages GenAI provider clients from Frigate config. Clients are created lazily
|
||||||
in _update_config(); no other code should read config.genai. Exposes clients
|
on first access so that providers whose roles are never used (e.g. chat when
|
||||||
by role: chat_client, description_client, embeddings_client.
|
no chat feature is active) are never initialized.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Optional
|
from typing import TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from frigate.config import FrigateConfig
|
from frigate.config import FrigateConfig
|
||||||
from frigate.config.camera.genai import GenAIRoleEnum
|
from frigate.config.camera.genai import GenAIConfig, GenAIRoleEnum
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from frigate.genai import GenAIClient
|
from frigate.genai import GenAIClient
|
||||||
@ -21,24 +21,22 @@ class GenAIClientManager:
|
|||||||
"""Manages GenAI provider clients from Frigate config."""
|
"""Manages GenAI provider clients from Frigate config."""
|
||||||
|
|
||||||
def __init__(self, config: FrigateConfig) -> None:
|
def __init__(self, config: FrigateConfig) -> None:
|
||||||
self._chat_client: Optional[GenAIClient] = None
|
self._configs: dict[str, GenAIConfig] = {}
|
||||||
self._description_client: Optional[GenAIClient] = None
|
self._role_map: dict[GenAIRoleEnum, str] = {}
|
||||||
self._embeddings_client: Optional[GenAIClient] = None
|
|
||||||
self._clients: dict[str, "GenAIClient"] = {}
|
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:
|
||||||
"""Build role clients from current Frigate config.genai.
|
"""Store provider configs and build the role→name mapping.
|
||||||
|
|
||||||
Called from __init__ and can be called again when config is reloaded.
|
Called from __init__ and can be called again when config is reloaded.
|
||||||
Each role (chat, descriptions, embeddings) gets the client for the
|
Clients are not created here; they are instantiated lazily on first
|
||||||
provider that has that role in its roles list.
|
access via a role property or list_models().
|
||||||
"""
|
"""
|
||||||
from frigate.genai import PROVIDERS, load_providers
|
from frigate.genai import PROVIDERS, load_providers
|
||||||
|
|
||||||
self._chat_client = None
|
self._configs = {}
|
||||||
self._description_client = None
|
self._role_map = {}
|
||||||
self._embeddings_client = None
|
|
||||||
self._clients = {}
|
self._clients = {}
|
||||||
|
|
||||||
if not config.genai:
|
if not config.genai:
|
||||||
@ -46,51 +44,72 @@ class GenAIClientManager:
|
|||||||
|
|
||||||
load_providers()
|
load_providers()
|
||||||
|
|
||||||
for _name, genai_cfg in config.genai.items():
|
for name, genai_cfg in config.genai.items():
|
||||||
if not genai_cfg.provider:
|
if not genai_cfg.provider:
|
||||||
continue
|
continue
|
||||||
provider_cls = PROVIDERS.get(genai_cfg.provider)
|
if genai_cfg.provider not in PROVIDERS:
|
||||||
if not provider_cls:
|
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Unknown GenAI provider %s in config, skipping.",
|
"Unknown GenAI provider %s in config, skipping.",
|
||||||
genai_cfg.provider,
|
genai_cfg.provider,
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
try:
|
|
||||||
client = provider_cls(genai_cfg)
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception(
|
|
||||||
"Failed to create GenAI client for provider %s: %s",
|
|
||||||
genai_cfg.provider,
|
|
||||||
e,
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._clients[_name] = client
|
self._configs[name] = genai_cfg
|
||||||
|
|
||||||
for role in genai_cfg.roles:
|
for role in genai_cfg.roles:
|
||||||
if role == GenAIRoleEnum.chat:
|
self._role_map[role] = name
|
||||||
self._chat_client = client
|
|
||||||
elif role == GenAIRoleEnum.descriptions:
|
def _get_client(self, name: str) -> "Optional[GenAIClient]":
|
||||||
self._description_client = client
|
"""Return the client for *name*, creating it on first access."""
|
||||||
elif role == GenAIRoleEnum.embeddings:
|
if name in self._clients:
|
||||||
self._embeddings_client = client
|
return self._clients[name]
|
||||||
|
|
||||||
|
from frigate.genai import PROVIDERS
|
||||||
|
|
||||||
|
genai_cfg = self._configs.get(name)
|
||||||
|
if not genai_cfg:
|
||||||
|
return None
|
||||||
|
|
||||||
|
provider_cls = PROVIDERS.get(genai_cfg.provider)
|
||||||
|
if not provider_cls:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
client = provider_cls(genai_cfg)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(
|
||||||
|
"Failed to create GenAI client for provider %s: %s",
|
||||||
|
genai_cfg.provider,
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
self._clients[name] = client
|
||||||
|
return client
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def chat_client(self) -> "Optional[GenAIClient]":
|
def chat_client(self) -> "Optional[GenAIClient]":
|
||||||
"""Client configured for the chat role (e.g. chat with function calling)."""
|
"""Client configured for the chat role (e.g. chat with function calling)."""
|
||||||
return self._chat_client
|
name = self._role_map.get(GenAIRoleEnum.chat)
|
||||||
|
return self._get_client(name) if name else None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def description_client(self) -> "Optional[GenAIClient]":
|
def description_client(self) -> "Optional[GenAIClient]":
|
||||||
"""Client configured for the descriptions role (e.g. review descriptions, object descriptions)."""
|
"""Client configured for the descriptions role (e.g. review descriptions, object descriptions)."""
|
||||||
return self._description_client
|
name = self._role_map.get(GenAIRoleEnum.descriptions)
|
||||||
|
return self._get_client(name) if name else None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
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
|
name = self._role_map.get(GenAIRoleEnum.embeddings)
|
||||||
|
return self._get_client(name) if name else None
|
||||||
|
|
||||||
def list_models(self) -> dict[str, list[str]]:
|
def list_models(self) -> dict[str, list[str]]:
|
||||||
"""Return available models keyed by config entry name."""
|
"""Return available models keyed by config entry name."""
|
||||||
return {name: client.list_models() for name, client in self._clients.items()}
|
result: dict[str, list[str]] = {}
|
||||||
|
for name in self._configs:
|
||||||
|
client = self._get_client(name)
|
||||||
|
if client:
|
||||||
|
result[name] = client.list_models()
|
||||||
|
return result
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { defineConfig } from "vite";
|
|||||||
import react from "@vitejs/plugin-react-swc";
|
import react from "@vitejs/plugin-react-swc";
|
||||||
import monacoEditorPlugin from "vite-plugin-monaco-editor";
|
import monacoEditorPlugin from "vite-plugin-monaco-editor";
|
||||||
|
|
||||||
const proxyHost = process.env.PROXY_HOST || "localhost:5000";
|
const proxyHost = process.env.PROXY_HOST || "192.168.50.106:5002";
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user