@blueking/chat-x 0.0.45-beta.3 → 0.0.45-beta.5

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.
@@ -30,18 +30,19 @@
30
30
  - **消息分组**:内置 `useMessageGroup` 自动处理消息分组、Tool 合并、Loading 注入
31
31
  - **输入区状态推导**:传给 `MessageContainer` 与 `ChatInput` 的 `messageStatus` 为内部计算值 `inputStatus`:当分组中存在 id 为 `LOADING_MESSAGE_ID`(`'__loading__'`,由 `useMessageGroup` 注入的占位 Loading 消息)时,对内使用 `MessageStatus.Fetching`;否则使用外部传入的 `messageStatus`。用于在「已发用户消息、尚未流式」阶段与流式中一致地展示停止能力,并避免输入区重复发送
32
32
  - **待审批发送阻塞**:当消息中存在 `AIDevToolApproval` 且状态为 `pending` / `draft` 的中断项时,`useMessageGroup` 会返回待审批提示,容器在输入区上方展示提示并通过 `ChatInput.sendDisabledTip` 禁止继续发送
33
- - **用户问题中断**:当消息中存在待回答 `UserQuestion` 中断时,容器会在输入区上方挂载 `UserQuestionCard`;若配置了 `onInterruptResume`,用户也可直接在输入框输入自由文本并作为 Others 回答 resume
33
+ - **用户问题中断**:当消息中存在待回答 `UserQuestion` 中断时,容器会在输入区上方挂载 `UserQuestionCard`;结构化作答走 `onInterruptResume`,用户在输入框直接发送时走 `onSendMessage` 并在第三参数附带 skip 用的 `payload`(`status: 'cancelled'`)与 `interrupt`,且不会自动清空输入框
34
34
  - **执行摘要**:侧边栏展示工具调用 / FlowAgent 执行记录,支持关键词搜索和对话定位
35
35
  - **侧栏全屏**:Tab 栏右侧提供全屏/退出全屏按钮,基于 `useFullScreen` 将侧栏区域(`.ai-full-screen-wrapper`)以浏览器原生全屏展示;全屏时 Tippy 的 `appendTo` 自动切换为全屏容器,避免 tooltip 被遮挡
36
36
  - **自定义 Tab**:通过 `useCustomTabProvider` 支持动态添加自定义 Tab(如节点详情)
37
37
  - **分享模式**:内置消息多选分享流程,选中用户消息后确认分享
38
38
  - **渲染模式注入**:`renderMode` 会通过内部 Provider 下传给后代内容组件;例如 FlowAgent 节点在 `Share` 模式下隐藏耗时和「详情」入口
39
+ - **字号主题**:通过 `size` 控制 `small`(默认 12px)/ `normal`(14px)两档字号;根节点设置 `data-ai-size`,子组件通过 CSS 变量(`--ai-font-size` 等)响应式缩放;浮层(Tippy / Teleport)会同步 `document.body.dataset.aiSize`,卸载时自动清理
39
40
  - **空状态欢迎页**:无消息时展示欢迎语和开场白
40
41
 
41
42
  ## 组件结构
42
43
 
