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}
{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 ? (
) : (
)}
}
/>
)}
);
};