Agent 会话流

New

AI agent 会话流组件族:用户消息 pill、回合头、Markdown 排版容器、思考与工具调用状态行、审批请求卡、流式输出光标、带展开动画的文件与变更产物卡、命令执行行,以及悬停显现的回合操作栏。

Read the handoff doc and prep the release.
Release prep1/4
Read handoff doc
Draft launch steps
Verify build
Stage the diff
Searching the webrelease checklist
Read backend/pom.xml
The smoke suite is green so far — pulling the checklist together and drafting the launch steps
Running ./mvnw -q verify

安装

用 shadcn CLI 添加,或手动复制源码。

$ bunx --bun shadcn add @uilab/agent-thread

API 参考

Thread

className?
string

ThreadItem

className?
string

ThreadUserMessage

className?
string

ThreadTurnHeader

open?
boolean

Controlled open state — purely a chevron-rotation signal (see below).

onOpenChange?
((next: boolean) => void)
working?
boolean

While the turn is still executing: shimmers the label. The header stays fully interactive — a running turn's live work log can be expanded and collapsed too.

false
className?
string

ThreadCollapse

open
boolean
className?
string

ThreadMessage

streaming?
boolean

Appends a blinking `ThreadStreamingCaret` after `children` while the response is still streaming in.

false
className?
string

ThreadInlineCode

className?
string

ThreadCodeBlock

label?
ReactNode

Small label in the top-right corner, e.g. a language name like "bash".

className?
string

ThreadActionBar

timestamp?
ReactNode

Rendered after the buttons, e.g. a relative send time.

className?
string

ThreadActionButton

aria-label
string
onClick?
(() => void)
className?
string

ThreadCard

className?
string

ThreadCardButton

variant?
"primary" | "ghost" | "outline"

"outline" (default) draws a hairline border; "ghost" is borderless — for a de-emphasized action beside it (e.g. "Undo" next to "Review"); "primary" is a filled emphasis button (e.g. "Approve").

outline
onClick?
(() => void)
aria-label?
string
className?
string

ThreadCommandRow

icon?
ReactNode

16px leading icon, e.g. `<SquareTerminal className="h-4 w-4" />`.

running?
boolean

Pulses the icon's opacity while the command is executing.

className?
string

ThreadDiffCard

icon?
ReactNode

20px icon rendered in a 40px rounded slot, e.g. `<SquarePen className="h-5 w-5" />`.

title
ReactNode
added?
number
removed?
number
actions?
ReactNode

Trailing slot for the caller's own controls, e.g. an "Undo" ghost button plus a "Review" outline button.

children?
ReactNode

Visible `ThreadDiffRow`s.

hiddenRows?
ReactNode

Extra `ThreadDiffRow`s revealed by the "show more" row below `children`.

moreLabel?
ReactNode

Label for the "show more" row, e.g. "Show 2 more files".

moreCount?
number

Row count represented by `hiddenRows` — the "show more" row only renders when this is greater than 0.

0
className?
string

ThreadDiffRow

path?
string

Split at the last `/` into a muted directory prefix and a bright filename. Ignored when `children` is passed.

added?
number
removed?
number
className?
string

ThreadFileCard

icon?
ReactNode

24px icon rendered in a 40px rounded slot, e.g. `<FileText className="h-6 w-6" />`.

title
ReactNode
subtitle?
ReactNode
action?
ReactNode

Trailing slot for the caller's own controls, e.g. an "Open" `ThreadCardButton`.

className?
string
children?
ReactNode

Optional content appended below the header row, extending the card body.

ThreadShimmerText

className?
string

ThreadApprovalCard

icon?
ReactNode

20px icon rendered in a 40px rounded slot, e.g. `<ShieldAlert className="h-5 w-5" />`.

title
ReactNode
description?
ReactNode

Sub-line under the title — wraps, never truncated.

command?
ReactNode

Optional mono one-liner of what will run.

status?
"pending" | "approved" | "denied"
pending
resolution?
ReactNode

Shown in place of the buttons once `status` is no longer "pending".

onApprove?
(() => void)
onDeny?
(() => void)
approveLabel?
ReactNode
Approve
denyLabel?
ReactNode
Deny
className?
string

ThreadBranchSwitcher

index
number

1-based position of the branch currently shown.

count
number
onPrev?
(() => void)
onNext?
(() => void)
className?
string

ThreadCheckpoint

label?
ReactNode
Checkpoint
timestamp?
ReactNode
onRestore?
(() => void)
restoreLabel?
ReactNode
Restore
className?
string

ThreadElicitation

icon?
ReactNode

20px icon rendered in a 40px rounded slot, e.g. `<MessageCircleQuestion className="h-5 w-5" />`.

prompt
ReactNode
options
{ value: string; label: ReactNode; description?: ReactNode; }[]
value?
string | null

Selected option value; `null`/`undefined` means still awaiting an answer.

null
onSelect?
((value: string) => void)
className?
string

ThreadErrorState

message
ReactNode
detail?
ReactNode
onRetry?
(() => void)
retryLabel?
ReactNode
Retry
className?
string

ThreadScrollPill

open
boolean
count?
number
onClick?
(() => void)
className?
string

ThreadStreamingCaret

className?
string

ThreadSuggestions

suggestions
{ value: string; label: ReactNode; }[]
onSelect?
((value: string) => void)
className?
string

ThreadSystemBanner

icon?
ReactNode
className?
string

ThreadTask

status?
"done" | "pending" | "active"
pending
className?
string

ThreadTaskList

title?
ReactNode
progress?
ReactNode

Short counter, e.g. "2/5". Swaps with a `popLayout` crossfade when it changes.

className?
string

ThreadThinking

thinking?
boolean

Still reasoning: the label shimmers, the chevron is hidden and expansion is disabled (there is no summary to show yet).

false
open?
boolean

Controlled open state for the summary region.

onOpenChange?
((next: boolean) => void)
className?
string
label
ReactNode

"Thinking…" while `thinking`, then e.g. "Thought for 8s".

children?
ReactNode

Optional reasoning summary revealed below the header once `thinking` is over.

ThreadToolCall

icon?
ReactNode

16px leading icon, e.g. `<Globe className="h-4 w-4" />`.

status?
"done" | "error" | "running" | "stopped"
done
detail?
ReactNode

Supplement after the label — e.g. a mono query or path; wrapping (such as `font-mono text-[13px]`) is the caller's choice.

elapsed?
ReactNode

Trailing elapsed-time readout.

className?
string
children?
ReactNode

The label, verb-tensed by the caller: "Searching the web" while running, "Searched the web" when done.

ThreadUsage

cost?
number
inputTokens?
number
outputTokens?
number
duration?
ReactNode
cacheHitRate?
number
className?
string

Keep in mind

Some components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.