43
44
  ```
44
- ai-chat-container
45
+ ai-chat-container(:data-ai-size="size")
45
46
  ├── Loading(chatLoading 时)
46
47
  └── ResizeLayout
47
48
  ├── aside(侧边栏)
@@ -117,6 +118,26 @@ ai-chat-container
117
118
 
118
119
  **渲染效果**
119
120
 
121
+ ## 字号主题
122
+
123
+ 通过 `size` 切换两档字号主题。未传时默认为 `small`(12px 基准字号);设为 `normal` 时使用 14px 基准字号,并联动行高、间距与图标尺寸。
124
+
125
+ ```vue
126
+ <template>
127
+ <ChatContainer
128
+ v-model="inputValue"
129
+ :messages="messages"
130
+ message-status="complete"
131
+ size="normal"
132
+ :on-send-message="handleSendMessage"
133
+ />
134
+ </template>
135
+ ```
136
+
137
+ **渲染效果**(左右对比 `size="small"` 与 `size="normal"`)
138
+
139
+ > CSS 变量与档位取值详见 [主题配置 — 字号主题](../../theme/theme#字号主题)。
140
+
120
141
  ## 侧边栏与执行摘要
121
142
 
122
143
  侧边栏默认包含「执行情况」Tab,展示所有工具调用和 FlowAgent 类型的 Activity 消息。支持关键词搜索过滤和点击定位到对话中的消息位置。
@@ -347,7 +368,10 @@ ai-chat-container
347
368
 
348
369
  ## 用户问题中断
349
370
 
350
- 当会话中最近一条待处理 interrupt 包含 `InterruptReason.UserQuestion` 时,`ChatContainer` 会在 `ChatInput` 上方显示 [UserQuestionCard](/components/agent/user-question-card)。用户完成或跳过后通过 `onInterruptResume(payload, interrupt)` 通知业务侧继续 Agent
371
+ 当会话中最近一条待处理 interrupt 包含 `InterruptReason.UserQuestion` 时,`ChatContainer` 会在 `ChatInput` 上方显示 [UserQuestionCard](/components/agent/user-question-card)。
372
+
373
+ - **结构化作答**:用户在卡片内完成选择或点击「跳过」后,通过 `onInterruptResume(payload, interrupt)` 回传 `UserQuestionResume`。
374
+ - **输入框发送**:用户也可在输入框直接点击发送;容器会调用 `onSendMessage(content, docSchema, options)`,其中 `options.interrupt` 为当前激活的 UserQuestion,`options.payload` 为 `buildSkipResumePayload` 生成的 skip resume(`status: 'cancelled'`,`answers: []`)。此时**不会自动清空**输入框,由业务侧在 `onSendMessage` 内决定如何处理 `content` 与中断恢复。
351
375
 
352
376
  ```vue
353
377
  <template>
@@ -361,18 +385,35 @@ ai-chat-container
361
385
  </template>
362
386
 
363
387
  <script setup lang="ts">
364
- import { type OnInterruptResume } from '@blueking/chat-x';
388
+ import {
389
+ type OnInterruptResume,
390
+ type UserMessage,
391
+ type TagSchema,
392
+ type Interrupt,
393
+ type InterruptResume,
394
+ } from '@blueking/chat-x';
365
395
 
366
396
  const handleInterruptResume: OnInterruptResume = async (payload, interrupt) => {
367
- // UserQuestion 完成时 payload 为 UserQuestionResume
368
- // 自由文本输入也会转换为 label: 'others' 的单条回答
397
+ // UserQuestionCard 完成 / 跳过时 payload 为 UserQuestionResume
369
398
  await resumeAgent({ interruptId: interrupt.id, resume: payload });
370
399
  };
400
+
401
+ const handleSendMessage = async (
402
+ content: UserMessage['content'],
403
+ docSchema: TagSchema,
404
+ options?: { interrupt?: Interrupt; payload?: InterruptResume },
405
+ ) => {
406
+ if (options?.interrupt && options?.payload) {
407
+ // 存在 UserQuestion 时发送:附带 skip resume,content 仍为输入框文本
408
+ await resumeAgent({ interruptId: options.interrupt.id, resume: options.payload });
409
+ // 业务侧自行决定是否将 content 作为新用户消息继续发送
410
+ return;
411
+ }
412
+ await sendMessage(content, docSchema);
413
+ };
371
414
  </script>
372
415
  ```
373
416
 
374
- 如果没有传入 `onInterruptResume`,输入框自由文本不会被中断逻辑截获,仍然走普通 `onSendMessage`,避免输入被静默清空。
375
-
376
417
  ## 自定义消息组渲染
377
418
 
378
419
  通过 `#group` 插槽可替换单个消息组的默认内容,透传至内部 `MessageContainer`。外层消息组容器(`id`、hover、选中背景)仍由 `MessageContainer` 管理。
