mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-08-02 17:12:16 +03:00
Migrate object genai configuration (#19437)
* Move genAI object to objects section * Adjust config propogation behavior * Refactor genai config usage * Automatic migration * Always start the embeddings process * Always init embeddings * Config fixes * Adjust reference config * Adjust docs * Formatting * Fix
This commit is contained in:
committed by
Blake Blackshear
parent
7c1681e344
commit
1f3755e45d
@@ -28,7 +28,6 @@ from .audio import AudioConfig
|
||||
from .birdseye import BirdseyeCameraConfig
|
||||
from .detect import DetectConfig
|
||||
from .ffmpeg import CameraFfmpegConfig, CameraInput
|
||||
from .genai import GenAICameraConfig
|
||||
from .live import CameraLiveConfig
|
||||
from .motion import MotionConfig
|
||||
from .mqtt import CameraMqttConfig
|
||||
@@ -71,9 +70,6 @@ class CameraConfig(FrigateBaseModel):
|
||||
default_factory=CameraFaceRecognitionConfig, title="Face recognition config."
|
||||
)
|
||||
ffmpeg: CameraFfmpegConfig = Field(title="FFmpeg configuration for the camera.")
|
||||
genai: GenAICameraConfig = Field(
|
||||
default_factory=GenAICameraConfig, title="Generative AI configuration."
|
||||
)
|
||||
live: CameraLiveConfig = Field(
|
||||
default_factory=CameraLiveConfig, title="Live playback settings."
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
from enum import Enum
|
||||
from typing import Optional, Union
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
from pydantic import Field
|
||||
|
||||
from ..base import FrigateBaseModel
|
||||
from ..env import EnvString
|
||||
|
||||
__all__ = ["GenAIConfig", "GenAICameraConfig", "GenAIProviderEnum"]
|
||||
__all__ = ["GenAIConfig", "GenAIProviderEnum"]
|
||||
|
||||
|
||||
class GenAIProviderEnum(str, Enum):
|
||||
@@ -16,70 +16,8 @@ class GenAIProviderEnum(str, Enum):
|
||||
ollama = "ollama"
|
||||
|
||||
|
||||
class GenAISendTriggersConfig(BaseModel):
|
||||
tracked_object_end: bool = Field(
|
||||
default=True, title="Send once the object is no longer tracked."
|
||||
)
|
||||
after_significant_updates: Optional[int] = Field(
|
||||
default=None,
|
||||
title="Send an early request to generative AI when X frames accumulated.",
|
||||
ge=1,
|
||||
)
|
||||
|
||||
|
||||
# uses BaseModel because some global attributes are not available at the camera level
|
||||
class GenAICameraConfig(BaseModel):
|
||||
enabled: bool = Field(default=False, title="Enable GenAI for camera.")
|
||||
use_snapshot: bool = Field(
|
||||
default=False, title="Use snapshots for generating descriptions."
|
||||
)
|
||||
prompt: str = Field(
|
||||
default="Analyze the sequence of images containing the {label}. Focus on the likely intent or behavior of the {label} based on its actions and movement, rather than describing its appearance or the surroundings. Consider what the {label} is doing, why, and what it might do next.",
|
||||
title="Default caption prompt.",
|
||||
)
|
||||
object_prompts: dict[str, str] = Field(
|
||||
default_factory=dict, title="Object specific prompts."
|
||||
)
|
||||
|
||||
objects: Union[str, list[str]] = Field(
|
||||
default_factory=list,
|
||||
title="List of objects to run generative AI for.",
|
||||
)
|
||||
required_zones: Union[str, list[str]] = Field(
|
||||
default_factory=list,
|
||||
title="List of required zones to be entered in order to run generative AI.",
|
||||
)
|
||||
debug_save_thumbnails: bool = Field(
|
||||
default=False,
|
||||
title="Save thumbnails sent to generative AI for debugging purposes.",
|
||||
)
|
||||
send_triggers: GenAISendTriggersConfig = Field(
|
||||
default_factory=GenAISendTriggersConfig,
|
||||
title="What triggers to use to send frames to generative AI for a tracked object.",
|
||||
)
|
||||
|
||||
enabled_in_config: Optional[bool] = Field(
|
||||
default=None, title="Keep track of original state of generative AI."
|
||||
)
|
||||
|
||||
@field_validator("required_zones", mode="before")
|
||||
@classmethod
|
||||
def validate_required_zones(cls, v):
|
||||
if isinstance(v, str) and "," not in v:
|
||||
return [v]
|
||||
|
||||
return v
|
||||
|
||||
|
||||
class GenAIConfig(FrigateBaseModel):
|
||||
enabled: bool = Field(default=False, title="Enable GenAI.")
|
||||
prompt: str = Field(
|
||||
default="Analyze the sequence of images containing the {label}. Focus on the likely intent or behavior of the {label} based on its actions and movement, rather than describing its appearance or the surroundings. Consider what the {label} is doing, why, and what it might do next.",
|
||||
title="Default caption prompt.",
|
||||
)
|
||||
object_prompts: dict[str, str] = Field(
|
||||
default_factory=dict, title="Object specific prompts."
|
||||
)
|
||||
"""Primary GenAI Config to define GenAI Provider."""
|
||||
|
||||
api_key: Optional[EnvString] = Field(default=None, title="Provider API key.")
|
||||
base_url: Optional[str] = Field(default=None, title="Provider base url.")
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from typing import Any, Optional, Union
|
||||
|
||||
from pydantic import Field, PrivateAttr, field_serializer
|
||||
from pydantic import Field, PrivateAttr, field_serializer, field_validator
|
||||
|
||||
from ..base import FrigateBaseModel
|
||||
|
||||
__all__ = ["ObjectConfig", "FilterConfig"]
|
||||
__all__ = ["ObjectConfig", "GenAIObjectConfig", "FilterConfig"]
|
||||
|
||||
|
||||
DEFAULT_TRACKED_OBJECTS = ["person"]
|
||||
@@ -49,12 +49,69 @@ class FilterConfig(FrigateBaseModel):
|
||||
return None
|
||||
|
||||
|
||||
class GenAIObjectTriggerConfig(FrigateBaseModel):
|
||||
tracked_object_end: bool = Field(
|
||||
default=True, title="Send once the object is no longer tracked."
|
||||
)
|
||||
after_significant_updates: Optional[int] = Field(
|
||||
default=None,
|
||||
title="Send an early request to generative AI when X frames accumulated.",
|
||||
ge=1,
|
||||
)
|
||||
|
||||
|
||||
class GenAIObjectConfig(FrigateBaseModel):
|
||||
enabled: bool = Field(default=False, title="Enable GenAI for camera.")
|
||||
use_snapshot: bool = Field(
|
||||
default=False, title="Use snapshots for generating descriptions."
|
||||
)
|
||||
prompt: str = Field(
|
||||
default="Analyze the sequence of images containing the {label}. Focus on the likely intent or behavior of the {label} based on its actions and movement, rather than describing its appearance or the surroundings. Consider what the {label} is doing, why, and what it might do next.",
|
||||
title="Default caption prompt.",
|
||||
)
|
||||
object_prompts: dict[str, str] = Field(
|
||||
default_factory=dict, title="Object specific prompts."
|
||||
)
|
||||
|
||||
objects: Union[str, list[str]] = Field(
|
||||
default_factory=list,
|
||||
title="List of objects to run generative AI for.",
|
||||
)
|
||||
required_zones: Union[str, list[str]] = Field(
|
||||
default_factory=list,
|
||||
title="List of required zones to be entered in order to run generative AI.",
|
||||
)
|
||||
debug_save_thumbnails: bool = Field(
|
||||
default=False,
|
||||
title="Save thumbnails sent to generative AI for debugging purposes.",
|
||||
)
|
||||
send_triggers: GenAIObjectTriggerConfig = Field(
|
||||
default_factory=GenAIObjectTriggerConfig,
|
||||
title="What triggers to use to send frames to generative AI for a tracked object.",
|
||||
)
|
||||
enabled_in_config: Optional[bool] = Field(
|
||||
default=None, title="Keep track of original state of generative AI."
|
||||
)
|
||||
|
||||
@field_validator("required_zones", mode="before")
|
||||
@classmethod
|
||||
def validate_required_zones(cls, v):
|
||||
if isinstance(v, str) and "," not in v:
|
||||
return [v]
|
||||
|
||||
return v
|
||||
|
||||
|
||||
class ObjectConfig(FrigateBaseModel):
|
||||
track: list[str] = Field(default=DEFAULT_TRACKED_OBJECTS, title="Objects to track.")
|
||||
filters: dict[str, FilterConfig] = Field(
|
||||
default_factory=dict, title="Object filters."
|
||||
)
|
||||
mask: Union[str, list[str]] = Field(default="", title="Object mask.")
|
||||
genai: GenAIObjectConfig = Field(
|
||||
default_factory=GenAIObjectConfig,
|
||||
title="Config for using genai to analyze objects.",
|
||||
)
|
||||
_all_objects: list[str] = PrivateAttr()
|
||||
|
||||
@property
|
||||
|
||||
@@ -99,7 +99,7 @@ class CameraConfigUpdateSubscriber:
|
||||
elif update_type == CameraConfigUpdateEnum.enabled:
|
||||
config.enabled = updated_config
|
||||
elif update_type == CameraConfigUpdateEnum.genai:
|
||||
config.genai = updated_config
|
||||
config.objects.genai = updated_config
|
||||
elif update_type == CameraConfigUpdateEnum.motion:
|
||||
config.motion = updated_config
|
||||
elif update_type == CameraConfigUpdateEnum.notifications:
|
||||
|
||||
@@ -352,6 +352,11 @@ class FrigateConfig(FrigateBaseModel):
|
||||
default_factory=ModelConfig, title="Detection model configuration."
|
||||
)
|
||||
|
||||
# GenAI config
|
||||
genai: GenAIConfig = Field(
|
||||
default_factory=GenAIConfig, title="Generative AI configuration."
|
||||
)
|
||||
|
||||
# Camera config
|
||||
cameras: Dict[str, CameraConfig] = Field(title="Camera configuration.")
|
||||
audio: AudioConfig = Field(
|
||||
@@ -366,9 +371,6 @@ class FrigateConfig(FrigateBaseModel):
|
||||
ffmpeg: FfmpegConfig = Field(
|
||||
default_factory=FfmpegConfig, title="Global FFmpeg configuration."
|
||||
)
|
||||
genai: GenAIConfig = Field(
|
||||
default_factory=GenAIConfig, title="Generative AI configuration."
|
||||
)
|
||||
live: CameraLiveConfig = Field(
|
||||
default_factory=CameraLiveConfig, title="Live playback settings."
|
||||
)
|
||||
@@ -458,7 +460,6 @@ class FrigateConfig(FrigateBaseModel):
|
||||
"live": ...,
|
||||
"objects": ...,
|
||||
"review": ...,
|
||||
"genai": ...,
|
||||
"motion": ...,
|
||||
"notifications": ...,
|
||||
"detect": ...,
|
||||
@@ -606,7 +607,9 @@ class FrigateConfig(FrigateBaseModel):
|
||||
camera_config.review.detections.enabled_in_config = (
|
||||
camera_config.review.detections.enabled
|
||||
)
|
||||
camera_config.genai.enabled_in_config = camera_config.genai.enabled
|
||||
camera_config.objects.genai.enabled_in_config = (
|
||||
camera_config.objects.genai.enabled
|
||||
)
|
||||
|
||||
# Add default filters
|
||||
object_keys = camera_config.objects.track
|
||||
|
||||
Reference in New Issue
Block a user