Files
UHD_Media_Tool/docs/design/agent-ui-reference.md
T
2026-09-29 22:41:47 +08:00

19 KiB
Raw Blame History

Agent UI(agentui.pro)组件库调研 → Agent 会话页参考

调研对象:https://www.agentui.pro/(shadcn 目录第三方社区 registry @agentui)。结论先说:这是一套纯前端交互参考,MIT 协议、可自由复制修改;组件本身自包含(不依赖 radix-ui/ai-sdk,registryDependencies 为空),但视觉上大量使用 Tailwind 调色板色(emerald-*/rose-*/amber-*/blue-*)与个别十六进制硬编码,与本项目 docs/design/README.md 的 token 纪律正面冲突,不能直接 shadcn add 落地,只能复制源码后逐组件替换视觉层。交互设计(状态机、折叠策略、滚动跟随阈值)成熟度高于我们目前的空白,值得原样借用。

1. 项目身份

项 内容
定位 "Copy-paste AI agent components built with Motion and Tailwind CSS."
公开仓库 https://github.com/ashish200729/agentui(经 shadcn-ui/ui PR #11607 确认,ashish200729 为提交者,LICENSE 落款人 Saurabh Chauhan,应为同一团队)
许可证 MIT(仓库根目录 LICENSE,标准 MIT 全文,保留版权声明即可商用/修改/私有项目使用,无需开源回馈)
技术栈 React ^19.0.0、Next.js 16.3.5(仅站点本身,组件不依赖 Next 特性)、Tailwind CSS ^4.0.0、TypeScript ^5.7.3、动效库 motion(Framer Motion 后继,motion/react)、代码高亮 shiki、clsx + tailwind-merge
shadcn style 未取得。仓库根目录无 components.json,registry.json 也无 style 字段;组件不引用 shadcn 的 Button/Card 等基础原语(registryDependencies: []),只假设消费方项目已有 bg-muted/text-foreground/border-border 等 shadcn 语义 CSS 变量,style 差异对能否使用没有实质影响
依赖 radix/ai-sdk 均不依赖。折叠/弹层是 motion 手写实现,不是 Radix Primitive,复制后需自查无障碍(aria)行为,不能假设 Radix 默认可访问性
安装方式 逐组件走 shadcn registry:bunx --bun shadcn add https://www.agentui.pro/r/<component>(npm/pnpm/yarn 等价);无独立可发布的 npm 包,也可直接 git clone 仓库复制 components/agents/*.tsx 源码,本项目应选后者(见第 5 节)
组件规模 18 个组件文档页(footer 分「Primitives」「Surfaces」两组),registry.json 汇总 22 个 registry item(component/lib/hook 混计,如 lib/ease.ts、message-context.tsx 各自单独登记)
未取得 LICENSE 与 PR 里的作者姓名不一致但均指向同一仓库,未进一步核实组织关系;/pricing、/license、/playground 页面均 404 或未抓取

2. 组件清单与交互语义

统一安装命令 bunx --bun shadcn add https://www.agentui.pro/r/<name>,依赖均含 clsx lucide-react motion tailwind-merge(部分另加 shiki)。

消息列表/气泡

组件 用途 关键 props 视觉要点
Message 消息行容器,按 from 控制左右布局与头像位 from: "user"|"assistant"、animateIn;子件 MessageAvatar/MessageHeader/MessageFooter/MessageTyping 7×7 圆形头像,header 时间戳 text-[11px]
MessageBubble 气泡本体 variant: solid|soft|tint|outline|ghost|danger、align、MessageBubbleCollapsible.collapsedLines(2~6 行截断) rounded-2xl px-3.5 py-2.5,max-w-[82%],长内容 line-clamp 折叠
MessageScroller 会话滚动容器(见"滚动跟随") — —

流式文本(打字/光标)

