import * as React from "react"; import { type ScoreSourceType, type AggregatedScoreData, } from "@langfuse/shared"; import { MessageCircleMore } from "lucide-react"; import { HoverCard, HoverCardContent, HoverCardTrigger, } from "@/src/components/ui/hover-card"; import { Tooltip, TooltipContent, TooltipTrigger, } from "@/src/components/ui/tooltip"; import { api } from "@/src/utils/api"; import { JSONView } from "@/src/components/ui/CodeJsonViewer"; import { Skeleton } from "@/src/components/ui/skeleton"; import { type BaselineDiff } from "@/src/features/datasets/lib/calculateBaselineDiff"; import { DiffLabel } from "@/src/features/datasets/components/DiffLabel"; const resolveScoreValue = (aggregate: AggregatedScoreData): string => { if (aggregate.type === "NUMERIC") { return aggregate.average.toFixed(4); } return aggregate.values.map((value: string) => value).join(", "); }; const ScoreDetailRow = ({ label, value, }: { label: string; value: React.ReactNode; }) => (
{label}
{typeof value === "string" ? ( {value} ) : ( value )}
); const ScoreValueSection = ({ aggregate, diff, }: { aggregate: AggregatedScoreData | null; diff?: BaselineDiff; }) => { return (
{aggregate ? ( <> {resolveScoreValue(aggregate)} {diff && ( value.toFixed(2)} /> )} ) : ( - )} {aggregate?.comment && (
)}
); }; export const ScoreRow = ({ projectId, name, source, aggregate, diff, }: { projectId: string; name: string; source: ScoreSourceType; aggregate: AggregatedScoreData | null; diff?: BaselineDiff; }) => { const [isHovered, setIsHovered] = React.useState(false); // ensure only loaded if user actually just hovered over the score const { data: metadata } = api.scores.getScoreMetadataById.useQuery( { projectId, id: aggregate?.id as string, }, { enabled: isHovered && Boolean(aggregate && aggregate.id && aggregate.hasMetadata), refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false, staleTime: Infinity, }, ); if (!aggregate) { return (
{name}
); } return (
{name}

{name}

{aggregate.comment && ( {aggregate.comment} } /> )} {aggregate.hasMetadata && ( {(() => { try { return metadata && Object.keys(metadata).length > 0 ? JSON.stringify(metadata) : "Loading..."; } catch { return "Invalid JSON"; } })()} {metadata && Object.keys(metadata).length > 0 ? ( ) : ( )} } /> )}
); };