"use client";
import { useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { formatCost, formatTokens, type QueryResponse } from "@/lib/query";
import { AnswerMarkdown } from "./AnswerMarkdown";
import { AnswerMetaFooter, StatusStrip } from "./StatusStrip";
function UsageTab({ result }: { result: QueryResponse }) {
const [open, setOpen] = useState(false);
const usage = result.usage;
if (!usage) return null;
const total = usage.total_tokens ?? (usage.prompt_tokens ?? 0) + (usage.completion_tokens ?? 0);
return (
{open && (
{[
{ label: "Prompt", value: formatTokens(usage.prompt_tokens) },
{ label: "Completion", value: formatTokens(usage.completion_tokens) },
{ label: "Total", value: formatTokens(total) },
{ label: "Est. cost", value: formatCost(usage.cost_usd) },
].map((row) => (
-
{row.label}
-
{row.value}
))}
)}
);
}
export function AnswerPanel({
result,
headingRef,
onCitationSelect,
}: {
result: QueryResponse;
headingRef: React.RefObject;
onCitationSelect: (citationId: string) => void;
}) {
const confidence = typeof result.confidence === "number" ? result.confidence : 0;
const isRefused = result.refused || result.grounding_status === "refused";
return (
<>
Generated answer
{isRefused && (
No grounded answer.
{result.refused_reason || "The available evidence was not sufficient to answer."}
)}
{!isRefused && result.generic && (
General answer.
Explained freely, with extra context beyond your document. Cited
statements still come from the document.
)}
{result.answer ? (
) : (
No answer returned.
)}
{confidence > 0 && (
Confidence
{Math.round(confidence * 100)}%
)}
>
);
}