@blueking/chat-x 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/components/chat-content/content-render/content-render.vue.d.ts +8 -2
  2. package/dist/components/chat-content/markdown-content/markdown-content.vue.d.ts +16 -2
  3. package/dist/components/chat-message/message-render/message-render.vue.d.ts +5 -0
  4. package/dist/components/markdown-token/code-content/code-content.vue.d.ts +14 -1
  5. package/dist/composables/use-global-config.d.ts +6 -8
  6. package/dist/index.css +1 -1
  7. package/dist/index.js +1914 -1900
  8. package/dist/index.js.map +1 -1
  9. package/dist/lang/lang.d.ts +1 -4
  10. package/dist/mcp/generated/docs/activity-message.md +0 -2
  11. package/dist/mcp/generated/docs/chat-container.md +6 -5
  12. package/dist/mcp/generated/docs/code-content.md +7 -0
  13. package/dist/mcp/generated/docs/content-render.md +4 -3
  14. package/dist/mcp/generated/docs/markdown-content.md +25 -10
  15. package/dist/mcp/generated/docs/message-render.md +4 -3
  16. package/dist/mcp/generated/docs/use-global-config.md +66 -95
  17. package/dist/mcp/generated/docs/user-message.md +4 -0
  18. package/dist/mcp/generated/index.json +4 -36
  19. package/package.json +2 -2
  20. package/dist/components/chat-message/flow-message/flow-detail.vue.d.ts +0 -11
  21. package/dist/components/chat-message/flow-message/flow-message.vue.d.ts +0 -4
  22. package/dist/components/chat-message/flow-message/flow-node-group.vue.d.ts +0 -12
  23. package/dist/components/chat-message/flow-message/flow-node-item.vue.d.ts +0 -11
  24. package/dist/components/chat-message/flow-message/flow-status-icons.d.ts +0 -36
  25. package/dist/components/chat-message/flow-message/index.d.ts +0 -6
  26. package/dist/components/chat-message/flow-message/mock.d.ts +0 -13
  27. package/dist/components/chat-message/flow-message/types.d.ts +0 -132
  28. package/dist/mcp/generated/docs/flow-message.md +0 -305
