@blueking/chat-x 0.0.51-beta.5 → 0.0.52-dev.1
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/README.md +15 -8
- package/dist/ag-ui/types/contents.d.ts +2 -0
- package/dist/ag-ui/types/messages.d.ts +6 -1
- package/dist/common/constants.d.ts +2 -0
- package/dist/components/ai-buttons/add-menu-btn/add-menu-btn.vue.d.ts +24 -0
- package/dist/components/chat-content/collapsible-content/collapsible-content.vue.d.ts +28 -0
- package/dist/components/chat-content/file-content/upload-file-item.vue.d.ts +5 -2
- package/dist/components/chat-content/file-content/upload-image-item.vue.d.ts +1 -0
- package/dist/components/chat-content/flow-agent-content/use-flow-node-actions.d.ts +1 -1
- package/dist/components/chat-input/ai-slash-input/ai-slash-input.vue.d.ts +21 -10
- package/dist/components/chat-input/ai-slash-input/command.d.ts +6 -3
- package/dist/components/chat-input/ai-slash-input/constants.d.ts +2 -0
- package/dist/components/chat-input/ai-slash-input/use-menu-trigger.d.ts +17 -0
- package/dist/components/chat-input/build-default-placeholder.d.ts +9 -3
- package/dist/components/chat-input/chat-input.vue.d.ts +30 -18
- package/dist/components/chat-input/input-menu/constants.d.ts +60 -0
- package/dist/components/chat-input/input-menu/index.d.ts +4 -0
- package/dist/components/chat-input/input-menu/input-menu-option.vue.d.ts +14 -0
- package/dist/components/chat-input/input-menu/input-menu-panel.vue.d.ts +17 -0
- package/dist/components/chat-input/input-menu/use-input-menu.d.ts +22 -0
- package/dist/components/chat-input/model-selector/types.d.ts +3 -2
- package/dist/components/chat-message/message-container/message-container.vue.d.ts +1 -1
- package/dist/components/chat-message/user-message/user-message.vue.d.ts +1 -1
- package/dist/components/mention/create-mention-tippy.d.ts +27 -0
- package/dist/components/mention/index.d.ts +4 -0
- package/dist/components/{chat-input/ai-slash-input/ai-prompt-list/ai-prompt-list.vue.d.ts → mention/mention-popover.vue.d.ts} +3 -2
- package/dist/components/{chat-input/ai-slash-input/ai-skill-list/ai-skill-list.vue.d.ts → mention/mention-tag.vue.d.ts} +7 -3
- package/dist/components/{chat-input/ai-slash-input/ai-slash-menu/ai-slash-menu.vue.d.ts → mention/mention-text.vue.d.ts} +3 -3
- package/dist/components/resource-icon/index.d.ts +1 -0
- package/dist/components/resource-icon/resource-icon.vue.d.ts +11 -0
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/use-artifact-preview.d.ts +5 -2
- package/dist/composables/use-common.d.ts +0 -9
- package/dist/composables/use-global-config.d.ts +4 -0
- package/dist/composables/use-input-mention.d.ts +13 -0
- package/dist/composables/use-message-group.d.ts +1011 -72
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/input.d.ts +21 -0
- package/dist/icons/menu-item.d.ts +22 -0
- package/dist/index.css +1 -1
- package/dist/index.js +4953 -4429
- package/dist/index.js.map +1 -1
- package/dist/lang/lang.d.ts +13 -3
- package/dist/mcp/generated/docs/activity-message.md +3 -3
- package/dist/mcp/generated/docs/add-menu-btn.md +91 -0
- package/dist/mcp/generated/docs/ai-slash-input.md +72 -26
- package/dist/mcp/generated/docs/assistant-message.md +7 -1
- package/dist/mcp/generated/docs/chat-container.md +45 -6
- package/dist/mcp/generated/docs/chat-input.md +327 -483
- package/dist/mcp/generated/docs/collapsible-content.md +78 -0
- package/dist/mcp/generated/docs/constants.md +36 -3
- package/dist/mcp/generated/docs/execution-summary.md +1 -23
- package/dist/mcp/generated/docs/file-artifact-panel.md +24 -5
- package/dist/mcp/generated/docs/file-content.md +4 -0
- package/dist/mcp/generated/docs/file-upload-btn.md +15 -12
- package/dist/mcp/generated/docs/flow-agent-content.md +10 -12
- package/dist/mcp/generated/docs/input-menu-panel.md +166 -0
- package/dist/mcp/generated/docs/mention-tag.md +83 -0
- package/dist/mcp/generated/docs/mention-text.md +86 -0
- package/dist/mcp/generated/docs/message-container.md +1 -1
- package/dist/mcp/generated/docs/message-render.md +1 -1
- package/dist/mcp/generated/docs/message-tools.md +15 -4
- package/dist/mcp/generated/docs/messages.md +3 -0
- package/dist/mcp/generated/docs/model-selector.md +4 -2
- package/dist/mcp/generated/docs/overflow-tips.md +3 -3
- package/dist/mcp/generated/docs/resource-icon.md +102 -0
- package/dist/mcp/generated/docs/text-content.md +7 -3
- package/dist/mcp/generated/docs/theme.md +27 -35
- package/dist/mcp/generated/docs/use-artifact-preview.md +7 -3
- package/dist/mcp/generated/docs/use-command-selection.md +1 -1
- package/dist/mcp/generated/docs/use-container-scroll.md +2 -1
- package/dist/mcp/generated/docs/use-flow-node-actions.md +8 -15
- package/dist/mcp/generated/docs/use-global-config.md +11 -4
- package/dist/mcp/generated/docs/use-input-mention.md +119 -0
- package/dist/mcp/generated/docs/use-menu-keydown.md +15 -16
- package/dist/mcp/generated/docs/use-message-group.md +3 -6
- package/dist/mcp/generated/docs/user-message.md +39 -17
- package/dist/mcp/generated/index.json +233 -81
- package/dist/types/editor.d.ts +0 -29
- package/dist/types/index.d.ts +1 -0
- package/dist/types/input-menu.d.ts +46 -0
- package/dist/utils/artifact-tags.d.ts +36 -0
- package/dist/utils/collect-message-artifacts.d.ts +14 -0
- package/dist/utils/file.d.ts +3 -3
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/upload-file.d.ts +6 -1
- package/package.json +3 -2
- package/skills/blueking-chat-x/SKILL.md +143 -0
- package/skills/blueking-chat-x/references/_index.md +153 -0
- package/skills/blueking-chat-x/references/components/activity-layout.md +134 -0
- package/skills/blueking-chat-x/references/components/activity-message.md +486 -0
- package/skills/blueking-chat-x/references/components/add-menu-btn.md +88 -0
- package/skills/blueking-chat-x/references/components/ai-image.md +230 -0
- package/skills/blueking-chat-x/references/components/ai-loading.md +131 -0
- package/skills/blueking-chat-x/references/components/ai-selection.md +439 -0
- package/skills/blueking-chat-x/references/components/ai-slash-input.md +102 -0
- package/skills/blueking-chat-x/references/components/animation-text.md +202 -0
- package/skills/blueking-chat-x/references/components/assistant-message.md +504 -0
- package/skills/blueking-chat-x/references/components/chat-container.md +912 -0
- package/skills/blueking-chat-x/references/components/chat-input.md +614 -0
- package/skills/blueking-chat-x/references/components/cite-content.md +142 -0
- package/skills/blueking-chat-x/references/components/code-content.md +211 -0
- package/skills/blueking-chat-x/references/components/collapsible-content.md +76 -0
- package/skills/blueking-chat-x/references/components/common-error-content.md +73 -0
- package/skills/blueking-chat-x/references/components/content-render.md +233 -0
- package/skills/blueking-chat-x/references/components/delete-tool.md +191 -0
- package/skills/blueking-chat-x/references/components/desc-panel.md +162 -0
- package/skills/blueking-chat-x/references/components/detail-section.md +91 -0
- package/skills/blueking-chat-x/references/components/execution-summary.md +150 -0
- package/skills/blueking-chat-x/references/components/file-artifact-panel.md +307 -0
- package/skills/blueking-chat-x/references/components/file-content.md +340 -0
- package/skills/blueking-chat-x/references/components/file-icon.md +109 -0
- package/skills/blueking-chat-x/references/components/file-upload-btn.md +162 -0
- package/skills/blueking-chat-x/references/components/flow-agent-content.md +266 -0
- package/skills/blueking-chat-x/references/components/flow-agent-node-detail.md +236 -0
- package/skills/blueking-chat-x/references/components/highlight-keyword.md +146 -0
- package/skills/blueking-chat-x/references/components/image-content.md +182 -0
- package/skills/blueking-chat-x/references/components/image-preview-group.md +184 -0
- package/skills/blueking-chat-x/references/components/image-preview.md +226 -0
- package/skills/blueking-chat-x/references/components/info-message.md +144 -0
- package/skills/blueking-chat-x/references/components/input-attachment.md +49 -0
- package/skills/blueking-chat-x/references/components/input-info-alert.md +42 -0
- package/skills/blueking-chat-x/references/components/input-menu-panel.md +162 -0
- package/skills/blueking-chat-x/references/components/interrupt-message.md +212 -0
- package/skills/blueking-chat-x/references/components/key-value-content.md +128 -0
- package/skills/blueking-chat-x/references/components/knowledge-rag-content.md +122 -0
- package/skills/blueking-chat-x/references/components/latex-content.md +200 -0
- package/skills/blueking-chat-x/references/components/loading-message.md +192 -0
- package/skills/blueking-chat-x/references/components/markdown-content.md +232 -0
- package/skills/blueking-chat-x/references/components/mention-tag.md +79 -0
- package/skills/blueking-chat-x/references/components/mention-text.md +83 -0
- package/skills/blueking-chat-x/references/components/mermaid-content.md +189 -0
- package/skills/blueking-chat-x/references/components/message-container.md +645 -0
- package/skills/blueking-chat-x/references/components/message-loading.md +118 -0
- package/skills/blueking-chat-x/references/components/message-render.md +327 -0
- package/skills/blueking-chat-x/references/components/message-time.md +177 -0
- package/skills/blueking-chat-x/references/components/message-tools.md +427 -0
- package/skills/blueking-chat-x/references/components/model-selector.md +157 -0
- package/skills/blueking-chat-x/references/components/preview-toolbar.md +42 -0
- package/skills/blueking-chat-x/references/components/questions-container.md +85 -0
- package/skills/blueking-chat-x/references/components/reasoning-message.md +232 -0
- package/skills/blueking-chat-x/references/components/reference-content.md +135 -0
- package/skills/blueking-chat-x/references/components/reference-doc-content.md +109 -0
- package/skills/blueking-chat-x/references/components/resource-icon.md +98 -0
- package/skills/blueking-chat-x/references/components/scroll-btn.md +159 -0
- package/skills/blueking-chat-x/references/components/selection-footer.md +78 -0
- package/skills/blueking-chat-x/references/components/selection-question.md +88 -0
- package/skills/blueking-chat-x/references/components/shortcut-btn.md +204 -0
- package/skills/blueking-chat-x/references/components/shortcut-btns.md +266 -0
- package/skills/blueking-chat-x/references/components/shortcut-render.md +424 -0
- package/skills/blueking-chat-x/references/components/simple-table.md +101 -0
- package/skills/blueking-chat-x/references/components/text-content.md +80 -0
- package/skills/blueking-chat-x/references/components/tool-approval-card.md +183 -0
- package/skills/blueking-chat-x/references/components/tool-btn.md +317 -0
- package/skills/blueking-chat-x/references/components/tool-message.md +235 -0
- package/skills/blueking-chat-x/references/components/toolcall-render.md +348 -0
- package/skills/blueking-chat-x/references/components/user-feedback.md +233 -0
- package/skills/blueking-chat-x/references/components/user-message.md +444 -0
- package/skills/blueking-chat-x/references/components/user-question-answered-card.md +104 -0
- package/skills/blueking-chat-x/references/components/user-question-card.md +231 -0
- package/skills/blueking-chat-x/references/components/user-question-choice.md +105 -0
- package/skills/blueking-chat-x/references/components/user-question-option.md +42 -0
- package/skills/blueking-chat-x/references/components/vnode-renderer.md +122 -0
- package/skills/blueking-chat-x/references/composables/use-animation-text.md +196 -0
- package/skills/blueking-chat-x/references/composables/use-artifact-preview.md +235 -0
- package/skills/blueking-chat-x/references/composables/use-clipboard.md +203 -0
- package/skills/blueking-chat-x/references/composables/use-command-selection.md +150 -0
- package/skills/blueking-chat-x/references/composables/use-container-scroll.md +57 -0
- package/skills/blueking-chat-x/references/composables/use-custom-tab.md +158 -0
- package/skills/blueking-chat-x/references/composables/use-flow-node-actions.md +164 -0
- package/skills/blueking-chat-x/references/composables/use-full-screen.md +112 -0
- package/skills/blueking-chat-x/references/composables/use-global-config.md +155 -0
- package/skills/blueking-chat-x/references/composables/use-input-mention.md +115 -0
- package/skills/blueking-chat-x/references/composables/use-menu-keydown.md +161 -0
- package/skills/blueking-chat-x/references/composables/use-message-group.md +244 -0
- package/skills/blueking-chat-x/references/composables/use-observer-visible-list.md +188 -0
- package/skills/blueking-chat-x/references/composables/use-parent-scrolling.md +46 -0
- package/skills/blueking-chat-x/references/directives/index.md +61 -0
- package/skills/blueking-chat-x/references/directives/overflow-tips.md +205 -0
- package/skills/blueking-chat-x/references/icons/index.md +185 -0
- package/skills/blueking-chat-x/references/plugins/index.md +56 -0
- package/skills/blueking-chat-x/references/plugins/markdown-container.md +55 -0
- package/skills/blueking-chat-x/references/plugins/markdown-latex.md +205 -0
- package/skills/blueking-chat-x/references/plugins/markdown-mermaid.md +247 -0
- package/skills/blueking-chat-x/references/theme/theme.md +423 -0
- package/skills/blueking-chat-x/references/types/constants.md +340 -0
- package/skills/blueking-chat-x/references/types/index.md +120 -0
- package/skills/blueking-chat-x/references/types/interrupt.md +379 -0
- package/skills/blueking-chat-x/references/types/messages.md +556 -0
- package/skills/blueking-chat-x/references/types/schema.md +91 -0
- package/skills/blueking-chat-x/references/utils/index.md +196 -0
- package/skills/blueking-chat-x/scripts/generate-references.mjs +536 -0
- package/dist/components/chat-input/ai-slash-editor/ai-slash-editor.vue.d.ts +0 -28
- package/dist/components/chat-input/ai-slash-editor/theme.d.ts +0 -24
- package/dist/mcp/generated/docs/ai-prompt-list.md +0 -45
- package/dist/mcp/generated/docs/ai-skill-list.md +0 -75
- package/dist/mcp/generated/docs/ai-slash-editor.md +0 -43
- package/dist/mcp/generated/docs/ai-slash-menu.md +0 -42
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# ExecutionSummary 执行摘要
|
|
2
|
+
|
|
3
|
+
> 能力域:Agent 能力 | 导入:`import { ExecutionSummary } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
+
|
|
5
|
+
按消息流提取执行摘要,支持关键词定位和消息渲染。 通过 useExecutionPanelProvider 提供 EXECUTION_PANEL_TOKEN,面板内消息按只读呈现, FlowAgent 失败节点在面板内不展示重试/跳过,只保留详情。 源码位置:src/components/execution-summary/execution-summary.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:message-render(摘要列表内渲染消息内容)、highlight-keyword(搜索关键词注入与高亮)、chat-container(常与侧栏「执行情况」Tab 组合)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ExecutionSummary 执行摘要
|
|
12
|
+
## 源码事实
|
|
13
|
+
|
|
14
|
+
- **源码位置**:`src/components/execution-summary/execution-summary.vue`
|
|
15
|
+
- **能力域**:Agent 能力
|
|
16
|
+
- **能力说明**:按消息流提取执行摘要,支持关键词定位和消息渲染。
|
|
17
|
+
|
|
18
|
+
> **能力域**:Agent 能力
|
|
19
|
+
|
|
20
|
+
执行摘要面板组件,以时间线形式展示对话中的工具调用和 FlowAgent 活动记录。支持关键词搜索过滤和点击定位到对话中的消息位置。
|
|
21
|
+
|
|
22
|
+
通常不需要直接使用,`ChatContainer` 会在侧边栏的「执行情况」Tab 中自动渲染。
|
|
23
|
+
|
|
24
|
+
## 核心能力
|
|
25
|
+
|
|
26
|
+
- **时间线布局**:每组消息按时间节点排列,带连接线
|
|
27
|
+
- **关键词搜索**:实时过滤匹配的执行记录
|
|
28
|
+
- **对话定位**:hover 显示「在对话中定位」按钮,点击滚动到对应消息
|
|
29
|
+
- **空状态处理**:无数据或搜索无结果时显示空状态提示
|
|
30
|
+
- **面板上下文(只读呈现)**:组件 setup 时通过 `useExecutionPanelProvider()` 提供 `EXECUTION_PANEL_TOKEN`,供内部消息组件识别「当前处于侧栏面板内」并隐藏交互操作。目前 `FlowAgentContent` 据此不展示节点「重试 / 跳过」,只保留「详情」
|
|
31
|
+
|
|
32
|
+
## 基础用法
|
|
33
|
+
|
|
34
|
+
```vue
|
|
35
|
+
<template>
|
|
36
|
+
<ExecutionSummary
|
|
37
|
+
:message-groups="executionGroups"
|
|
38
|
+
@locate-message-group="handleLocate"
|
|
39
|
+
@update-keyword="handleUpdateKeyword"
|
|
40
|
+
/>
|
|
41
|
+
</template>
|
|
42
|
+
|
|
43
|
+
<script setup lang="ts">
|
|
44
|
+
import { ExecutionSummary, type MessageGroup } from '@blueking/chat-x';
|
|
45
|
+
|
|
46
|
+
const handleLocate = (uid: string, group: MessageGroup) => {
|
|
47
|
+
const dom = document.getElementById(uid);
|
|
48
|
+
dom?.scrollIntoView({ behavior: 'smooth' });
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const handleUpdateKeyword = (keyword: string) => {
|
|
52
|
+
console.log('搜索关键词:', keyword);
|
|
53
|
+
};
|
|
54
|
+
</script>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**渲染效果**(包含搜索过滤和定位功能,hover 消息组可看到「在对话中定位」按钮)
|
|
58
|
+
|
|
59
|
+
## 组件结构
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
ai-execution-summary
|
|
63
|
+
├── ai-execution-summary-header(仅 messageGroups 非空时渲染)
|
|
64
|
+
│ └── Input(关键词搜索框,clearable)
|
|
65
|
+
└── ai-execution-summary-content
|
|
66
|
+
├── 有数据时:
|
|
67
|
+
│ └── content-item × N(时间线节点)
|
|
68
|
+
│ ├── timeline-dot(时间节点圆点)
|
|
69
|
+
│ ├── content-item-time(格式化时间)
|
|
70
|
+
│ ├── content-item-locate(hover 显示定位按钮)
|
|
71
|
+
│ ├── content-item-messages(MessageRender × N)
|
|
72
|
+
│ └── timeline-line(连接线,最后一项不显示)
|
|
73
|
+
└── 无数据时:
|
|
74
|
+
└── Exception(scene="part")+「暂无数据」/「搜索结果为空」文案(有关键词时附带「清空搜索」)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 空状态
|
|
78
|
+
|
|
79
|
+
当 `messageGroups` 为空数组时,**不渲染搜索 header**,内容区整块展示空态(bkui `Exception` +「暂无数据」;若仍有搜索关键词则为「搜索结果为空」并提供「清空搜索」):
|
|
80
|
+
|
|
81
|
+
## 与 ChatContainer 配合
|
|
82
|
+
|
|
83
|
+
`ChatContainer` 通过 `useMessageGroup` 计算 `executionGroups`(仅包含工具调用和 FlowAgent 消息),并传给 `ExecutionSummary`:
|
|
84
|
+
|
|
85
|
+
```vue
|
|
86
|
+
<!-- ChatContainer 内部 -->
|
|
87
|
+
<ExecutionSummary
|
|
88
|
+
:message-groups="executionGroups"
|
|
89
|
+
@locate-message-group="handleLocateMessageGroup"
|
|
90
|
+
@update-keyword="handleUpdateKeyword"
|
|
91
|
+
/>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 面板内的消息按只读呈现
|
|
95
|
+
|
|
96
|
+
面板与对话流复用同一套渲染链路(`MessageRender` → `ContentRender` → 具体内容组件),但面板定位是「回看执行过程」,不承载操作。为此组件在 setup 阶段 provide 面板上下文:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// 源码:src/composables/use-common.ts(内部上下文,未从包入口导出)
|
|
100
|
+
import { useExecutionPanelProvider } from '../../composables/use-common';
|
|
101
|
+
|
|
102
|
+
// 面板身份在组件树中恒定,provide 常量 true 即可,无需响应式
|
|
103
|
+
useExecutionPanelProvider();
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
内容组件用 `useExecutionPanelInject()` 读取(缺省 `false`,即对话流内)。当前的差异:
|
|
107
|
+
|
|
108
|
+
| 内容 | 对话流内 | 侧栏「执行情况」面板内 |
|
|
109
|
+
| ---- | -------- | ---------------------- |
|
|
110
|
+
| FlowAgent 失败节点「重试 / 跳过」 | 展示(依赖 `retryable` / `skippable`) | **不展示** |
|
|
111
|
+
| FlowAgent 节点「详情」 | 展示 | 展示 |
|
|
112
|
+
|
|
113
|
+
新增内容组件若也需要区分这两种场景,同样注入 `useExecutionPanelInject()` 即可,不必扩展 props。`EXECUTION_PANEL_TOKEN` 与这两个函数同属 `use-common.ts` 的内部上下文,未从 `@blueking/chat-x` 包入口导出,仅供库内组件使用。详见 [FlowAgentContent](/components/agent/flow-agent-content)。
|
|
114
|
+
|
|
115
|
+
## API
|
|
116
|
+
|
|
117
|
+
### Props
|
|
118
|
+
|
|
119
|
+
| 属性名 | 类型 | 必填 | 说明 |
|
|
120
|
+
| ------------- | ---------------- | ---- | ---------------- |
|
|
121
|
+
| messageGroups | `MessageGroup[]` | ✓ | 执行摘要消息分组 |
|
|
122
|
+
|
|
123
|
+
### Events
|
|
124
|
+
|
|
125
|
+
| 事件名 | 参数 | 说明 |
|
|
126
|
+
| ------------------ | ------------------------------------- | ------------------------ |
|
|
127
|
+
| locateMessageGroup | `(uid: string, group: MessageGroup)` | 点击「在对话中定位」按钮,参数为消息组 `MessageGroup.uid` |
|
|
128
|
+
| updateKeyword | `(keyword: string)` | 搜索关键词变更 |
|
|
129
|
+
|
|
130
|
+
## 类型定义
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import { type MessageGroup } from '@blueking/chat-x';
|
|
134
|
+
|
|
135
|
+
interface MessageGroup {
|
|
136
|
+
uid: string;
|
|
137
|
+
type: MessageRole;
|
|
138
|
+
messages: Message[];
|
|
139
|
+
checked: boolean;
|
|
140
|
+
isHover: boolean;
|
|
141
|
+
pause?: boolean;
|
|
142
|
+
startTime?: number;
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## 关联组件
|
|
147
|
+
|
|
148
|
+
- [MessageRender](/components/message/message-render) — 摘要内消息渲染
|
|
149
|
+
- [HighlightKeyword](/components/helper/highlight-keyword) — 搜索高亮
|
|
150
|
+
- [ChatContainer](/components/setup/chat-container) — 侧栏挂载场景
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# FileArtifactPanel 文件产物预览
|
|
2
|
+
|
|
3
|
+
> 能力域:消息系统 | 未从包入口导出:内部组件,请通过上层组件使用 | since 0.0.20
|
|
4
|
+
|
|
5
|
+
汇总当前会话所有 AssistantMessage 的 artifacts(按 outputId 去重),支持关键词搜索、列表选中、复制、引用到输入框与下载; 预览区委托 ArtifactPreviewHost:由 resolveFileKind 把扩展名归入 code / markdown / html / text / image / binary 六类, 前四类走 text_from_download 拉正文(code 交给 highlight.js 高亮),image / binary 走 preview_url; download_url / preview_url 经 onArtifactClick 每次异步获取(无 URL 缓存,并发去重); 预览重载键为 outputId:type;重试再次调用 load() 重新取链。 源码位置:src/components/chat-message/assistant-message/message-artifacts/file-artifact-panel.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:assistant-message(文件产物来源于 AssistantMessage.property.artifacts)、chat-container(面板挂载在侧栏「文件产物」Tab(固定、不可关闭),并通过 onArtifactClick 异步取链)、execution-summary(同为 ChatContainer 侧栏 Tab 面板,交互形态一致)、message-loading(ArtifactPreviewHost 取链 / 拉取正文过程使用 MessageLoading)、mention-tag(引用后文件以资源标签形态进入输入框)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# FileArtifactPanel 文件产物预览
|
|
12
|
+
|
|
13
|
+
## 源码事实
|
|
14
|
+
|
|
15
|
+
- **源码位置**:`src/components/chat-message/assistant-message/message-artifacts/file-artifact-panel.vue`
|
|
16
|
+
- **能力域**:消息系统
|
|
17
|
+
- **能力说明**:汇总当前会话全部文件产物;左侧列表搜索与选中,右侧预览委托内部 `ArtifactPreviewHost`。
|
|
18
|
+
|
|
19
|
+
> **导出说明**:内部侧栏面板组件,**通常不直接使用**;由 `ChatContainer` 在「文件产物」Tab 内自动挂载。预览加载与渲染为同目录下 `artifact-preview/` 内部实现,不单独导出。
|
|
20
|
+
|
|
21
|
+
点击 AI 回复中的[文件卡片](/components/message/assistant-message)后,`ChatContainer` 侧栏会弹出固定的「文件产物」Tab,聚合展示当前会话**所有** `AssistantMessage` 的文件产物(按 `outputId` 去重),并命中被点击的文件进行预览。
|
|
22
|
+
|
|
23
|
+
面板左侧为可搜索的文件列表,右侧为预览区。通常不需要直接使用,由 `ChatContainer` 在侧栏内自动渲染。
|
|
24
|
+
|
|
25
|
+
## 核心能力
|
|
26
|
+
|
|
27
|
+
- **会话级聚合**:拍平当前会话所有 `AssistantMessage.property.artifacts`,以 `outputId` 去重后统一在一个列表内展示
|
|
28
|
+
- **唯一命中**:以 `outputId` 作为会话内唯一键(同 `outputId` 视为同一文件);文件名可能重复,不可作唯一键
|
|
29
|
+
- **关键词搜索**:按文件名实时过滤列表
|
|
30
|
+
- **整块空态**:`artifacts` 为空时不渲染列表与预览区,整块展示 bkui `Exception`「暂无数据」(Tab 常驻,无数据也可正常打开侧栏)
|
|
31
|
+
- **异步取链**:`AIFileInfo` 本身不含 `url` / `previewUrl`,通过 `ChatContainer` 的 `onArtifactClick` 按 `outputId` 获取 `download_url` / `preview_url`(不做 URL 缓存,每次重新取链;同文件进行中的请求并发去重)
|
|
32
|
+
- **引用到输入框**:预览头提供「引用」按钮(位于下载左侧),点击后该文件以资源标签形态进入输入框
|
|
33
|
+
- **职责拆分**:
|
|
34
|
+
- **面板本身**:列表、搜索、预览头(文件名 / 图标 / 复制 / 引用 / 下载)
|
|
35
|
+
- **`ArtifactPreviewHost`**:按策略加载正文或预览 URL,分派到对应 renderer;展示 loading / empty / error(含重试)
|
|
36
|
+
- **未传 `onArtifactClick`**:下载按钮隐藏,预览区展示无数据
|
|
37
|
+
|
|
38
|
+
## 基础用法
|
|
39
|
+
|
|
40
|
+
面板**未从包入口导出**,业务侧请走下方「业务接入」;下列示例仅用于文档站 / 本地调试(与 `ExecutionSummary` 文档站写法一致:相对路径引入 + 自行挂 Provider)。
|
|
41
|
+
|
|
42
|
+
```vue
|
|
43
|
+
<template>
|
|
44
|
+
<div style="height: 480px; border: 1px solid #dcdee5; border-radius: 8px; overflow: hidden;">
|
|
45
|
+
<FileArtifactPanel
|
|
46
|
+
:active-id="activeArtifactId"
|
|
47
|
+
:artifacts="sessionArtifacts"
|
|
48
|
+
@select="handleSelect"
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<script setup lang="ts">
|
|
54
|
+
import { shallowRef } from 'vue'
|
|
55
|
+
import { useArtifactPreviewProvider } from '@blueking/chat-x'
|
|
56
|
+
import type { AIFileInfo, SessionArtifact } from '@blueking/chat-x'
|
|
57
|
+
// 内部组件:仅文档 / 调试;业务请用 ChatContainer 自动挂载
|
|
58
|
+
import FileArtifactPanel from './message-artifacts/file-artifact-panel.vue'
|
|
59
|
+
|
|
60
|
+
const sessionArtifacts: SessionArtifact[] = [
|
|
61
|
+
{ name: '周报.html', outputId: 'a-html', size: 10240, type: 'html' },
|
|
62
|
+
{ name: '说明.md', outputId: 'a-md', size: 8192, type: 'md' },
|
|
63
|
+
{ name: '纪要.txt', outputId: 'a-txt', size: 4096, type: 'txt' },
|
|
64
|
+
{ name: '配置.json', outputId: 'a-json', size: 2048, type: 'json' },
|
|
65
|
+
{ name: '立项.pdf', outputId: 'a-pdf', size: 204800, type: 'pdf' },
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
useArtifactPreviewProvider({
|
|
69
|
+
getOnArtifactClick: () => async file => {
|
|
70
|
+
// 文本类返回可 fetch 的 download_url;iframe 类返回 preview_url
|
|
71
|
+
const res = await api.getArtifactUrls(file.outputId)
|
|
72
|
+
return { download_url: res.download_url, preview_url: res.preview_url }
|
|
73
|
+
},
|
|
74
|
+
onOpen: () => {},
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const activeArtifactId = shallowRef(sessionArtifacts[0].outputId)
|
|
78
|
+
const handleSelect = (id: string) => {
|
|
79
|
+
activeArtifactId.value = id
|
|
80
|
+
}
|
|
81
|
+
</script>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**渲染效果**(点击左侧列表切换类型;文本类直渲染,PDF 走 iframe。Mock 取链约 600ms)
|
|
85
|
+
|
|
86
|
+
## 业务接入(ChatContainer)
|
|
87
|
+
|
|
88
|
+
日常用法是给容器传 `messages`(含 `property.artifacts`)与 `onArtifactClick`,点击文件卡片即可打开侧栏面板:
|
|
89
|
+
|
|
90
|
+
```vue
|
|
91
|
+
<template>
|
|
92
|
+
<ChatContainer
|
|
93
|
+
v-model="input"
|
|
94
|
+
:messages="messages"
|
|
95
|
+
:on-artifact-click="onArtifactClick"
|
|
96
|
+
@send-message="handleSend"
|
|
97
|
+
/>
|
|
98
|
+
</template>
|
|
99
|
+
|
|
100
|
+
<script setup lang="ts">
|
|
101
|
+
import { ref, shallowRef } from 'vue'
|
|
102
|
+
import {
|
|
103
|
+
ChatContainer,
|
|
104
|
+
MessageRole,
|
|
105
|
+
MessageStatus,
|
|
106
|
+
type AIFileInfo,
|
|
107
|
+
type Message,
|
|
108
|
+
} from '@blueking/chat-x'
|
|
109
|
+
|
|
110
|
+
const input = ref('')
|
|
111
|
+
const messages = shallowRef<Message[]>([
|
|
112
|
+
{
|
|
113
|
+
id: 'u1',
|
|
114
|
+
messageId: 'u1',
|
|
115
|
+
role: MessageRole.User,
|
|
116
|
+
status: MessageStatus.Complete,
|
|
117
|
+
content: '整理本周评审材料',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: 'a1',
|
|
121
|
+
messageId: 'a1',
|
|
122
|
+
uid: 'assistant-uid-1',
|
|
123
|
+
role: MessageRole.Assistant,
|
|
124
|
+
status: MessageStatus.Complete,
|
|
125
|
+
content: '已生成评审材料,点击卡片可在侧栏预览:',
|
|
126
|
+
property: {
|
|
127
|
+
artifacts: [
|
|
128
|
+
{ name: '周报.html', outputId: 'a-html', size: 10240, type: 'html' },
|
|
129
|
+
{ name: '说明.md', outputId: 'a-md', size: 8192, type: 'md' },
|
|
130
|
+
{ name: '配置.json', outputId: 'a-json', size: 2048, type: 'json' },
|
|
131
|
+
{ name: '立项.pdf', outputId: 'a-pdf', size: 204800, type: 'pdf' },
|
|
132
|
+
] satisfies AIFileInfo[],
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
])
|
|
136
|
+
|
|
137
|
+
const onArtifactClick = async (file: AIFileInfo) => {
|
|
138
|
+
const res = await api.getArtifactUrls(file.outputId)
|
|
139
|
+
return {
|
|
140
|
+
download_url: res.download_url,
|
|
141
|
+
preview_url: res.preview_url,
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const handleSend = () => {
|
|
146
|
+
/* ... */
|
|
147
|
+
}
|
|
148
|
+
</script>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## 触发链路
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
ArtifactFileCard(点击文件卡片)
|
|
155
|
+
└─ useArtifactPreviewConsumer().openPreview({ file })
|
|
156
|
+
└─ useArtifactPreviewProvider(ChatContainer 内)
|
|
157
|
+
├─ 记录命中文件 activeArtifactId = file.outputId
|
|
158
|
+
└─ onOpen → addCustomTab('file-artifact') 展开并选中侧栏 Tab
|
|
159
|
+
└─ FileArtifactPanel
|
|
160
|
+
├─ 列表 @select → setActiveArtifactId(outputId)
|
|
161
|
+
├─ 下载 → resolveArtifactUrls + triggerArtifactDownload
|
|
162
|
+
└─ ArtifactPreviewHost
|
|
163
|
+
├─ useArtifactPreviewLoader(策略 + fetch / 取链,防竞态)
|
|
164
|
+
└─ HtmlPreview | MarkdownPreview | TxtPreview | UrlIframePreview
|
|
165
|
+
|
|
166
|
+
容器初始化
|
|
167
|
+
└─ ensureCustomTab('file-artifact') 常驻挂上(不展开侧栏);因 order:-1 排在首位,
|
|
168
|
+
未主动切换过 Tab 时会成为默认选中面板;无产物时由面板展示整块空态
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
- 文件卡片通过 `useArtifactPreviewConsumer` 注入预览上下文,无 Provider 时卡片不可点击(兜底 `undefined`)
|
|
172
|
+
- `ChatContainer` 通过 `useArtifactPreviewProvider` 提供上下文,并把「打开侧栏 Tab」这一副作用以 `onOpen` 注入,保持 composable 职责单一
|
|
173
|
+
- 侧栏「文件产物」Tab 固定不可关闭,`order: -1` 排在「执行情况」之前;**常驻不随产物有无增删**,无产物时由面板展示整块空态
|
|
174
|
+
|
|
175
|
+
## 引用到输入框
|
|
176
|
+
|
|
177
|
+
预览头与消息区文件卡片都提供「引用」入口(设计稿中位于下载左侧),点击后文件以资源标签形态追加进输入框,等价于用户在 `@` 菜单里选中它:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
预览头 / 文件卡片「引用」
|
|
181
|
+
└─ useInputMentionConsumer()?.insertMention(toArtifactMenuItem(file))
|
|
182
|
+
└─ ChatContainer 提供的 insertMention
|
|
183
|
+
└─ ChatInput.insertMention → AiSlashInput.appendMention(追加到文档末尾)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
- **入口显隐**:`useInputMentionConsumer()` 为 `undefined`(没有输入框,如 `Share` 只读态)时不渲染引用按钮,无需额外开关
|
|
187
|
+
- **id 一致性**:统一走 [`toArtifactMenuItem`](/utils/#会话产物收集) 生成菜单条目,与 `@` 菜单里自动收集的产物同源;id 不一致会导致去重与已插入标签匹配同时失效
|
|
188
|
+
- **消息区文件卡片**:`ArtifactFileCard` 右侧操作区 hover 时显示,引用在下载左侧
|
|
189
|
+
|
|
190
|
+
## 唯一键规则
|
|
191
|
+
|
|
192
|
+
会话内以 **`outputId`** 作为文件产物唯一键:
|
|
193
|
+
|
|
194
|
+
- 同一 `outputId` 在多条消息中出现时,聚合列表去重并保留最后一次出现的文件信息
|
|
195
|
+
- `activeId`、列表 `:key`、`select` 事件参数均使用 `outputId`
|
|
196
|
+
- 文件名可能重复,**不可**作为唯一键
|
|
197
|
+
|
|
198
|
+
## 预览机制
|
|
199
|
+
|
|
200
|
+
预览分两步:先由 `resolveFileKind(type, name)`(`src/utils/file-type.ts`)把扩展名归入六个**分类**,再由 `getArtifactPreviewStrategy` 查表得到 **加载方式** 与 **渲染器**。面板与 Host 都不写死具体扩展名分支,后台新增文件类型时只需在分类表里补一行。
|
|
201
|
+
|
|
202
|
+
| 分类 | 覆盖扩展名 | load | 取链字段 | renderer |
|
|
203
|
+
| ---- | ---------- | ---- | -------- | -------- |
|
|
204
|
+
| `code` | `py` `js` `mjs` `cjs` `ts` `tsx` `jsx` `vue` `go` `rs` `rb` `java` `kt` `swift` `c` `h` `cpp` `hpp` `cs` `php` `lua` `r` `scala` `dart` `sh` `bash` `zsh` `ps1` `sql` `css` `scss` `less` `json` `jsonc` `yaml` `yml` `toml` `ini` `cfg` `conf` `env` `xml` `tex` `Dockerfile` `Makefile` `gitignore` `dockerignore` `editorconfig` | `text_from_download` | `download_url` → `fetch` 正文 | `CodePreview`(highlight.js 高亮) |
|
|
205
|
+
| `markdown` | `md` `markdown` | `text_from_download` | 同上 | `MarkdownPreview`(`MarkdownContent`) |
|
|
206
|
+
| `html` | `html` `htm` | `text_from_download` | 同上 | `HtmlPreview`(`<iframe srcdoc>`) |
|
|
207
|
+
| `text` | `txt` `rst` | `text_from_download` | 同上 | `TxtPreview`(`<pre>`) |
|
|
208
|
+
| `image` | `png` `jpg` `jpeg` `svg` | `preview_url` | `preview_url` | `ImagePreview`(`<img>`,`object-fit: contain`) |
|
|
209
|
+
| `binary` | `pdf` `docx` `xlsx` `xlsm` `xls` `pptx` `csv` `tsv`,以及**所有未登记的扩展名** | `preview_url` | `preview_url` | `UrlIframePreview`(`<iframe src>`,一般为后台转好的 PDF) |
|
|
210
|
+
|
|
211
|
+
关于类型解析:
|
|
212
|
+
|
|
213
|
+
- `AIFileInfo.type` 为**扩展名字符串**(如 `'pdf'` / `'py'`)或无扩展名的文件名(如 `'Dockerfile'`),大小写不敏感
|
|
214
|
+
- `type` 缺省时回退 `name` 推断;`报告.final.xlsx` 取 `xlsx`,`.gitignore` 取 `gitignore`
|
|
215
|
+
- `md` 为后台扩展名别名,与 `markdown` 等价,共用 Markdown 直渲染
|
|
216
|
+
- 未登记的扩展名一律落入 `binary` 走后台预览,前端不会因为新类型报错
|
|
217
|
+
|
|
218
|
+
`CodePreview` 的语言由扩展名映射到 highlight.js(`vue → xml`、`tsx → typescript`、`env / cfg / conf → ini` 等,其余交给 hljs 自身别名表,识别不了则按 `plaintext` 转义输出)。单文件超过 300KB 时跳过高亮直接转义,避免同步解析阻塞主线程。
|
|
219
|
+
|
|
220
|
+
### 加载态
|
|
221
|
+
|
|
222
|
+
| status | 表现 |
|
|
223
|
+
| ------ | ---- |
|
|
224
|
+
| `loading` | 预览区 [MessageLoading](/components/helper/message-loading) |
|
|
225
|
+
| `ready` | 对应 renderer 渲染 |
|
|
226
|
+
| `empty` | 「暂无可预览的文件」(无文件 / 未传 `onArtifactClick` / 缺所需 URL) |
|
|
227
|
+
| `error` | 「预览加载失败」+ 重试按钮 |
|
|
228
|
+
|
|
229
|
+
### 重载与取链约定
|
|
230
|
+
|
|
231
|
+
- **重载键**:`ArtifactPreviewHost` 以 `` `${outputId}:${type}` `` 监听文件变化;`outputId` 或 `type` 任一变化会重新 `load()`,仅改文件名等其它字段不会
|
|
232
|
+
- **取链**:`resolveArtifactUrls(file)` 每次重新调用 `onArtifactClick`;同文件进行中的请求会复用(并发去重)
|
|
233
|
+
- **重试**:错误态点击重试再次走 `load()`,重新取链并加载
|
|
234
|
+
- **竞态**:切换文件时 `useArtifactPreviewLoader` 用 `loadSeq` + `AbortController` 中断上一次 `fetch`,避免过期结果覆盖最新内容
|
|
235
|
+
|
|
236
|
+
下载图标仍由面板用 bkui `Loading` spin 单独表达。
|
|
237
|
+
|
|
238
|
+
## 内部结构(不导出)
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
message-artifacts/
|
|
242
|
+
├── file-artifact-panel.vue # 列表 + 下载头 + 挂载 Host
|
|
243
|
+
└── artifact-preview/
|
|
244
|
+
├── artifact-preview-host.vue # 状态机 UI + 分派 renderer
|
|
245
|
+
├── preview-strategy.ts # getArtifactPreviewStrategy(分类 → 策略查表)
|
|
246
|
+
├── use-artifact-preview-loader.ts
|
|
247
|
+
└── renderers/
|
|
248
|
+
├── code-preview.vue
|
|
249
|
+
├── html-preview.vue
|
|
250
|
+
├── image-preview.vue
|
|
251
|
+
├── markdown-preview.vue
|
|
252
|
+
├── txt-preview.vue
|
|
253
|
+
└── url-iframe-preview.vue
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
分类表与扩展名归一化在 `src/utils/file-type.ts`(导出 `AIFileKind` / `resolveFileKind` / `normalizeFileExtension`),与[文件图标](/components/helper/file-icon)共用同一份解析入口。
|
|
257
|
+
|
|
258
|
+
## API
|
|
259
|
+
|
|
260
|
+
### Props
|
|
261
|
+
|
|
262
|
+
| 属性名 | 类型 | 必填 | 说明 |
|
|
263
|
+
| --------- | ------------------- | ---- | -------------------------------------- |
|
|
264
|
+
| activeId | `string` | ✓ | 当前命中的文件 `outputId` |
|
|
265
|
+
| artifacts | `SessionArtifact[]` | ✓ | 当前会话全部文件产物(已按 `outputId` 去重) |
|
|
266
|
+
|
|
267
|
+
### Events
|
|
268
|
+
|
|
269
|
+
| 事件名 | 参数 | 说明 |
|
|
270
|
+
| ------ | ----------------- | -------------------------- |
|
|
271
|
+
| select | `(id: string)` | 列表内切换选中文件,参数为文件 `outputId` |
|
|
272
|
+
|
|
273
|
+
### Slots / Expose
|
|
274
|
+
|
|
275
|
+
无。
|
|
276
|
+
|
|
277
|
+
## 类型定义
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import type { AIFileInfo, SessionArtifact } from '@blueking/chat-x';
|
|
281
|
+
|
|
282
|
+
// 会话级文件产物:拍平去重后即为 AIFileInfo
|
|
283
|
+
type SessionArtifact = AIFileInfo;
|
|
284
|
+
|
|
285
|
+
type AIFileInfo = {
|
|
286
|
+
name: string;
|
|
287
|
+
outputId: string;
|
|
288
|
+
size: number;
|
|
289
|
+
/** 扩展名(如 'pdf' / 'py')或无扩展名文件名(如 'Dockerfile'),大小写不敏感 */
|
|
290
|
+
type: string;
|
|
291
|
+
};
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
> **破坏性变更**:原 `AIFileType` 枚举已移除,`AIFileInfo.type` 改为 `string`。此前写 `type: AIFileType.Pdf` 的代码改为 `type: 'pdf'` 即可;枚举成员的值与新字符串一一对应,运行时数据无需迁移。
|
|
295
|
+
|
|
296
|
+
## 关联 Composable
|
|
297
|
+
|
|
298
|
+
预览**命中与取链**由 [useArtifactPreview](/composables/use-artifact-preview) 提供(Provider / Consumer + `ARTIFACT_PREVIEW_TOKEN`)。**正文加载与渲染**由内部 `useArtifactPreviewLoader` + `ArtifactPreviewHost` 完成,不在该 composable 内。**引用到输入框**由 [useInputMention](/composables/use-input-mention) 提供。
|
|
299
|
+
|
|
300
|
+
## 关联组件
|
|
301
|
+
|
|
302
|
+
- [AssistantMessage](/components/message/assistant-message) — 文件产物来源(`property.artifacts`)
|
|
303
|
+
- [ChatContainer](/components/setup/chat-container) — 侧栏「文件产物」Tab 挂载场景,提供 `onArtifactClick`
|
|
304
|
+
- [MessageLoading](/components/helper/message-loading) — Host 预览区异步加载态
|
|
305
|
+
- [ExecutionSummary](/components/agent/execution-summary) — 同为侧栏 Tab 面板
|
|
306
|
+
- [MentionTag](/components/rendering/mention-tag) — 引用后在输入框内的标签形态
|
|
307
|
+
- [useInputMention](/composables/use-input-mention) — 引用入口的上下文来源
|