Files
frigate/frigate/genai/openai.py
T

103 lines
3.3 KiB
Python
Raw Normal View History

2024-06-21 17:30:19 -04:00
"""OpenAI Provider for Frigate AI."""
import base64
2024-09-24 15:04:35 -05:00
import logging
2024-06-21 17:30:19 -04:00
from typing import Optional
from httpx import TimeoutException
from openai import OpenAI
from frigate.config import GenAIProviderEnum
from frigate.genai import GenAIClient, register_genai_provider
2024-09-24 15:04:35 -05:00
logger = logging.getLogger(__name__)
2024-06-21 17:30:19 -04:00
@register_genai_provider(GenAIProviderEnum.openai)
class OpenAIClient(GenAIClient):
"""Generative AI client for Frigate using OpenAI."""
provider: OpenAI
2025-10-31 12:40:31 -06:00
context_size: Optional[int] = None
2024-06-21 17:30:19 -04:00
def _init_provider(self):
"""Initialize the client."""
return OpenAI(
api_key=self.genai_config.api_key, **self.genai_config.provider_options
)
2024-06-21 17:30:19 -04:00
def _send(self, prompt: str, images: list[bytes]) -> Optional[str]:
"""Submit a request to OpenAI."""
encoded_images = [base64.b64encode(image).decode("utf-8") for image in images]
2025-03-03 11:53:24 -08:00
messages_content = []
for image in encoded_images:
messages_content.append(
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{image}",
"detail": "low",
},
}
)
messages_content.append(
{
"type": "text",
"text": prompt,
}
)
2024-06-21 17:30:19 -04:00
try:
result = self.provider.chat.completions.create(
model=self.genai_config.model,
messages=[
{
"role": "user",
2025-03-03 11:53:24 -08:00
"content": messages_content,
2024-06-21 17:30:19 -04:00
},
],
timeout=self.timeout,
)
if (
result is not None
and hasattr(result, "choices")
and len(result.choices) > 0
):
return result.choices[0].message.content.strip()
return None
except (TimeoutException, Exception) as e:
2024-09-24 15:04:35 -05:00
logger.warning("OpenAI returned an error: %s", str(e))
2024-06-21 17:30:19 -04:00
return None
2025-10-02 09:17:25 -06:00
def get_context_size(self) -> int:
"""Get the context window size for OpenAI."""
2025-10-31 12:40:31 -06:00
if self.context_size is not None:
return self.context_size
try:
models = self.provider.models.list()
for model in models.data:
if model.id == self.genai_config.model:
if hasattr(model, "max_model_len") and model.max_model_len:
self.context_size = model.max_model_len
logger.debug(
f"Retrieved context size {self.context_size} for model {self.genai_config.model}"
)
return self.context_size
except Exception as e:
logger.debug(
f"Failed to fetch model context size from API: {e}, using default"
)
# Default to 128K for ChatGPT models, 8K for others
model_name = self.genai_config.model.lower()
if "gpt" in model_name:
2025-10-31 12:40:31 -06:00
self.context_size = 128000
else:
self.context_size = 8192
logger.debug(
f"Using default context size {self.context_size} for model {self.genai_config.model}"
)
return self.context_size