@@ -43,7 +43,6 @@ export declare const lang: {
43
43
  readonly 挂起: "Pending";
44
44
  readonly 待执行: "To Be Executed";
45
45
  readonly 详情: "Details";
46
- readonly 节点详情: "Node Details";
47
46
  readonly 节点: "Node";
48
47
  readonly 节点配置: "Node Config";
49
48
  readonly 节点输出: "Node Output";
@@ -55,7 +54,6 @@ export declare const lang: {
55
54
  readonly 是否可选: "Optional";
56
55
  readonly 失败处理: "Failure Handler";
57
56
  readonly 超时控制: "Timeout Control";
58
- readonly 总是使用最新版本: "Always Use Latest Version";
59
57
  readonly 是: "Yes";
60
58
  readonly 否: "No";
61
59
  readonly 输入参数: "Input Params";
@@ -67,7 +65,6 @@ export declare const lang: {
67
65
  readonly 结构化输出: "Structured Output";
68
66
  readonly 手动跳过: "Manual Skip";
69
67
  readonly 暂无数据: "No Data";
70
- readonly '\u8282\u70B9\u8F93\u51FA\u5185\u5BB9...': "Node output content...";
71
68
  readonly '\u8C03\u7528 MCP\uFF1A': "Call MCP:";
72
69
  readonly 更多: "More";
73
70
  readonly 检索中: "Searching";
@@ -99,4 +96,4 @@ export declare const lang: {
99
96
  readonly 清空搜索: "Clear Search";
100
97
  readonly 搜索结果为空: "Search Result is Empty";
101
98
  };
102
- export declare const t: (key: keyof typeof lang) => "Send" | "Stop" | "Ask AI" | "Copy" | "Share" | "Like" | "Unsatisfied" | "Delete" | "Quote" | "Regenerate" | "Submit" | "Cancel" | "Preview Content" | "Jump to Detail" | "Call Tool:" | "Calling..." | "Call Success" | "Call Failed" | "Tell us your thoughts" | "What makes you satisfied?" | "What makes you dissatisfied?" | "Return Content" | "Edit" | "Deep Thinking" | "Loading image..." | "Failed to load image" | "Thinking..." | "Thinking Completed" | "Thinking Failed" | "Copy Success" | "Copy Failed" | "Return to bottom" | "Stop generating" | "Stopping" | "Duration" | "Parameters" | "Description" | "Execution Status" | "Running" | "Success" | "Failed" | "Pending" | "To Be Executed" | "Details" | "Node Details" | "Node" | "Node Config" | "Node Output" | "Basic Info" | "Flow Template" | "Node Name" | "Step Name" | "Execution Plan" | "Optional" | "Failure Handler" | "Timeout Control" | "Always Use Latest Version" | "Yes" | "No" | "Input Params" | "Output Params" | "Param Name" | "Param Value" | "Name" | "Structured Output" | "Manual Skip" | "No Data" | "Node output content..." | "Call MCP:" | "More" | "Searching" | "Search Completed" | "Upload File" | "Requesting..." | "Cancel satisfied" | "Cancel dissatisfied" | "Confirm delete this answer?" | "This operation cannot be undone. Please proceed with caution!" | "Preview" | "Zoom Out" | "Zoom In" | "Rotate" | "Download" | "Sorry, image loading failed. Please try reloading." | "Reset" | "Reload" | "W" | "H" | "Upload Image" | "Search keyword" | "Select date" | "Locate in Chat" | "Select All" | "Confirm" | "Upload Image, up to 3 images supported, max 2.4MB each" | "Hello, I am BlueKing AI Bot" | "Clear Search" | "Search Result is Empty" | "发送" | "停止" | "问问小鲸" | "复制" | "分享" | "点赞" | "不满意" | "删除" | "引用" | "重新生成" | "提交" | "取消" | "预览内容" | "跳转详情" | "调用工具:" | "调用中" | "调用成功" | "调用失败" | "说出您的想法" | "什么原因让你满意?" | "什么原因让你不满意?" | "返回内容" | "编辑" | "深度思考" | "图片加载中..." | "图片加载失败" | "思考中" | "已思考完成" | "思考失败" | "复制成功" | "复制失败" | "返回底部" | "停止生成" | "正在停止" | "耗时" | "参数" | "描述" | "执行情况" | "执行中" | "成功" | "失败" | "挂起" | "待执行" | "详情" | "节点详情" | "节点" | "节点配置" | "节点输出" | "基础信息" | "流程模板" | "节点名称" | "步骤名称" | "执行方案" | "是否可选" | "失败处理" | "超时控制" | "总是使用最新版本" | "是" | "否" | "输入参数" | "输出参数" | "参数名" | "参数值" | "名称" | "变量说明" | "结构化输出" | "手动跳过" | "暂无数据" | "节点输出内容..." | "调用 MCP:" | "更多" | "检索中" | "检索完成" | "上传文件" | "请求中..." | "取消满意" | "取消不满意" | "确认删除该回答?" | "删除操作无法撤回,请谨慎操作!" | "预览" | "缩小" | "放大" | "旋转" | "下载" | "抱歉,图片加载失败,可尝试重新加载" | "重置" | "重新加载" | "宽" | "高" | "上传图片" | "搜索 关键字" | "选择日期" | "在对话中定位" | "全选" | "确定" | "上传图片, 最多支持上传 3 个, 最大支持 2.4MB" | "你好,我是小鲸" | "清空搜索" | "搜索结果为空";
99
+ export declare const t: (key: keyof typeof lang) => "Send" | "Stop" | "Ask AI" | "Copy" | "Share" | "Like" | "Unsatisfied" | "Delete" | "Quote" | "Regenerate" | "Submit" | "Cancel" | "Preview Content" | "Jump to Detail" | "Call Tool:" | "Calling..." | "Call Success" | "Call Failed" | "Tell us your thoughts" | "What makes you satisfied?" | "What makes you dissatisfied?" | "Return Content" | "Edit" | "Deep Thinking" | "Loading image..." | "Failed to load image" | "Thinking..." | "Thinking Completed" | "Thinking Failed" | "Copy Success" | "Copy Failed" | "Return to bottom" | "Stop generating" | "Stopping" | "Duration" | "Parameters" | "Description" | "Execution Status" | "Running" | "Success" | "Failed" | "Pending" | "To Be Executed" | "Details" | "Node" | "Node Config" | "Node Output" | "Basic Info" | "Flow Template" | "Node Name" | "Step Name" | "Execution Plan" | "Optional" | "Failure Handler" | "Timeout Control" | "Yes" | "No" | "Input Params" | "Output Params" | "Param Name" | "Param Value" | "Name" | "Structured Output" | "Manual Skip" | "No Data" | "Call MCP:" | "More" | "Searching" | "Search Completed" | "Upload File" | "Requesting..." | "Cancel satisfied" | "Cancel dissatisfied" | "Confirm delete this answer?" | "This operation cannot be undone. Please proceed with caution!" | "Preview" | "Zoom Out" | "Zoom In" | "Rotate" | "Download" | "Sorry, image loading failed. Please try reloading." | "Reset" | "Reload" | "W" | "H" | "Upload Image" | "Search keyword" | "Select date" | "Locate in Chat" | "Select All" | "Confirm" | "Upload Image, up to 3 images supported, max 2.4MB each" | "Hello, I am BlueKing AI Bot" | "Clear Search" | "Search Result is Empty" | "发送" | "停止" | "问问小鲸" | "复制" | "分享" | "点赞" | "不满意" | "删除" | "引用" | "重新生成" | "提交" | "取消" | "预览内容" | "跳转详情" | "调用工具:" | "调用中" | "调用成功" | "调用失败" | "说出您的想法" | "什么原因让你满意?" | "什么原因让你不满意?" | "返回内容" | "编辑" | "深度思考" | "图片加载中..." | "图片加载失败" | "思考中" | "已思考完成" | "思考失败" | "复制成功" | "复制失败" | "返回底部" | "停止生成" | "正在停止" | "耗时" | "参数" | "描述" | "执行情况" | "执行中" | "成功" | "失败" | "挂起" | "待执行" | "详情" | "节点" | "节点配置" | "节点输出" | "基础信息" | "流程模板" | "节点名称" | "步骤名称" | "执行方案" | "是否可选" | "失败处理" | "超时控制" | "是" | "否" | "输入参数" | "输出参数" | "参数名" | "参数值" | "名称" | "变量说明" | "结构化输出" | "手动跳过" | "暂无数据" | "调用 MCP:" | "更多" | "检索中" | "检索完成" | "上传文件" | "请求中..." | "取消满意" | "取消不满意" | "确认删除该回答?" | "删除操作无法撤回,请谨慎操作!" | "预览" | "缩小" | "放大" | "旋转" | "下载" | "抱歉,图片加载失败,可尝试重新加载" | "重置" | "重新加载" | "宽" | "高" | "上传图片" | "搜索 关键字" | "选择日期" | "在对话中定位" | "全选" | "确定" | "上传图片, 最多支持上传 3 个, 最大支持 2.4MB" | "你好,我是小鲸" | "清空搜索" | "搜索结果为空";
@@ -5,7 +5,6 @@ ActivityMessage 展示活动类消息:知识检索(knowledge_rag)、引用
5
5
 
6
6
  ### 关联组件
7
7
  - **message-render** — 由 MessageRender 在 role 为 activity 时创建
8
- - **flow-message** — 与流程编排执行可视化同属一类场景,组件形态不同
9
8
  - **assistant-message** — 常与助手回复相邻,描述检索或执行背景
10
9
 
11
10
  ---
@@ -424,5 +423,4 @@ enum MessageContentType {
424
423
  ## 关联组件
425
424
 
426
425
  - [MessageRender](./message-render.md) — activity 角色由其实例化
427
- - [FlowMessage](./flow-message.md) — 独立流程消息与 FlowAgent 模式场景相近
428
426
  - [AssistantMessage](./assistant-message.md) — 常与助手主回复配合出现
@@ -358,11 +358,12 @@ ChatContainer 的 Props 继承自 `ChatInputProps` 和 `MessageContainerProps`
358
358
 
359
359
  ### Slots
360
360
 
361
- | 插槽名 | 参数 | 说明 |
362
- | ------- | --------------------------------- | ------------------------------------------------------------- |
363
- | default | 消息列表相关绑定(messages 等) | 自定义消息列表区域 |
364
- | message | `{ message, messageToolsStatus }` | 自定义单条消息渲染 |
365
- | welcome | `{ openingRemark: string }` | 自定义欢迎页内容,替换默认的 openingRemark 渲染,无消息时显示 |
361
+ | 插槽名 | 参数 | 说明 |
362
+ | ---------- | -------------------------------------- | ---------------------------------------------------------------------------------------------- |
363
+ | codeHeader | `{ language: string; token: Token[] }` | 代码块头部自定义操作区域,透传给 MessageRender → ContentRender → MarkdownContent → CodeContent |
364
+ | default | 消息列表相关绑定(messages 等) | 自定义消息列表区域 |
365
+ | message | `{ message, messageToolsStatus }` | 自定义单条消息渲染 |
366
+ | welcome | `{ openingRemark: string }` | 自定义欢迎页内容,替换默认的 openingRemark 渲染,无消息时显示 |
366
367
 
367
368
  ### Expose
368
369
 
@@ -21,6 +21,7 @@ CodeContent 接收 markdown-it 的 fence/code_block token,按行 highlight.js
21
21
  .code-content-wrapper(width: 100%,margin-bottom: 12px)
22
22
  ├── .code-content-header(height: 40px,bg: #2f333d,border: 1px solid #1a1a1a)
23
23
  │ ├── .code-header-language(color: #999,显示 token.info 原始字符串)
24
+ │ ├── slot#header({ language, token })— 自定义头部操作按钮区域
24
25
  │ └── ToolBtn id="copy"(点击复制 codeRef.innerText)
25
26
 
26
27
  └── .hljs-pre(bg: #282c34,padding: 8×16,overflow-x: auto)
@@ -163,6 +164,12 @@ if (lineHighlightCache.size > MAX_CACHE_SIZE) {
163
164
  | ------- | ----------------------------- | --------------------------------------------------------------------------------- |
164
165
  | mounted | `{ el: HTMLElement \| null }` | 每次 `token` 变化后 `nextTick` 完成时;`el` 为 `<code>` 元素引用(懒加载 getter) |
165
166
 
167
+ ### Slots
168
+
169
+ | 插槽名 | 参数 | 说明 |
170
+ | ------ | -------------------------------------- | ------------------------------------------------------------------------------------------ |
171
+ | header | `{ language: string; token: Token[] }` | 代码块头部自定义内容区域,渲染在语言标签和复制按钮之间,可用于添加"插入"、"应用"等操作按钮 |
172
+
166
173
  > **`mounted` 频率**:由于 `watch` 设置了 `immediate: true` 和 `deep: true`,每次 `token` 内容变化(包括初始化)都会触发 `mounted` 事件。
167
174
 
168
175
  ## Token 结构
@@ -174,9 +174,10 @@ ContentRender
174
174
 
175
175
  ### Slots
176
176
 
177
- | 插槽名 | 参数 | 说明 |
178
- | ------- | ---------------------------- | ------------------------------------------------------ |
179
- | default | `{ content: ContentMap[T] }` | 自定义渲染,接收原始 content prop 值,替换全部默认逻辑 |
177
+ | 插槽名 | 参数 | 说明 |
178
+ | ---------- | -------------------------------------- | ----------------------------------------------------------------------------- |
179
+ | codeHeader | `{ language: string; token: Token[] }` | 代码块头部自定义操作区域,透传给 MarkdownContent CodeContent 的 header 插槽 |
180
+ | default | `{ content: ContentMap[T] }` | 自定义渲染,接收原始 content prop 值,替换全部默认逻辑 |
180
181
 
181
182
  ## 流式渲染机制
182
183
 
@@ -25,11 +25,11 @@ AI 消息内容渲染的核心原子组件,集成代码高亮、LaTeX 公式
25
25
  ```
26
26
  props.content → completeMarkdownSyntax → md.parse → groupTokens → groupedTokens
27
27
 
28
- div.markdown-content(contain: layout style)
28
+ div.ai-markdown-content(contain: layout style)
29
29
 
30
30
  status === 'error' → CommonErrorContent(:content)
31
31
 
32
- else → div.markdown-body(contain: content)
32
+ else → div.markdown-body[data-theme](contain: content)
33
33
 
34
34
  v-for groupedToken
35
35
 
@@ -134,14 +134,23 @@ props.content → completeMarkdownSyntax → md.parse → groupTokens → groupe
134
134
 
135
135
  ### 流式优化机制
136
136
 
137
- | 机制 | 实现 | 作用 |
138
- | ----------------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
139
- | 极速节流 | `parseMarkdownContent` throttle **5ms**,leading + trailing | 每 5ms 最多解析一次,兼顾实时性与性能 |
140
- | Markdown 语法补全 | `completeMarkdownSyntax(content)` | 自动闭合代码块、行内代码、粗斜体、删除线、链接等未完成语法 |
141
- | LaTeX 防闪烁 | `isIncomplete=true` 且已有渲染结果 → **跳过本次更新** | 正在输入 LaTeX 命令时保持上一帧,避免闪白 |
142
- | 子组件 throttle | `handleTokenMounted` throttle 100ms | 限制子组件挂载后触发的滚动到底部频率 |
143
- | CSS contain | `.markdown-content { contain: layout style }`<br>`.markdown-body { contain: content }` | 限制重排/重绘范围,减少流式渲染的布局开销 |
144
- | 渐显动画 | 每组首 token 追加 `.ai-blueking-markdown-fade-in` | 新内容块淡入,减少视觉跳跃感 |
137
+ | 机制 | 实现 | 作用 |
138
+ | ----------------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
139
+ | 极速节流 | `parseMarkdownContent` throttle **5ms**,leading + trailing | 每 5ms 最多解析一次,兼顾实时性与性能 |
140
+ | Markdown 语法补全 | `completeMarkdownSyntax(content)` | 自动闭合代码块、行内代码、粗斜体、删除线、链接等未完成语法 |
141
+ | LaTeX 防闪烁 | `isIncomplete=true` 且已有渲染结果 → **跳过本次更新** | 正在输入 LaTeX 命令时保持上一帧,避免闪白 |
142
+ | 子组件 throttle | `handleTokenMounted` throttle 100ms | 限制子组件挂载后触发的滚动到底部频率 |
143
+ | CSS contain | `.ai-markdown-content { contain: layout style }`<br>`.markdown-body { contain: content }` | 限制重排/重绘范围,减少流式渲染的布局开销 |
144
+ | 渐显动画 | 每组首 token 追加 `.ai-blueking-markdown-fade-in` | 新内容块淡入,减少视觉跳跃感 |
145
+
146
+ ## 主题支持
147
+
148
+ 组件通过 `data-theme` 属性和内联 CSS 变量覆盖来控制主题,默认为 `light`。引入完整版 `github-markdown.css`(同时包含 light/dark 定义),并通过内联变量强制指定主题色,避免受宿主页面 `@media (prefers-color-scheme)` 影响。
149
+
150
+ - **Light 模式**(默认):`.markdown-body[data-theme="light"]`,内联 light 变量 + `color-scheme: light`
151
+ - **Dark 模式**:`.markdown-body[data-theme="dark"]`,内联 dark 变量 + `color-scheme: dark`
152
+
153
+ > 根容器类名为 `.ai-markdown-content`(而非 `.markdown-content`),以避免与 `github-markdown-css` 库自身样式冲突。
145
154
 
146
155
  ## API
147
156
 
@@ -152,6 +161,12 @@ props.content → completeMarkdownSyntax → md.parse → groupTokens → groupe
152
161
  | content | `string` | — | Markdown 文本;为空时清空渲染结果 |
153
162
  | status | `MessageStatus` | — | `'error'` 时显示 `CommonErrorContent`,其余状态均正常渲染 |
154
163
 
164
+ ### Slots
165
+
166
+ | 插槽名 | 参数 | 说明 |
167
+ | ---------- | -------------------------------------- | --------------------------------------------------------------------------------------- |
168
+ | codeHeader | `{ language: string; token: Token[] }` | 代码块头部自定义操作区域,透传给 CodeContent 的 header 插槽,可添加"插入"、"应用"等按钮 |
169
+
155
170
  ### 内置插件
156
171
 
157
172
  | 插件 | 语法 | 功能 |
@@ -272,9 +272,10 @@ slot 参数类型与 `AssistantMessage` 的 slot 保持一致(`Partial<Assista
272
272
 
273
273
  ### Slots
274
274
 
275
- | 插槽名 | 参数 | 说明 |
276
- | ------- | -------------------------------------------- | ----------------------------------------------------------------------- |
277
- | default | `{ content: string, status: MessageStatus }` | 替换 AssistantMessage 的内容区域渲染;**仅对 `role: 'assistant'` 生效** |
275
+ | 插槽名 | 参数 | 说明 |
276
+ | ---------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
277
+ | codeHeader | `{ language: string; token: Token[] }` | 代码块头部自定义操作区域,透传给 ContentRender MarkdownContent → CodeContent;**仅对 assistant 生效** |
278
+ | default | `{ content: string, status: MessageStatus }` | 替换 AssistantMessage 的内容区域渲染;**仅对 `role: 'assistant'` 生效** |
278
279
 
279
280
  ## 消息类型映射
280
281
 
@@ -1,154 +1,125 @@
1
1
  <!-- AI SUMMARY -->
2
2
  ## 快速了解
3
3
 
4
- useGlobalConfig 提供 messageSlotId('#ai-blueking-message-slot')与 rawMessageSlotId,并 provide AI_BLUEKING_MESSAGE_SLOT_ID。 useMessageSlotId 在子组件 inject 得到 ShallowRef,供 Teleport :to 挂载到消息容器内节点。名称易误解为全局配置,仅与 Teleport 插槽相关。 ChatContainer 使用 useMessageSlotId messageSlotId;FlowMessage 等用 Teleport 展示详情。
4
+ useGlobalConfig 接收 GlobalConfig(含 supportUpload: ComputedRef<boolean>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer setup 中调用 useGlobalConfig; UserMessage 等通过 injectGlobalConfig 读取 supportUpload。
5
5
 
6
6
  ### 关联组件
7
- - **chat-container** — 侧栏 messageSlotId 与自定义 Tab 内容区
8
- - **flow-message** — useMessageSlotId + Teleport 流程详情
7
+ - **chat-container** — 根容器调用 useGlobalConfig 注入 supportUpload
9
8
 
10
9
  ---
11
10
  <!-- FULL DOC -->
12
11
 
13
- # useGlobalConfig 消息面板 Teleport 插槽
12
+ # useGlobalConfig 全局配置
14
13
 
15
14
  > **分类**:composable
16
15
 
17
- 为消息容器内的子组件提供共享 **Teleport 目标 ID** 的 Provider/Consumer 工具。
18
-
19
- 根容器注册一个 `id="ai-blueking-message-slot"` 的 DOM 节点,并通过 `provide` 将其 CSS 选择器下发;子组件(如 `FlowMessage`)通过 `inject` 取到该选择器,作为 `<Teleport :to="...">` 的挂载目标,从而将详情面板等覆盖层 Teleport 到消息容器内部的指定位置,而非 `body`。
20
-
21
- > 名称"useGlobalConfig"具有一定误导性——该模块实际上**只负责管理 Teleport 插槽 ID**,不涉及任何 locale / zIndex 等通用全局配置。
16
+ 在聊天容器根组件与子组件之间通过 Vue `provide` / `inject` 共享**全局展示相关配置**(当前主要为是否支持上传 `supportUpload`)。与 Teleport 插槽 ID 无关。
22
17
 
23
18
  ## 工作原理
24
19
 
25
20
  ```
26
- 根容器组件
27
- ├── useGlobalConfig()
28
- ├── provide(AI_BLUEKING_MESSAGE_SLOT_ID, computed(() => '#ai-blueking-message-slot'))
29
- │ └── return { messageSlotId: '#ai-blueking-message-slot', rawMessageSlotId: 'ai-blueking-message-slot' }
21
+ ChatContainer(根)
22
+ ├── useGlobalConfig({ supportUpload: computed(() => props.supportUpload ?? false) })
23
+ └── provide(GLOBAL_CONFIG_TOKEN, { supportUpload })
30
24
 
31
- └── <div :id="rawMessageSlotId" /> ← Teleport 实际挂载的 DOM 节点
25
+ └── MessageContainer UserMessage
32
26
 
33
- 后代子组件(如 FlowMessage)
34
- ├── useMessageSlotId()
35
- ├── onMountedwatchEffect inject(AI_BLUEKING_MESSAGE_SLOT_ID).value
36
- └── return { messageSlotId: ShallowRef<'#ai-blueking-message-slot' | undefined> }
37
-
38
- └── <Teleport :to="messageSlotId"> ← Teleport 至根容器内
39
- <FlowDetail />
40
- </Teleport>
27
+ UserMessage(后代)
28
+ ├── injectGlobalConfig()
29
+ └── inject(GLOBAL_CONFIG_TOKEN)GlobalConfig | undefined
30
+ └── 模板中:globalConfig?.supportUpload.value ?? false
41
31
  ```
42
32
 
33
+ - **Provider**:必须在组件树的祖先(如 `ChatContainer`)的 `setup` 中调用 `useGlobalConfig`,否则后代 `injectGlobalConfig()` 得到 `undefined`。
34
+ - **Consumer**:任意后代在 `setup` 中调用 `injectGlobalConfig()`,拿到与 Provider 相同的 `GlobalConfig` 对象引用;`supportUpload` 为 `ComputedRef<boolean>`,可随根 props 响应式更新。
35
+
43
36
  ## 渲染示例
44
37
 
45
- ## 根容器用法(useGlobalConfig
38
+ ## 根容器用法(ChatContainer
46
39
 
47
40
  ```vue
48
- <template>
49
- <div class="chat-container">
50
- <!-- 1. 创建 Teleport 挂载目标 DOM 节点 -->
51
- <div
52
- :id="rawMessageSlotId"
53
- class="ai-blueking-container-slot"
54
- />
55
-
56
- <!-- 2. 消息列表(FlowMessage 等子组件从此处注入插槽 ID) -->
57
- <MessageRender :messages="messages" />
58
- </div>
59
- </template>
60
-
61
41
  <script setup lang="ts">
42
+ import { computed } from 'vue';
62
43
  import { useGlobalConfig } from '@blueking/chat-x';
63
44
 
64
- // provide 插槽 ID 给所有后代,同时获取 rawMessageSlotId 作为 DOM id
65
- const { rawMessageSlotId } = useGlobalConfig();
45
+ const props = defineProps<{
46
+ supportUpload?: boolean;
47
+ }>();
48
+
49
+ useGlobalConfig({
50
+ supportUpload: computed(() => props.supportUpload ?? false),
51
+ });
66
52
  </script>
67
53
  ```
68
54
 
69
- ## 子组件用法(useMessageSlotId
55
+ ## 子组件用法(UserMessage
70
56
 
71
57
  ```vue
72
- <!-- FlowMessage 内部(简化) -->
73
- <template>
74
- <div class="flow-message">
75
- <!-- 节点列表... -->
76
-
77
- <!-- 点击节点后,将详情面板 Teleport 到根容器的插槽节点 -->
78
- <template v-if="detailVisible && messageSlotId">
79
- <Teleport :to="messageSlotId">
80
- <FlowDetail
81
- :node="selectedNode"
82
- @close="detailVisible = false"
83
- />
84
- </Teleport>
85
- </template>
86
- </div>
87
- </template>
88
-
89
58
  <script setup lang="ts">
90
- import { useMessageSlotId } from '@blueking/chat-x';
59
+ import { injectGlobalConfig } from '@blueking/chat-x';
91
60
 
92
- // 注入根容器提供的 CSS 选择器('#ai-blueking-message-slot')
93
- const { messageSlotId } = useMessageSlotId();
61
+ const globalConfig = injectGlobalConfig();
94
62
  </script>
63
+
64
+ <template>
65
+ <ChatInput :support-upload="globalConfig?.supportUpload.value ?? false" />
66
+ </template>
95
67
  ```
96
68
 
97
69
  ## API
98
70
 
99
- ### useGlobalConfig()
71
+ ### 类型与函数签名(摘要)
100
72
 
101
73
  ```typescript
102
- function useGlobalConfig(): {
103
- messageSlotId: ComputedRef<string>; // '#ai-blueking-message-slot'(CSS 选择器)
104
- readonly rawMessageSlotId: string; // 'ai-blueking-message-slot'(DOM id 属性值)
105
- };
106
- ```
74
+ import type { ComputedRef } from 'vue';
107
75
 
108
- - 调用后立即 `provide(AI_BLUEKING_MESSAGE_SLOT_ID, messageSlotId)` 向后代注入
109
- - 必须在 Vue 组件的 `setup()` 中调用(有组件上下文才能 `provide`)
76
+ export const GLOBAL_CONFIG_TOKEN: unique symbol;
110
77
 
111
- ### useMessageSlotId()
78
+ export type GlobalConfig = {
79
+ supportUpload: ComputedRef<boolean>;
80
+ };
112
81
 
113
- ```typescript
114
- function useMessageSlotId(): {
115
- messageSlotId: ShallowRef<string | undefined>;
116
- // 初始值:undefined(onMounted 前)
117
- // 挂载后:'#ai-blueking-message-slot'(由 inject 注入)
82
+ export function useGlobalConfig(options: GlobalConfig): {
83
+ supportUpload: ComputedRef<boolean>;
118
84
  };
85
+
86
+ export function injectGlobalConfig(): GlobalConfig | undefined;
119
87
  ```
120
88
 
121
- - `onMounted` 后通过 `watchEffect` + `inject` 填充 `messageSlotId.value`
122
- - 无父级 Provider 时 `inject` 返回 `undefined`,`messageSlotId.value` 保持 `undefined`
123
- - 使用前建议配合 `v-if="messageSlotId"` 防止 Teleport 找不到目标
89
+ ### `GLOBAL_CONFIG_TOKEN`
124
90
 
125
- ### getMessageSlotId()(内部辅助)
91
+ | 名称 | 说明 |
92
+ | --------------------- | -------------------------------------- |
93
+ | `GLOBAL_CONFIG_TOKEN` | `provide` / `inject` 使用的 Symbol key |
126
94
 
127
- ```typescript
128
- function getMessageSlotId(): ComputedRef<string> | undefined;
129
- // = inject(AI_BLUEKING_MESSAGE_SLOT_ID)
130
- ```
95
+ ### `GlobalConfig`
131
96
 
132
- - `useMessageSlotId` 内部调用,通常不需要直接使用
97
+ | 字段 | 说明 |
98
+ | --------------- | ------------------------------------------------------------------------ |
99
+ | `supportUpload` | 是否支持上传,与根容器 `ChatContainer` 的 `supportUpload` 等展示策略对齐 |
133
100
 
134
- ### 导出常量
101
+ ### `useGlobalConfig(options)`
135
102
 
136
- ```typescript
137
- // Teleport 目标元素的 id 属性值
138
- export const MESSAGE_SLOT_ID = 'ai-blueking-message-slot';
103
+ | 参数 | 说明 |
104
+ | ----------------------- | ------------------------------------------------------------------------------------- |
105
+ | `options.supportUpload` | 是否支持上传,建议使用 `computed(() => props.supportUpload ?? false)` 与根 props 同步 |
139
106
 
140
- // provide/inject 使用的 Symbol key
141
- export const AI_BLUEKING_MESSAGE_SLOT_ID: unique symbol;
142
- ```
107
+ - 调用后立即 `provide(GLOBAL_CONFIG_TOKEN, options)`。
108
+ - 必须在具有组件实例上下文的 `setup` 中调用(与 Vue `provide` 要求一致)。
109
+
110
+ ### `injectGlobalConfig()`
111
+
112
+ | 返回值 | 说明 |
113
+ | -------------- | ----------------------------------------------------------- |
114
+ | `GlobalConfig` | 祖先已调用 `useGlobalConfig` 时,与 Provider 传入的同一对象 |
115
+ | `undefined` | 组件树中无对应 `provide` 时 |
143
116
 
144
117
  ## 注意事项
145
118
 
146
- 1. **`useGlobalConfig` 必须在祖先组件调用**:子组件的 `useMessageSlotId` 通过 `inject` 获取,必须在同一组件树内存在对应 Provider
147
- 2. **`messageSlotId` `onMounted` 后才有值**:`useMessageSlotId` 的返回值初始为 `undefined`,应配合 `v-if="messageSlotId"` 防止 Teleport 报错
148
- 3. **DOM 节点必须与 `rawMessageSlotId` 对应**:根容器需确保 `<div :id="rawMessageSlotId">` 存在于 DOM 中,Teleport 才能找到目标
149
- 4. **Teleport 目标在消息容器内**:相比直接 Teleport 到 `body`,此方案让覆盖层随消息容器的布局、z-index、overflow 上下文保持一致
119
+ 1. **Provider 须在祖先调用**:子组件的 `injectGlobalConfig` 依赖同一组件树内的 `useGlobalConfig`。
120
+ 2. **可选链访问**:无 Provider 时返回 `undefined`,模板中建议使用 `globalConfig?.supportUpload.value ?? false`。
121
+ 3. **扩展配置**:后续若在 `GlobalConfig` 中增加字段,应在根容器统一传入并在文档中说明。
150
122
 
151
123
  ## 关联组件
152
124
 
153
- - [ChatContainer](../components/molecular/chat-container.md) — 侧栏插槽节点与 messageSlotId
154
- - [FlowMessage](../components/molecular/flow-message.md) — Teleport 流程节点详情
125
+ - [ChatContainer](../components/molecular/chat-container.md) — 调用 `useGlobalConfig` 注入 `supportUpload`
@@ -297,6 +297,10 @@ binaryFiles 有值 → 进入编辑模式(editContent 可为空)
297
297
  | onShortcutConfirm | `(formModel: Record<string, unknown>) => Promise<void>` | 快捷指令消息编辑确认回调 |
298
298
  | tippyOptions | `Partial<Omit<TippyOptions, 'getReferenceClientRect' \| 'triggerTarget'>>` | 自定义工具栏 Tippy 配置,透传给内部 `MessageTools` 组件 |
299
299
 
300
+ ### 全局配置依赖
301
+
302
+ 编辑模式下的 `ChatInput` 会通过 `injectGlobalConfig()` 获取全局配置中的 `supportUpload` 值。需要确保祖先组件(通常是 `ChatContainer`)已调用 `useGlobalConfig()` 注册配置。
303
+
300
304
  ## 类型定义
301
305
 
302
306
  ```typescript
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "version": "2.0.0",
3
- "generatedAt": "2026-03-26T12:19:37.302Z",
3
+ "generatedAt": "2026-03-31T12:16:48.179Z",
4
4
  "domains": {
5
5
  "message": {
6
6
  "label": "消息展示",
7
7
  "components": [
8
8
  "activity-message",
9
9
  "assistant-message",
10
- "flow-message",
11
10
  "info-message",
12
11
  "loading-message",
13
12
  "message-container",
@@ -484,10 +483,6 @@
484
483
  "slug": "message-render",
485
484
  "relation": "由 MessageRender 在 role 为 activity 时创建"
486
485
  },
487
- {
488
- "slug": "flow-message",
489
- "relation": "与流程编排执行可视化同属一类场景,组件形态不同"
490
- },
491
486
  {
492
487
  "slug": "assistant-message",
493
488
  "relation": "常与助手回复相邻,描述检索或执行背景"
@@ -684,29 +679,6 @@
684
679
  "docFile": "docs/file-content.md",
685
680
  "domain": "media"
686
681
  },
687
- {
688
- "name": "FlowMessage 流程消息",
689
- "slug": "flow-message",
690
- "category": "molecular",
691
- "description": "流程消息组件,用于展示流程编排(如标准运维 / CI/CD 流水线)的执行状态和节点详情。包含执行统计摘要、节点组列表、节点详情面板,提供完整的流程执行可视化能力。",
692
- "aiSummary": "FlowMessage 用于展示 BkFlow/流水线类流程的执行统计、节点分组与节点详情(含 Tab 详情)。消息类型为 flow,需在业务布局中显式嵌入; 标准 MessageRender 角色分发未包含 flow。与 Activity 的 FlowAgent 模式同属流程可视化但组件与数据模型不同。",
693
- "relatedComponents": [
694
- {
695
- "slug": "activity-message",
696
- "relation": "Activity 的 flow-agent 模式同样展示流程执行,场景互补"
697
- },
698
- {
699
- "slug": "message-container",
700
- "relation": "嵌入对话列表时需与消息容器等配合布局"
701
- },
702
- {
703
- "slug": "execution-summary",
704
- "relation": "对话级执行摘要与单条流程消息可共同构成执行态 UI"
705
- }
706
- ],
707
- "docFile": "docs/flow-message.md",
708
- "domain": "message"
709
- },
710
682
  {
711
683
  "name": "ImagePreviewGroup 图片预览组",
712
684
  "slug": "image-preview-group",
@@ -1086,16 +1058,12 @@
1086
1058
  "name": "useGlobalConfig",
1087
1059
  "slug": "use-global-config",
1088
1060
  "category": "composable",
1089
- "description": "为消息容器内的子组件提供共享 **Teleport 目标 ID** 的 Provider/Consumer 工具。",
1090
- "aiSummary": "useGlobalConfig 提供 messageSlotId('#ai-blueking-message-slot')与 rawMessageSlotId,并 provide AI_BLUEKING_MESSAGE_SLOT_ID。 useMessageSlotId 在子组件 inject 得到 ShallowRef,供 Teleport :to 挂载到消息容器内节点。名称易误解为全局配置,仅与 Teleport 插槽相关。 ChatContainer 使用 useMessageSlotId messageSlotId;FlowMessage 等用 Teleport 展示详情。",
1061
+ "description": "在聊天根容器与子组件之间通过 provide/inject 共享全局展示配置(如是否支持上传)。",
1062
+ "aiSummary": "useGlobalConfig 接收 GlobalConfig(含 supportUpload: ComputedRef<boolean>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer setup 中调用 useGlobalConfig; UserMessage 等通过 injectGlobalConfig 读取 supportUpload。",
1091
1063
  "relatedComponents": [
1092
1064
  {
1093
1065
  "slug": "chat-container",
1094
- "relation": "侧栏 messageSlotId 与自定义 Tab 内容区"
1095
- },
1096
- {
1097
- "slug": "flow-message",
1098
- "relation": "useMessageSlotId + Teleport 流程详情"
1066
+ "relation": "根容器调用 useGlobalConfig 注入 supportUpload"
1099
1067
  }
1100
1068
  ],
1101
1069
  "docFile": "docs/use-global-config.md"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blueking/chat-x",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -55,6 +55,7 @@
55
55
  "markdown-it-sup": "^2.0.0",
56
56
  "markdown-it-task-checkbox": "^1.0.6",
57
57
  "mermaid": "^11.12.2",
58
+ "github-markdown-css": "^5.8.1",
58
59
  "vue": "^3.5.24"
59
60
  },
60
61
  "devDependencies": {
@@ -70,7 +71,6 @@
70
71
  "bkui-vue": "latest",
71
72
  "echarts": "^6.0.0",
72
73
  "entities": "^8.0.0",
73
- "github-markdown-css": "^5.8.1",
74
74
  "glob": "^13.0.6",
75
75
  "gray-matter": "^4.0.3",
76
76
  "happy-dom": "^20.3.7",
@@ -1,11 +0,0 @@
1
- import type { FlowNode } from './types';
2
- type __VLS_Props = {
3
- node?: FlowNode;
4
- };
5
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
- close: () => any;
7
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
8
- onClose?: (() => any) | undefined;
9
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
- declare const _default: typeof __VLS_export;
11
- export default _default;
@@ -1,4 +0,0 @@
1
- import type { FlowMessage } from './types';
2
- declare const __VLS_export: import("vue").DefineComponent<Partial<FlowMessage>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Partial<FlowMessage>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
3
- declare const _default: typeof __VLS_export;
4
- export default _default;
@@ -1,12 +0,0 @@
1
- import { type FlowNode, type FlowNodeGroup } from './types';
2
- type __VLS_Props = {
3
- defaultCollapsed?: boolean;
4
- group: FlowNodeGroup;
5
- };
6
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
- nodeDetail: (node: FlowNode) => any;
8
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
9
- onNodeDetail?: ((node: FlowNode) => any) | undefined;
10
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
- declare const _default: typeof __VLS_export;
12
- export default _default;
@@ -1,11 +0,0 @@
1
- import { type FlowNode } from './types';
2
- type __VLS_Props = {
3
- node: FlowNode;
4
- };
5
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
- detail: (node: FlowNode) => any;
7
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
8
- onDetail?: ((node: FlowNode) => any) | undefined;
9
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
- declare const _default: typeof __VLS_export;
11
- export default _default;
@@ -1,36 +0,0 @@
1
- /**
2
- * 成功状态图标 - 绿色勾选
3
- */
4
- export declare const SuccessIcon: import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
5
- [key: string]: any;
6
- }>;
7
- /**
8
- * 失败状态图标 - 红色叉号
9
- */
10
- export declare const FailedIcon: import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
11
- [key: string]: any;
12
- }>;
13
- /**
14
- * 执行中状态图标 - 蓝色加载
15
- */
16
- export declare const RunningIcon: import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
17
- [key: string]: any;
18
- }>;
19
- /**
20
- * 挂起状态图标 - 橙色暂停
21
- */
22
- export declare const PendingIcon: import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
23
- [key: string]: any;
24
- }>;
25
- /**
26
- * 展开/折叠箭头图标
27
- */
28
- export declare const ArrowIcon: import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
29
- [key: string]: any;
30
- }>;
31
- /**
32
- * 关闭图标
33
- */
34
- export declare const CloseIcon: import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
35
- [key: string]: any;
36
- }>;
@@ -1,6 +0,0 @@
1
- export { default as FlowDetail } from './flow-detail.vue';
2
- export { default as FlowMessage } from './flow-message.vue';
3
- export { default as FlowNodeGroup } from './flow-node-group.vue';
4
- export { default as FlowNodeItem } from './flow-node-item.vue';
5
- export * from './mock';
6
- export * from './types';