import { Bot } from "lucide-react"; import type { LlmOpinion } from "@/lib/llmOpinion"; import { t as translate } from "@/lib/i18n"; /* * inbuxa: the language model's opinion on a message, where the server's AI * spam classification recorded one (lib/llmOpinion). * * Two rules, both from the server's spec. It is always labeled as one signal * the spam filter weighed among several, never as the reason a message was * filed where it was: the model can add a bounded amount to the score and no * more. And the explanation is the model's own output, so it is only ever * rendered as text. * * The category and confidence come from the server's configuration and aren't * translated; only the two framing strings are. */ function Verdict({ opinion }: { opinion: LlmOpinion }) { return ( <> {opinion.category} {opinion.confidence && {` ยท ${opinion.confidence}`}} ); } /** In the message details, beside the spam filter's own working. */ export function LlmOpinionDetail({ opinion }: { opinion: LlmOpinion }) { return (
{opinion.explanation &&
{opinion.explanation}
}
{translate("One of several signals the spam filter weighed")}
); } /** Above a message that's in Junk. */ export function LlmOpinionBanner({ opinion }: { opinion: LlmOpinion }) { return (
{translate("Language model's opinion")} {opinion.explanation && {opinion.explanation}} {translate("One of several signals the spam filter weighed")}
); } /** The banner shows only for a message in Junk that carries an opinion. */ export function llmBannerOpinion( opinion: LlmOpinion | null, mailboxIds: Record, junkId: string | null | undefined, ): LlmOpinion | null { return opinion && junkId && mailboxIds[junkId] ? opinion : null; }