diff --git a/frigate/config/camera/review.py b/frigate/config/camera/review.py index 3cb8d2bda..51268339b 100644 --- a/frigate/config/camera/review.py +++ b/frigate/config/camera/review.py @@ -80,6 +80,10 @@ class GenAIReviewConfig(FrigateBaseModel): enabled_in_config: Optional[bool] = Field( default=None, title="Keep track of original state of generative AI." ) + preferred_language: str | None = Field( + title="Preferred language for GenAI Response", + default=None, + ) class ReviewConfig(FrigateBaseModel): diff --git a/frigate/data_processing/post/review_descriptions.py b/frigate/data_processing/post/review_descriptions.py index 19063dc9d..cc116d291 100644 --- a/frigate/data_processing/post/review_descriptions.py +++ b/frigate/data_processing/post/review_descriptions.py @@ -112,6 +112,7 @@ class ReviewDescriptionProcessor(PostProcessorApi): final_data, thumbs, camera_config.review.genai.additional_concerns, + camera_config.review.genai.preferred_language, ), ).start() @@ -162,6 +163,7 @@ def run_analysis( final_data: dict[str, str], thumbs: list[bytes], concerns: list[str], + preferred_language: str | None, ) -> None: start = datetime.datetime.now().timestamp() metadata = genai_client.generate_review_description( @@ -174,6 +176,7 @@ def run_analysis( }, thumbs, concerns, + preferred_language, ) review_inference_speed.update(datetime.datetime.now().timestamp() - start) diff --git a/frigate/genai/__init__.py b/frigate/genai/__init__.py index b883268d7..0e11e67e4 100644 --- a/frigate/genai/__init__.py +++ b/frigate/genai/__init__.py @@ -41,17 +41,23 @@ class GenAIClient: review_data: dict[str, Any], thumbnails: list[bytes], concerns: list[str], + preferred_language: str | None, ) -> ReviewMetadata | None: """Generate a description for the review item activity.""" if concerns: concern_list = "\n - ".join(concerns) - other_concerns = f""" + concern_prompt = f""" - `other_concerns` (list of strings): Include a list of any of the following concerns that are occurring: - {concern_list} """ else: - other_concerns = None + concern_prompt = "" + + if preferred_language: + language_prompt = f"Provide your answer in {preferred_language}" + else: + language_prompt = "" context_prompt = f""" Please analyze the image(s), which are in chronological order, strictly from the perspective of the {review_data["camera"].replace("_", " ")} security camera. @@ -80,10 +86,11 @@ Your response **MUST** be a flat JSON object with: - 1 = Unusual but not overtly threatening - 2 = Suspicious or potentially harmful - 3 = Clear and immediate threat -{other_concerns} +{concern_prompt} **IMPORTANT:** - Values must be plain strings, floats, or integers — no nested objects, no extra commentary. +{language_prompt} """ logger.debug( f"Sending {len(thumbnails)} images to create review description on {review_data['camera']}" diff --git a/web/src/components/overlay/detail/ReviewDetailDialog.tsx b/web/src/components/overlay/detail/ReviewDetailDialog.tsx index cfa01b4f6..70eaa5872 100644 --- a/web/src/components/overlay/detail/ReviewDetailDialog.tsx +++ b/web/src/components/overlay/detail/ReviewDetailDialog.tsx @@ -76,10 +76,6 @@ export default function ReviewDetailDialog({ const aiAnalysis = useMemo(() => review?.data?.metadata, [review]); const aiThreatLevel = useMemo(() => { - console.log( - `${aiAnalysis?.potential_threat_level} || ${aiAnalysis?.other_concerns}`, - ); - if ( !aiAnalysis || (!aiAnalysis.potential_threat_level && !aiAnalysis.other_concerns)