KQ-1291 · ANSWER/PANEL

Answer Panel

An AI answer you can read while it is written: thoughts arrive one at a time on snap, then the answer streams token by token behind a caret, its numbered citation pills scaling in on snap where each claim is made and lifting their source card on snap when hovered or focused. When the text is done the Thinking block collapses on glide into a one-line summary, the actions and follow-ups rise in a cascade, a pressed thumb lands on recoil, and Regenerate rewinds the text on the move ease before writing again. Tab reaches every pill, thumb and follow-up; focusing a pill opens its card, Enter opens the source and Escape closes the card.

KQ-1291 · ANSWER/PANEL

Why did the 14 March payout land a day late?

  1. Reading the 14 March batch log
The answer stopped partway.

Ask next

thinking · reading the batch log

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/answer-panel

Props

question
string
default defaultQuestion
What was asked; names the panel.
answer
string
default defaultAnswer
The answer. Blank lines split paragraphs, "- " starts a bullet, and [n] cites sources[n - 1].
sources
AnswerSource[]
default defaultSources
The sources the answer can cite, in citation order: title, site, snippet, meta.
thoughts
AnswerThought[]
default defaultThoughts
The steps taken before writing, each with its duration in ms.
suggestions
string[]
default defaultSuggestions
Follow-up questions offered once the answer is done.
model
string
default "Fernworks Model 3"
The model that wrote it, printed in the action row.
status / defaultStatus
"thinking" | "streaming" | "done" | "error"
default — / "thinking"
The lifecycle. Controlled, the panel asks for the next status and waits for the host.
onStatusChange
(status: AnswerStatus) => void
default —
Fires when the panel moves on: thinking finished, text finished, or Regenerate pressed.
speed
number
default 32
Tokens per second the answer is written at; thoughts hold longer when it is slow.
citations
"pill" | "number" | "none"
default "pill"
Citation markers as numbered pills, bare superscript numbers, or not at all.
followups
"list" | "chips" | "none"
default "list"
Follow-ups as full-width rows, wrapping chips, or not at all.
feedback / defaultFeedback
"up" | "down" | null
default — / null
The visitor's rating of the answer.
onFeedbackChange
(feedback: AnswerFeedback) => void
default —
Fires from the thumb that changed it, and with null when Regenerate clears it.
onFeedbackReason
(reason: string) => void
default —
The reason picked after Not helpful.
reasons
string[]
default ["Inaccurate", "Out of date", "Missed the question", "Too long"]
Reasons offered after Not helpful.
onRegenerate
() => void
default —
Regenerate or Retry was pressed. Swap `answer` here; the old text rewinds first.
onFollowup
(text: string) => void
default —
A follow-up was chosen.
onSourceOpen
(source: AnswerSource) => void
default —
A citation or a listed source was opened.
onCopy
(text: string) => void
default —
Copy was pressed, with the plain text sent to the clipboard (markers out, sources listed after).
errorMessage
string
default "The answer stopped partway."
What the error line says.
sound
boolean
default false
Play the thumbs, the copy, the disclosure and the rewind. The stream itself is silent.
disabled
boolean
default false
Disables the actions, feedback and follow-ups; the answer still reads.
className
string
default —
Give the panel a height (h-[32rem]) and its body scrolls inside it.