"use client"; import { Fragment, type ReactNode } from "react"; import { CitationChip } from "@/components/CitationChip"; import { segmentAnswer } from "@/lib/citations"; import type { CitationView } from "@/lib/api"; /** * Renders a generated answer: paragraphs, a small safe subset of inline markdown, and * citation chips. * * Everything is built as React elements — there is no `dangerouslySetInnerHTML` and no * markdown library. Model output is untrusted text that may quote a hostile document * verbatim, so the renderer is deliberately incapable of producing markup: the worst a * malicious passage can do is render as literal characters. * * The supported subset is what a grounded legal answer actually uses — bold for the * provision being named, inline code, numbered and bulleted clause lists — and nothing * more. Links are intentionally NOT rendered: the only trustworthy destination in this * product is a citation chip, which resolves through the verifier. */ const BOLD = /\*\*([^*]+)\*\*/g; const CODE = /`([^`]+)`/g; export function AnswerText({ text, citations, onOpenEvidence, }: { text: string; citations: CitationView[]; onOpenEvidence: (chunkId: string) => void; }) { const blocks = text.split(/\n{2,}/).filter((block) => block.trim().length > 0); return (
{lines.map((line, lineIndex) => (
: null}
{codeBody}
,
);
}
key += 1;
cursor = match.index + match[0].length;
match = pattern.exec(value);
}
if (cursor < value.length) nodes.push(value.slice(cursor));
return nodes;
}