其他
构建或定制 assistant-ui 无样式聊天 UI 时…
当需要用 @assistant-ui/react primitives 从零组装、定制或接线无样式聊天界面时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 38/100 ×0.15
适用场景
构建或定制 assistant-ui 无特定
解决思路
- 先访问 https://www.assistant-ui.com/llms.txt 获取最新 API,再按需查阅 references 下的 thread、composer、message、action-bar、part-grouping、mentions、composer-input、messages、suggestions 文档。
- 从 @assistant-ui/react 导入 AuiIf、ThreadPrimitive、ComposerPrimitive、MessagePrimitive、MessagePartPrimitive、ActionBarPrimitive、ActionBarMorePrimitive、BranchPickerPrimitive、AttachmentPrimitive、ErrorPrimitive、AssistantModalPrimitive、ChainOfThoughtPrimitive、SelectionToolbarPrimitive、SuggestionPrimitive、QueueItemPrimitive、ThreadListPrimitive、ThreadListItemPrimitive、ThreadListItemMorePrimitive。
- 按 Radix 风格组合 primitives:用 .Root 提供上下文,.PartName 子组件读取上下文;自定义元素需要继承行为时给 part 传 asChild,而不是渲染额外 wrapper。
- 使用前用 AssistantRuntimeProvider runtime={...} 包裹整棵树;若要隔离作用域,嵌套 AuiProvider extends={aui} config={AuiConfig({...})}。
- 新条件统一用 AuiIf,condition 接收完整状态 s.thread、s.message、s.composer、s.part、s.attachment;不要再用已弃用的 .If;在 JSX 外类型化条件函数用 AuiIf.Condition;注意 s.message、s.part 只在消息或 part 上下文内有值。
- 按 primitive parts 表选择正确子组件:ThreadPrimitive 用 .Root、.Viewport、.ViewportProvider、.ViewportFooter、.Messages、.MessageByIndex、.Unstable_MessageById、.ScrollToBottom、.Suggestions、.SuggestionByIndex、.Suggestion;ComposerPrimitive 用 .Root、.Input、.Send、.Cancel、.AddAttachment、.Attachments、.AttachmentByIndex、.AttachmentDropzone、.Dictate、.StopDictation、.DictationTranscript、.Quote、.QuoteText、.QuoteDismiss、.Queue 及 Unstable_TriggerPopover 系列;MessagePrimitive 用 .Root、.Parts、.PartByIndex、.GroupedParts、.Unstable_PartsGrouped、.Unstable_PartsGroupedByParentId、.Attachments、.AttachmentByIndex、.Quote、.Error、.GenerativeUI;其他 primitive 按表使用。
- 构建自定义 Thread:用 ThreadPrimitive.Root 包外层,Viewport 包滚动区,ViewportFooter 放 composer 底部;空状态用 AuiIf 判断 s.thread.isEmpty,并用 ThreadPrimitive.Suggestions 加 SuggestionPrimitive.Trigger、SuggestionPrimitive.Title 渲染欢迎建议。
- 用 ThreadPrimitive.Messages 的 render prop 按 message.role 分流:user 消息在 message.composer.isEditing 为真时渲染 EditComposer,否则渲染 UserMessage;assistant 消息渲染 AssistantMessage。
- 渲染用户消息:MessagePrimitive.Root 内用 MessagePrimitive.Quote 渲染引用;用 MessagePrimitive.Parts 按 part.type 渲染 text 到 MessagePartPrimitive.Text、image 到 MessagePartPrimitive.Image;ActionBarPrimitive.Root 设 hideWhenRunning 和 autohide=not-last,并加 ActionBarPrimitive.Edit。
- 渲染编辑 composer:在 MessagePrimitive.Root 内放 ComposerPrimitive.Root,再放 ComposerPrimitive.Input、ComposerPrimitive.Cancel、ComposerPrimitive.Send,分别处理取消和保存。
- 渲染助手消息:MessagePrimitive.Parts 的 render function 处理八类 part:text、image、file、reasoning、source、tool-call、data、generative-ui;分别用 MessagePartPrimitive.Text、MessagePartPrimitive.Image、下载链接、details、source 链接或标题、part.toolUI、part.dataRendererUI、MessagePrimitive.GenerativeUI;default 返回 null 以允许按名称注册的 tool 或 data UI 自动接管,返回空 fragment 可彻底抑制该 part。
- 为助手消息加错误 UI:在 MessagePrimitive.Error 内放 ErrorPrimitive.Root 和 ErrorPrimitive.Message。
- 使用 BranchPickerPrimitive 必须在 MessagePrimitive.Root 内;用 Root 的 hideWhenSingleBranch 避免单分支时抖动,用 Previous、Number、Count、Next 组合;Previous 和 Next 会在边界自动禁用,运行中也会禁用,除非 runtime 支持 switchBranchDuringRun;新分支由编辑重发用户消息或 ActionBarPrimitive.Reload、aui.message.reload() 产生;程序化切换用 aui.message.switchToBranch。
- 操作栏用 ActionBarPrimitive.Root 包 ActionBarPrimitive.Copy、Reload、Edit、Speak、StopSpeaking、FeedbackPositive、FeedbackNegative、ExportMarkdown;如需更多菜单用 ActionBarMorePrimitive.Root、Trigger、Content、Item、Separator;注意它需要 MessagePrimitive.Root 祖先。
- 编辑器输入用 ComposerPrimitive.Input、Send、Cancel、AddAttachment、Attachments、AttachmentByIndex、AttachmentDropzone、Dictate、StopDictation、DictationTranscript、Quote、QuoteText、QuoteDismiss、Queue 等实现无样式输入、发送或取消、附件、听写、引用和队列。
- 实现 @ mentions 和 / slash commands:用 ComposerPrimitive.Unstable_TriggerPopoverRoot、Unstable_TriggerPopover,含 Directive 和 Action、Unstable_TriggerPopoverCategories、CategoryItem、Unstable_TriggerPopoverItems、Item、Unstable_TriggerPopoverBack;需要自定义 trigger matcher 时按 references/mentions 配置。
- 使用消息部件管线:MessagePrimitive.Parts、PartByIndex、GroupedParts、Unstable_PartsGrouped、Unstable_PartsGroupedByParentId、Attachments、AttachmentByIndex、Quote、Error、GenerativeUI;MessagePartPrimitive 用 Text、Image、InProgress、Messages。
- 做 part 分组和 chain of thought:用 GroupedParts、groupPartByType;chain of thought 优先用 MessagePrimitive.GroupedParts,而不是 legacy 的 ChainOfThoughtPrimitive.Parts;不要再用 groupPartByType 的 mcp-app 键,0.15 已移除,改用 standalone-tool-call,它是超集,也匹配注册 UI 设 display: standalone 的 tool call。
- 需要消息编辑、分支、消息计时、虚拟化、滚动条、图片部件时按 references/messages 实现;需要 suggestions 时用 Suggestions([...])、suggestion adapter、ThreadPrimitive.Suggestions。
- 多线程侧边栏由 ThreadListPrimitive、ThreadListItemPrimitive、ThreadListItemMorePrimitive 驱动;完整自定义 UI、CRUD 操作、远程 adapter 走 thread-list 技能;本技能只给 parts 表。
- 处理常见 gotcha:若 primitive 不渲染或 hook 在 provider 外抛错,检查最近的 runtime context,补 AssistantRuntimeProvider 或嵌套 AuiProvider;ActionBarPrimitive、BranchPickerPrimitive、ErrorPrimitive 还需要 MessagePrimitive.Root 祖先;SelectionToolbarPrimitive 需要 ThreadPrimitive.Root 祖先且必须放在 ThreadPrimitive.Viewport 外。
- 处理无样式:primitives 渲染裸原生元素且无 class,自己加 className,或用 asChild 把行为合并到你已有的样式组件。
- 处理已移除或弃用 API:ThreadPrimitive.ViewportSlack 已移除;当 Viewport 使用 turnAnchor=top 时,顶部锚点目标注册会在 MessagePrimitive.Root 内自动发生;用 Viewport 的 topAnchorMessageClamp 替代 fillClampThreshold 和 fillClampOffset;MessagePrimitive.Content 是 .Parts 的弃用别名,ThreadPrimitive.Empty 和各 primitive 的 .If 由 AuiIf 取代,仅在未迁移代码中保留。
- 处理 Unstable_ 前缀:composer trigger popover 家族、unstable_useComposerInput、unstable_useComposerInputHistory、unstable_useThreadMessageIds 明确不稳定,可构建但升级前锁定依赖行为。
适用边界 · 注意事项
- 需要预构建 UI 时用 setup 技能,不要用 primitives 手工搭建。
- 需要带样式的 catalog 组件时用 elements 技能,不要直接使用无样式 primitives。
- 多线程侧边栏的完整自定义 UI、CRUD、远程 adapter 用 thread-list 技能;本技能只覆盖 parts 表。