@blueking/chat-x 0.0.50 → 0.0.51-beta.2

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 (147) hide show
  1. package/dist/ag-ui/types/contents.d.ts +2 -0
  2. package/dist/ag-ui/types/messages.d.ts +5 -0
  3. package/dist/common/constants.d.ts +1 -1
  4. package/dist/components/ai-buttons/file-upload-btn/file-upload-btn.vue.d.ts +0 -2
  5. package/dist/components/chat-content/file-content/file-content.vue.d.ts +5 -2
  6. package/dist/components/chat-content/file-content/upload-file-item.vue.d.ts +12 -0
  7. package/dist/components/chat-content/file-content/upload-image-item.vue.d.ts +21 -0
  8. package/dist/components/chat-input/ai-slash-editor/ai-slash-editor.vue.d.ts +1 -1
  9. package/dist/components/chat-input/build-default-placeholder.d.ts +7 -0
  10. package/dist/components/chat-input/chat-input.vue.d.ts +1 -1
  11. package/dist/components/chat-message/message-container/message-container.vue.d.ts +1 -0
  12. package/dist/components/chat-message/message-render/message-render.vue.d.ts +2 -0
  13. package/dist/components/chat-message/user-message/user-message.vue.d.ts +3 -1
  14. package/dist/components/index.d.ts +2 -1
  15. package/dist/components/message-tools/message-time/format-message-time.d.ts +8 -0
  16. package/dist/components/message-tools/message-time/message-time.vue.d.ts +8 -0
  17. package/dist/components/message-tools/message-tools.vue.d.ts +11 -1
  18. package/dist/composables/use-custom-tab.d.ts +5 -3
  19. package/dist/composables/use-global-config.d.ts +3 -0
  20. package/dist/composables/use-message-group.d.ts +150 -72
  21. package/dist/icons/execution.d.ts +6 -0
  22. package/dist/icons/tools.d.ts +3 -0
  23. package/dist/index.css +1 -1
  24. package/dist/index.js +3124 -2837
  25. package/dist/index.js.map +1 -1
  26. package/dist/lang/lang.d.ts +8 -7
  27. package/dist/mcp/generated/docs/ai-slash-input.md +2 -0
  28. package/dist/mcp/generated/docs/assistant-message.md +9 -7
  29. package/dist/mcp/generated/docs/chat-container.md +38 -32
  30. package/dist/mcp/generated/docs/chat-input.md +18 -12
  31. package/dist/mcp/generated/docs/cite-content.md +3 -3
  32. package/dist/mcp/generated/docs/desc-panel.md +32 -10
  33. package/dist/mcp/generated/docs/execution-summary.md +3 -3
  34. package/dist/mcp/generated/docs/file-artifact-panel.md +6 -4
  35. package/dist/mcp/generated/docs/file-content.md +89 -73
  36. package/dist/mcp/generated/docs/file-upload-btn.md +16 -18
  37. package/dist/mcp/generated/docs/message-container.md +3 -0
  38. package/dist/mcp/generated/docs/message-render.md +2 -1
  39. package/dist/mcp/generated/docs/message-time.md +180 -0
  40. package/dist/mcp/generated/docs/message-tools.md +47 -12
  41. package/dist/mcp/generated/docs/messages.md +9 -0
  42. package/dist/mcp/generated/docs/toolcall-render.md +82 -43
  43. package/dist/mcp/generated/docs/use-artifact-preview.md +19 -17
  44. package/dist/mcp/generated/docs/use-custom-tab.md +12 -8
  45. package/dist/mcp/generated/docs/use-global-config.md +15 -5
  46. package/dist/mcp/generated/docs/user-message.md +9 -0
  47. package/dist/mcp/generated/docs/user-question-card.md +2 -0
  48. package/dist/mcp/generated/index.json +46 -6
  49. package/dist/types/input.d.ts +6 -0
  50. package/dist/utils/file.d.ts +7 -1
  51. package/dist/utils/index.d.ts +2 -0
  52. package/dist/utils/merge-tools-by-id.d.ts +6 -0
  53. package/dist/utils/upload-file.d.ts +35 -0
  54. package/package.json +3 -2
  55. package/skills/blueking-chat-x/SKILL.md +139 -0
  56. package/skills/blueking-chat-x/references/_index.md +131 -0
  57. package/skills/blueking-chat-x/references/components/activity-layout.md +134 -0
  58. package/skills/blueking-chat-x/references/components/activity-message.md +486 -0
  59. package/skills/blueking-chat-x/references/components/ai-image.md +230 -0
  60. package/skills/blueking-chat-x/references/components/ai-loading.md +131 -0
  61. package/skills/blueking-chat-x/references/components/ai-prompt-list.md +44 -0
  62. package/skills/blueking-chat-x/references/components/ai-selection.md +439 -0
  63. package/skills/blueking-chat-x/references/components/ai-skill-list.md +73 -0
  64. package/skills/blueking-chat-x/references/components/ai-slash-editor.md +43 -0
  65. package/skills/blueking-chat-x/references/components/ai-slash-input.md +56 -0
  66. package/skills/blueking-chat-x/references/components/ai-slash-menu.md +42 -0
  67. package/skills/blueking-chat-x/references/components/animation-text.md +202 -0
  68. package/skills/blueking-chat-x/references/components/assistant-message.md +498 -0
  69. package/skills/blueking-chat-x/references/components/chat-container.md +869 -0
  70. package/skills/blueking-chat-x/references/components/chat-input.md +769 -0
  71. package/skills/blueking-chat-x/references/components/cite-content.md +142 -0
  72. package/skills/blueking-chat-x/references/components/code-content.md +211 -0
  73. package/skills/blueking-chat-x/references/components/common-error-content.md +73 -0
  74. package/skills/blueking-chat-x/references/components/content-render.md +233 -0
  75. package/skills/blueking-chat-x/references/components/delete-tool.md +191 -0
  76. package/skills/blueking-chat-x/references/components/desc-panel.md +162 -0
  77. package/skills/blueking-chat-x/references/components/detail-section.md +91 -0
  78. package/skills/blueking-chat-x/references/components/execution-summary.md +128 -0
  79. package/skills/blueking-chat-x/references/components/file-artifact-panel.md +289 -0
  80. package/skills/blueking-chat-x/references/components/file-content.md +319 -0
  81. package/skills/blueking-chat-x/references/components/file-icon.md +109 -0
  82. package/skills/blueking-chat-x/references/components/file-upload-btn.md +159 -0
  83. package/skills/blueking-chat-x/references/components/flow-agent-content.md +264 -0
  84. package/skills/blueking-chat-x/references/components/flow-agent-node-detail.md +236 -0
  85. package/skills/blueking-chat-x/references/components/highlight-keyword.md +146 -0
  86. package/skills/blueking-chat-x/references/components/image-content.md +182 -0
  87. package/skills/blueking-chat-x/references/components/image-preview-group.md +184 -0
  88. package/skills/blueking-chat-x/references/components/image-preview.md +226 -0
  89. package/skills/blueking-chat-x/references/components/info-message.md +144 -0
  90. package/skills/blueking-chat-x/references/components/input-attachment.md +49 -0
  91. package/skills/blueking-chat-x/references/components/input-info-alert.md +42 -0
  92. package/skills/blueking-chat-x/references/components/interrupt-message.md +212 -0
  93. package/skills/blueking-chat-x/references/components/key-value-content.md +128 -0
  94. package/skills/blueking-chat-x/references/components/knowledge-rag-content.md +122 -0
  95. package/skills/blueking-chat-x/references/components/latex-content.md +200 -0
  96. package/skills/blueking-chat-x/references/components/loading-message.md +192 -0
  97. package/skills/blueking-chat-x/references/components/markdown-content.md +232 -0
  98. package/skills/blueking-chat-x/references/components/mermaid-content.md +189 -0
  99. package/skills/blueking-chat-x/references/components/message-container.md +645 -0
  100. package/skills/blueking-chat-x/references/components/message-loading.md +118 -0
  101. package/skills/blueking-chat-x/references/components/message-render.md +327 -0
  102. package/skills/blueking-chat-x/references/components/message-time.md +177 -0
  103. package/skills/blueking-chat-x/references/components/message-tools.md +416 -0
  104. package/skills/blueking-chat-x/references/components/model-selector.md +155 -0
  105. package/skills/blueking-chat-x/references/components/preview-toolbar.md +42 -0
  106. package/skills/blueking-chat-x/references/components/questions-container.md +85 -0
  107. package/skills/blueking-chat-x/references/components/reasoning-message.md +232 -0
  108. package/skills/blueking-chat-x/references/components/reference-content.md +135 -0
  109. package/skills/blueking-chat-x/references/components/reference-doc-content.md +109 -0
  110. package/skills/blueking-chat-x/references/components/scroll-btn.md +159 -0
  111. package/skills/blueking-chat-x/references/components/selection-footer.md +78 -0
  112. package/skills/blueking-chat-x/references/components/selection-question.md +88 -0
  113. package/skills/blueking-chat-x/references/components/shortcut-btn.md +204 -0
  114. package/skills/blueking-chat-x/references/components/shortcut-btns.md +266 -0
  115. package/skills/blueking-chat-x/references/components/shortcut-render.md +424 -0
  116. package/skills/blueking-chat-x/references/components/simple-table.md +101 -0
  117. package/skills/blueking-chat-x/references/components/text-content.md +77 -0
  118. package/skills/blueking-chat-x/references/components/tool-approval-card.md +183 -0
  119. package/skills/blueking-chat-x/references/components/tool-btn.md +317 -0
  120. package/skills/blueking-chat-x/references/components/tool-message.md +235 -0
  121. package/skills/blueking-chat-x/references/components/toolcall-render.md +348 -0
  122. package/skills/blueking-chat-x/references/components/user-feedback.md +233 -0
  123. package/skills/blueking-chat-x/references/components/user-message.md +424 -0
  124. package/skills/blueking-chat-x/references/components/user-question-answered-card.md +104 -0
  125. package/skills/blueking-chat-x/references/components/user-question-card.md +231 -0
  126. package/skills/blueking-chat-x/references/components/user-question-choice.md +105 -0
  127. package/skills/blueking-chat-x/references/components/user-question-option.md +42 -0
  128. package/skills/blueking-chat-x/references/components/vnode-renderer.md +122 -0
  129. package/skills/blueking-chat-x/references/composables/use-animation-text.md +196 -0
  130. package/skills/blueking-chat-x/references/composables/use-artifact-preview.md +231 -0
  131. package/skills/blueking-chat-x/references/composables/use-clipboard.md +203 -0
  132. package/skills/blueking-chat-x/references/composables/use-command-selection.md +150 -0
  133. package/skills/blueking-chat-x/references/composables/use-container-scroll.md +57 -0
  134. package/skills/blueking-chat-x/references/composables/use-custom-tab.md +158 -0
  135. package/skills/blueking-chat-x/references/composables/use-flow-node-actions.md +157 -0
  136. package/skills/blueking-chat-x/references/composables/use-full-screen.md +112 -0
  137. package/skills/blueking-chat-x/references/composables/use-global-config.md +148 -0
  138. package/skills/blueking-chat-x/references/composables/use-menu-keydown.md +163 -0
  139. package/skills/blueking-chat-x/references/composables/use-message-group.md +247 -0
  140. package/skills/blueking-chat-x/references/composables/use-observer-visible-list.md +188 -0
  141. package/skills/blueking-chat-x/references/composables/use-parent-scrolling.md +46 -0
  142. package/skills/blueking-chat-x/references/theme/theme.md +431 -0
  143. package/skills/blueking-chat-x/references/types/constants.md +307 -0
  144. package/skills/blueking-chat-x/references/types/interrupt.md +379 -0
  145. package/skills/blueking-chat-x/references/types/messages.md +553 -0
  146. package/skills/blueking-chat-x/references/types/schema.md +91 -0
  147. package/skills/blueking-chat-x/scripts/generate-references.mjs +314 -0