StreamingResponse:status: streaming\|complete\|error,sources(接 Citations)、showActions(复制/重试/反馈)。是"内容整段替换后平滑重排"模型,不是逐字符打字机,也没有光标闪烁效果;富文本用 [&_a]/[&_code]/[&_pre] 选择器样式化。

推理/思考折叠块

没有专门的"可展开查看完整思考记录"组件。两个近似方案:

  • Agent Activity:contentType: text\|search\|mixed\|step\|tool\|trace,时间线渐进渲染,完成后折叠为摘要"Thought for Ns"(formatDuration()),原始推理文本不保留可展开入口。
  • Loading States 里的 ReasoningText:phrases(循环短语)+ variant: cascade\|swap\|scramble,纯"正在思考"提示,无历史、无折叠。

工具调用卡片

组件 状态 折叠/耗时 备注
ToolResult running|success|error|cancelled open/defaultOpen/collapseOnComplete(完成自动折叠),meta 显示耗时/状态码,maxHeight 默认 220 ToolResultOutput 承载语法高亮的输入/输出,kind: terminal|request|custom
ToolApproval pending|approving|approved|denied|running|complete|error parameters: {id,label,value}[] 展示参数,无风险分级 三按钮:Allow once / Always allow / Deny

计划/步骤

TodoList:扁平数组 items: TodoItem[](不支持嵌套子任务),状态 pending\|in-progress\|completed\|cancelled,in-progress 可带 progress 百分比,collapseOnComplete 默认折叠,maxHeight 默认 248。

审批/确认

组件 场景 状态机 交互
ApprovalCard 通用审批 + 多步问答 pending|submitting|approved|rejected|changes-requested|answered Approve / Reject / Request Changes,或问题流的单选/多选/自由填写 + 步骤导航
ToolApproval 单个工具执行权限 见上 Allow once / Always allow / Deny

两者均没有 riskLevel/scope 字段,风险信息属于应用层自行拼进 title/description/parameters。

代码/JSON 展示

CodeBlock:shiki 高亮,language: text\|bash\|diff\|json\|tsx\|typescript,showLineNumbers(默认 true)、highlightLines、status: streaming\|complete、copyable,无折叠功能。FileDiff 是它的 diff 变体:lines: FileDiffLine[],新增行 bg-emerald-500/[0.07]、删除行 bg-rose-500/[0.07],同样支持 collapseOnComplete。

引用来源

Citations:行内角标(Citation + idPrefix 关联)+ 底部可折叠来源列表(Citations,defaultOpen 默认 false),支持网站 favicon、新增项弹簧动效。

附件/图片

ImageGeneration:状态机 queued\|generating\|refining\|complete\|error(带 onRetry),aspectRatio/resolution 固定占位避免布局跳动,悬浮有跟随鼠标的抖动叠层特效;不支持多图网格、不支持点击放大。PromptInput 的 "Attach image"/"Add context" 只是 Actions 菜单里的两个按钮项,没有真正的附件预览/管理组件。

用量与费用

