Add embeddings reindex progress to the UI (#14268)

* refactor dispatcher

* add reindex to dictionary

* add circular progress bar component

* Add progress to UI when embeddings are reindexing

* readd comments to dispatcher for clarity

* Only report progress every 10 events so we don't spam the logs and websocket

* clean up
This commit is contained in:
Josh Hawkins
2024-10-10 14:28:43 -05:00
committed by GitHub
parent 8ade85edec
commit f67ec241d4
8 changed files with 397 additions and 99 deletions

View File

@@ -1,5 +1,10 @@
import { useEventUpdate, useModelState } from "@/api/ws";
import {
useEmbeddingsReindexProgress,
useEventUpdate,
useModelState,
} from "@/api/ws";
import ActivityIndicator from "@/components/indicators/activity-indicator";
import AnimatedCircularProgressBar from "@/components/ui/circular-progress-bar";
import { useApiFilterArgs } from "@/hooks/use-api-filter";
import { useTimezone } from "@/hooks/use-date-utils";
import { FrigateConfig } from "@/types/frigateConfig";
@@ -182,6 +187,18 @@ export default function Explore() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [eventUpdate]);
// embeddings reindex progress
const { payload: reindexProgress } = useEmbeddingsReindexProgress();
const embeddingsReindexing = useMemo(
() =>
reindexProgress
? reindexProgress.total_objects - reindexProgress.processed_objects > 0
: undefined,
[reindexProgress],
);
// model states
const { payload: textModelState } = useModelState(
@@ -238,59 +255,101 @@ export default function Explore() {
return (
<>
{config?.semantic_search.enabled && !allModelsLoaded ? (
{config?.semantic_search.enabled &&
(!allModelsLoaded || embeddingsReindexing) ? (
<div className="absolute inset-0 left-1/2 top-1/2 flex h-96 w-96 -translate-x-1/2 -translate-y-1/2">
<div className="flex flex-col items-center justify-center space-y-3 rounded-lg bg-background/50 p-5">
<div className="flex max-w-96 flex-col items-center justify-center space-y-3 rounded-lg bg-background/50 p-5">
<div className="my-5 flex flex-col items-center gap-2 text-xl">
<TbExclamationCircle className="mb-3 size-10" />
<div>Search Unavailable</div>
</div>
<div className="max-w-96 text-center">
Frigate is downloading the necessary embeddings models to support
semantic searching. This may take several minutes depending on the
speed of your network connection.
</div>
<div className="flex w-96 flex-col gap-2 py-5">
<div className="flex flex-row items-center justify-center gap-2">
{renderModelStateIcon(visionModelState)}
Vision model
</div>
<div className="flex flex-row items-center justify-center gap-2">
{renderModelStateIcon(visionFeatureExtractorState)}
Vision model feature extractor
</div>
<div className="flex flex-row items-center justify-center gap-2">
{renderModelStateIcon(textModelState)}
Text model
</div>
<div className="flex flex-row items-center justify-center gap-2">
{renderModelStateIcon(textTokenizerState)}
Text tokenizer
</div>
</div>
{(textModelState === "error" ||
textTokenizerState === "error" ||
visionModelState === "error" ||
visionFeatureExtractorState === "error") && (
<div className="my-3 max-w-96 text-center text-danger">
An error has occurred. Check Frigate logs.
</div>
{embeddingsReindexing && (
<>
<div className="text-center text-primary-variant">
Search can be used after tracked object embeddings have
finished reindexing.
</div>
<div className="pt-5 text-center">
<AnimatedCircularProgressBar
min={0}
max={reindexProgress.total_objects}
value={reindexProgress.processed_objects}
gaugePrimaryColor="hsl(var(--selected))"
gaugeSecondaryColor="hsl(var(--secondary))"
/>
</div>
<div className="flex w-96 flex-col gap-2 py-5">
<div className="flex flex-row items-center justify-center gap-3">
<span className="text-primary-variant">
Thumbnails embedded:
</span>
{reindexProgress.thumbnails}
</div>
<div className="flex flex-row items-center justify-center gap-3">
<span className="text-primary-variant">
Descriptions embedded:
</span>
{reindexProgress.descriptions}
</div>
<div className="flex flex-row items-center justify-center gap-3">
<span className="text-primary-variant">
Tracked objects processed:
</span>
{reindexProgress.processed_objects}
</div>
</div>
</>
)}
{!allModelsLoaded && (
<>
<div className="text-center text-primary-variant">
Frigate is downloading the necessary embeddings models to
support semantic searching. This may take several minutes
depending on the speed of your network connection.
</div>
<div className="flex w-96 flex-col gap-2 py-5">
<div className="flex flex-row items-center justify-center gap-2">
{renderModelStateIcon(visionModelState)}
Vision model
</div>
<div className="flex flex-row items-center justify-center gap-2">
{renderModelStateIcon(visionFeatureExtractorState)}
Vision model feature extractor
</div>
<div className="flex flex-row items-center justify-center gap-2">
{renderModelStateIcon(textModelState)}
Text model
</div>
<div className="flex flex-row items-center justify-center gap-2">
{renderModelStateIcon(textTokenizerState)}
Text tokenizer
</div>
</div>
{(textModelState === "error" ||
textTokenizerState === "error" ||
visionModelState === "error" ||
visionFeatureExtractorState === "error") && (
<div className="my-3 max-w-96 text-center text-danger">
An error has occurred. Check Frigate logs.
</div>
)}
<div className="text-center text-primary-variant">
You may want to reindex the embeddings of your tracked objects
once the models are downloaded.
</div>
<div className="flex items-center text-primary-variant">
<Link
to="https://docs.frigate.video/configuration/semantic_search"
target="_blank"
rel="noopener noreferrer"
className="inline"
>
Read the documentation{" "}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</>
)}
<div className="max-w-96 text-center">
You may want to reindex the embeddings of your tracked objects
once the models are downloaded.
</div>
<div className="flex max-w-96 items-center text-primary-variant">
<Link
to="https://docs.frigate.video/configuration/semantic_search"
target="_blank"
rel="noopener noreferrer"
className="inline"
>
Read the documentation{" "}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</div>
</div>
) : (