@blueking/chat-x 0.0.48-beta.1 → 0.0.49-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.
- package/dist/ag-ui/types/constants.d.ts +1 -0
- package/dist/ag-ui/types/file.d.ts +23 -0
- package/dist/ag-ui/types/index.d.ts +1 -0
- package/dist/ag-ui/types/messages.d.ts +2 -0
- package/dist/components/chat-message/assistant-message/assistant-message.vue.d.ts +12 -1
- package/dist/components/chat-message/assistant-message/message-artifacts/artifact-file-card.vue.d.ts +12 -0
- package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/artifact-preview-host.vue.d.ts +7 -0
- package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/preview-strategy.d.ts +9 -0
- package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/renderers/html-preview.vue.d.ts +6 -0
- package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/renderers/markdown-preview.vue.d.ts +6 -0
- package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/renderers/txt-preview.vue.d.ts +6 -0
- package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/renderers/url-iframe-preview.vue.d.ts +6 -0
- package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/use-artifact-preview-loader.d.ts +23 -0
- package/dist/components/chat-message/assistant-message/message-artifacts/file-artifact-panel.vue.d.ts +12 -0
- package/dist/components/chat-message/assistant-message/message-artifacts/file-icon.d.ts +29 -0
- package/dist/components/chat-message/assistant-message/message-artifacts/message-artifacts.vue.d.ts +9 -0
- package/dist/components/chat-message/interrupt-message/user-question/use-user-question.d.ts +7 -2
- package/dist/components/chat-message/user-message/user-message.vue.d.ts +14 -2
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/use-artifact-preview.d.ts +56 -0
- package/dist/composables/use-custom-tab.d.ts +2 -0
- package/dist/composables/use-message-group.d.ts +433 -0
- package/dist/icons/file.d.ts +24 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/index.css +1 -1
- package/dist/index.js +2217 -1689
- package/dist/index.js.map +1 -1
- package/dist/lang/lang.d.ts +8 -1
- package/dist/mcp/generated/docs/activity-message.md +122 -97
- package/dist/mcp/generated/docs/assistant-message.md +125 -62
- package/dist/mcp/generated/docs/chat-container.md +97 -18
- package/dist/mcp/generated/docs/chat-input.md +2 -10
- package/dist/mcp/generated/docs/constants.md +3 -1
- package/dist/mcp/generated/docs/content-render.md +2 -10
- package/dist/mcp/generated/docs/file-artifact-panel.md +275 -0
- package/dist/mcp/generated/docs/info-message.md +29 -12
- package/dist/mcp/generated/docs/interrupt.md +1 -0
- package/dist/mcp/generated/docs/loading-message.md +36 -17
- package/dist/mcp/generated/docs/message-container.md +4 -21
- package/dist/mcp/generated/docs/message-render.md +47 -59
- package/dist/mcp/generated/docs/messages.md +5 -0
- package/dist/mcp/generated/docs/reasoning-message.md +17 -20
- package/dist/mcp/generated/docs/tool-message.md +61 -45
- package/dist/mcp/generated/docs/toolcall-render.md +8 -8
- package/dist/mcp/generated/docs/use-artifact-preview.md +232 -0
- package/dist/mcp/generated/docs/use-custom-tab.md +18 -5
- package/dist/mcp/generated/docs/use-message-group.md +29 -0
- package/dist/mcp/generated/docs/user-message.md +185 -121
- package/dist/mcp/generated/docs/user-question-card.md +6 -3
- package/dist/mcp/generated/index.json +83 -13
- package/dist/mcp/index.js +0 -0
- package/package.json +20 -21
|
@@ -1,54 +1,61 @@
|
|
|
1
1
|
<!-- AI SUMMARY -->
|
|
2
2
|
## 快速了解
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
渲染助手 Markdown 正文、ToolCallRender 工具调用列表,以及 property.artifacts 文件卡片; 默认插槽仅覆盖正文。源码位置:src/components/chat-message/assistant-message/assistant-message.vue。
|
|
5
5
|
|
|
6
6
|
### 关联组件
|
|
7
7
|
- **message-render** — 由 MessageRender 在 role 为 assistant 时创建
|
|
8
8
|
- **tool-message** — 工具结果通过 toolCall.toolMessage 内联或独立 tool 消息关联展示
|
|
9
9
|
- **toolcall-render** — 多条工具调用由 ToolcallRender 统一渲染
|
|
10
|
+
- **file-artifact-panel** — property.artifacts 文件产物点击后在侧栏预览
|
|
10
11
|
|
|
11
12
|
---
|
|
12
13
|
<!-- FULL DOC -->
|
|
13
14
|
|
|
14
15
|
# AssistantMessage AI 助手消息
|
|
16
|
+
|
|
15
17
|
## 源码事实
|
|
16
18
|
|
|
17
19
|
- **源码位置**:`src/components/chat-message/assistant-message/assistant-message.vue`
|
|
18
20
|
- **能力域**:消息系统
|
|
19
|
-
-
|
|
21
|
+
- **能力说明**:渲染助手 Markdown 正文、工具调用列表与 `property.artifacts` 文件产物。
|
|
20
22
|
|
|
21
|
-
>
|
|
23
|
+
> **导出说明**:`AssistantMessage` **未**从 `@blueking/chat-x` 包入口导出(入口同名是 TS interface)。消费方请用 `MessageRender` / `MessageContainer`。下文 `AssistantMessageComp` 为文档站内部相对路径示例。
|
|
22
24
|
|
|
23
|
-
AI
|
|
25
|
+
AI 助手消息展示组件:正文(Markdown)、工具调用(Tool Calls)、文件产物卡片。
|
|
24
26
|
|
|
25
27
|
## 渲染管线
|
|
26
28
|
|
|
27
29
|
```
|
|
28
30
|
AssistantMessage(根类名:ai-assistant-message)
|
|
29
|
-
├── ai-assistant-message-content
|
|
30
|
-
│ └── [default slot] 或 ContentRender → MarkdownContent
|
|
31
|
-
|
|
31
|
+
├── ai-assistant-message-content(内容区,v-if content)
|
|
32
|
+
│ └── [default slot { content }] 或 ContentRender → MarkdownContent
|
|
33
|
+
├── ToolCallRender × N(toolCalls,不受 slot 影响)
|
|
34
|
+
└── MessageArtifacts(v-if property.artifacts 非空)
|
|
35
|
+
└── ArtifactFileCard × N(点击 → useArtifactPreview → 侧栏 FileArtifactPanel → ArtifactPreviewHost)
|
|
32
36
|
```
|
|
33
37
|
|
|
34
|
-
- **内容区**:`content`
|
|
35
|
-
-
|
|
38
|
+
- **内容区**:`content` 经 `ContentRender`(`MessageContentType.Text`)由 `MarkdownContent` 渲染;default slot 仅收到 `{ content }`
|
|
39
|
+
- **工具调用区**:每个 `toolCall` 渲染一个 `ToolCallRender`,位于内容区下方
|
|
40
|
+
- **文件产物区**:读取 `property.artifacts`,用 `uid ?? String(id)` 作为 `messageUid` 传给 `MessageArtifacts`
|
|
36
41
|
|
|
37
42
|
## 基础用法
|
|
38
43
|
|
|
39
44
|
```vue
|
|
40
45
|
<template>
|
|
41
|
-
<
|
|
42
|
-
:content="content"
|
|
43
|
-
:status="status"
|
|
44
|
-
/>
|
|
46
|
+
<MessageRender :message="message" />
|
|
45
47
|
</template>
|
|
46
48
|
|
|
47
49
|
<script setup lang="ts">
|
|
48
|
-
import {
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
50
|
+
import { MessageRender, MessageRole, MessageStatus } from '@blueking/chat-x';
|
|
51
|
+
|
|
52
|
+
const message = {
|
|
53
|
+
id: '1',
|
|
54
|
+
messageId: '1',
|
|
55
|
+
role: MessageRole.Assistant,
|
|
56
|
+
content: '你好!我是 AI 助手,有什么可以帮助你的吗?',
|
|
57
|
+
status: MessageStatus.Complete,
|
|
58
|
+
};
|
|
52
59
|
</script>
|
|
53
60
|
```
|
|
54
61
|
|
|
@@ -60,16 +67,18 @@ AssistantMessage(根类名:ai-assistant-message)
|
|
|
60
67
|
|
|
61
68
|
```vue
|
|
62
69
|
<template>
|
|
63
|
-
<
|
|
64
|
-
:content="markdownContent"
|
|
65
|
-
status="complete"
|
|
66
|
-
/>
|
|
70
|
+
<MessageRender :message="message" />
|
|
67
71
|
</template>
|
|
68
72
|
|
|
69
73
|
<script setup lang="ts">
|
|
70
|
-
import {
|
|
74
|
+
import { MessageRender, MessageRole, MessageStatus } from '@blueking/chat-x';
|
|
71
75
|
|
|
72
|
-
const
|
|
76
|
+
const message = {
|
|
77
|
+
id: '1',
|
|
78
|
+
messageId: '1',
|
|
79
|
+
role: MessageRole.Assistant,
|
|
80
|
+
status: MessageStatus.Complete,
|
|
81
|
+
content: `## Vue 3 核心特性
|
|
73
82
|
|
|
74
83
|
Vue 3 引入了多项重要更新:
|
|
75
84
|
|
|
@@ -84,7 +93,8 @@ const count = ref(0);
|
|
|
84
93
|
const doubled = computed(() => count.value * 2);
|
|
85
94
|
\\\`\\\`\\\`
|
|
86
95
|
|
|
87
|
-
> 更多详情请参考 [Vue 3 官方文档](https://vuejs.org)
|
|
96
|
+
> 更多详情请参考 [Vue 3 官方文档](https://vuejs.org)。`,
|
|
97
|
+
};
|
|
88
98
|
</script>
|
|
89
99
|
```
|
|
90
100
|
|
|
@@ -126,27 +136,30 @@ const doubled = computed(() => count.value * 2);
|
|
|
126
136
|
|
|
127
137
|
```vue
|
|
128
138
|
<template>
|
|
129
|
-
<
|
|
130
|
-
content="让我帮你查询一下天气信息。"
|
|
131
|
-
:status="MessageStatus.Complete"
|
|
132
|
-
:tool-calls="toolCalls"
|
|
133
|
-
/>
|
|
139
|
+
<MessageRender :message="message" />
|
|
134
140
|
</template>
|
|
135
141
|
|
|
136
142
|
<script setup lang="ts">
|
|
137
|
-
import {
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
143
|
+
import { MessageRender, MessageRole, MessageStatus } from '@blueking/chat-x';
|
|
144
|
+
|
|
145
|
+
const message = {
|
|
146
|
+
id: '1',
|
|
147
|
+
messageId: '1',
|
|
148
|
+
role: MessageRole.Assistant,
|
|
149
|
+
content: '让我帮你查询一下天气信息。',
|
|
150
|
+
status: MessageStatus.Complete,
|
|
151
|
+
toolCalls: [
|
|
152
|
+
{
|
|
153
|
+
id: 'call_1',
|
|
154
|
+
type: 'function',
|
|
155
|
+
function: {
|
|
156
|
+
name: 'get_weather',
|
|
157
|
+
arguments: '{"city": "北京", "unit": "celsius"}',
|
|
158
|
+
description: '获取指定城市的天气信息',
|
|
159
|
+
},
|
|
147
160
|
},
|
|
148
|
-
|
|
149
|
-
|
|
161
|
+
],
|
|
162
|
+
};
|
|
150
163
|
</script>
|
|
151
164
|
```
|
|
152
165
|
|
|
@@ -285,20 +298,17 @@ AI 可在一次回复中发起多个工具调用,组件依次渲染:
|
|
|
285
298
|
|
|
286
299
|
```vue
|
|
287
300
|
<template>
|
|
288
|
-
<
|
|
289
|
-
:content="content"
|
|
290
|
-
:tool-calls="toolCalls"
|
|
291
|
-
>
|
|
301
|
+
<MessageRender :message="message">
|
|
292
302
|
<template #default="{ content }">
|
|
293
303
|
<div style="padding: 12px; background: #f0f9ff; border-left: 3px solid #3a84ff; border-radius: 4px;">
|
|
294
|
-
|
|
304
|
+
{{ content }}
|
|
295
305
|
</div>
|
|
296
306
|
</template>
|
|
297
|
-
</
|
|
307
|
+
</MessageRender>
|
|
298
308
|
</template>
|
|
299
309
|
```
|
|
300
310
|
|
|
301
|
-
>
|
|
311
|
+
> **注意**:使用默认插槽后,内置 Markdown 渲染被替换,需自行处理格式化。slot 运行时仅保证 `{ content }`(见 [MessageRender](/components/message/message-render))。
|
|
302
312
|
|
|
303
313
|
**渲染效果**
|
|
304
314
|
|
|
@@ -358,28 +368,80 @@ AI 可在一次回复中发起多个工具调用,组件依次渲染:
|
|
|
358
368
|
</script>
|
|
359
369
|
```
|
|
360
370
|
|
|
371
|
+
## 文件产物
|
|
372
|
+
|
|
373
|
+
当 `property.artifacts` 非空时,在工具调用区下方渲染 `MessageArtifacts` 文件卡片列表。点击卡片会通过 `useArtifactPreview` 打开 `ChatContainer` 侧栏「文件产物」Tab(见 [FileArtifactPanel](/components/message/file-artifact-panel))。
|
|
374
|
+
|
|
375
|
+
`AIFileInfo` 仅含元信息(`name` / `outputId` / `size` / `type`);`download_url` / `preview_url` 由容器 `onArtifactClick` 异步获取。命中唯一文件依赖 `messageUid = uid ?? String(id)` + 卡片下标 + `outputId`。
|
|
376
|
+
|
|
377
|
+
侧栏预览由面板内 `ArtifactPreviewHost` 按类型分派(详见面板文档「预览机制」):
|
|
378
|
+
|
|
379
|
+
| type | 预览依赖 | 渲染 |
|
|
380
|
+
| ---- | -------- | ---- |
|
|
381
|
+
| `html` / `markdown` / `md` / `txt` / `json` | `download_url` | 正文直渲染(srcdoc / MarkdownContent / `<pre>`) |
|
|
382
|
+
| `pdf` / `jpg` 等 | `preview_url` | iframe(一般为后台转好的 PDF) |
|
|
383
|
+
|
|
384
|
+
`md` 与 `markdown` 等价(见 `AIFileType.Md` / `AIFileType.Markdown`)。预览重载、`force` 重试与取链约定见 [FileArtifactPanel 预览机制](/components/message/file-artifact-panel#预览机制)。
|
|
385
|
+
|
|
386
|
+
```vue
|
|
387
|
+
<template>
|
|
388
|
+
<MessageRender :message="message" />
|
|
389
|
+
</template>
|
|
390
|
+
|
|
391
|
+
<script setup lang="ts">
|
|
392
|
+
import { MessageRender, MessageRole, MessageStatus } from '@blueking/chat-x';
|
|
393
|
+
import type { AIFileInfo } from '@blueking/chat-x';
|
|
394
|
+
|
|
395
|
+
const artifacts: AIFileInfo[] = [
|
|
396
|
+
{ name: '监控大盘周报.html', outputId: 'output-html', size: 10240, type: 'html' },
|
|
397
|
+
{ name: '系统配置说明.md', outputId: 'output-md', size: 8192, type: 'md' },
|
|
398
|
+
{ name: '周例会纪要.txt', outputId: 'output-txt', size: 4096, type: 'txt' },
|
|
399
|
+
{ name: '告警策略配置.json', outputId: 'output-json', size: 2048, type: 'json' },
|
|
400
|
+
{ name: '立项说明书.pdf', outputId: 'output-pdf', size: 204800, type: 'pdf' },
|
|
401
|
+
{ name: '巡检现场照片.jpg', outputId: 'output-jpg', size: 1048576, type: 'jpg' },
|
|
402
|
+
];
|
|
403
|
+
|
|
404
|
+
const message = {
|
|
405
|
+
id: 'a1',
|
|
406
|
+
messageId: 'a1',
|
|
407
|
+
uid: 'assistant-uid-1',
|
|
408
|
+
role: MessageRole.Assistant,
|
|
409
|
+
status: MessageStatus.Complete,
|
|
410
|
+
content: '已为你生成一组评审材料,可点击卡片在侧栏预览或下载:',
|
|
411
|
+
property: { artifacts },
|
|
412
|
+
};
|
|
413
|
+
</script>
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**渲染效果(文档站内部示例;无 Provider 时卡片不可点击预览)**
|
|
417
|
+
|
|
361
418
|
## API
|
|
362
419
|
|
|
363
420
|
### Props
|
|
364
421
|
|
|
365
422
|
组件 Props 来自 `Partial<AssistantMessage>`(所有字段均可选):
|
|
366
423
|
|
|
367
|
-
| 属性名 | 类型 | 说明
|
|
368
|
-
| --------- | ----------------------- |
|
|
369
|
-
| content | `string` | AI
|
|
370
|
-
| status | `MessageStatus` |
|
|
371
|
-
| toolCalls | `ToolCall[]` | 工具调用列表,每项渲染一个 `ToolCallRender`
|
|
372
|
-
| id | `number \| string` | 消息 ID
|
|
373
|
-
| messageId | `number \| string` | 消息唯一标识
|
|
374
|
-
|
|
|
375
|
-
|
|
|
376
|
-
|
|
|
424
|
+
| 属性名 | 类型 | 说明 |
|
|
425
|
+
| --------- | ----------------------- | ----------------------------------------------------------------------------------------- |
|
|
426
|
+
| content | `string` | AI 回复文本,支持 Markdown;空值时不渲染内容区 |
|
|
427
|
+
| status | `MessageStatus` | 影响 ContentRender / ToolCallRender 状态表现 |
|
|
428
|
+
| toolCalls | `ToolCall[]` | 工具调用列表,每项渲染一个 `ToolCallRender` |
|
|
429
|
+
| id | `number \| string` | 消息 ID;无 `uid` 时回退为 `messageUid` |
|
|
430
|
+
| messageId | `number \| string` | 消息唯一标识 |
|
|
431
|
+
| uid | `string` | 优先作为文件产物命中 / 「在对话中定位」的 `messageUid` |
|
|
432
|
+
| name | `string` | 消息发送者名称(可选) |
|
|
433
|
+
| role | `MessageRole.Assistant` | 消息角色,固定为 `'assistant'` |
|
|
434
|
+
| property | `{ artifacts?: AIFileInfo[]; extra?: ... }` | **本组件消费** `property.artifacts` 渲染文件卡片;`extra` 等由上层按需使用 |
|
|
377
435
|
|
|
378
436
|
### Slots
|
|
379
437
|
|
|
380
|
-
| 插槽名 | 参数 | 说明
|
|
381
|
-
| ------- | --------------------- |
|
|
382
|
-
| default | `{ content: string }` |
|
|
438
|
+
| 插槽名 | 参数 | 说明 |
|
|
439
|
+
| ------- | --------------------- | ----------------------------------------------------------------- |
|
|
440
|
+
| default | `{ content: string }` | 替换内容区渲染;toolCalls / MessageArtifacts 在内容区外独立渲染 |
|
|
441
|
+
|
|
442
|
+
### Events / Expose
|
|
443
|
+
|
|
444
|
+
无。
|
|
383
445
|
|
|
384
446
|
## 类型定义
|
|
385
447
|
|
|
@@ -426,4 +488,5 @@ interface ToolMessage extends BaseMessage<MessageRole.Tool, string> {
|
|
|
426
488
|
|
|
427
489
|
- [MessageRender](/components/message/message-render) — assistant 角色由其实例化
|
|
428
490
|
- [ToolMessage](/components/message/tool-message) — 工具执行结果可通过 toolCall.toolMessage 内联
|
|
429
|
-
- [ToolcallRender](/components/agent/toolcall-render) — 工具调用列表渲染
|
|
491
|
+
- [ToolcallRender](/components/agent/toolcall-render) — 工具调用列表渲染
|
|
492
|
+
- [FileArtifactPanel](/components/message/file-artifact-panel) — 文件产物侧栏列表与分类型预览 Host
|
|
@@ -133,9 +133,9 @@ ai-chat-container(:data-ai-size="size")
|
|
|
133
133
|
|
|
134
134
|
侧边栏默认包含「执行情况」Tab,展示所有工具调用和 FlowAgent 类型的 Activity 消息。支持关键词搜索过滤和点击定位到对话中的消息位置。
|
|
135
135
|
|
|
136
|
-
**展示条件**:当 `executionGroups` 为空且 `keyword` 为空时,不渲染侧栏 Tab 与 `ExecutionSummary`(折叠按钮亦隐藏);主区域仍可正常展示 `messages` 中的对话内容。用户在执行情况中输入搜索词后,侧栏会保持展示以显示「搜索结果为空」等状态。`renderMode === Share`
|
|
136
|
+
**展示条件**:当 `executionGroups` 为空且 `keyword` 为空时,不渲染侧栏 Tab 与 `ExecutionSummary`(折叠按钮亦隐藏);主区域仍可正常展示 `messages` 中的对话内容。用户在执行情况中输入搜索词后,侧栏会保持展示以显示「搜索结果为空」等状态。`renderMode === Share` 分享态同样按上述执行数据条件展示侧栏(开放只读查看流程智能体详情/证据/执行情况),不再强制隐藏折叠;仅底部输入区保持隐藏。**例外**:当[「文件产物」Tab](#内置-文件产物-tab)存在时,侧栏不再受「`executionGroups` 为空」约束,可独立展示文件预览。
|
|
137
137
|
|
|
138
|
-
**自定义 Tab 联动**:当 `executionGroups` 变为空且搜索词已清空时,容器会**自动重置自定义 Tab**(`resetCustomTab`),避免残留节点详情等 Tab;若用户仍在搜索(`keyword`
|
|
138
|
+
**自定义 Tab 联动**:当 `executionGroups` 变为空且搜索词已清空时,容器会**自动重置自定义 Tab**(`resetCustomTab`),避免残留节点详情等 Tab;若用户仍在搜索(`keyword` 非空)或存在「文件产物」Tab,不会触发重置。
|
|
139
139
|
|
|
140
140
|
```vue
|
|
141
141
|
<template>
|
|
@@ -239,6 +239,84 @@ ai-chat-container(:data-ai-size="size")
|
|
|
239
239
|
</script>
|
|
240
240
|
```
|
|
241
241
|
|
|
242
|
+
### 内置「文件产物」Tab
|
|
243
|
+
|
|
244
|
+
除「执行情况」外,容器内置一个按需出现的固定 Tab —— **「文件产物」**(`name: 'file-artifact'`),用于聚合预览当前会话所有 `AssistantMessage.property.artifacts`(按 `outputId` 去重):
|
|
245
|
+
|
|
246
|
+
- **静默挂载**:会话已有文件产物时,容器通过 `ensureCustomTab` 挂上该 Tab,**不展开侧栏、不切换当前选中**(避免从「执行情况」展开时被抢走焦点),并保证命中态有效(默认第一个 `outputId`)
|
|
247
|
+
- **主动打开**:点击 AI 回复中的文件卡片([ArtifactFileCard](/components/message/assistant-message))时,容器通过 `useArtifactPreviewProvider` 以 `outputId` 命中该文件,再 `addCustomTab` 展开侧栏并选中「文件产物」
|
|
248
|
+
- **排序 / 关闭**:`order: -1` 排在「执行情况」之前,`closable: false` 不可关闭
|
|
249
|
+
- **显隐解耦**:该 Tab 存在时,侧栏展示不再受「`executionGroups` 为空」约束(即使当前会话没有执行类消息,也能独立展示文件产物侧栏);会话切换或无文件产物时自动移除并重置命中态
|
|
250
|
+
- **内容**:由 [FileArtifactPanel](/components/message/file-artifact-panel) 渲染列表与下载头,预览委托内部 `ArtifactPreviewHost`;`download_url` / `preview_url` 通过 `onArtifactClick` 异步获取。文本类(`html` / `markdown` / `md` / `txt` / `json`)拉 `download_url` 正文直渲染(`md` 与 `markdown` 等价);其余类型用 `preview_url` iframe(一般为后台转好的 PDF)。预览重载键为 `outputId:type`;失败重试会 `force` 绕过 URL 缓存
|
|
251
|
+
- **状态管理**:命中、切换与 URL 缓存由 [useArtifactPreview](/composables/use-artifact-preview) 提供(Provider 在容器内、Consumer 在文件卡片 / 面板内);正文加载与分类型渲染由 Host 内部完成;常规取链只传 `file`,勿传 `undefined` 作为第二参
|
|
252
|
+
- **未传 `onArtifactClick`**:下载按钮隐藏,预览区展示无数据
|
|
253
|
+
|
|
254
|
+
详见 [FileArtifactPanel 文件产物预览](/components/message/file-artifact-panel) 与 [useArtifactPreview 文件产物预览](/composables/use-artifact-preview)。
|
|
255
|
+
|
|
256
|
+
#### 接入示例
|
|
257
|
+
|
|
258
|
+
```vue
|
|
259
|
+
<template>
|
|
260
|
+
<ChatContainer
|
|
261
|
+
v-model="input"
|
|
262
|
+
:messages="messages"
|
|
263
|
+
:on-artifact-click="onArtifactClick"
|
|
264
|
+
@send-message="handleSend"
|
|
265
|
+
/>
|
|
266
|
+
</template>
|
|
267
|
+
|
|
268
|
+
<script setup lang="ts">
|
|
269
|
+
import { ref, shallowRef } from 'vue'
|
|
270
|
+
import {
|
|
271
|
+
ChatContainer,
|
|
272
|
+
MessageRole,
|
|
273
|
+
MessageStatus,
|
|
274
|
+
type AIFileInfo,
|
|
275
|
+
type Message,
|
|
276
|
+
} from '@blueking/chat-x'
|
|
277
|
+
|
|
278
|
+
const input = ref('')
|
|
279
|
+
const messages = shallowRef<Message[]>([
|
|
280
|
+
{
|
|
281
|
+
id: 'u1',
|
|
282
|
+
messageId: 'u1',
|
|
283
|
+
role: MessageRole.User,
|
|
284
|
+
status: MessageStatus.Complete,
|
|
285
|
+
content: '整理本周评审材料',
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
id: 'a1',
|
|
289
|
+
messageId: 'a1',
|
|
290
|
+
uid: 'assistant-uid-1',
|
|
291
|
+
role: MessageRole.Assistant,
|
|
292
|
+
status: MessageStatus.Complete,
|
|
293
|
+
content: '已生成评审材料,点击卡片可在侧栏预览:',
|
|
294
|
+
property: {
|
|
295
|
+
artifacts: [
|
|
296
|
+
{ name: '周报.html', outputId: 'a-html', size: 10240, type: 'html' },
|
|
297
|
+
{ name: '说明.md', outputId: 'a-md', size: 8192, type: 'md' },
|
|
298
|
+
{ name: '配置.json', outputId: 'a-json', size: 2048, type: 'json' },
|
|
299
|
+
{ name: '立项.pdf', outputId: 'a-pdf', size: 204800, type: 'pdf' },
|
|
300
|
+
] satisfies AIFileInfo[],
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
])
|
|
304
|
+
|
|
305
|
+
/** 文本类预览依赖 download_url;iframe 类依赖 preview_url */
|
|
306
|
+
const onArtifactClick = async (file: AIFileInfo) => {
|
|
307
|
+
const res = await api.getArtifactUrls(file.outputId)
|
|
308
|
+
return {
|
|
309
|
+
download_url: res.download_url,
|
|
310
|
+
preview_url: res.preview_url,
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const handleSend = () => {
|
|
315
|
+
/* ... */
|
|
316
|
+
}
|
|
317
|
+
</script>
|
|
318
|
+
```
|
|
319
|
+
|
|
242
320
|
### 自定义 Tab 与「在对话中定位」
|
|
243
321
|
|
|
244
322
|
`addCustomTab` 的 `data` 可携带 **`messageUid`**(与对应活动消息的 `message.uid` 一致)。`ChatContainer` 在侧栏用 `<component :is="sideRenderComponent">`(内部计算属性,见上文「侧栏渲染扩展」)渲染自定义 Tab 时,会向子组件提供 **`locateButton` 插槽**:默认渲染「在对话中定位」按钮,点击后调用内部 `handleLocateMessageGroup(messageUid)`,优先滚动到主区域 `document.getElementById(messageUid)`;若不存在该节点,则在当前 `messageGroups` 中查找包含 `message.uid === messageUid` 的消息组,并滚动到该组的容器(`MessageGroup.uid` 作为组级 `id`)。
|
|
@@ -376,9 +454,9 @@ ai-chat-container(:data-ai-size="size")
|
|
|
376
454
|
|
|
377
455
|
## 用户问题中断
|
|
378
456
|
|
|
379
|
-
当会话中最近一条待处理 interrupt 包含 `InterruptReason.UserQuestion` 时,`ChatContainer` 会在 `ChatInput` 上方显示 [UserQuestionCard](/components/agent/user-question-card)
|
|
457
|
+
当会话中最近一条待处理 interrupt 包含 `InterruptReason.UserQuestion` 时,`ChatContainer` 会在 `ChatInput` 上方显示 [UserQuestionCard](/components/agent/user-question-card)(一次一题,标题栏可切换题目)。
|
|
380
458
|
|
|
381
|
-
-
|
|
459
|
+
- **结构化作答**:用户在卡片内逐题选择(单选可自动跳下一题),点击「完成」或「跳过」后通过 `onInterruptResume(payload, interrupt)` 回传 `UserQuestionResume`。
|
|
382
460
|
- **输入框发送**:用户也可在输入框直接点击发送;容器会调用 `onSendMessage(content, docSchema, options)`,其中 `options.interrupt` 为当前激活的 UserQuestion,`options.payload` 为 `buildSkipResumePayload` 生成的 skip resume(`status: 'cancelled'`,`answers: []`)。此时**不会自动清空**输入框,由业务侧在 `onSendMessage` 内决定如何处理 `content` 与中断恢复。
|
|
383
461
|
|
|
384
462
|
```vue
|
|
@@ -618,20 +696,21 @@ ai-chat-container(:data-ai-size="size")
|
|
|
618
696
|
|
|
619
697
|
ChatContainer 的 Props 继承自 `ChatInputProps` 和 `MessageContainerProps`(排除 `enableSelection` 和 `messageGroups`),另外新增:
|
|
620
698
|
|
|
621
|
-
| 属性名 | 类型
|
|
622
|
-
| ------------------------- |
|
|
623
|
-
| chatLoading | `boolean`
|
|
624
|
-
| commonTippyOptions | `AITippyProps`
|
|
625
|
-
| executionTabVisible | `boolean`
|
|
626
|
-
| getSideRenderComponent | `(h, props?) => VNode \| undefined`
|
|
627
|
-
| getSideTabRenderComponent | `(h, tab, { removeCustomTab }) => VNode \| undefined`
|
|
628
|
-
| models | `IModelOption[]`
|
|
629
|
-
| openingRemark | `string`
|
|
630
|
-
| placement | `'left' \| 'right'`
|
|
631
|
-
| resizeProps | `{ disabled?: boolean; initialDivide?: number \| string; max?: number; min?: number }`
|
|
632
|
-
| size | `'normal' \| 'small'`
|
|
633
|
-
| welcomeTitle | `string`
|
|
634
|
-
| onCustomTabChange | `(tab: CustomTab) => Promise<any>`
|
|
699
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
700
|
+
| ------------------------- | ---------------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
701
|
+
| chatLoading | `boolean` | — | 整体加载状态,`true` 时显示 Loading 遮罩 |
|
|
702
|
+
| commonTippyOptions | `AITippyProps` | — | 通用 Tippy 配置,注入到所有使用 `v-overflow-tips` 的子组件 |
|
|
703
|
+
| executionTabVisible | `boolean` | `true` | 「执行情况」Tab 是否展示;为 `false` 时从 Tab 栏隐藏,若正被选中则切到首个可见 Tab |
|
|
704
|
+
| getSideRenderComponent | `(h, props?) => VNode \| undefined` | — | 自定义侧栏内容区渲染;未返回时使用 `selectedTab.data.component` |
|
|
705
|
+
| getSideTabRenderComponent | `(h, tab, { removeCustomTab }) => VNode \| undefined` | — | 自定义侧栏 Tab 标签渲染;未返回时使用默认图标 + 文案 + 关闭按钮 |
|
|
706
|
+
| models | `IModelOption[]` | — | 可选模型列表(继承自 ChatInput);传入后在发送按钮左侧展示 ModelSelector |
|
|
707
|
+
| openingRemark | `string` | — | 开场白,无消息时显示,支持 Markdown |
|
|
708
|
+
| placement | `'left' \| 'right'` | `'left'` | 侧边栏位置 |
|
|
709
|
+
| resizeProps | `{ disabled?: boolean; initialDivide?: number \| string; max?: number; min?: number }` | — | 透传给内部 `ResizeLayout`;与默认 `collapsible: false`、`immediate: true`、`min: 400` 合并;`placement` 始终取自本组件。**数字型** `initialDivide` 还会作为内部侧栏宽度初值(驱动 `--resize-main-width`,并在展开时作为 `collapseChange` 的 `width`);百分比等字符串则回退为 `400` |
|
|
710
|
+
| size | `'normal' \| 'small'` | `'small'` | 字号主题:`small` 12px / `normal` 14px;根节点设置 `data-ai-size` 并注入 `useGlobalConfig` |
|
|
711
|
+
| welcomeTitle | `string` | — | 欢迎页标题;未传时默认展示「你好,我是小鲸」 |
|
|
712
|
+
| onCustomTabChange | `(tab: CustomTab) => Promise<any>` | — | 自定义 Tab 切换回调,返回值作为 Tab 组件 props |
|
|
713
|
+
| onArtifactClick | `(file: AIFileInfo) => Promise<{ download_url?: string; preview_url?: string }>` | — | 异步获取下载 / 预览链接(按 `outputId` 缓存)。文本类预览依赖 `download_url`,iframe 类依赖 `preview_url`;未传则隐藏下载、预览无数据 |
|
|
635
714
|
|
|
636
715
|
> 其余 Props(如 `messages`、`messageStatus`、`onSendMessage`、`shortcuts` 等)继承自 [ChatInput](/components/input/chat-input) 与 [MessageContainer](/components/setup/message-container)。
|
|
637
716
|
|
|
@@ -654,19 +654,11 @@ const handleSendMessage = async (
|
|
|
654
654
|
|
|
655
655
|
## 类型定义
|
|
656
656
|
|
|
657
|
+
> `MessageStatus` 完整取值见 [常量枚举](../../types/constants)。与输入区相关:`pending` / `streaming` / `fetching` → 停止按钮;`complete` / `completed` / `error` / `stop` → 发送;`disabled` → 置灰。
|
|
658
|
+
|
|
657
659
|
```typescript
|
|
658
660
|
import type { UserMessage } from '@blueking/chat-x';
|
|
659
661
|
|
|
660
|
-
// 消息状态
|
|
661
|
-
enum MessageStatus {
|
|
662
|
-
Pending = 'pending', // 等待中(显示停止按钮)
|
|
663
|
-
Streaming = 'streaming', // 流式输出中(显示停止按钮)
|
|
664
|
-
Complete = 'complete', // 完成(显示发送按钮)
|
|
665
|
-
Error = 'error', // 错误(显示发送按钮)
|
|
666
|
-
Stop = 'stop', // 已停止(显示发送按钮)
|
|
667
|
-
Disabled = 'disabled', // 禁用(发送按钮置灰)
|
|
668
|
-
}
|
|
669
|
-
|
|
670
662
|
// 上传状态
|
|
671
663
|
enum UploadStatus {
|
|
672
664
|
Pending = 'pending', // 上传中
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- AI SUMMARY -->
|
|
2
2
|
## 快速了解
|
|
3
3
|
|
|
4
|
-
汇总 MessageRole、MessageStatus(含 Fetching
|
|
4
|
+
汇总 MessageRole、MessageStatus(含 Fetching 请求中、Complete/Completed 完成态兼容)、MessageContentType、MessageToolsStatus、MessageState、Z-Index 与 CONST_MESSAGE_TOOLS 等导出常量。 用于构造消息、配置 MessageContainer 工具栏与输入态,以及层级与默认快捷指令。与类型 messages 配套使用。
|
|
5
5
|
|
|
6
6
|
### 关联组件
|
|
7
7
|
- **message-tools** — 默认工具 ID 与展示
|
|
@@ -58,6 +58,7 @@ enum MessageRole {
|
|
|
58
58
|
```typescript
|
|
59
59
|
enum MessageStatus {
|
|
60
60
|
Complete = 'complete',
|
|
61
|
+
Completed = 'completed', // 与 Complete 同为完成态,兼容后端/协议返回的 completed
|
|
61
62
|
Disabled = 'disabled',
|
|
62
63
|
Error = 'error',
|
|
63
64
|
Fetching = 'fetching', // 请求中(例如已发用户消息、尚未开始流式,与末尾 Loading 占位一致)
|
|
@@ -71,6 +72,7 @@ enum MessageStatus {
|
|
|
71
72
|
|
|
72
73
|
| 枚举值 | 说明 |
|
|
73
74
|
| --------------- | ---- |
|
|
75
|
+
| `Complete` / `Completed` | 已完成。`complete` 为库内常用值;`completed` 与之语义相同,用于兼容外部协议或后端返回。`ToolcallRender` 等将二者与 `success` 一并视为成功态。 |
|
|
74
76
|
| `Fetching` | 请求中:与 `useMessageGroup` 在末尾用户消息后注入的 Loading 占位(`LOADING_MESSAGE_ID`)配合时,`ChatContainer` 会将传入输入区与列表底部的状态推导为该值,便于展示「停止」与禁止重复发送。 |
|
|
75
77
|
|
|
76
78
|
### InterruptReason
|
|
@@ -216,18 +216,10 @@ enum MessageContentType {
|
|
|
216
216
|
KnowledgeRag = 'knowledge_rag',
|
|
217
217
|
Other = 'other',
|
|
218
218
|
}
|
|
219
|
-
|
|
220
|
-
// 消息状态
|
|
221
|
-
enum MessageStatus {
|
|
222
|
-
Pending = 'pending',
|
|
223
|
-
Streaming = 'streaming',
|
|
224
|
-
Complete = 'complete',
|
|
225
|
-
Error = 'error',
|
|
226
|
-
Stop = 'stop',
|
|
227
|
-
Disabled = 'disabled',
|
|
228
|
-
}
|
|
229
219
|
```
|
|
230
220
|
|
|
221
|
+
> `MessageStatus` 完整取值见 [常量枚举](../../types/constants);本组件主要关心 `error`(错误内容)与流式相关状态。
|
|
222
|
+
|
|
231
223
|
## 使用场景
|
|
232
224
|
|
|
233
225
|
- **AI 文本回复渲染**:`AssistantMessage` 内部用 `ContentRender` 渲染 AI 回复内容,`status` 配合流式响应
|