import { useState, useRef, useEffect } from "react";
import { Send, Sparkles } from "lucide-react";
import api from "@/lib/api";
const SUGGESTIONS = [
"Why is the hallucination risk highest at step 1?",
"Did internal state at step 1 causally affect step 3?",
"Which features drift the most across the trajectory?",
"Summarize the cross-step patch matrix findings.",
];
export default function CircuitQueryBox({ runId, trajectoryReady }) {
const [msgs, setMsgs] = useState([]);
const [val, setVal] = useState("");
const [busy, setBusy] = useState(false);
const endRef = useRef(null);
useEffect(() => {
if (!runId) return;
api.listQueries(runId)
.then((d) => {
const ordered = (d.queries || []).slice().reverse();
setMsgs(
ordered.flatMap((q) => [
{ role: "user", text: q.query },
{ role: "assistant", text: q.answer },
]),
);
})
.catch(() => {});
}, [runId]);
useEffect(() => {
endRef.current?.scrollIntoView({ behavior: "smooth" });
}, [msgs.length]);
async function send(text) {
const t = (text ?? val).trim();
if (!t || !trajectoryReady) return;
setMsgs((m) => [...m, { role: "user", text: t }]);
setVal("");
setBusy(true);
try {
const res = await api.query(runId, { query: t });
setMsgs((m) => [...m, { role: "assistant", text: res.answer }]);
} catch (e) {
setMsgs((m) => [
...m,
{ role: "assistant", text: `[error: ${e.message}]` },
]);
} finally {
setBusy(false);
}
}
return (
NL circuit query
grounded in run artifacts • claude-sonnet-4-5
{msgs.length === 0 ? (
Ask any question about the trajectory. Suggestions:
{SUGGESTIONS.map((s, i) => (
))}
) : (
msgs.map((m, i) => (
{m.role === "user" ? "you" : "neuroscope"}
{m.text}
))
)}
{busy && (
thinking… (model + sae + patch context being summarized for the LLM)
)}
setVal(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && send()}
placeholder={
trajectoryReady
? "e.g. why is risk highest at step 3?"
: "trajectory still running…"
}
disabled={!trajectoryReady || busy}
className="flex-1 rounded-md border bg-transparent px-2 py-1.5 font-mono text-[12px] text-[color:var(--ns-fg-primary)] placeholder:text-[color:var(--ns-fg-faint)] focus:outline-none"
style={{ borderColor: "var(--ns-border-subtle)" }}
data-testid="nl-circuit-query-input"
/>
);
}