@blueking/chat-x 0.0.47-beta.4 → 0.0.49-beta.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.
Files changed (56) hide show
  1. package/dist/ag-ui/types/file.d.ts +23 -0
  2. package/dist/ag-ui/types/index.d.ts +1 -0
  3. package/dist/ag-ui/types/messages.d.ts +2 -0
  4. package/dist/components/chat-input/chat-input.vue.d.ts +15 -2
  5. package/dist/components/chat-input/input-attachment/input-attachment.vue.d.ts +4 -2
  6. package/dist/components/chat-input/model-selector/capabilities.d.ts +3 -0
  7. package/dist/components/chat-input/model-selector/index.d.ts +3 -0
  8. package/dist/components/chat-input/model-selector/model-selector-panel.vue.d.ts +26 -0
  9. package/dist/components/chat-input/model-selector/model-selector-trigger.vue.d.ts +14 -0
  10. package/dist/components/chat-input/model-selector/model-selector.vue.d.ts +39 -0
  11. package/dist/components/chat-input/model-selector/types.d.ts +61 -0
  12. package/dist/components/chat-input/model-selector/use-model-selector.d.ts +17 -0
  13. package/dist/components/chat-message/assistant-message/message-artifacts/artifact-file-card.vue.d.ts +14 -0
  14. package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/artifact-preview-host.vue.d.ts +8 -0
  15. package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/preview-strategy.d.ts +9 -0
  16. package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/renderers/html-preview.vue.d.ts +6 -0
  17. package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/renderers/markdown-preview.vue.d.ts +6 -0
  18. package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/renderers/txt-preview.vue.d.ts +6 -0
  19. package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/renderers/url-iframe-preview.vue.d.ts +6 -0
  20. package/dist/components/chat-message/assistant-message/message-artifacts/artifact-preview/use-artifact-preview-loader.d.ts +21 -0
  21. package/dist/components/chat-message/assistant-message/message-artifacts/file-artifact-panel.vue.d.ts +12 -0
  22. package/dist/components/chat-message/assistant-message/message-artifacts/file-icon.d.ts +29 -0
  23. package/dist/components/chat-message/assistant-message/message-artifacts/message-artifacts.vue.d.ts +10 -0
  24. package/dist/components/chat-message/message-container/message-container.vue.d.ts +2 -0
  25. package/dist/components/index.d.ts +3 -1
  26. package/dist/composables/index.d.ts +1 -0
  27. package/dist/composables/use-artifact-preview.d.ts +59 -0
  28. package/dist/composables/use-message-group.d.ts +434 -0
  29. package/dist/icons/file.d.ts +24 -0
  30. package/dist/icons/index.d.ts +1 -0
  31. package/dist/icons/input.d.ts +7 -0
  32. package/dist/index.css +1 -1
  33. package/dist/index.js +2761 -1984
  34. package/dist/index.js.map +1 -1
  35. package/dist/lang/lang.d.ts +10 -1
  36. package/dist/mcp/generated/docs/activity-message.md +122 -97
  37. package/dist/mcp/generated/docs/assistant-message.md +125 -62
  38. package/dist/mcp/generated/docs/chat-container.md +269 -76
  39. package/dist/mcp/generated/docs/chat-input.md +57 -0
  40. package/dist/mcp/generated/docs/file-artifact-panel.md +279 -0
  41. package/dist/mcp/generated/docs/info-message.md +23 -7
  42. package/dist/mcp/generated/docs/input-attachment.md +1 -0
  43. package/dist/mcp/generated/docs/loading-message.md +36 -17
  44. package/dist/mcp/generated/docs/message-container.md +47 -0
  45. package/dist/mcp/generated/docs/message-render.md +44 -33
  46. package/dist/mcp/generated/docs/message-tools.md +5 -1
  47. package/dist/mcp/generated/docs/model-selector.md +157 -0
  48. package/dist/mcp/generated/docs/reasoning-message.md +15 -11
  49. package/dist/mcp/generated/docs/tool-btn.md +33 -4
  50. package/dist/mcp/generated/docs/tool-message.md +61 -45
  51. package/dist/mcp/generated/docs/use-artifact-preview.md +237 -0
  52. package/dist/mcp/generated/docs/use-message-group.md +24 -0
  53. package/dist/mcp/generated/docs/user-message.md +185 -121
  54. package/dist/mcp/generated/index.json +109 -11
  55. package/dist/types/tool.d.ts +6 -2
  56. package/package.json +2 -2