UsageDashboard:records: UsageRecord[](inputTokens/outputTokens/cachedInputTokens/costUsd/requests/date/provider/model),range: 7|30 天切换,输出「按天令牌趋势折线图 + 按 provider/model 汇总 + 计费金额表」,没有预算/额度、没有进度条,图表配色是 4 组写死的十六进制 CSS 变量(--usage-first:#0e857e 等,深浅各一套)。

会话列表/分支

AISidebar:资源树(folders/projects/files/bookmarks),支持拖拽移动、内联重命名(F2/双击)、键盘导航,不支持搜索,也没有"会话分支"概念,是文件系统式的资源管理器而非对话历史列表。

输入框

PromptInput:自增高文本域 minRows=2/maxRows=8,Enter 发送、Shift+Enter 换行,loading 时按钮变"停止"(onStop),models(模型选择器)、actions(附加动作菜单)。

空态与错误态

没有独立的 EmptyState 组件。错误态分散在各组件里:StreamingResponse.status="error"、ImageGeneration.status="error"(带重试)、ToolResult.status="error"、ToolApproval.status="error";会话为空时没有专门占位方案。

滚动跟随策略

MessageScroller 精确对应需求:内部按 scrollHeight - scrollTop - clientHeight 算与底部距离,小于 followThreshold(默认 56px)才判定为"跟随中";滚轮/触摸/方向键会主动 leaveLiveEdge() 退出跟随,直到用户手动滚回底部;followOutput 开关、onFollowChange 回调、ResizeObserver 监听内容增长。这是本次调研里与我们需求匹配度最高的单个组件。

3. 与本项目的映射

我们的事件/对象(packages/contracts/src/*) agentui 对应组件 需要改造的点
run_started(agent-events.ts) 无对应"轮次开始"组件 需自建,可借 Message 起新一行 + AgentProgress 计时
text_delta StreamingResponse 该组件是整段替换模型,需要自己把增量 delta 拼接成累积字符串再喂入;无逐字符/光标效果
thinking_delta AgentActivity(contentType="text")/ReasoningText 都不满足"可展开查看完整推理文本"——AgentActivity 完成后只留"Thought for Ns"摘要,ReasoningText 无历史;需要在其骨架上新增可展开的完整文本区
tool_call_start/tool_call_end(字段 capabilityId/toolCallId/inputSummary/outputSummary/isError) ToolResult 状态映射 running→running、!isError→success、isError→error 基本可套;inputSummary/outputSummary 对应 ToolResultOutput 折叠内容,耗时对应 meta
tool_call_rejected(带 toolName/reason) ToolApproval.denied 需要改造:库里 denied 只是三按钮里的弱化态,不够醒目;需要新增一个突出的"已拒绝"卡片(destructive 材质 + 拒绝原因文案),不能照抄
compaction(phase/reason/status) 无对应组件 该库没有"上下文压缩"概念,需全新设计系统提示卡片
run_completed/run_failed(含 AgentUsageTotals、budget 超限原因) StreamingResponse.status="complete"/"error" 可复用完成态操作条,失败态需要自己接超限原因(tool_calls/duration/tokens/cost)文案
Capability scope/riskLevel/idempotent(capability.ts)、idempotencyKey(agent.ts CapabilityInvocation) ToolApproval.parameters 只有 key/value 参数列表,没有风险等级视觉(红/黄/绿)、没有幂等键/审计信息位,需要在参数区之外加风险徽章 + 审计元数据条
Approval(agent.ts ~222,status: pending|approved|rejected|revoked|expired|consumed) ApprovalCard/ToolApproval 状态集不对齐:我们多出 revoked/expired/consumed,库多出 submitting/changes-requested/answered,需要做一层状态映射并砍掉/新增对应视觉
AgentGoalReport(modelText vs buildGoalReport() 系统汇总)、UI FinalReport()(agent-conversation.tsx,"模型说的"/"系统核实的结果"双栏) 无对应组件 该库完全没有"声明 vs 核实"双轨展示,StreamingResponse 只有单一正文 + Citations;需要新写一张"系统核实结果"卡片,可能借 ToolResult 或 Citations 的折叠壳改造
AgentBudget/AgentUsage、BudgetBar()+Meter()(agent-conversation.tsx,四项:工具调用/token/时长/费用) UsageDashboard 该组件是历史用量仪表盘(按天图表 + 汇总表),没有"当前额度 vs 已用"的进度条,量级和展示逻辑都不同,预算条要另写
AgentRunMode(execute/plan_only) — AG-2 已取消运行模式;"先看方案再执行"是输入框的单次指令 /先给方案(AGUI-3,scope.proposeFirst)

4. 设计纪律冲突

对照 docs/design/README.md 的硬规则(禁原色/十六进制/调色板色/字面量字号/字面量时长/裸 rounded):

  • 调色板色(命中"禁止"规则):ApprovalCard/ToolApproval/TodoList/CodeBlock/FileDiff 大量使用 text-emerald-600、text-rose-600、text-amber-600、text-blue-600(及各自 dark: 变体)表示成功/失败/等待/进行中,直接对应我们要求的 success/destructive/warning/(进行中无专用状态色,需另议)。
  • 十六进制硬编码(命中"禁止"规则):UsageDashboard 图表配色写死 --usage-first:#0e857e 等 4 组变量,亮暗各一套。按我们规则,图表这类"只接受颜色值的地方"允许组件内常量表 + token-allow 注释,但当前写法未走语义 token,需要重新登记。
  • 字号:多用 Tailwind 语义档 text-xs/text-sm,不是字面量 text-[13px],和我们规则里"Tailwind 档继续用"部分相容,但两套字号阶梯(我们的 micro/label/meta/caption/body/control...)档位不完全对齐(如我们 caption=13px 在 Tailwind 默认档里没有对应),混用会出现两套字号语言,需要逐组件按角色替换成我们的 text-* token。
  • 圆角:rounded-md/lg/xl/2xl/full 与我们"控件/输入/卡片/面板/药丸"的角色划分基本对齐,迁移成本低;但我们另有 rounded-tight/rounded-slab 等角色名,复制后要重新按角色套。
  • 动效时长:docs/motion-patterns 文档直接写 duration: 0.22/0.18/0.12 等字面量秒数,命中"禁止 duration-N"类规则,需要批量替换成 duration-micro/base/layout 具名档。
  • 材质体系:agentui 全部是纯 shadcn 语义色平面卡片(bg-muted/bg-background/border-border),没有玻璃拟态、没有 backdrop-blur,与我们三层材质(pg-surface/pg-slab/pg-float)是完全不同的视觉语言;复制后每个容器要重新判断属于贴边/内容卡/悬浮层的哪一层并换成对应 pg-* 类,不能直接沿用 bg-muted。

改造成本估算(以复制源码后逐项替换为准):

  • 调色板色 → 语义状态色:每组件 515 处 className,18 个组件全量约 23 人日。
  • 十六进制清理(仅 UsageDashboard 4 组图表色):新增语义 token 并跑 deno task gen:tokens,约 0.5 人日。
  • 字号/圆角对齐:圆角基本零成本,字号逐组件替换约 0.5 人日。
  • 动效时长具名化:批量替换,约 0.5 人日。
  • 材质分层改造(成本最大项):需要设计判断 + 重写外层 class,尤其 ChatApp 整合布局改动最大,预估 2~4 人日(取决于选用组件数量)。
  • 全量 18 个组件改造合计约 58 人日;若只挑第 5 节列出的核心 68 个组件,约 3~4 人日。

5. 建议采用方案

优先"复制源码改 token",不建议"只借鉴交互自己写"。 理由:组件本就是自包含源码(registryDependencies: [],不依赖 Radix 基座),复制后完全在自己仓库维护,和门户现有 shadcn 组件的接入方式一致;MIT 协议允许修改与内部使用,仅需保留源码头部版权声明;MessageScroller 的跟随阈值、ToolResult/TodoList 的折叠状态机等细节比从零设计更省时间。只有个别极简组件(如 Citations 的行内角标)从零写可能比适配 motion 依赖更快,可视情况自写。

落地优先顺序(按覆盖我们 9 类事件/对象的紧迫度 + 改造成本排序):

  1. Message + MessageBubble + MessageScroller —— 会话主干,先落地,材质改造集中在气泡外壳。
  2. StreamingResponse —— 承载 text_delta,需先验证"整段替换"模型能否套我们的增量拼接。
  3. ToolResult + ToolApproval —— 覆盖 tool_call_* 与 approval 对象;tool_call_rejected 需新增比 denied 更醒目的拒绝态。
  4. TodoList —— agent.plan 步骤清单(会话页顶部;抽屉压缩为一行进度)。
  5. ApprovalCard —— 覆盖非工具类通用审批。
  6. CodeBlock/FileDiff —— 系统核实结果与 diff 类工具输出的展示载体。
  7. Citations —— 改造成本最低,可较早排期。
  8. AgentActivity/ReasoningText —— 只借鉴时间线骨架与"Thought for Ns"摘要交互,不直接复制状态机(缺"保留完整推理文本可展开"这一我们需要的能力)。
  9. UsageDashboard —— 仅作历史用量图表参考;预算条(BudgetBar/Meter)在此库能力范围之外,需独立新写。
  10. AISidebar/ChatApp —— 不支持会话分支、无搜索,只作整体布局排版参考,不建议直接采用其资源树数据模型。

6. 已采用清单(W4-F,2026-09-27)

源码取自 ashish200729/agentui@b2b752b(MIT),放在 apps/web/app/components/agentui/,每个文件头保留版权与来源, 许可证全文见同目录 LICENSE-agentui.md。统一改造:去掉 motion/shiki/Next.js 依赖(入场用 tw-animate 的 animate-in,折叠用 CSS grid-rows 过渡,全部带 motion-reduce: 关闭);调色板色 → success/warning/destructive 并配文字;字号/圆角/时长/缓动换项目 token;文案中文化。

上游组件 本项目文件 用在哪 主要改造
Message(+message-context) message.tsx 会话流的用户/Agent/系统行 新增 from="system";MessageMarker 作压缩提示;MessageTyping 用 animate-pulse
MessageBubble message-bubble.tsx 用户消息、失败/超预算/中止提示 变体换语义底色,新增 warning;去 layout 动画
MessageScroller message-scroller.tsx 会话页与侧栏抽屉的滚动区 保留跟随阈值状态机;只有"往上翻"才离开跟随;新增"回到底部"按钮;首屏回放直接跳底;log 只播报新增行
StreamingResponse streaming-response.tsx 流式文本、"模型说的"栏 新增流式光标;去点赞/点踩;来源接 CitationList
ToolResult tool-result.tsx 工具调用卡片 新增 badges(类别/scope/风险/幂等/恢复补记)与收起摘要;输入输出用 CodeBlock
ToolApproval tool-approval.tsx 拒绝态(白名单拦截 tool_call_rejected 与授权校验失败的 unauthorized) 新增 rejected 醒目态:destructive 材质 + role=alert + 原因 + 授权说明;去掉 "Always allow"
TodoList todo-list.tsx agent.plan 步骤清单(新增 skipped 态) SVG 状态图标保留,弹簧动画换 CSS;新增 error 态
ApprovalCard approval-card.tsx Approval 对象(计划、payload hash、版本、到期、风险) 状态集对齐 pending/approved/rejected/revoked/expired/consumed(+submitting);去掉问答模式;非管理员会话按钮禁用并说明
CodeBlock(+agent-code) code-block.tsx 工具输入/输出 不做语法高亮;JSON 自动缩进
FileDiff file-diff.tsx 系统核实栏的"入库目标" +/− 符号保留,底色换 success/destructive 洗层
Citations citations.tsx 系统核实栏的下载任务/整理记录链接 去 favicon;站内链接走 Link
PromptInput prompt-input.tsx 新目标与追加消息输入框 保留自增高、Enter 发送/Shift+Enter 换行/组字不发送、运行中"停止";去模型选择与动作菜单,换 toolbar 槽
AgentDisclosure disclosure.tsx 所有折叠区 motion → CSS grid-rows;收起时 inert

未采用:AgentActivity/ReasoningText(思考块自写,保留完整推理文本可展开)、UsageDashboard(预算条自写,带超限态)、 AISidebar/ChatApp(会话列表自写:状态筛选 + 目标/状态/模式/时间/用量)、ImageGeneration。

已知限制:幂等键来自审计事件(/audit-events 按 payload.agentRunId 过滤,最多翻 3 页、按同能力先后与工具调用配对), 较早的运行可能取不到;审批卡片的计划来自工具调用输入/输出里能解析到的 planId(摘要被截断时可能漏)与服务端汇报。