diff --git a/web/src/components/chat/ChatEventThumbnailsRow.tsx b/web/src/components/chat/ChatEventThumbnailsRow.tsx index bf2c5e88f..da26f8dd6 100644 --- a/web/src/components/chat/ChatEventThumbnailsRow.tsx +++ b/web/src/components/chat/ChatEventThumbnailsRow.tsx @@ -1,42 +1,73 @@ import { useApiHost } from "@/api"; +import { useTranslation } from "react-i18next"; +import { cn } from "@/lib/utils"; + +type ChatEvent = { id: string; score?: number }; type ChatEventThumbnailsRowProps = { - events: { id: string }[]; + events: ChatEvent[]; + anchor?: { id: string } | null; }; /** - * Horizontal scroll row of event thumbnail images for chat (e.g. after search_objects). - * Renders nothing when events is empty. + * Horizontal scroll row of event thumbnail images for chat. + * Optionally renders an anchor thumbnail with a "reference" badge above the + * results, and per-event similarity scores when provided. + * Renders nothing when there is nothing to show. */ export function ChatEventThumbnailsRow({ events, + anchor = null, }: ChatEventThumbnailsRowProps) { const apiHost = useApiHost(); + const { t } = useTranslation(["views/chat"]); - if (events.length === 0) return null; + if (events.length === 0 && !anchor) return null; + + const renderThumb = (event: ChatEvent, isAnchor = false) => ( + + + {typeof event.score === "number" && !isAnchor && ( + + {Math.round(event.score * 100)}% + + )} + {isAnchor && ( + + {t("anchor")} + + )} + + ); return ( -
-
-
- {events.map((event) => ( - - - - ))} +
+ {anchor && ( +
+
{renderThumb(anchor, true)}
-
+ )} + {events.length > 0 && ( +
+
+ {events.map((event) => renderThumb(event))} +
+
+ )}
); } diff --git a/web/src/pages/Chat.tsx b/web/src/pages/Chat.tsx index bd154f1a4..bab238fa1 100644 --- a/web/src/pages/Chat.tsx +++ b/web/src/pages/Chat.tsx @@ -12,6 +12,7 @@ import { ChatStartingState } from "@/components/chat/ChatStartingState"; import type { ChatMessage } from "@/types/chat"; import { getEventIdsFromSearchObjectsToolCalls, + getFindSimilarObjectsFromToolCalls, streamChatCompletion, } from "@/utils/chatUtil"; @@ -161,6 +162,17 @@ export default function ChatPage() { {msg.role === "assistant" && isComplete && (() => { + const similar = getFindSimilarObjectsFromToolCalls( + msg.toolCalls, + ); + if (similar) { + return ( + + ); + } const events = getEventIdsFromSearchObjectsToolCalls( msg.toolCalls, );