@@ -0,0 +1,237 @@
1
+ <!-- AI SUMMARY -->
2
+ ## 快速了解
3
+
4
+ useArtifactPreviewProvider 维护 activeArtifactId,openPreview 命中文件并触发 onOpen 打开侧栏 Tab; 并通过 getOnArtifactClick 封装 resolveArtifactUrls(按 outputId 缓存 download_url / preview_url); useArtifactPreviewConsumer 在后代注入同一套 API。buildArtifactId 用 messageUid#index#outputId 生成唯一 id。 正文加载与分类型渲染不在本 composable,由 FileArtifactPanel 内 ArtifactPreviewHost 完成。 FILE_ARTIFACT_TAB_NAME 标识固定「文件产物」Tab。
5
+
6
+ ### 关联组件
7
+ - **chat-container** — Provider 主场景,聚合 sessionArtifacts 并挂载 FileArtifactPanel
8
+ - **file-artifact-panel** — 侧栏面板消费 activeArtifactId 与 setActiveArtifactId;预览加载在面板内 Host
9
+ - **assistant-message** — 文件产物来源 property.artifacts
10
+
11
+ ---
12
+ <!-- FULL DOC -->
13
+
14
+ # useArtifactPreview 文件产物预览
15
+
16
+ > **分类**:composable
17
+
18
+ Provider/Consumer 模式的文件产物预览状态管理。Provider 在 `ChatContainer` 中创建,负责维护当前命中的文件 id;Consumer 在深层 `ArtifactFileCard` 中注入,用于点击卡片触发预览。
19
+
20
+ **职责边界**:
21
+
22
+ - **本 composable**:维护「命中文件」与「URL 解析缓存」;打开侧栏 Tab(`addCustomTab`)由容器通过 `onOpen` 注入
23
+ - **不在本 composable**:聚合会话文件列表、渲染预览面板、按类型 fetch 正文 / iframe 展示 —— 分别由 `useMessageGroup.sessionArtifacts`、`FileArtifactPanel`、内部 `ArtifactPreviewHost` + `useArtifactPreviewLoader` 承担
24
+
25
+ ## 函数签名
26
+
27
+ ### useArtifactPreviewProvider
28
+
29
+ ```typescript
30
+ function useArtifactPreviewProvider(options: {
31
+ /** 读取业务侧异步取链回调(getter 保持对 props 变更敏感) */
32
+ getOnArtifactClick?: () => OnArtifactClick | undefined;
33
+ /** 命中文件后触发:由容器负责 addCustomTab + 展开侧栏 + 选中 Tab */
34
+ onOpen: (artifactId: string) => void;
35
+ }): {
36
+ activeArtifactId: ShallowRef<string>;
37
+ canResolveArtifactUrl: ComputedRef<boolean>;
38
+ openPreview: (payload: OpenArtifactPreviewPayload) => void;
39
+ resolveArtifactUrls: (file: AIFileInfo) => Promise<ArtifactUrlResult>;
40
+ setActiveArtifactId: (id: string) => void;
41
+ };
42
+ ```
43
+
44
+ ### useArtifactPreviewConsumer
45
+
46
+ ```typescript
47
+ function useArtifactPreviewConsumer():
48
+ | undefined
49
+ | {
50
+ activeArtifactId: Ref<string>;
51
+ canResolveArtifactUrl: ComputedRef<boolean>;
52
+ openPreview: (payload: OpenArtifactPreviewPayload) => void;
53
+ resolveArtifactUrls: (file: AIFileInfo) => Promise<ArtifactUrlResult>;
54
+ setActiveArtifactId: (id: string) => void;
55
+ };
56
+ ```
57
+
58
+ ### buildArtifactId
59
+
60
+ ```typescript
61
+ function buildArtifactId(messageUid: string, index: number, outputId: string): string;
62
+ // => `${messageUid}#${index}#${outputId}`
63
+ ```
64
+
65
+ ## 使用示例
66
+
67
+ ### Provider(ChatContainer)
68
+
69
+ 会话级文件产物由 [`useMessageGroup`](./use-message-group) 统一聚合(`sessionArtifacts`),Provider 只负责命中与打开侧栏 Tab:
70
+
71
+ ```typescript
72
+ import {
73
+ useArtifactPreviewProvider,
74
+ useCustomTabProvider,
75
+ useMessageGroup,
76
+ FILE_ARTIFACT_TAB_NAME,
77
+ } from '@blueking/chat-x';
78
+ import { t } from '@blueking/chat-x/lang';
79
+
80
+ const { addCustomTab, removeCustomTab } = useCustomTabProvider({ /* ... */ });
81
+
82
+ // 会话级文件产物聚合已内聚在 useMessageGroup,直接消费
83
+ const { sessionArtifacts } = useMessageGroup({ keyword, messages, selectedUserMessages });
84
+
85
+ const { activeArtifactId, setActiveArtifactId } = useArtifactPreviewProvider({
86
+ getOnArtifactClick: () => props.onArtifactClick,
87
+ onOpen: () => {
88
+ addCustomTab({
89
+ closable: false,
90
+ label: t('文件产物'),
91
+ name: FILE_ARTIFACT_TAB_NAME,
92
+ order: -1,
93
+ });
94
+ },
95
+ });
96
+
97
+ // 无文件产物时清理 Tab 与命中态
98
+ watch(sessionArtifacts, list => {
99
+ if (!list.length) {
100
+ removeCustomTab(FILE_ARTIFACT_TAB_NAME);
101
+ setActiveArtifactId('');
102
+ }
103
+ });
104
+ ```
105
+
106
+ ### Consumer(ArtifactFileCard)
107
+
108
+ ```typescript
109
+ import { useArtifactPreviewConsumer } from '@blueking/chat-x';
110
+
111
+ const artifactPreview = useArtifactPreviewConsumer();
112
+
113
+ // 有 Provider 时卡片可点击;无 Provider 时返回 undefined,卡片不可点击
114
+ const clickable = computed(() => !!props.onPreview || !!artifactPreview);
115
+
116
+ const handleCardClick = () => {
117
+ if (props.onPreview) {
118
+ props.onPreview(props.file);
119
+ return;
120
+ }
121
+ artifactPreview?.openPreview({
122
+ file: props.file,
123
+ index: props.index ?? 0,
124
+ messageUid: props.messageUid ?? '',
125
+ });
126
+ };
127
+ ```
128
+
129
+ ### 侧栏列表内切换命中文件
130
+
131
+ ```typescript
132
+ // FileArtifactPanel 列表点击 → emit select → 容器调用 setActiveArtifactId
133
+ // 右侧预览由面板内 ArtifactPreviewHost 消费 activeArtifact,自行取链并按类型渲染
134
+ <FileArtifactPanel
135
+ :active-id="activeArtifactId"
136
+ :artifacts="sessionArtifacts"
137
+ @select="setActiveArtifactId"
138
+ />
139
+ ```
140
+
141
+ ### 业务侧取链(ChatContainer `onArtifactClick`)
142
+
143
+ 文本类预览需要可 `fetch` 的 `download_url`;iframe 类需要 `preview_url`(一般为后台转好的 PDF):
144
+
145
+ ```typescript
146
+ const onArtifactClick = async (file: AIFileInfo) => {
147
+ const res = await api.getArtifactUrls(file.outputId);
148
+ return {
149
+ download_url: res.download_url,
150
+ preview_url: res.preview_url,
151
+ };
152
+ };
153
+ ```
154
+
155
+ ## 内置常量
156
+
157
+ | 常量名 | 值 | 说明 |
158
+ | ------------------------- | ------------------ | ----------------------------------------- |
159
+ | `FILE_ARTIFACT_TAB_NAME` | `'file-artifact'` | 「文件产物」侧栏 Tab 的固定标识,不可关闭 |
160
+ | `ARTIFACT_PREVIEW_TOKEN` | `Symbol` | provide/inject 注入 Token |
161
+
162
+ ## 返回值说明
163
+
164
+ | 属性/方法名 | 类型 | 说明 |
165
+ | ------------------- | ----------------------------------------- | -------------------------------------------------------------------- |
166
+ | activeArtifactId | `ShallowRef<string>` | 当前命中的文件 id(`messageUid#index#outputId`) |
167
+ | canResolveArtifactUrl | `ComputedRef<boolean>` | 是否具备异步取链能力(有 `onArtifactClick` 时为 true,下载按钮据此显隐) |
168
+ | openPreview | `(payload: OpenArtifactPreviewPayload) => void` | 由文件卡片触发:计算 id、更新命中态、调用 `onOpen` |
169
+ | resolveArtifactUrls | `(file: AIFileInfo) => Promise<ArtifactUrlResult>` | 调用 `onArtifactClick` 并按 `outputId` 缓存结果;并发请求去重 |
170
+ | setActiveArtifactId | `(id: string) => void` | 直接设置命中文件 id;侧栏列表内切换选中时使用 |
171
+
172
+ ## 类型定义
173
+
174
+ ```typescript
175
+ import type { AIFileInfo, ArtifactUrlResult, OnArtifactClick } from '@blueking/chat-x';
176
+
177
+ /** 打开预览时的入参:文件 + 消息内下标 + 所属消息 uid */
178
+ type OpenArtifactPreviewPayload = {
179
+ file: AIFileInfo;
180
+ index: number;
181
+ messageUid: string;
182
+ };
183
+
184
+ /**
185
+ * 会话级文件产物:在 AIFileInfo 基础上补充命中所需的唯一 id 与所属消息。
186
+ * 同一会话可能出现多个 AssistantMessage + 同名文件,文件名不可作唯一键。
187
+ */
188
+ type SessionArtifact = AIFileInfo & {
189
+ artifactId: string;
190
+ messageUid: string;
191
+ };
192
+
193
+ /** onArtifactClick 返回值(snake_case) */
194
+ type ArtifactUrlResult = {
195
+ download_url?: string;
196
+ preview_url?: string;
197
+ };
198
+ ```
199
+
200
+ ## 唯一 id 规则
201
+
202
+ 同一会话可能存在多个 `AssistantMessage`,且不同消息里可能有同名文件,因此**文件名不可作为唯一键**。Provider 侧聚合与 Consumer 侧透传必须使用同一 `buildArtifactId` 规则:
203
+
204
+ ```typescript
205
+ buildArtifactId('msg-a', 2, 'output-9'); // => 'msg-a#2#output-9'
206
+ ```
207
+
208
+ - `messageUid`:所属 `AssistantMessage` 的 `uid`(回退 `String(id)`)
209
+ - `index`:文件在所属消息 `property.artifacts` 数组中的下标
210
+ - `outputId`:文件自身的 `AIFileInfo.outputId`
211
+
212
+ ## 完整触发链路
213
+
214
+ ```
215
+ ArtifactFileCard(点击)
216
+ └─ useArtifactPreviewConsumer().openPreview({ file, index, messageUid })
217
+ └─ useArtifactPreviewProvider(ChatContainer)
218
+ ├─ activeArtifactId = buildArtifactId(...)
219
+ └─ onOpen(artifactId) → addCustomTab(FILE_ARTIFACT_TAB_NAME)
220
+ └─ FileArtifactPanel(列表 + 下载头,@select → setActiveArtifactId)
221
+ └─ ArtifactPreviewHost(loader + 分类型 renderer)
222
+ ```
223
+
224
+ 分类型预览策略见 [FileArtifactPanel 预览机制](../components/message/file-artifact-panel#预览机制)。
225
+
226
+ ## 设计特点
227
+
228
+ - **职责单一**:composable 不直接调用 `useCustomTab`,侧栏 Tab 打开逻辑由 `onOpen` 注入;也不做正文 fetch / iframe 渲染
229
+ - **ShallowRef 优先**:`activeArtifactId` 使用 `shallowRef`,避免不必要的深层响应式开销
230
+ - **Consumer 兜底**:`useArtifactPreviewConsumer` 无 Provider 时返回 `undefined`,文件卡片在无容器上下文时自动不可点击
231
+ - **与 useCustomTab 协作**:「文件产物」Tab 通过 `addCustomTab` 按需添加(`order: -1`、`closable: false`),会话无文件产物时由容器 `removeCustomTab` 清理
232
+
233
+ ## 关联组件
234
+
235
+ - [ChatContainer](../components/setup/chat-container) — Provider 主场景,内置「文件产物」Tab
236
+ - [FileArtifactPanel](../components/message/file-artifact-panel) — 侧栏列表与预览 Host 挂载
237
+ - [AssistantMessage](../components/message/assistant-message) — 文件产物来源(`property.artifacts`)
@@ -28,6 +28,7 @@ function useMessageGroup(options: {
28
28
  }): {
29
29
  messageGroups: Ref<MessageGroup[]>;
30
30
  executionGroups: ComputedRef<MessageGroup[]>;
31
+ sessionArtifacts: ComputedRef<SessionArtifact[]>;
31
32
  pendingApprovalCount: ComputedRef<number>;
32
33
  pendingApprovalTipText: ComputedRef<string>;
33
34
  isShareMode: ShallowRef<boolean>;
@@ -116,6 +117,28 @@ const isExecutionMessage = (m: Message): boolean => {
116
117
  | toolCall | `function.name`、`mcpName`、`description`、`arguments`、`id` |
117
118
  | flow_agent | 各任务 `task_name`、各节点 `name` |
118
119
 
120
+ ## sessionArtifacts 会话级文件产物
121
+
122
+ `sessionArtifacts` 拍平当前会话所有 `AssistantMessage.property.artifacts`,供 `ChatContainer` 侧栏「文件产物」Tab 聚合预览。由于同一会话可能出现「多个 AssistantMessage + 同名文件」,文件名不可作为唯一键,统一用 `messageUid`(回退 `String(id)`)+ 消息内下标 + `outputId` 通过 [`buildArtifactId`](./use-artifact-preview) 生成全局唯一 `artifactId`:
123
+
124
+ ```typescript
125
+ const sessionArtifacts = computed(() => {
126
+ const list = [];
127
+ for (const message of messages.value) {
128
+ if (message.role !== MessageRole.Assistant) continue;
129
+ const artifacts = message.property?.artifacts;
130
+ if (!artifacts?.length) continue;
131
+ const messageUid = message.uid ?? String(message.id);
132
+ artifacts.forEach((file, index) => {
133
+ list.push({ ...file, artifactId: buildArtifactId(messageUid, index, file.outputId), messageUid });
134
+ });
135
+ }
136
+ return list;
137
+ });
138
+ ```
139
+
140
+ 预览命中与取链见 [useArtifactPreview](./use-artifact-preview);侧栏列表与分类型预览(`ArtifactPreviewHost`)见 [FileArtifactPanel](../components/message/file-artifact-panel)。
141
+
119
142
  ## 待审批统计
120
143
 
121
144
  `useMessageGroup` 会统计消息列表中处于待审批状态的 AI Dev 审批中断:
@@ -186,6 +209,7 @@ const {
186
209
  | ---------------- | ----------------------------- | --------------------------------------------------------------------------- |
187
210
  | messageGroups | `Ref<MessageGroup[]>` | 完整消息分组列表 |
188
211
  | executionGroups | `ComputedRef<MessageGroup[]>` | 仅包含执行类消息的分组(工具调用 + FlowAgent),自动提取 `userMessageTitle` |
212
+ | sessionArtifacts | `ComputedRef<SessionArtifact[]>` | 拍平会话所有 AssistantMessage 文件产物,含全局唯一 `artifactId` |
189
213
  | pendingApprovalCount | `ComputedRef<number>` | 当前消息中待审批 AI Dev 审批中断的数量 |
190
214
  | pendingApprovalTipText | `ComputedRef<string>` | 待审批阻塞发送提示文案;无待审批时为空字符串 |
191
215
  | isShareMode | `ShallowRef<boolean>` | 是否处于分享模式 |