@@ -0,0 +1,202 @@
1
+ # AnimationText 动画文本
2
+
3
+ > 能力域:内容渲染 | 导入:`import { AnimationText } from '@blueking/chat-x'` | since 1.0.0
4
+
5
+ 按文本增量播放流式动画。 源码位置:src/components/animation-text/animation-text.vue。
6
+
7
+ **关联**:use-animation-text(提供 chunk 拆分与 animationStyle 的 composable)、markdown-content(流式 Markdown 中可与渐显策略配合)
8
+
9
+ ---
10
+
11
+ # AnimationText 动画文本
12
+ ## 源码事实
13
+
14
+ - **源码位置**:`src/components/animation-text/animation-text.vue`
15
+ - **能力域**:内容渲染
16
+ - **能力说明**:按文本增量播放流式动画。
17
+
18
+ > **能力域**:内容渲染
19
+
20
+ 动画文本基础组件,将文本以**淡入(fade-in)**方式渐显。内部由 `useAnimationText` composable 驱动,核心能力是将增量文本拆分为独立 chunk,每个 chunk 单独触发一次淡入动画,适用于流式文本的逐段渐显效果。
21
+
22
+ ## 组件结构
23
+
24
+ ```
25
+ AnimationText
26
+ └── <span v-for="chunk in chunks" :style="animationStyle">
27
+ {{ chunk }}
28
+ </span>
29
+
30
+ animationStyle = {
31
+ animation: `ai-markdown-fade-in {fadeDuration}ms {easing} forwards`,
32
+ color: 'inherit',
33
+ }
34
+
35
+ @keyframes ai-markdown-fade-in {
36
+ 0% { opacity: 0; }
37
+ 100% { opacity: 1; }
38
+ }
39
+ ```
40
+
41
+ > **注意**:`AnimationText` 组件将 `props.text`(字符串原始值)传给 `useAnimationText`,watch 只触发一次(挂载时),**prop 变化后不会触发新动画**。若需响应式流式效果,请直接使用 `useAnimationText` composable,并传入 `Ref<string>`。
42
+
43
+ ## 基础用法
44
+
45
+ 挂载时文本以淡入方式显示,适合一次性展示的短文本动画:
46
+
47
+ ```vue
48
+ <template>
49
+ <AnimationText text="这是一段带动画效果的文本" />
50
+ </template>
51
+
52
+ <script setup lang="ts">
53
+ import { AnimationText } from '@blueking/chat-x';
54
+ </script>
55
+ ```
56
+
57
+ ## 流式文本(推荐使用 composable)
58
+
59
+ 对于流式输出场景,需直接使用 `useAnimationText` 并传入响应式 `Ref<string>`:
60
+
61
+ ```vue
62
+ <template>
63
+ <span
64
+ v-for="(chunk, index) in streamChunks"
65
+ :key="index"
66
+ :style="streamAnimStyle"
67
+ >{{ chunk }}</span
68
+ >
69
+ </template>
70
+
71
+ <script setup lang="ts">
72
+ import { ref, watch } from 'vue';
73
+
74
+ const streamText = ref('');
75
+ const streamChunks = ref<string[]>([]);
76
+ const streamAnimStyle = {
77
+ animation: 'ai-markdown-fade-in 200ms ease-in-out forwards',
78
+ color: 'inherit',
79
+ };
80
+
81
+ // 直接 watch Ref(Vue 自动追踪 .value 变化)
82
+ // ⚠️ 不能写成 watch(() => streamText, ...),那样 getter 每次返回同一个 Ref 引用,永远不触发
83
+ watch(streamText, (newVal, oldVal) => {
84
+ if (!oldVal || !newVal.startsWith(oldVal)) {
85
+ streamChunks.value = [newVal]; // 内容替换 → 整体重置
86
+ } else {
87
+ const chunk = newVal.slice(oldVal.length);
88
+ if (chunk) streamChunks.value = [...streamChunks.value, chunk]; // 追加 → 新 chunk 淡入
89
+ }
90
+ });
91
+
92
+ // 模拟流式追加
93
+ async function receiveStream() {
94
+ streamText.value = '';
95
+ streamChunks.value = [];
96
+ for (const char of '来自 AI 的流式回复内容...') {
97
+ streamText.value += char;
98
+ await new Promise(r => setTimeout(r, 80));
99
+ }
100
+ }
101
+ </script>
102
+ ```
103
+
104
+ **效果演示**(点击按钮触发流式输出)
105
+
106
+ ## chunk 增量算法
107
+
108
+ `useAnimationText` 内部通过**前缀检测**将文本变化拆分为增量 chunk:
109
+
110
+ ```
111
+ 新文本以旧文本为前缀(即纯追加)→ 截取增量部分 → 追加新 chunk(触发新动画)
112
+ 新文本与旧文本无前缀关系(内容替换)→ 清空所有 chunk → 用完整新文本创建单一 chunk
113
+ ```
114
+
115
+ ```typescript
116
+ // watch 内部逻辑(简化)
117
+ if (newText === prevText) return; // 无变化,跳过
118
+
119
+ if (prevText && newText.startsWith(prevText)) {
120
+ // 追加模式:只有新增部分触发淡入
121
+ const newChunk = newText.slice(prevText.length);
122
+ chunks.value = [...chunks.value, newChunk];
123
+ } else {
124
+ // 重置模式:内容替换,整体重新淡入
125
+ chunks.value = [newText];
126
+ }
127
+ prevText = newText;
128
+ ```
129
+
130
+ | 场景 | 示例 | 行为 |
131
+ | --------------- | ------------------------------------------ | ------------------------------ |
132
+ | 流式追加(SSE) | `"Hello"` → `"Hello Wo"` → `"Hello World"` | 每次增量部分单独淡入 |
133
+ | 内容完全替换 | `"旧文本"` → `"新文本"` | 清空所有 chunk,新文本整体淡入 |
134
+ | 相同内容 | `"文本"` → `"文本"` | 不做任何处理,跳过 |
135
+
136
+ ## 自定义动画参数
137
+
138
+ `useAnimationText` 支持通过第二个参数自定义动画时长和缓动:
139
+
140
+ ```typescript
141
+ import { ref } from 'vue';
142
+ import { useAnimationText } from '@blueking/chat-x';
143
+
144
+ const text = ref('');
145
+ const { chunks, animationStyle } = useAnimationText(text, {
146
+ fadeDuration: 400, // 动画时长(ms),默认 200
147
+ easing: 'ease-out', // CSS easing,默认 'ease-in-out'
148
+ });
149
+ ```
150
+
151
+ 生成的 `animationStyle`:
152
+
153
+ ```typescript
154
+ // animationStyle 是 computed,格式为:
155
+ {
156
+ animation: `ai-markdown-fade-in ${fadeDuration}ms ${easing} forwards`,
157
+ color: 'inherit',
158
+ }
159
+ ```
160
+
161
+ > **关键帧**:`ai-markdown-fade-in` 定义在库的全局样式中,仅做透明度变化(`opacity: 0 → 1`),无位移或缩放。
162
+
163
+ ## API
164
+
165
+ ### AnimationText Props
166
+
167
+ | 属性名 | 类型 | 必填 | 说明 |
168
+ | ------ | -------- | ---- | ----------------------------------------------- |
169
+ | text | `string` | ✓ | 要显示的文本;仅挂载时触发动画,prop 更新后无效 |
170
+
171
+ ### useAnimationText
172
+
173
+ ```typescript
174
+ function useAnimationText(
175
+ text: MaybeRef<string>, // 字符串或 Ref<string>,传 Ref 才能响应变化
176
+ options?: AnimationConfig,
177
+ ): {
178
+ chunks: Ref<string[]>; // 分割后的文本块数组,v-for 遍历渲染
179
+ animationStyle: ComputedRef<{
180
+ // 应用到每个 <span> 的 inline style
181
+ animation: string;
182
+ color: 'inherit';
183
+ }>;
184
+ };
185
+
186
+ interface AnimationConfig {
187
+ fadeDuration?: number; // 动画时长(ms),默认 200
188
+ easing?: string; // CSS easing,默认 'ease-in-out'
189
+ }
190
+ ```
191
+
192
+ ## 注意事项
193
+
194
+ 1. **`AnimationText` 不响应 prop 更新**:组件内部传的是字符串原始值,若需动态响应,直接用 `watch(myRef, ...)` 手动实现 chunk 逻辑
195
+ 2. **流式场景不要使用 `useAnimationText`**:该 composable 内部使用 `watch(() => text, ...)` 的 getter 形式,当传入 `Ref<string>` 时,getter 每次返回同一个 Ref 引用,Vue 无法检测到 `.value` 变化,watch 只触发一次(immediate)。正确做法是直接 `watch(streamText, callback)` 绑定 Ref
196
+ 3. **动画 keyframe 依赖全局样式**:使用 `@blueking/chat-x` 时会自动引入;独立使用时需确保 `ai-markdown-fade-in` 已定义
197
+ 4. **chunks 只增不减**(追加模式下):流式结束后 chunks 保留所有历史分段,若需复用,手动清空 `chunks.value = []` 再重置文本即可
198
+
199
+ ## 关联组件
200
+
201
+ - [useAnimationText](../../composables/use-animation-text.md) — chunk 与动画样式逻辑
202
+ - [MarkdownContent](/components/rendering/markdown-content) — 流式正文渲染时可配合渐显
@@ -0,0 +1,498 @@
1
+ # AssistantMessage AI 助手消息
2
+
3
+ > 能力域:消息系统 | 导入:`import { AssistantMessage } from '@blueking/chat-x'` | since 0.0.20
4
+
5
+ 渲染助手 Markdown 正文、ToolCallRender 工具调用列表,以及 property.artifacts 文件卡片; 默认插槽仅覆盖正文。源码位置:src/components/chat-message/assistant-message/assistant-message.vue。
6
+
7
+ **关联**:message-render(由 MessageRender 在 role 为 assistant 时创建)、tool-message(工具结果通过 toolCall.toolMessage 内联或独立 tool 消息关联展示)、toolcall-render(多条工具调用由 ToolcallRender 统一渲染)、file-artifact-panel(property.artifacts 文件产物点击后在侧栏预览)
8
+
9
+ ---
10
+
11
+ # AssistantMessage AI 助手消息
12
+
13
+ ## 源码事实
14
+
15
+ - **源码位置**:`src/components/chat-message/assistant-message/assistant-message.vue`
16
+ - **能力域**:消息系统
17
+ - **能力说明**:渲染助手 Markdown 正文、工具调用列表与 `property.artifacts` 文件产物。
18
+
19
+ > **导出说明**:`AssistantMessage` **未**从 `@blueking/chat-x` 包入口导出(入口同名是 TS interface)。消费方请用 `MessageRender` / `MessageContainer`。下文 `AssistantMessageComp` 为文档站内部相对路径示例。
20
+
21
+ AI 助手消息展示组件:正文(Markdown)、工具调用(Tool Calls)、文件产物卡片。
22
+
23
+ ## 渲染管线
24
+
25
+ ```
26
+ AssistantMessage(根类名:ai-assistant-message)
27
+ ├── ai-assistant-message-content(内容区,v-if content)
28
+ │ └── [default slot { content }] 或 ContentRender → MarkdownContent
29
+ ├── ai-assistant-message-toolcalls(v-if toolCalls 非空,flex column,gap: 8px)
30
+ │ └── ToolCallRender × N(toolCalls,不受 slot 影响)
31
+ └── MessageArtifacts(v-if property.artifacts 非空)
32
+ └── ArtifactFileCard × N(点击 → useArtifactPreview → 侧栏 FileArtifactPanel → ArtifactPreviewHost)
33
+ ```
34
+
35
+ - **内容区**:`content` 经 `ContentRender`(`MessageContentType.Text`)由 `MarkdownContent` 渲染;default slot 仅收到 `{ content }`
36
+ - **工具调用区**:每个 `toolCall` 渲染一个 `ToolCallRender`,位于内容区下方;多条工具调用由 `.ai-assistant-message-toolcalls` 容器统一控制为 `8px` 间距,不受消息根节点 `12px` 间距影响
37
+ - **文件产物区**:读取 `property.artifacts`,用 `uid ?? String(id)` 作为 `messageUid` 传给 `MessageArtifacts`
38
+
39
+ ## 基础用法
40
+
41
+ ```vue
42
+ <template>
43
+ <MessageRender :message="message" />
44
+ </template>
45
+
46
+ <script setup lang="ts">
47
+ import { MessageRender, MessageRole, MessageStatus } from '@blueking/chat-x';
48
+
49
+ const message = {
50
+ id: '1',
51
+ messageId: '1',
52
+ role: MessageRole.Assistant,
53
+ content: '你好!我是 AI 助手,有什么可以帮助你的吗?',
54
+ status: MessageStatus.Complete,
55
+ };
56
+ </script>
57
+ ```
58
+
59
+ **渲染效果**
60
+
61
+ ## Markdown 内容渲染
62
+
63
+ `content` 支持 Markdown 格式,组件内部通过 `MarkdownContent` 自动渲染标题、列表、代码块、链接等:
64
+
65
+ ```vue
66
+ <template>
67
+ <MessageRender :message="message" />
68
+ </template>
69
+
70
+ <script setup lang="ts">
71
+ import { MessageRender, MessageRole, MessageStatus } from '@blueking/chat-x';
72
+
73
+ const message = {
74
+ id: '1',
75
+ messageId: '1',
76
+ role: MessageRole.Assistant,
77
+ status: MessageStatus.Complete,
78
+ content: `## Vue 3 核心特性
79
+
80
+ Vue 3 引入了多项重要更新:
81
+
82
+ 1. **Composition API**:提供更灵活的逻辑组织方式
83
+ 2. **性能优化**:虚拟 DOM 重写,编译时优化
84
+ 3. **TypeScript 支持**:内置完整的类型定义
85
+
86
+ \\\`\\\`\\\`typescript
87
+ import { ref, computed } from 'vue';
88
+
89
+ const count = ref(0);
90
+ const doubled = computed(() => count.value * 2);
91
+ \\\`\\\`\\\`
92
+
93
+ > 更多详情请参考 [Vue 3 官方文档](https://vuejs.org)。`,
94
+ };
95
+ </script>
96
+ ```
97
+
98
+ **渲染效果**
99
+
100
+ ## 消息状态
101
+
102
+ `status` 直接影响 **内容区**(`ContentRender`)。`ToolCallRender` 的状态**按工具维度推导**(见下方「工具调用状态推导」),不直接等于本组件的 `status`。
103
+
104
+ | `status` | 内容区效果 |
105
+ | ----------- | ----------------------------------- |
106
+ | `pending` | 正常渲染(通常 content 为空) |
107
+ | `streaming` | Markdown 自动补全未闭合语法 |
108
+ | `complete` | 正常渲染完整 Markdown |
109
+ | `error` | 红色错误图标 + content 作为错误提示 |
110
+ | `stop` | 正常渲染(内容停留在中止时的状态) |
111
+
112
+ ### Pending
113
+
114
+ ### Streaming
115
+
116
+ 流式输出中,`MarkdownContent` 自动补全未闭合的 Markdown 语法(代码块、列表等),适合逐字/逐段追加内容:
117
+
118
+ ### Complete
119
+
120
+ ### Error
121
+
122
+ 渲染为错误信息样式(红色错误图标),`content` 作为错误提示文案展示:
123
+
124
+ ### Stop
125
+
126
+ 用户手动中止生成,内容停留在中止时的状态,与 `complete` 表现相同:
127
+
128
+ ## 工具调用
129
+
130
+ 当 AI 回复中包含工具调用时,传入 `toolCalls` 数组,每项自动渲染为 `ToolCallRender`,位于内容区下方。传给每个 `ToolCallRender` 的 `status` 按下方优先级从 `toolCall.toolMessage` 推导,而非直接同步本组件的 `status`。
131
+
132
+ ### 单个工具调用
133
+
134
+ ```vue
135
+ <template>
136
+ <MessageRender :message="message" />
137
+ </template>
138
+
139
+ <script setup lang="ts">
140
+ import { MessageRender, MessageRole, MessageStatus } from '@blueking/chat-x';
141
+
142
+ const message = {
143
+ id: '1',
144
+ messageId: '1',
145
+ role: MessageRole.Assistant,
146
+ content: '让我帮你查询一下天气信息。',
147
+ status: MessageStatus.Complete,
148
+ toolCalls: [
149
+ {
150
+ id: 'call_1',
151
+ type: 'function',
152
+ function: {
153
+ name: 'get_weather',
154
+ arguments: '{"city": "北京", "unit": "celsius"}',
155
+ description: '获取指定城市的天气信息',
156
+ },
157
+ },
158
+ ],
159
+ };
160
+ </script>
161
+ ```
162
+
163
+ **渲染效果**
164
+
165
+ ### 多个工具调用
166
+
167
+ AI 可在一次回复中发起多个工具调用,组件依次渲染:
168
+
169
+ ```vue
170
+ <script setup lang="ts">
171
+ const toolCalls = [
172
+ {
173
+ id: 'call_1',
174
+ type: 'function',
175
+ function: {
176
+ name: 'search_documents',
177
+ arguments: '{"query": "Vue 3 Composition API"}',
178
+ description: '搜索知识库中的相关文档',
179
+ },
180
+ },
181
+ {
182
+ id: 'call_2',
183
+ type: 'function',
184
+ function: {
185
+ name: 'get_code_snippet',
186
+ arguments: '{"language": "typescript", "topic": "ref vs reactive"}',
187
+ description: '获取代码示例片段',
188
+ },
189
+ },
190
+ ];
191
+ </script>
192
+ ```
193
+
194
+ **渲染效果**
195
+
196
+ ### MCP 工具调用
197
+
198
+ `function.type` 为 `'mcp'`(或旧数据仅有 `mcpName`)时,`ToolCallRender` 头部显示为「调用 MCP {mcpName} / {name}」:
199
+
200
+ ```vue
201
+ <script setup lang="ts">
202
+ const toolCalls = [
203
+ {
204
+ id: 'call_mcp_1',
205
+ type: 'function',
206
+ function: {
207
+ type: 'mcp', // 调用类型,缺省时有 mcpName 也会兼容判定为 MCP
208
+ name: 'query_database',
209
+ arguments: '{"sql": "SELECT * FROM users LIMIT 10"}',
210
+ description: '执行数据库查询',
211
+ mcpName: 'database-server', // MCP 服务名
212
+ },
213
+ },
214
+ ];
215
+ </script>
216
+ ```
217
+
218
+ **渲染效果**
219
+
220
+ ### 携带执行结果
221
+
222
+ `toolMessage` 字段包含工具的执行结果;`ToolCallRender` 会展示返回内容(JSON 自动解析为键值对)和执行耗时:
223
+
224
+ ```vue
225
+ <script setup lang="ts">
226
+ const toolCalls = [
227
+ {
228
+ id: 'call_1',
229
+ type: 'function',
230
+ function: {
231
+ name: 'get_weather',
232
+ arguments: '{"city": "北京"}',
233
+ description: '获取天气信息',
234
+ },
235
+ toolMessage: {
236
+ role: 'tool',
237
+ content: '{"weather":"晴","temperature":"22°C","humidity":"45%","wind":"东北风 3 级"}',
238
+ status: 'complete',
239
+ duration: 1200, // 毫秒
240
+ toolCallId: 'call_1',
241
+ },
242
+ },
243
+ ];
244
+ </script>
245
+ ```
246
+
247
+ **渲染效果**(点击展开箭头可查看返回结果)
248
+
249
+ ### 工具调用失败
250
+
251
+ `toolMessage.error` 不为空时,`ToolCallRender` 显示错误信息:
252
+
253
+ ```vue
254
+ <script setup lang="ts">
255
+ const toolCalls = [
256
+ {
257
+ id: 'call_1',
258
+ type: 'function',
259
+ function: {
260
+ name: 'get_weather',
261
+ arguments: '{"city": "北京"}',
262
+ description: '获取天气信息',
263
+ },
264
+ toolMessage: {
265
+ role: 'tool',
266
+ content: '',
267
+ status: 'error',
268
+ error: 'API rate limit exceeded',
269
+ duration: 350,
270
+ toolCallId: 'call_1',
271
+ },
272
+ },
273
+ ];
274
+ </script>
275
+ ```
276
+
277
+ **渲染效果**
278
+
279
+ ### 工具调用状态推导
280
+
281
+ 传给每个 `ToolCallRender` 的 `status` 按以下优先级计算:
282
+
283
+ 1. 无 `toolMessage` → `MessageStatus.Pending`(进行中)
284
+ 2. `toolMessage.error` 为真 → `MessageStatus.Error`(失败)
285
+ 3. 否则 → `toolMessage.status ??` 本组件 `status`
286
+
287
+ **进行中**(有 `toolCalls`、尚无 `toolMessage`;即便助手 `status` 已是 `complete`,工具调用仍显示「正在调用」):
288
+
289
+ **成功**(`toolMessage.status = "complete"`):
290
+
291
+ ## 自定义内容渲染
292
+
293
+ 默认插槽替换**内容区**的渲染(即 `ContentRender` 部分),工具调用仍在内容区外独立渲染,不受插槽影响:
294
+
295
+ ```
296
+ [自定义 slot 内容] ← 替换 ai-assistant-message-content 内默认渲染
297
+ [ToolCallRender] ← 不受影响,仍正常渲染
298
+ [ToolCallRender]
299
+ ```
300
+
301
+ ```vue
302
+ <template>
303
+ <MessageRender :message="message">
304
+ <template #default="{ content }">
305
+ <div style="padding: 12px; background: #f0f9ff; border-left: 3px solid #3a84ff; border-radius: 4px;">
306
+ {{ content }}
307
+ </div>
308
+ </template>
309
+ </MessageRender>
310
+ </template>
311
+ ```
312
+
313
+ > **注意**:使用默认插槽后,内置 Markdown 渲染被替换,需自行处理格式化。slot 运行时仅保证 `{ content }`(见 [MessageRender](/components/message/message-render))。
314
+
315
+ **渲染效果**
316
+
317
+ ## 在 MessageContainer 中使用
318
+
319
+ `AssistantMessage` 通常不需要单独引入,`MessageContainer` 会对 `role: 'assistant'` 的消息自动渲染:
320
+
321
+ ```vue
322
+ <template>
323
+ <MessageContainer :messages="messages" />
324
+ </template>
325
+
326
+ <script setup lang="ts">
327
+ import { MessageContainer } from '@blueking/chat-x';
328
+
329
+ const messages = [
330
+ {
331
+ id: '1',
332
+ messageId: '1',
333
+ role: 'user',
334
+ content: '北京今天天气怎么样?',
335
+ status: 'complete',
336
+ },
337
+ {
338
+ id: '2',
339
+ messageId: '2',
340
+ role: 'assistant',
341
+ content: '让我帮你查询一下天气信息。',
342
+ status: 'complete',
343
+ toolCalls: [
344
+ {
345
+ id: 'call_1',
346
+ type: 'function',
347
+ function: {
348
+ name: 'get_weather',
349
+ arguments: '{"city": "北京"}',
350
+ description: '获取天气',
351
+ },
352
+ toolMessage: {
353
+ role: 'tool',
354
+ content: '{"weather":"晴","temperature":"22°C"}',
355
+ status: 'complete',
356
+ duration: 800,
357
+ toolCallId: 'call_1',
358
+ },
359
+ },
360
+ ],
361
+ },
362
+ {
363
+ id: '3',
364
+ messageId: '3',
365
+ role: 'assistant',
366
+ content: '北京今天天气晴朗,气温 22°C,适合出行。',
367
+ status: 'complete',
368
+ },
369
+ ];
370
+ </script>
371
+ ```
372
+
373
+ ## 文件产物
374
+
375
+ 当 `property.artifacts` 非空时,在工具调用区下方渲染 `MessageArtifacts` 文件卡片列表。点击卡片会通过 `useArtifactPreview` 打开 `ChatContainer` 侧栏「文件产物」Tab(见 [FileArtifactPanel](/components/message/file-artifact-panel))。
376
+
377
+ `AIFileInfo` 仅含元信息(`name` / `outputId` / `size` / `type`);`download_url` / `preview_url` 由容器 `onArtifactClick` 异步获取。命中唯一文件依赖 `messageUid = uid ?? String(id)` + 卡片下标 + `outputId`。
378
+
379
+ 侧栏预览由面板内 `ArtifactPreviewHost` 按**文件分类**分派(详见面板文档「预览机制」):
380
+
381
+ | 分类 | 典型 type | 预览依赖 | 渲染 |
382
+ | ---- | --------- | -------- | ---- |
383
+ | 源码 / 配置 | `py` / `ts` / `json` / `yaml` / `Dockerfile` | `download_url` | highlight.js 高亮 |
384
+ | Markdown | `md` / `markdown` | `download_url` | MarkdownContent 富文本 |
385
+ | HTML | `html` / `htm` | `download_url` | `<iframe srcdoc>` 真实渲染 |
386
+ | 纯文本 | `txt` / `rst` | `download_url` | `<pre>` |
387
+ | 图片 | `png` / `jpg` / `svg` | `preview_url` | `<img>` |
388
+ | 其余(含未知类型) | `pdf` / `docx` / `xlsx` | `preview_url` | iframe(一般为后台转好的 PDF) |
389
+
390
+ `type` 为扩展名字符串(大小写不敏感),缺省时回退文件名推断;`md` 与 `markdown` 等价。预览重载、重试与取链约定见 [FileArtifactPanel 预览机制](/components/message/file-artifact-panel#预览机制)。
391
+
392
+ ```vue
393
+ <template>
394
+ <MessageRender :message="message" />
395
+ </template>
396
+
397
+ <script setup lang="ts">
398
+ import { MessageRender, MessageRole, MessageStatus } from '@blueking/chat-x';
399
+ import type { AIFileInfo } from '@blueking/chat-x';
400
+
401
+ const artifacts: AIFileInfo[] = [
402
+ { name: '监控大盘周报.html', outputId: 'output-html', size: 10240, type: 'html' },
403
+ { name: '系统配置说明.md', outputId: 'output-md', size: 8192, type: 'md' },
404
+ { name: '周例会纪要.txt', outputId: 'output-txt', size: 4096, type: 'txt' },
405
+ { name: '告警策略配置.json', outputId: 'output-json', size: 2048, type: 'json' },
406
+ { name: '立项说明书.pdf', outputId: 'output-pdf', size: 204800, type: 'pdf' },
407
+ { name: '巡检现场照片.jpg', outputId: 'output-jpg', size: 1048576, type: 'jpg' },
408
+ ];
409
+
410
+ const message = {
411
+ id: 'a1',
412
+ messageId: 'a1',
413
+ uid: 'assistant-uid-1',
414
+ role: MessageRole.Assistant,
415
+ status: MessageStatus.Complete,
416
+ content: '已为你生成一组评审材料,可点击卡片在侧栏预览或下载:',
417
+ property: { artifacts },
418
+ };
419
+ </script>
420
+ ```
421
+
422
+ **渲染效果(文档站内部示例;无 Provider 时卡片不可点击预览)**
423
+
424
+ ## API
425
+
426
+ ### Props
427
+
428
+ 组件 Props 来自 `Partial<AssistantMessage>`(所有字段均可选):
429
+
430
+ | 属性名 | 类型 | 说明 |
431
+ | --------- | ----------------------- | ----------------------------------------------------------------------------------------- |
432
+ | content | `string` | AI 回复文本,支持 Markdown;空值时不渲染内容区 |
433
+ | status | `MessageStatus` | 影响 ContentRender;ToolCallRender 在无 toolMessage.status 时回退使用此值 |
434
+ | toolCalls | `ToolCall[]` | 工具调用列表,每项渲染一个 `ToolCallRender` |
435
+ | id | `number \| string` | 消息 ID;无 `uid` 时回退为 `messageUid` |
436
+ | messageId | `number \| string` | 消息唯一标识 |
437
+ | uid | `string` | 优先作为文件产物命中 / 「在对话中定位」的 `messageUid` |
438
+ | name | `string` | 消息发送者名称(可选) |
439
+ | role | `MessageRole.Assistant` | 消息角色,固定为 `'assistant'` |
440
+ | property | `{ artifacts?: AIFileInfo[]; extra?: ... }` | **本组件消费** `property.artifacts` 渲染文件卡片;`extra` 等由上层按需使用 |
441
+
442
+ ### Slots
443
+
444
+ | 插槽名 | 参数 | 说明 |
445
+ | ------- | --------------------- | ----------------------------------------------------------------- |
446
+ | default | `{ content: string }` | 替换内容区渲染;toolCalls / MessageArtifacts 在内容区外独立渲染 |
447
+
448
+ ### Events / Expose
449
+
450
+ 无。
451
+
452
+ ## 类型定义
453
+
454
+ ```typescript
455
+ import type { AssistantMessage, ToolCall, FunctionCall, ToolMessage } from '@blueking/chat-x';
456
+
457
+ interface AssistantMessage extends BaseMessage<MessageRole.Assistant> {
458
+ toolCalls?: ToolCall[];
459
+ }
460
+
461
+ // 工具调用
462
+ type ToolCall = {
463
+ id: string;
464
+ type: MessageContentType.Function; // 固定为 'function'
465
+ function: FunctionCall;
466
+ toolMessage?: Partial<ToolMessage>; // 工具执行结果(可选)
467
+ };
468
+
469
+ // 函数调用信息
470
+ type FunctionCall = {
471
+ name: string; // 函数名
472
+ arguments: string; // JSON 字符串格式的参数
473
+ description?: string; // 函数描述
474
+ mcpName?: string; // MCP 服务名(存在时标题显示 "调用 MCP")
475
+ };
476
+
477
+ // 工具执行结果
478
+ interface ToolMessage extends BaseMessage<MessageRole.Tool, string> {
479
+ toolCallId: string; // 对应的 ToolCall.id
480
+ duration: number; // 执行耗时(ms)
481
+ error?: string; // 错误信息(存在时 ToolCallRender 显示失败状态)
482
+ }
483
+ ```
484
+
485
+ ## 使用场景
486
+
487
+ - **文本消息展示**:聊天界面渲染 AI 回复的 Markdown 文本
488
+ - **工具调用过程展示**:展示 Function Call / MCP 调用的参数、状态和返回结果
489
+ - **流式输出**:`streaming` 状态下 Markdown 自动补全未闭合语法,配合流式响应实时更新
490
+ - **自动渲染**:通过 `MessageContainer` 对 `role: 'assistant'` 消息自动处理,无需手动引入
491
+ - **自定义内容渲染**:通过默认插槽替换内置 Markdown 渲染器,保留工具调用渲染
492
+
493
+ ## 关联组件
494
+
495
+ - [MessageRender](/components/message/message-render) — assistant 角色由其实例化
496
+ - [ToolMessage](/components/message/tool-message) — 工具执行结果可通过 toolCall.toolMessage 内联
497
+ - [ToolcallRender](/components/agent/toolcall-render) — 工具调用列表渲染
498
+ - [FileArtifactPanel](/components/message/file-artifact-panel) — 文件产物侧栏列表与分类型预览 Host