AIChatDialogue

AI 对话消息流,支持多种消息类型、引用标注、选择模式与自定义渲染。

设计文档(新窗口打开)

使用场景

AIChatDialogue 组件可搭配 AIChatInput 使用,实现更丰富的、功能覆盖更全面、定制更加便捷的 AI 会话场景。 组件消息格式以 OpenAI 的 Response Object 为原型,默认支持 OpenAI 社区 Response / Chat Completion 格式标准,对 GPT-5、GPT-4o 系列模型的响应均支持开箱即用,详见消息数据转换。

代码演示

如何引入

import { AIChatDialogue } from '@chenzy-design/svelte';

基本用法

通过 chats 传入消息列表、roleConfig 配置角色元数据(名称/头像/色),onChatsChange 接收变更。

本库补充

示例额外传了 messageEditRender,让 user 消息的编辑按钮点击可用(复用 AIChatInput 编辑器)。 Semi 官方基本用法 demo 未传该 prop——未传时点击编辑,内容会直接变空白(messageEditRender 未传 返回 undefined),详见消息编辑一节的完整说明。

模式
会话布局方式
系统
系统
我
我
助手
助手

消息状态

status 支持 queued、in_progress、incomplete、completed、failed、cancelled,对应 3 种展示样式:成功(completed)、请求中(queued / in_progress / incomplete)、失败(failed / cancelled)。

我
我
助手
助手
助手
助手
请稍候...
助手
助手
请稍候...
助手
助手
请稍候...
助手
助手

消息展示

消息内容支持字符串或 ContentItem[],涵盖文本、输入图片(input_image)、输入文件(input_file)、推理过程(reasoning)、工具调用(function_call)、带引用标注(annotations)的正文、以及分步展示(steps)等类型。

助手
助手
助手
助手
get_weather { "location": "Paris, France" }
搜索北京旅游景点介绍及门票信息
正在搜索: 北京旅游景点介绍及门票信息
读取指定文件的指定行内容
正在创建文档: 北京旅游攻略
创建包含北京旅游攻略的文件
正在创建代码文件: beijing_travel_guide.html

分步展示还可以用 Semi 官方 demo 那套写法:自定义类型(如 plan)+ renderDialogueContentItem + AIChatDialogue.Step 静态子组件手动接线——renderDialogueContentItem 命中时优先于内置 steps 分支,可以完全接管任意自定义类型名。

我
我
助手
助手
搜索北京旅游景点介绍及门票信息
正在搜索: 北京旅游景点介绍及门票信息
读取指定文件的指定行内容
正在创建文档: 北京旅游攻略
创建包含北京旅游攻略的文件
正在创建代码文件: beijing_travel_guide.html

引用

通过消息的 references 字段定义当前消息引用的文件或文本,showReference 在用户消息上展示可引用图标,onReferenceClick 接收点击。

我
我
这是一段被引用的长文本,用于展示纯文本引用的裁剪与展示效果,超出两行会省略。
飞书文档.docx
Music.mp4
Image.jpeg
code.json
助手
助手

助手消息的 output_text 若带 annotations,会渲染成正文上方的来源徽标,点击触发 onAnnotationClick(回传整组,file_citation / container_file_citation 已过滤)。同一示例还演示了 escapeHtml(用户消息里的 HTML 标签原样显示)与 onMessageShare(消息 completed 时分享按钮恒渲染,点击触发该回调)。

我
我
助手
助手

选择

selecting 开启选择模式,onSelect 回传选中的消息 id 列表;可通过实例方法 selectAll / deselectAll 批量操作。

会话布局方式
是否开启选择
选择方式
我
我
助手
助手
我
我

提示

通过 hints 传入提示词,点击触发 onHintClick;hintCls / hintStyle 可定制提示区外层样式。

助手
助手

自定义渲染提示

通过 renderHintBox 自定义每个提示项的渲染。

助手
助手
写一首诗
解释一段代码
翻译成英文

自定义渲染会话框

通过 dialogueRenderConfig 分区块自定义渲染,每个区块都是 Snippet,未提供则走默认渲染:

  • renderDialogueAvatar: Snippet<[RenderAvatarProps]> —— 头像。参数:message、role、defaultAvatar(默认头像节点)。
  • renderDialogueTitle: Snippet<[RenderTitleProps]> —— 标题。参数:message、role、defaultTitle(默认标题节点)。
  • renderDialogueContent: Snippet<[RenderContentProps]> —— 内容区。参数:message、role、defaultContent(默认内容节点)、className(气泡/角色/错误态修饰类)。提供该回调后默认的气泡外层容器不再渲染——想保留气泡外观就把 className 挂在自己的容器上,不想要就完全自定义(如卡片样式)。
  • renderDialogueAction: Snippet<[RenderActionProps]> —— 操作栏。参数:message、defaultAction(默认整块操作栏节点)、className(值为 cd-ai-chat-dialogue-action,供包一层容器时复用默认显隐样式)、defaultActions(按钮节点 Snippet[],可按下标单独取用,如只渲染复制按钮:{@render defaultActions[0]()})、defaultActionsObj({ copyNode?, likeNode?, dislikeNode?, resetNode?, moreNode? },按名字单独取用;当前消息不该显示的按钮对应字段为 undefined)。
  • renderFullDialogue: Snippet<[RenderFullDialogueProps]> —— 整条会话框替换,优先级最高。参数:message、role、defaultNodes({ avatar, title, content, action } 四个默认节点集合,可自由组合复用)。