@@ -496,6 +537,7 @@ ChatContainer 的 Props 继承自 `ChatInputProps` 和 `MessageContainerProps`
496
537
  | getSideTabRenderComponent | `(h, tab, { removeCustomTab }) => VNode \| undefined` | — | 自定义侧栏 Tab 标签渲染;未返回时使用默认图标 + 文案 + 关闭按钮 |
497
538
  | openingRemark | `string` | — | 开场白,无消息时显示,支持 Markdown |
498
539
  | placement | `'left' \| 'right'` | `'left'` | 侧边栏位置 |
540
+ | size | `'normal' \| 'small'` | `'small'` | 字号主题档位:`small` 为 12px 基准,`normal` 为 14px 基准;根节点设置 `data-ai-size` 并注入 `useGlobalConfig` |
499
541
  | resizeProps | `{ disabled?: boolean; initialDivide?: number \| string; max?: number; min?: number }` | — | 透传给内部 `ResizeLayout` 的可选配置,与默认 `collapsible: false`、`immediate: true`、`min: 400` 合并;`placement` 始终取自本组件 `placement`;`initialDivide` 可为像素数字或百分比等字符串(与 bkui ResizeLayout 一致) |
500
542
  | onCustomTabChange | `(tab: CustomTab) => Promise<any>` | — | 自定义 Tab 切换回调,返回值作为 Tab 组件 props |
501
543
 
