import { useActionState, useState } from "react"; import { compareAiDetectors } from "../api"; import type { AiDetectItem } from "../api"; import ConfidenceBars from "./ConfidenceBars"; /** * AI text detector tab. The teaching point is disagreement: one input is run * through EVERY detector at once (compareAiDetectors with no model_ids), so * users see that "is this AI?" has no single answer. Two guardrails are load * bearing here, not decoration: * - the API's own uncertainty warning is rendered verbatim and prominently, * so a probability can never read as proof of authorship; * - when detectors disagree we say so out loud and frame it as uncertainty. */ // A generic, formal, hedge-heavy paragraph — the register detectors flag most // readily — so the tab demonstrates a real verdict (and likely disagreement) // on first load without the user having to hunt for AI-ish text. const DEFAULT_TEXT = "In today's rapidly evolving digital landscape, leveraging cutting-edge solutions is " + "essential for organizations seeking to optimize operational efficiency and drive " + "sustainable, long-term growth across every facet of the enterprise."; interface DetectState { rows: AiDetectItem[]; disagreement: boolean; warning: string; error: string | null; } const EMPTY: DetectState = { rows: [], disagreement: false, warning: "", error: null }; export default function AiTextDetector() { const [text, setText] = useState(DEFAULT_TEXT); // Same form-action lifecycle as the Compare tab: submit -> pending -> result // or error, owned by useActionState (no hand-rolled loading/error state). const [state, formAction, isPending] = useActionState(async () => { try { const res = await compareAiDetectors(text); return { rows: res.results, disagreement: res.disagreement, warning: res.warning, error: null, }; } catch (e) { return { ...EMPTY, error: e instanceof Error ? e.message : "Detection failed" }; } }, EMPTY); return (
{/* Always-on educational copy. This is the app's own framing, distinct from the API warning callout that appears with results below. */}

AI detectors are probabilistic. Treat this as a model signal, not proof of authorship.

P(ai) is each detector's estimated probability that the text is AI-generated — a calibrated-ish score, never a verdict.