My-System
My-User
My-Assistant

自定义渲染消息内容

通过 renderDialogueContentItem 按消息块类型返回渲染映射,覆盖内置的分块渲染。渲染器签名统一是 (item: ContentItem, message: AIDialogueMessage) => Snippet,第二个参数是该块所属的完整消息,常见用法是按 message.role 分支渲染不同样式;工具调用类型(function_call / custom_tool_call / mcp_call)支持二级映射,按 item.name 精确匹配;default 键签名是 (text: string, message: AIDialogueMessage) => Snippet,仅当消息内容是纯字符串、或非字符串但 output_text 有值时生效,命中后整条消息改由它接管,不再逐块渲染。

我
我
助手
助手
调用 get_weather {"city":"Beijing"}

覆盖 reasoning 类型时,可以把 item 展开传给 AIChatDialogue.Reasoning 静态子组件,用它的 customRenderer 自定义内容区渲染(仅替换折叠面板内部,不影响头部图标/标题/箭头);customRenderer 收到组件的完整 props(含展开传入的额外字段,如消息数据里挂的 annotations)。

我
我
你好
助手
助手
你好呀,请问有什么可以帮助你的吗~
我
我
帮我生成类似的图片
助手
助手
Function Tool Call: create_travel_guide { "city": "北京" }

消息数据转换

把服务端返回的数据适配成组件消息结构后传入 chats:responseToMessage / chatCompletionToMessage 处理非流式返回;streamingResponseToMessage / streamingChatCompletionToMessage 处理流式返回,逐 chunk 增量归约。

使用 Chat Completion API 接口返回非流式数据时,可以通过 chatCompletionToMessage 函数将 Chat Completion Object 转换为 Dialogue Message 消息块格式。注意,因为 Chat Completion API 可以通过 n 来控制每条输入消息生成多少个结果,所以该函数的返回值为数组(如果 n > 1,需自行决定将哪条数据添加到 message 中展示)。

Assistant
Assistant
get_current_weather { "location": "Boston, MA" }

使用 Chat Completion API 接口返回流式数据时,可以通过 streamingChatCompletionToMessage 函数将 Chat Completion Chunk Object List 转换为 Dialogue Message 消息块格式。

使用 Response API 接口返回非流式数据时,可以通过 responseToMessage 函数将 Response Object 转换为 Dialogue Message 消息块格式。

Assistant
Assistant
get_semi_page { "pageName": "AIChatDialogue" }

使用 Response API 接口返回流式数据时,可以通过 streamingResponseToMessage 函数将 Response Chunk Object List 转换为 Dialogue Message 消息块格式。

消息编辑

本库补充

本库补充的示例,演示 messageEditRender + onMessageEdit 的编辑态(Semi 无对应文档章节)。点击 user 消息的编辑按钮后,组件内部会把该消息 editing 置为 true 并通过 onChatsChange 回写, messageEditRender 用它替代内容渲染——未传该 prop 时,内容区会直接变空白(对齐 Semi messageEditRender?.() 未传返回 undefined 的行为)。

我
我
助手
助手

API 参考

AIChatDialogue