@@ -613,4 +655,6 @@ interface Shortcut {
613
655
  - [ExecutionSummary](/components/agent/execution-summary) — 执行摘要侧栏
614
656
  - [SelectionFooter](/components/input/selection-footer) — 多选操作栏
615
657
  - [ToolBtn](/components/feedback/tool-btn) — 侧栏全屏按钮(自定义插槽)
616
- - [useFullScreen](/composables/use-full-screen) — 侧栏全屏控制
658
+ - [useFullScreen](/composables/use-full-screen) — 侧栏全屏控制
659
+ - [useGlobalConfig](/composables/use-global-config) — 注入 `size` 与 `supportUpload`
660
+ - [主题配置](/theme/theme) — 字号主题 CSS 变量
@@ -93,6 +93,31 @@ chat-input-container
93
93
 
94
94
  > **实现细节**:组件内部用 `messageState` 计算属性决定实际按钮状态:当 `messageStatus` 为 `pending`、`streaming` 或 `fetching` 时直接使用该状态(确保停止按钮始终可用);否则当输入为空或仅含空白字符时强制为 `disabled`,其余情况使用 `messageStatus` 的值。`fetching` 时按 Enter **不会**触发发送(避免请求中与 Loading 占位阶段重复提交)。
95
95
 
96
+ ### onSendMessage 第三参数 options(UserQuestion 上下文)
97
+
98
+ `ChatInput` 自身调用 `onSendMessage` 时只传前两个参数。当组件被 [ChatContainer](/components/setup/chat-container) 包裹且存在待回答 `UserQuestion` 中断时,容器会在用户点击发送时注入第三个参数:
99
+
100
+ | 字段 | 类型 | 说明 |
101
+ | ----------- | ------------------ | -------------------------------------------------------------------- |
102
+ | `interrupt` | `Interrupt` | 当前激活的 `UserQuestionInterrupt` |
103
+ | `payload` | `InterruptResume` | skip resume(`status: 'cancelled'`,`payload.answers` 为空数组) |
104
+
105
+ 此场景下容器**不会**自动清空 `modelValue`,业务侧需在 `onSendMessage` 内自行处理消息发送与 `resumeAgent` 的先后顺序。结构化作答仍通过 `UserQuestionCard` → `onInterruptResume` 完成。
106
+
107
+ ```typescript
108
+ const handleSendMessage = async (
109
+ content: UserMessage['content'],
110
+ docSchema: TagSchema,
111
+ options?: { interrupt?: Interrupt; payload?: InterruptResume },
112
+ ) => {
113
+ if (options?.interrupt && options?.payload) {
114
+ await resumeAgent({ interruptId: options.interrupt.id, resume: options.payload });
115
+ return;
116
+ }
117
+ await sendMessage(content, docSchema);
118
+ };
119
+ ```
120
+
96
121
  ### sendDisabledTip(业务阻塞发送)
97
122
 
98
123
  当业务侧需要临时阻止发送但仍允许用户输入时,可传入 `sendDisabledTip`。组件会置灰发送按钮,按钮 tooltip 展示该文案,并拦截点击发送、按 Enter 发送和 `triggerSendMessage()`:
@@ -504,7 +529,7 @@ chat-input-container
504
529
  | sendDisabledTip | `string` | - | - | 业务阻塞发送时的 tooltip 提示;传入后发送按钮置灰,点击、Enter 与 `triggerSendMessage()` 均不会发送 |
505
530
  | supportUpload | `boolean` | `true` | - | 是否显示文件上传按钮 |
506
531
  | tippyOptions | `AITippyProps` | — | - | 透传给 FileUploadBtn 和 InputAttachment 的 tooltip 配置 |
507
- | onSendMessage | `(content: UserMessage['content'], docSchema: TagSchema) => Promise<void>` | - | - | 发送消息回调,无文件时 content 为字符串,有文件时为数组 |
532
+ | onSendMessage | `(content: UserMessage['content'], docSchema: TagSchema, options?: { interrupt?: Interrupt; payload?: InterruptResume }) => Promise<void>` | - | - | 发送消息回调,无文件时 content 为字符串,有文件时为数组;经 [ChatContainer](/components/setup/chat-container) 使用时,存在待回答 UserQuestion 会传入第三参数 `options` |
508
533
  | onStopSending | `() => Promise<void>` | - | - | 停止发送回调,点击停止按钮时触发 |
509
534
  | onUpload | `(file: File) => Promise<{ download_url?: string }>` | - | - | 文件上传回调(每次单文件) |
510
535
 
@@ -600,6 +625,13 @@ type SendContent =
600
625
  // 有文件时:数组
601
626
  { type: 'binary'; url?: string; mimeType: string; filename: string } | { type: 'text'; text: string }
602
627
  >;
628
+
629
+ // onSendMessage 完整签名(第三参数由 ChatContainer 在 UserQuestion 场景注入)
630
+ type OnSendMessage = (
631
+ content: SendContent,
632
+ docSchema: TagSchema,
633
+ options?: { interrupt?: Interrupt; payload?: InterruptResume },
634
+ ) => Promise<void>;
603
635
  ```
604
636
 
605
637
  ## 完整集成示例
@@ -1,7 +1,7 @@
1
1
  <!-- AI SUMMARY -->
2
2
  ## 快速了解
3
3
 
4
- 说明通过 SCSS 变量(尺寸、颜色、z-index)与 CSS 类覆盖(chat-input、用户/助手消息、shortcut-btns、ai-markdown-body、tool-btn 等)自定义主题。 含渐变边框 mixin、ai-markdown-fade-in 与弹窗过渡。暗色示例通过根 class 切换。组件随包引入样式,业务侧按需覆写。
4
+ 说明通过 SCSS 变量(尺寸、颜色、z-index)、字号主题 CSS 变量(data-ai-size 切换 small/normal)与 CSS 类覆盖自定义主题。 ChatContainer.size 控制根节点 data-ai-size;浮层同步 document.body.dataset.aiSize。含渐变边框 mixin、骨架屏类 ai-skeleton-element 等。
5
5
 
6
6
  ### 关联组件
7
7
  - **chat-container** — 整体布局与侧栏
@@ -26,6 +26,51 @@
26
26
  import { ChatInput, MessageContainer } from '@blueking/chat-x';
27
27
  ```
28
28
 
29
+ ## 字号主题
30
+
31
+ 组件库通过根节点 `[data-ai-size]` 切换两档字号主题,内部组件统一引用 CSS 变量(均带兜底值,无 provider 时退回 `small`)。
32
+
33
+ ### 切换方式
34
+
35
+ | 方式 | 说明 |
36
+ | ---- | ---- |
37
+ | `ChatContainer` 的 `size` prop | 推荐。根节点 `.ai-chat-container` 设置 `data-ai-size`;同时通过 `useGlobalConfig` 注入 `size` 供逻辑层读取 |
38
+ | 手动设置 `data-ai-size` | 在任意祖先元素上设置 `data-ai-size="small"` 或 `data-ai-size="normal"`,后代继承 CSS 变量 |
39
+ | `document.body.dataset.aiSize` | `ChatContainer` 会自动同步,供 Tippy / Teleport 等挂载到 `body` 的浮层继承字号变量;容器卸载时清理 |
40
+
41
+ ```vue
42
+ <template>
43
+ <ChatContainer v-model="input" :messages="messages" size="normal" />
44
+ </template>
45
+ ```
46
+
47
+ ### CSS 变量
48
+
49
+ 定义于 `src/styles/size-theme.scss`,随 `global.scss` 自动引入:
50
+
51
+ | 变量名 | `small`(默认) | `normal` | 说明 |
52
+ | ------ | --------------- | -------- | ---- |
53
+ | `--ai-font-size` | `12px` | `14px` | 基准字号 |
54
+ | `--ai-line-height` | `20px` | `24px` | 标准行高 |
55
+ | `--ai-line-height-compact` | `20px` | `22px` | 紧凑行高 |
56
+ | `--ai-spacing-comfortable` | `8px` | `12px` | 舒适间距(如消息气泡水平内边距) |
57
+ | `--ai-icon-size` | `16px` | `20px` | 标准图标尺寸 |
58
+ | `--ai-icon-size-sm` | `16px` | `18px` | 小号图标尺寸 |
59
+
60
+ 组件样式中统一使用 `var(--ai-font-size, 12px)` 等形式引用,保证无 `data-ai-size` 时仍退回 small 档位。
61
+
62
+ ```scss
63
+ // 示例:在自定义样式中复用字号主题变量
64
+ .my-custom-panel {
65
+ font-size: var(--ai-font-size, 12px);
66
+ line-height: var(--ai-line-height, 20px);
67
+ }
68
+ ```
69
+
70
+ ### 骨架屏
71
+
72
+ 全局类 `.ai-skeleton-element` 用于加载占位(如 FlowAgent 节点详情、UserFeedback 原因列表)。可通过 `.skeleton-element-lg` 修饰尺寸。详见各业务组件文档中的加载态说明。
73
+
29
74
  ## SCSS 变量
30
75
 
31
76
  组件库使用以下 SCSS 变量,可以在项目中覆盖:
@@ -383,6 +428,7 @@ $selection-z-index: $shortcut-menu-z-index + 1;
383
428
 
384
429
  ## 关联组件
385
430
 
386
- - [ChatContainer](../components/setup/chat-container) — 布局与主题根节点
431
+ - [ChatContainer](../components/setup/chat-container) — 布局与字号主题根节点(`size` prop)
432
+ - [useGlobalConfig](../composables/use-global-config) — 注入 `size` 供后代读取
387
433
  - [ChatInput](../components/input/chat-input) — 输入区变量与类名
388
434
  - [MessageContainer](../components/setup/message-container) — 消息列表区域
@@ -65,7 +65,7 @@ useFullScreen(target?)
65
65
 
66
66
  `ChatContainer` 将侧栏包裹在 `.ai-full-screen-wrapper` 中,通过 `useFullScreen(fullScreenRef)` 控制侧栏全屏;Tab 栏 `#setting` 插槽内的 `ToolBtn` 使用自定义插槽渲染 `FullScreenIcon` / `UnFullScreenIcon`。
67
67
 
68
- 详见 [ChatContainer 侧栏全屏](../components/molecular/chat-container.md#侧栏全屏)。
68
+ 详见 [ChatContainer 侧栏全屏](../components/setup/chat-container.md#侧栏全屏)。
69
69
 
70
70
  ## API
71
71
 
@@ -110,5 +110,5 @@ declare function useFullScreen(target?: MaybeRef<HTMLElement | null>): UseFullSc
110
110
 
111
111
  ## 关联组件
112
112
 
113
- - [ChatContainer](../components/molecular/chat-container.md) — 内置侧栏全屏按钮
114
- - [ToolBtn](../components/atomic/tool-btn.md) — 全屏按钮自定义插槽
113
+ - [ChatContainer](../components/setup/chat-container.md) — 内置侧栏全屏按钮
114
+ - [ToolBtn](../components/feedback/tool-btn.md) — 全屏按钮自定义插槽
@@ -1,7 +1,7 @@
1
1
  <!-- AI SUMMARY -->
2
2
  ## 快速了解
3
3
 
4
- useGlobalConfig 接收 GlobalConfig(含 supportUpload: ComputedRef<boolean>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer 在 setup 中调用 useGlobalConfig; UserMessage 等通过 injectGlobalConfig 读取 supportUpload。
4
+ useGlobalConfig 接收 GlobalConfig(含 size?: ComputedRef<AiSizeMode>、supportUpload: ComputedRef<boolean>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer 在 setup 中调用 useGlobalConfig 注入 size 与 supportUpload后代组件可通过 injectGlobalConfig 读取配置;字号主题主要通过根节点 data-ai-size 与 CSS 变量生效。
5
5
 
6
6
  ### 关联组件
7
7
  - **chat-container** — 根容器调用 useGlobalConfig 注入 supportUpload
@@ -13,14 +13,20 @@ useGlobalConfig 接收 GlobalConfig(含 supportUpload: ComputedRef<boolean>)
13
13
 
14
14
  > **分类**:composable
15
15
 
16
- 在聊天容器根组件与子组件之间通过 Vue `provide` / `inject` 共享**全局展示相关配置**(当前主要为是否支持上传 `supportUpload`)。与 Teleport 插槽 ID 无关。
16
+ 在聊天容器根组件与子组件之间通过 Vue `provide` / `inject` 共享**全局展示相关配置**(当前包括字号主题档位 `size`、是否支持上传 `supportUpload`)。与 Teleport 插槽 ID 无关。
17
+
18
+ > 字号主题主要通过 `ChatContainer` 根节点的 `data-ai-size` 与 CSS 变量(`--ai-font-size` 等)生效;`GlobalConfig.size` 供后代在逻辑层读取当前档位,样式层无需逐组件传参。
17
19
 
18
20
  ## 工作原理
19
21
 
20
22
  ```
21
23
  ChatContainer(根)
22
- ├── useGlobalConfig({ supportUpload: computed(() => props.supportUpload ?? false) })
23
- │ └── provide(GLOBAL_CONFIG_TOKEN, { supportUpload })
24
+ ├── :data-ai-size="size"(CSS 变量作用域)
25
+ ├── useGlobalConfig({
26
+ │ size: computed(() => props.size ?? 'small'),
27
+ │ supportUpload: computed(() => props.supportUpload ?? false),
28
+ │ })
29
+ │ └── provide(GLOBAL_CONFIG_TOKEN, { size, supportUpload })
24
30
 
25
31
  └── MessageContainer → … → UserMessage 等
26
32
 
@@ -43,10 +49,12 @@ UserMessage(后代)
43
49
  import { useGlobalConfig } from '@blueking/chat-x';
44
50
 
45
51
  const props = defineProps<{
52
+ size?: 'normal' | 'small';
46
53
  supportUpload?: boolean;
47
54
  }>();
48
55
 
49
56
  useGlobalConfig({
57
+ size: computed(() => props.size ?? 'small'),
50
58
  supportUpload: computed(() => props.supportUpload ?? false),
51
59
  });
52
60
  </script>
@@ -75,11 +83,15 @@ import type { ComputedRef } from 'vue';
75
83
 
76
84
  export const GLOBAL_CONFIG_TOKEN: unique symbol;
77
85
 
86
+ export type AiSizeMode = 'normal' | 'small';
87
+
78
88
  export type GlobalConfig = {
89
+ size?: ComputedRef<AiSizeMode>;
79
90
  supportUpload: ComputedRef<boolean>;
80
91
  };
81
92
 
82
93
  export function useGlobalConfig(options: GlobalConfig): {
94
+ size?: ComputedRef<AiSizeMode>;
83
95
  supportUpload: ComputedRef<boolean>;
84
96
  };
85
97
 
@@ -96,12 +108,14 @@ export function injectGlobalConfig(): GlobalConfig | undefined;
96
108
 
97
109
  | 字段 | 说明 |
98
110
  | --------------- | ------------------------------------------------------------------------ |
111
+ | `size` | 可选。字号主题档位 `normal`(14px)/ `small`(12px),与 `ChatContainer.size` 对齐 |
99
112
  | `supportUpload` | 是否支持上传,与根容器 `ChatContainer` 的 `supportUpload` 等展示策略对齐 |
100
113
 
101
114
  ### `useGlobalConfig(options)`
102
115
 
103
116
  | 参数 | 说明 |
104
117
  | ----------------------- | ------------------------------------------------------------------------------------- |
118
+ | `options.size` | 可选。字号主题档位,建议使用 `computed(() => props.size ?? 'small')` 与根 props 同步 |
105
119
  | `options.supportUpload` | 是否支持上传,建议使用 `computed(() => props.supportUpload ?? false)` 与根 props 同步 |
106
120
 
107
121
  - 调用后立即 `provide(GLOBAL_CONFIG_TOKEN, options)`。
@@ -122,4 +136,5 @@ export function injectGlobalConfig(): GlobalConfig | undefined;
122
136
 
123
137
  ## 关联组件
124
138
 
125
- - [ChatContainer](../components/setup/chat-container) — 调用 `useGlobalConfig` 注入 `supportUpload`
139
+ - [ChatContainer](../components/setup/chat-container) — 调用 `useGlobalConfig` 注入 `size` 与 `supportUpload`
140
+ - [主题配置](../theme/theme) — `data-ai-size` 与 CSS 变量说明
@@ -29,7 +29,7 @@
29
29
  - **自定义作答形态**:通过 `#question` slot 可替换默认选择题,渲染任意表单;作答有效时调用 `setAnswer` 回传 `UserQuestionAnswerItem`,无效时传 `undefined`。
30
30
  - **完成校验**:所有题目均已作答(`setAnswer` 收到有效答案)后才允许点击「完成」。
31
31
  - **跳过**:点击「跳过」返回 `status: 'cancelled'` 与空 `answers`。
32
- - **自由文本兜底**:当存在待回答 UserQuestion 且业务配置了 `onInterruptResume` 时,用户也可以直接在 `ChatInput` 输入文本;容器会将文本转换为单条 Others 回答。
32
+ - **输入框发送**:存在待回答 UserQuestion 时,用户也可在 `ChatInput` 直接发送;`ChatContainer` 会调用 `onSendMessage` 并在第三参数附带与「跳过」等价的 skip `payload` 及 `interrupt`,输入框内容不会自动清空。
33
33
 
34
34
  ## 数据协议
35
35
 
@@ -141,7 +141,24 @@ const payload = {
141
141
  />
142
142
  ```
143
143
 
144
- 如果没有配置 `onInterruptResume`,自由文本输入不会被截获,仍按普通 `onSendMessage` 发送,避免用户输入被静默清空。
144
+ - 卡片内「完成 / 跳过」→ `onInterruptResume(payload, interrupt)`
145
+ - 输入框直接发送 → `onSendMessage(content, docSchema, { interrupt, payload })`,其中 `payload` 由 `buildSkipResumePayload(interrupt)` 生成(`status: 'cancelled'`)
146
+
147
+ ## 工具函数 buildSkipResumePayload
148
+
149
+ 从 `@blueking/chat-x` 导出,用于构造 UserQuestion 的 skip resume(与卡片「跳过」及输入框发送时容器注入的 `options.payload` 一致):
150
+
151
+ ```typescript
152
+ import { buildSkipResumePayload, InterruptReason } from '@blueking/chat-x';
153
+
154
+ const payload = buildSkipResumePayload(interrupt);
155
+ // {
156
+ // interruptId: interrupt.id,
157
+ // reason: InterruptReason.UserQuestion,
158
+ // status: 'cancelled',
159
+ // payload: { answers: [] },
160
+ // }
161
+ ```
145
162
 
146
163
  ## 自定义题目渲染(#question slot)
147
164
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "2.0.0",
3
- "generatedAt": "2026-06-09T06:41:01.574Z",
3
+ "generatedAt": "2026-06-10T07:05:58.442Z",
4
4
  "domains": {
5
5
  "setup": {
6
6
  "label": "对话搭建",
@@ -1575,8 +1575,8 @@
1575
1575
  "name": "useGlobalConfig",
1576
1576
  "slug": "use-global-config",
1577
1577
  "kind": "composable",
1578
- "description": "在聊天根容器与子组件之间通过 provide/inject 共享全局展示配置(如是否支持上传)。",
1579
- "aiSummary": "useGlobalConfig 接收 GlobalConfig(含 supportUpload: ComputedRef<boolean>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer 在 setup 中调用 useGlobalConfig; UserMessage 等通过 injectGlobalConfig 读取 supportUpload。",
1578
+ "description": "在聊天根容器与子组件之间通过 provide/inject 共享全局展示配置(字号主题档位、是否支持上传等)。",
1579
+ "aiSummary": "useGlobalConfig 接收 GlobalConfig(含 size?: ComputedRef<AiSizeMode>、supportUpload: ComputedRef<boolean>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer 在 setup 中调用 useGlobalConfig 注入 size 与 supportUpload后代组件可通过 injectGlobalConfig 读取配置;字号主题主要通过根节点 data-ai-size 与 CSS 变量生效。",
1580
1580
  "relatedComponents": [
1581
1581
  {
1582
1582
  "slug": "chat-container",
@@ -1833,7 +1833,7 @@
1833
1833
  "slug": "theme",
1834
1834
  "kind": "theme",
1835
1835
  "description": "`@blueking/chat-x` 使用 SCSS 变量和 CSS 类来控制样式,支持通过覆盖变量或样式来自定义主题。",
1836
- "aiSummary": "说明通过 SCSS 变量(尺寸、颜色、z-index)与 CSS 类覆盖(chat-input、用户/助手消息、shortcut-btns、ai-markdown-body、tool-btn 等)自定义主题。 含渐变边框 mixin、ai-markdown-fade-in 与弹窗过渡。暗色示例通过根 class 切换。组件随包引入样式,业务侧按需覆写。",
1836
+ "aiSummary": "说明通过 SCSS 变量(尺寸、颜色、z-index)、字号主题 CSS 变量(data-ai-size 切换 small/normal)与 CSS 类覆盖自定义主题。 ChatContainer.size 控制根节点 data-ai-size;浮层同步 document.body.dataset.aiSize。含渐变边框 mixin、骨架屏类 ai-skeleton-element 等。",
1837
1837
  "relatedComponents": [
1838
1838
  {
1839
1839
  "slug": "chat-container",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blueking/chat-x",
3
- "version": "0.0.45-beta.3",
3
+ "version": "0.0.45-beta.5",
4
4
  "description": "蓝鲸智云 AI Chat 组件库 —— 遵循 AG-UI,为 AI Agent 和人类开发者共同设计的对话 UI 组件库。",
5
5
  "main": "index.js",
6
6
  "scripts": {