属性说明类型默认值
align对话布局方式'leftRight' \| 'leftAlign'leftRight
chats受控对话消息列表Message[][]
class自定义类名string-
dialogueRenderConfig自定义各区块渲染DialogueRenderConfig-
disabledFileItemClick是否禁用文件点击booleanfalse
escapeHtml是否对用户消息中的 HTML 标签进行转义,防止被 Markdown 解析器当作 HTML 处理导致内容丢失booleantrue
hintCls提示区最外层样式类名string-
hintStyle提示区最外层样式string-
hints提示信息string[]-
markdownRenderProps透传给对话框渲染所用的 MarkdownRender 组件,详见 MarkdownRenderPropsobject-
messageEditRender自定义消息编辑渲染Snippet<[MessageContent]>-
mode对话模式'bubble' \| 'noBubble' \| 'userBubble'bubble
onAnnotationClickannotation 点击回调(回传整组,已过滤 file_citation)(annotations) => void-
onChatsChange对话消息列表变更回调(chats: Message[]) => void-
onFileClick附件文件点击回调(file) => void-
onHintClick点击提示词回调(hint: string) => void-
onImageClick图片点击回调(image) => void-
onMessageBadFeedback消息负向反馈回调(message: Message) => void-
onMessageCopy复制消息回调(message: Message) => void-
onMessageDelete删除消息回调(message: Message) => void-
onMessageEdit编辑消息回调(message: Message) => void-
onMessageGoodFeedback消息正向反馈回调(message: Message) => void-
onMessageReset重置消息回调(message: Message) => void-
onMessageShare分享消息回调(消息 completed 时分享按钮恒渲染,与是否传入本回调无关)(message: Message) => void-
onReferenceClick引用按钮点击回调(item: Reference) => void-
onSelect选择项变更回调(selectedIds: string[]) => void-
renderActionIconsteps 块 action 图标渲染(Semi action.icon 直接是 ReactNode 可塞组件实例;本库 icon 字段类型为 unknown,靠这层 Snippet 间接渲染)Snippet<[{ icon: unknown }]>-
renderDialogueContentItem按消息类型返回内容渲染映射Record<string, Snippet<[ContentItem]>>-
renderHintBox自定义提示项渲染Snippet<[{ content, index, onHintClick }]>-
roleConfig角色配置(user/assistant/system 等元数据)RoleConfig-
selecting是否开启选择模式booleanfalse
showReference是否在文字或者文件消息中展示可被引用图标,仅对用户消息生效booleanfalse
showReset是否展示重置操作booleantrue
style样式string-

RoleConfig

Metadata \| Map<string, Metadata>:单一元数据或按消息 name 字段查表的多角色元数据(同一 role 下按不同 name 各配头像/名称,适合多智能体场景)。

属性说明类型默认值
assistant助手信息Metadata \| Map<string, Metadata>-
system系统信息Metadata \| Map<string, Metadata>-
user用户信息Metadata \| Map<string, Metadata>-

Metadata

属性说明类型默认值
avatar头像string-
color头像背景色,同 Avatar 组件的 color 参数stringgrey
name名称string-

Message

属性说明类型默认值
content消息内容string \| ContentItem[]-
createdAt创建时间number-
editing是否处于编辑态(本库补充;受控,仅 user 消息生效,编辑态用 messageEditRender 替代内容)booleanfalse
id唯一标识string \| number-
model模型名称string-
name名称string-
output_text助手消息的输出文本直读字段(对齐 OpenAI Response Object)string-
references该消息引用的文件或文本,showReference 开启时在 user 消息展示Reference[]-
role角色string-
status消息状态,可选值为 queued、in_progress、incomplete、completed、failed、cancelledstringcompleted
updatedAt更新时间number-

Reference

属性说明类型默认值
content文本内容string-
id唯一标识string \| number-
name名称string-
type类型string-
url地址string-

Methods

绑定在组件实例上的方法,通过 bind:this 拿到实例后调用。

方法说明
deselectAll取消全选所有消息
scrollToBottom(animation: boolean)滚动到最底部,animation 为 true 则有动画,反之无动画
scrollToTop(animation: boolean)滚动到最顶部,animation 为 true 则有动画,反之无动画
selectAll全选所有消息

Static Properties

挂在 AIChatDialogue 上的静态子组件,renderDialogueContentItem 自定义渲染时可直接复用它们手动组装节点(如把自定义类型映射成 <AIChatDialogue.Step steps={steps} />)。

属性说明类型
Annotation引用来源摘要组件Component(Props:annotation / description / maxCount / onClick)
Reasoning思考过程折叠块组件Component(Props:status / summary / content / markdownRenderProps / customRenderer)
Step分步展示组件Component(Props:steps / renderActionIcon)
defaultComponents默认的 Markdown 渲染组件集合,包含增强版的 Code 组件(语言标识 + 复制按钮),可用于 markdownRenderProps.components 的二次封装{ code: Component }

ContentItem

content 为 ContentItem[] 时,逐块渲染以下类型(对齐 Semi OpenAI Response Input/Output Item,工具调用相关的多个具体类型本库合并为一个宽松的 ToolCallContentItem):

类型type 值说明
InputMessagemessage(input 侧)用户输入消息,content 为字符串或 (InputText\|InputImage\|InputFile\|InputAudio)[]
ItemReference-携带 file_id 的引用项
OutputMessagemessage(output 侧)助手输出消息,content 为 (OutputText\|Refusal)[]
Reasoningreasoning思考过程块,summary / content 均为 {text,type}[]
StepsContentItemsteps(本库自有类型,对齐 Semi AIChatDialogue.Step)分步展示,steps 为 DialogueStep[]
ToolCallContentItemfunction_call / custom_tool_call / mcp_call / 其余以 _call 结尾工具调用块,含 name / arguments / call_id,其余字段按需透传
CustomContentItem任意未知 type兜底,交由 renderDialogueContentItem 自定义渲染

设计变量

变量
默认值
用法
--cd-ai-chat-input-motion-duration var(--cd-motion-duration-fast) 描边/按钮悬浮过渡时长
显示第 1 条-第 1 条,共 1 条
  • 1