@blueking/chat-x 0.0.5 → 0.0.6
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/mcp/generated/docs/activity-message.md +428 -0
- package/dist/mcp/generated/docs/ai-image.md +227 -0
- package/dist/mcp/generated/docs/ai-loading.md +129 -0
- package/dist/mcp/generated/docs/ai-selection.md +436 -0
- package/dist/mcp/generated/docs/animation-text.md +199 -0
- package/dist/mcp/generated/docs/assistant-message.md +424 -0
- package/dist/mcp/generated/docs/chat-container.md +365 -0
- package/dist/mcp/generated/docs/chat-input.md +625 -0
- package/dist/mcp/generated/docs/cite-content.md +138 -0
- package/dist/mcp/generated/docs/code-content.md +199 -0
- package/dist/mcp/generated/docs/common-error-content.md +70 -0
- package/dist/mcp/generated/docs/constants.md +216 -0
- package/dist/mcp/generated/docs/content-render.md +238 -0
- package/dist/mcp/generated/docs/delete-tool.md +188 -0
- package/dist/mcp/generated/docs/desc-panel.md +139 -0
- package/dist/mcp/generated/docs/execution-summary.md +126 -0
- package/dist/mcp/generated/docs/file-content.md +300 -0
- package/dist/mcp/generated/docs/file-upload-btn.md +174 -0
- package/dist/mcp/generated/docs/flow-message.md +305 -0
- package/dist/mcp/generated/docs/highlight-keyword.md +144 -0
- package/dist/mcp/generated/docs/image-content.md +178 -0
- package/dist/mcp/generated/docs/image-preview-group.md +181 -0
- package/dist/mcp/generated/docs/image-preview.md +224 -0
- package/dist/mcp/generated/docs/info-message.md +124 -0
- package/dist/mcp/generated/docs/key-value-content.md +124 -0
- package/dist/mcp/generated/docs/latex-content.md +196 -0
- package/dist/mcp/generated/docs/loading-message.md +171 -0
- package/dist/mcp/generated/docs/markdown-content.md +186 -0
- package/dist/mcp/generated/docs/markdown-latex.md +208 -0
- package/dist/mcp/generated/docs/markdown-mermaid.md +250 -0
- package/dist/mcp/generated/docs/mermaid-content.md +185 -0
- package/dist/mcp/generated/docs/message-container.md +534 -0
- package/dist/mcp/generated/docs/message-render.md +329 -0
- package/dist/mcp/generated/docs/message-tools.md +376 -0
- package/dist/mcp/generated/docs/messages.md +472 -0
- package/dist/mcp/generated/docs/overflow-tips.md +209 -0
- package/dist/mcp/generated/docs/reasoning-message.md +233 -0
- package/dist/mcp/generated/docs/reference-content.md +132 -0
- package/dist/mcp/generated/docs/scroll-btn.md +155 -0
- package/dist/mcp/generated/docs/selection-footer.md +75 -0
- package/dist/mcp/generated/docs/shortcut-btn.md +202 -0
- package/dist/mcp/generated/docs/shortcut-btns.md +264 -0
- package/dist/mcp/generated/docs/shortcut-render.md +418 -0
- package/dist/mcp/generated/docs/text-content.md +74 -0
- package/dist/mcp/generated/docs/theme.md +388 -0
- package/dist/mcp/generated/docs/tool-btn.md +254 -0
- package/dist/mcp/generated/docs/tool-message.md +217 -0
- package/dist/mcp/generated/docs/toolcall-render.md +299 -0
- package/dist/mcp/generated/docs/use-animation-text.md +198 -0
- package/dist/mcp/generated/docs/use-clipboard.md +206 -0
- package/dist/mcp/generated/docs/use-command-selection.md +128 -0
- package/dist/mcp/generated/docs/use-container-scroll.md +56 -0
- package/dist/mcp/generated/docs/use-custom-tab.md +122 -0
- package/dist/mcp/generated/docs/use-global-config.md +154 -0
- package/dist/mcp/generated/docs/use-menu-keydown.md +164 -0
- package/dist/mcp/generated/docs/use-message-group.md +175 -0
- package/dist/mcp/generated/docs/use-observer-visible-list.md +189 -0
- package/dist/mcp/generated/docs/use-parent-scrolling.md +46 -0
- package/dist/mcp/generated/docs/user-feedback.md +229 -0
- package/dist/mcp/generated/docs/user-message.md +347 -0
- package/dist/mcp/generated/index.json +1311 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +42 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +43 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/get-component-doc.d.ts +19 -0
- package/dist/mcp/tools/get-component-doc.js +60 -0
- package/dist/mcp/tools/get-component-doc.js.map +1 -0
- package/dist/mcp/tools/list-components.d.ts +35 -0
- package/dist/mcp/tools/list-components.js +147 -0
- package/dist/mcp/tools/list-components.js.map +1 -0
- package/dist/mcp/tools/search-docs.d.ts +14 -0
- package/dist/mcp/tools/search-docs.js +82 -0
- package/dist/mcp/tools/search-docs.js.map +1 -0
- package/dist/mcp/utils/doc-loader.d.ts +35 -0
- package/dist/mcp/utils/doc-loader.js +64 -0
- package/dist/mcp/utils/doc-loader.js.map +1 -0
- package/package.json +5 -7
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<!-- AI SUMMARY -->
|
|
2
|
+
## 快速了解
|
|
3
|
+
|
|
4
|
+
ToolMessage 展示工具(Function Call)执行返回,内部用 DescPanel 将 JSON 解析为 key-value 或纯文本。通常不单独使用: ToolcallRender 在 toolCall.toolMessage 有值时内联渲染;独立 role 为 tool 的消息由 MessageRender 统一渲染。核心关注 content 与 error。
|
|
5
|
+
|
|
6
|
+
### 关联组件
|
|
7
|
+
- **assistant-message** — 结果常作为 assistant 消息中 toolCall.toolMessage 内联展示
|
|
8
|
+
- **message-render** — 独立 tool 角色消息由 MessageRender 渲染为 ToolMessage
|
|
9
|
+
- **desc-panel** — 内部使用 DescPanel 展示「返回内容」
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
<!-- FULL DOC -->
|
|
13
|
+
|
|
14
|
+
# ToolMessage 工具消息
|
|
15
|
+
|
|
16
|
+
> **层级**:分子组件 · **功能域**:消息展示
|
|
17
|
+
|
|
18
|
+
工具(Function Call)执行结果展示组件。内部通过 `DescPanel` 渲染,标题固定为"返回内容",支持将 JSON 自动解析为 key-value 列表。
|
|
19
|
+
|
|
20
|
+
> **通常不需要直接使用此组件**。`ToolcallRender` 在 `toolCall.toolMessage` 有值时会自动内联渲染;`MessageContainer` 处理 `role: 'tool'` 消息时也会通过 `MessageRender` 自动渲染。
|
|
21
|
+
|
|
22
|
+
## 渲染架构
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
ToolMessage
|
|
26
|
+
└── DescPanel(desc="content || (typeof error === 'string' ? error : undefined)",title="返回内容")
|
|
27
|
+
├── JSON.parse(desc) 成功且结果为 object/array
|
|
28
|
+
│ └── key-value 列表(v-for 遍历)
|
|
29
|
+
│ 值超长时截断 + overflow-tips tooltip
|
|
30
|
+
└── 其他(parse 失败 / 结果为基本类型)
|
|
31
|
+
└── 纯文本展示
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 基础用法
|
|
35
|
+
|
|
36
|
+
```vue
|
|
37
|
+
<template>
|
|
38
|
+
<ToolMessage
|
|
39
|
+
:content="content"
|
|
40
|
+
tool-call-id="call_1"
|
|
41
|
+
:duration="850"
|
|
42
|
+
/>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script setup lang="ts">
|
|
46
|
+
import { ToolMessage } from '@blueking/chat-x';
|
|
47
|
+
|
|
48
|
+
const content = JSON.stringify({
|
|
49
|
+
city: '北京',
|
|
50
|
+
temperature: 22,
|
|
51
|
+
weather: '晴',
|
|
52
|
+
humidity: '45%',
|
|
53
|
+
wind: '东北风 3 级',
|
|
54
|
+
});
|
|
55
|
+
</script>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**JSON 对象内容(key-value 列表)**
|
|
59
|
+
|
|
60
|
+
**纯文本内容**
|
|
61
|
+
|
|
62
|
+
## 错误状态
|
|
63
|
+
|
|
64
|
+
`content` 为空时展示 `error`,由 `content || (typeof error === 'string' ? error : undefined)` 决定。仅当 `error` 为字符串类型时才会展示,非字符串类型的 `error`(如对象)会被忽略:
|
|
65
|
+
|
|
66
|
+
```vue
|
|
67
|
+
<template>
|
|
68
|
+
<ToolMessage
|
|
69
|
+
content=""
|
|
70
|
+
:error="error"
|
|
71
|
+
tool-call-id="call_3"
|
|
72
|
+
:duration="5000"
|
|
73
|
+
/>
|
|
74
|
+
</template>
|
|
75
|
+
|
|
76
|
+
<script setup lang="ts">
|
|
77
|
+
import { ToolMessage } from '@blueking/chat-x';
|
|
78
|
+
|
|
79
|
+
const error = 'Connection timeout: database server is unreachable (timeout: 5000ms)';
|
|
80
|
+
</script>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## DescPanel 内容渲染规则
|
|
84
|
+
|
|
85
|
+
`DescPanel` 内部对 `desc`(即 `content || (typeof error === 'string' ? error : undefined)`)进行 `JSON.parse`,然后根据解析结果类型决定渲染方式:
|
|
86
|
+
|
|
87
|
+
| `desc` 内容 | `JSON.parse` 结果 | 渲染方式 |
|
|
88
|
+
| --------------------------- | ------------------------------- | ----------------------------------- |
|
|
89
|
+
| 合法 JSON 对象 `{}` | `object`(非 null) | **key-value 列表**,键为字段名 |
|
|
90
|
+
| 合法 JSON 数组 `[]` | `array`(也是 `object`) | **index-keyed 列表**,键为 0、1、2… |
|
|
91
|
+
| 合法 JSON 基本类型 | `number` / `string` / `boolean` | 纯文本 |
|
|
92
|
+
| `"null"` 字符串 | `null`(`typeof 'object'`) | 空内容区(v-for 遍历 null 无输出) |
|
|
93
|
+
| 解析失败(非法 JSON) | 捕获异常,返回原字符串 | 纯文本 |
|
|
94
|
+
| `content` 和 `error` 均为空 | `''` → 解析失败 | 空内容区 |
|
|
95
|
+
|
|
96
|
+
> **注意**:JSON 数组在 JavaScript 中 `typeof [] === 'object'` 为 `true`,因此数组会以 `0:`、`1:`、`2:` 为键渲染为 key-value 列表,而**非**纯文本。
|
|
97
|
+
|
|
98
|
+
**嵌套对象值的处理**:当 value 本身是对象时,`{{ value }}` 会渲染为 `[object Object]`,但 hover 展示的 overflow-tips 会显示 `JSON.stringify(value)` 的完整字符串。
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// ✅ 渲染为 key-value 列表
|
|
102
|
+
const jsonObject = '{"city":"北京","temperature":22}';
|
|
103
|
+
|
|
104
|
+
// ✅ 渲染为 index-keyed 列表(0: item1, 1: item2)
|
|
105
|
+
const jsonArray = '["item1","item2","item3"]';
|
|
106
|
+
|
|
107
|
+
// ✅ 渲染为纯文本(基本类型)
|
|
108
|
+
const jsonNumber = '42';
|
|
109
|
+
const jsonBool = 'true';
|
|
110
|
+
|
|
111
|
+
// ✅ 渲染为纯文本(解析失败)
|
|
112
|
+
const plainText = '查询成功,共返回 10 条记录。';
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 与 ToolcallRender 的关系
|
|
116
|
+
|
|
117
|
+
`ToolcallRender` 在详情面板展开时,若 `toolCall.toolMessage` 有值,会在底部内联渲染 `ToolMessage`:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// toolcall-render.vue 内部逻辑(简化)
|
|
121
|
+
// <ToolMessage v-if="toolCall?.toolMessage" v-bind="toolCall.toolMessage" />
|
|
122
|
+
|
|
123
|
+
const toolCall = {
|
|
124
|
+
id: 'call_weather',
|
|
125
|
+
type: 'function',
|
|
126
|
+
function: {
|
|
127
|
+
name: 'get_weather',
|
|
128
|
+
arguments: '{"city":"北京"}',
|
|
129
|
+
description: '获取天气信息',
|
|
130
|
+
},
|
|
131
|
+
// 提供此字段后 ToolcallRender 会自动渲染 ToolMessage
|
|
132
|
+
toolMessage: {
|
|
133
|
+
id: '3',
|
|
134
|
+
messageId: '3',
|
|
135
|
+
role: 'tool',
|
|
136
|
+
content: '{"temperature":22,"weather":"晴"}',
|
|
137
|
+
status: 'complete',
|
|
138
|
+
duration: 850,
|
|
139
|
+
toolCallId: 'call_weather',
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## 与 MessageContainer 的关系
|
|
145
|
+
|
|
146
|
+
`MessageContainer` 通过 `toolCallId` 将 `role: 'tool'` 消息注入对应 AssistantMessage 的 `toolCall.toolMessage`,整个过程自动完成,无需手动引入 `ToolMessage`:
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
const messages = [
|
|
150
|
+
{
|
|
151
|
+
id: '1',
|
|
152
|
+
messageId: '1',
|
|
153
|
+
role: 'assistant',
|
|
154
|
+
content: '好的,我来查询天气。',
|
|
155
|
+
status: 'complete',
|
|
156
|
+
toolCalls: [
|
|
157
|
+
{
|
|
158
|
+
id: 'call_weather',
|
|
159
|
+
type: 'function',
|
|
160
|
+
function: { name: 'get_weather', arguments: '{"city":"北京"}' },
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
id: '2',
|
|
166
|
+
messageId: '2',
|
|
167
|
+
role: 'tool', // MessageContainer 自动处理
|
|
168
|
+
content: '{"temperature":22,"weather":"晴"}',
|
|
169
|
+
status: 'complete',
|
|
170
|
+
toolCallId: 'call_weather', // ← 通过此字段自动关联并注入上方 toolCall
|
|
171
|
+
duration: 850,
|
|
172
|
+
},
|
|
173
|
+
];
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## API
|
|
177
|
+
|
|
178
|
+
### Props
|
|
179
|
+
|
|
180
|
+
组件 Props 继承自 `Partial<ToolMessage>`,所有字段均可选:
|
|
181
|
+
|
|
182
|
+
| 属性名 | 类型 | 说明 |
|
|
183
|
+
| ---------- | ------------------ | ------------------------------------------------------------------------------- |
|
|
184
|
+
| content | `string` | 工具执行返回内容;与 `error` 通过 `\|\|` 决定优先级,**truthy 时 error 被忽略** |
|
|
185
|
+
| error | `string` | 工具执行错误信息;仅当 `content` 为 falsy 且 `error` 为 `string` 类型时展示 |
|
|
186
|
+
| toolCallId | `string` | 关联的工具调用 ID(透传,组件内不使用) |
|
|
187
|
+
| duration | `number` | 工具执行耗时(毫秒,透传,组件内不使用) |
|
|
188
|
+
| status | `MessageStatus` | 消息状态(透传,组件内不使用) |
|
|
189
|
+
| id | `string \| number` | 消息 ID(透传,组件内不使用) |
|
|
190
|
+
| messageId | `string \| number` | 消息唯一标识(透传,组件内不使用) |
|
|
191
|
+
|
|
192
|
+
> **说明**:`ToolMessage` 组件内部只使用 `content` 和 `error` 两个字段(传给 `DescPanel`),其他字段均被透传接收但不使用,由父组件(`ToolcallRender` / `MessageContainer`)在外部管理。
|
|
193
|
+
|
|
194
|
+
## 类型定义
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
import { MessageRole, MessageStatus, type ToolMessage } from '@blueking/chat-x';
|
|
198
|
+
|
|
199
|
+
// ToolMessage 继承自 BaseMessage<MessageRole.Tool, string>
|
|
200
|
+
interface ToolMessage {
|
|
201
|
+
id: string | number;
|
|
202
|
+
messageId: string | number;
|
|
203
|
+
role: MessageRole.Tool; // 'tool'
|
|
204
|
+
status: MessageStatus;
|
|
205
|
+
content: string;
|
|
206
|
+
toolCallId: string; // 关联的 ToolCall.id
|
|
207
|
+
duration: number; // 工具执行耗时(毫秒)
|
|
208
|
+
error?: string; // 执行错误信息
|
|
209
|
+
name?: string;
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## 关联组件
|
|
214
|
+
|
|
215
|
+
- [AssistantMessage](./assistant-message.md) — toolCall.toolMessage 内联场景
|
|
216
|
+
- [MessageRender](./message-render.md) — 独立 tool 消息派发
|
|
217
|
+
- [DescPanel](../atomic/desc-panel.md) — 返回内容面板
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
<!-- AI SUMMARY -->
|
|
2
|
+
## 快速了解
|
|
3
|
+
|
|
4
|
+
ToolcallRender 折叠展示一次工具/MCP 调用:头部显示名称、状态色、耗时与 MCP 标识,展开区展示参数与返回。 内部组合 DescPanel 与 HighlightKeyword;可在详情底部内联 ToolMessage 结果。
|
|
5
|
+
|
|
6
|
+
### 关联组件
|
|
7
|
+
- **desc-panel** — 详情区展示参数与描述文本
|
|
8
|
+
- **highlight-keyword** — 标题与状态文案关键词高亮
|
|
9
|
+
- **tool-message** — 详情底部可内联工具返回消息
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
<!-- FULL DOC -->
|
|
13
|
+
|
|
14
|
+
# ToolcallRender 工具调用渲染器
|
|
15
|
+
|
|
16
|
+
> **层级**:分子组件 · **功能域**:工具与反馈
|
|
17
|
+
|
|
18
|
+
展示 AI 调用外部工具/函数过程与结果的渲染组件。由**可折叠头部**和**详情面板**组成,根据 `status` 自动切换颜色和状态文案,支持 MCP 调用识别和内联结果展示。
|
|
19
|
+
|
|
20
|
+
## 组件结构
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
.ai-toolcall-render
|
|
24
|
+
├── .ai-toolcall-render-header(高 40px,class="toolcall-status-{status}")
|
|
25
|
+
│ ├── ArrowRightIcon(14×14px,点击切换折叠;默认 rotate(0deg),展开后 rotate(90deg))
|
|
26
|
+
│ ├── "调用工具:" / "调用 MCP:"(有 mcpName 时)
|
|
27
|
+
│ ├── .toolcall-header-title(工具名,overflow-tips 溢出截断)
|
|
28
|
+
│ └── .toolcall-status-title
|
|
29
|
+
│ ├── Loading(仅 pending / streaming 时显示)
|
|
30
|
+
│ ├── 状态文案(调用中 / 调用成功 / 调用失败)
|
|
31
|
+
│ └── .toolcall-duration(耗时,如 "(1.2s)")
|
|
32
|
+
│
|
|
33
|
+
└── .ai-toolcall-render-content(v-show,默认折叠)
|
|
34
|
+
├── DescPanel(title="描述",desc=function.description)← 始终渲染
|
|
35
|
+
├── DescPanel(title="参数",desc=function.arguments)← 始终渲染
|
|
36
|
+
└── ToolMessage(v-if="toolCall?.toolMessage")← 有结果时渲染
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 基础用法
|
|
40
|
+
|
|
41
|
+
```vue
|
|
42
|
+
<template>
|
|
43
|
+
<ToolcallRender
|
|
44
|
+
:tool-call="toolCall"
|
|
45
|
+
:status="MessageStatus.Complete"
|
|
46
|
+
/>
|
|
47
|
+
</template>
|
|
48
|
+
|
|
49
|
+
<script setup lang="ts">
|
|
50
|
+
import { ToolcallRender, MessageStatus, MessageContentType, type ToolCall } from '@blueking/chat-x';
|
|
51
|
+
|
|
52
|
+
const toolCall: ToolCall = {
|
|
53
|
+
id: 'call_1',
|
|
54
|
+
type: MessageContentType.Function,
|
|
55
|
+
function: {
|
|
56
|
+
name: 'get_weather',
|
|
57
|
+
arguments: JSON.stringify({ city: '北京', unit: 'celsius' }),
|
|
58
|
+
description: '获取指定城市的实时天气信息',
|
|
59
|
+
},
|
|
60
|
+
toolMessage: {
|
|
61
|
+
content: JSON.stringify({ city: '北京', temperature: 22, weather: '晴' }),
|
|
62
|
+
status: 'complete',
|
|
63
|
+
duration: 1200,
|
|
64
|
+
toolCallId: 'call_1',
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
</script>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**渲染效果**
|
|
71
|
+
|
|
72
|
+
## 调用状态
|
|
73
|
+
|
|
74
|
+
`status` prop 同时控制头部的 CSS class(`toolcall-status-{status}`)、背景/边框颜色、状态文案和 Loading 动画:
|
|
75
|
+
|
|
76
|
+
| `status` | 状态文案 | 背景色 | 边框色 | Loading |
|
|
77
|
+
| ----------------------- | -------- | ----------------- | --------- | ------- |
|
|
78
|
+
| `pending` / `streaming` | 调用中 | `#fafbfd` | `#dcdee5` | ✓ |
|
|
79
|
+
| `complete` / `success` | 调用成功 | `#ebfaf0` | `#a1e3ba` | - |
|
|
80
|
+
| `error` | 调用失败 | `#fff0f0` | `#f8b4b4` | - |
|
|
81
|
+
| 其他 / `undefined` | 调用中 | —(无匹配 class) | — | - |
|
|
82
|
+
|
|
83
|
+
> **说明**:`statusTitle` 的 `switch` 语句中 `default` 与 `case Pending` 共享同一返回值,`streaming` 和未知 status 均命中 `default` 分支,显示"调用中"。Loading 动画由 `v-if="status === 'pending' || status === 'streaming'"` 单独控制。
|
|
84
|
+
|
|
85
|
+
**三种状态对比**
|
|
86
|
+
|
|
87
|
+
## 工具标题(toolTitle)
|
|
88
|
+
|
|
89
|
+
头部标题的计算规则:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
有 mcpName → "{mcpName} / {function.name}"
|
|
93
|
+
无 mcpName → function.name || toolCall.id
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`function.name` 为空字符串时,自动回退到 `toolCall.id` 作为标题。标题超出容器宽度时截断并配备 overflow-tips。
|
|
97
|
+
|
|
98
|
+
## 折叠/展开详情面板
|
|
99
|
+
|
|
100
|
+
详情面板**默认折叠**,点击头部左侧的 **箭头图标**(14×14px 可点区域,非整行)切换折叠状态。折叠状态由 `collapsed`(默认 `true`)和 `superCollapsed` 两个 `shallowRef` 共同管理,不暴露为 prop/v-model。
|
|
101
|
+
|
|
102
|
+
| 折叠状态 | 箭头旋转角度 | 详情面板 |
|
|
103
|
+
| ------------ | ----------------------- | ------------- |
|
|
104
|
+
| 折叠(默认) | `rotate(0deg)`(朝右) | `v-show` 隐藏 |
|
|
105
|
+
| 展开 | `rotate(90deg)`(朝下) | 可见 |
|
|
106
|
+
|
|
107
|
+
详情面板由三块区域构成:
|
|
108
|
+
|
|
109
|
+
| 区块 | 数据来源 | 渲染方式 | 渲染条件 |
|
|
110
|
+
| -------- | ---------------------- | ---------------------------------------------------- | ---------------------------- |
|
|
111
|
+
| 描述 | `function.description` | `DescPanel`(纯文本 / key-value 列表) | **始终渲染**,无值则显示空白 |
|
|
112
|
+
| 参数 | `function.arguments` | `DescPanel`(JSON 对象 → key-value;其他 → 纯文本) | **始终渲染**,无值则显示空白 |
|
|
113
|
+
| 工具结果 | `toolCall.toolMessage` | `ToolMessage` 组件(`v-if="toolCall?.toolMessage"`) | 仅当 `toolMessage` 存在时 |
|
|
114
|
+
|
|
115
|
+
## 调用耗时
|
|
116
|
+
|
|
117
|
+
耗时来源优先级(`||` 运算符):
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
durationDisplay = formatDuration(props.duration || toolCall?.toolMessage?.duration);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
| 场景 | 耗时来源 |
|
|
124
|
+
| ------------------------------------------ | --------------------------- |
|
|
125
|
+
| 传入 `duration` prop | 使用 prop 值 |
|
|
126
|
+
| 未传 `duration`,toolMessage 有 `duration` | 使用 `toolMessage.duration` |
|
|
127
|
+
| 两者均无 | 不显示耗时 |
|
|
128
|
+
|
|
129
|
+
```vue
|
|
130
|
+
<!-- 方式一:直接传 duration prop(优先) -->
|
|
131
|
+
<ToolcallRender :tool-call="toolCall" status="complete" :duration="1200" />
|
|
132
|
+
|
|
133
|
+
<!-- 方式二(推荐):duration 放在 toolMessage 中,无需额外 prop -->
|
|
134
|
+
<ToolcallRender :tool-call="toolCallWithDuration" status="complete" />
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// 推荐:duration 统一由 toolMessage 管理
|
|
139
|
+
const toolCallWithDuration: ToolCall = {
|
|
140
|
+
id: 'call_1',
|
|
141
|
+
type: 'function',
|
|
142
|
+
function: { name: 'get_weather', arguments: '{"city":"北京"}' },
|
|
143
|
+
toolMessage: {
|
|
144
|
+
content: '{"temperature":22}',
|
|
145
|
+
status: 'complete',
|
|
146
|
+
duration: 1200, // ← 组件自动读取,无需额外传 duration prop
|
|
147
|
+
toolCallId: 'call_1',
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## MCP 工具调用
|
|
153
|
+
|
|
154
|
+
`function.mcpName` 有值时:
|
|
155
|
+
|
|
156
|
+
- 头部文案从 **"调用工具:"** 自动切换为 **"调用 MCP:"**
|
|
157
|
+
- 标题格式变为 `{mcpName} / {functionName}`
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
const mcpToolCall: ToolCall = {
|
|
161
|
+
id: 'call_mcp_1',
|
|
162
|
+
type: 'function',
|
|
163
|
+
function: {
|
|
164
|
+
name: 'query_table',
|
|
165
|
+
arguments: JSON.stringify({ table: 'events', limit: 50 }),
|
|
166
|
+
description: '通过 MCP 协议查询蓝鲸数据平台中的事件数据',
|
|
167
|
+
mcpName: 'bk-data-server', // ← 有值时头部显示"调用 MCP:"
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
// 头部显示:调用 MCP: bk-data-server / query_table
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**渲染效果**
|
|
174
|
+
|
|
175
|
+
## 调用失败
|
|
176
|
+
|
|
177
|
+
`toolMessage.error` 有值且 `content` 为空时,`ToolMessage` 内部展示错误信息(由 `content || error` 决定)。`status` 设为 `error` 控制头部红色样式:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const failedToolCall: ToolCall = {
|
|
181
|
+
id: 'call_1',
|
|
182
|
+
type: 'function',
|
|
183
|
+
function: {
|
|
184
|
+
name: 'execute_sql',
|
|
185
|
+
arguments: JSON.stringify({ sql: 'SELECT * FROM users' }),
|
|
186
|
+
description: '执行数据库查询',
|
|
187
|
+
},
|
|
188
|
+
toolMessage: {
|
|
189
|
+
content: '', // 空 content → ToolMessage 显示 error
|
|
190
|
+
error: 'Connection timeout: database is unreachable (5000ms)',
|
|
191
|
+
status: 'error',
|
|
192
|
+
duration: 5000,
|
|
193
|
+
toolCallId: 'call_1',
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**渲染效果**
|
|
199
|
+
|
|
200
|
+
## 无 description 场景
|
|
201
|
+
|
|
202
|
+
`function.description` 为可选字段,缺失时"描述"区块仍会渲染(`DescPanel` 始终存在),但内容为空白占位:
|
|
203
|
+
|
|
204
|
+
## 与 AssistantMessage 配合
|
|
205
|
+
|
|
206
|
+
`ToolcallRender` 通常不需要单独使用,将 `toolCalls` 传给 `AssistantMessage`,会自动为每个工具调用渲染 `ToolcallRender`:
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
const assistantMessage = {
|
|
210
|
+
id: '1',
|
|
211
|
+
role: 'assistant',
|
|
212
|
+
content: '好的,我来帮你查询天气。',
|
|
213
|
+
status: 'complete',
|
|
214
|
+
toolCalls: [
|
|
215
|
+
{
|
|
216
|
+
id: 'call_1',
|
|
217
|
+
type: 'function',
|
|
218
|
+
function: {
|
|
219
|
+
name: 'get_weather',
|
|
220
|
+
arguments: '{"city":"北京"}',
|
|
221
|
+
description: '获取天气信息',
|
|
222
|
+
},
|
|
223
|
+
toolMessage: {
|
|
224
|
+
content: '{"temperature":22,"weather":"晴"}',
|
|
225
|
+
status: 'complete',
|
|
226
|
+
duration: 850,
|
|
227
|
+
toolCallId: 'call_1',
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
};
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
需要自定义遍历渲染时:
|
|
235
|
+
|
|
236
|
+
```vue
|
|
237
|
+
<template>
|
|
238
|
+
<ToolcallRender
|
|
239
|
+
v-for="toolCall in assistantMessage.toolCalls"
|
|
240
|
+
:key="toolCall.id"
|
|
241
|
+
:tool-call="toolCall"
|
|
242
|
+
:status="toolCall.toolMessage?.status ?? MessageStatus.Pending"
|
|
243
|
+
/>
|
|
244
|
+
</template>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## API
|
|
248
|
+
|
|
249
|
+
### Props
|
|
250
|
+
|
|
251
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
252
|
+
| -------- | --------------- | ------ | --------------------------------------------------------------------------- |
|
|
253
|
+
| toolCall | `ToolCall` | — | 工具调用信息对象 |
|
|
254
|
+
| status | `MessageStatus` | — | 调用状态,控制头部颜色和状态文案;未传时 `default` 分支显示"调用中" |
|
|
255
|
+
| duration | `number` | — | 调用耗时(毫秒),优先于 `toolCall.toolMessage?.duration`;均无时不显示耗时 |
|
|
256
|
+
|
|
257
|
+
## 类型定义
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
import {
|
|
261
|
+
MessageStatus,
|
|
262
|
+
MessageContentType,
|
|
263
|
+
type ToolCall,
|
|
264
|
+
type FunctionCall,
|
|
265
|
+
type ToolMessage,
|
|
266
|
+
} from '@blueking/chat-x';
|
|
267
|
+
|
|
268
|
+
// ToolCall —— 工具调用对象
|
|
269
|
+
type ToolCall = {
|
|
270
|
+
id: string;
|
|
271
|
+
type: 'function'; // MessageContentType.Function
|
|
272
|
+
function: FunctionCall;
|
|
273
|
+
toolMessage?: Partial<ToolMessage>; // 有值时在详情面板底部内联渲染 ToolMessage
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
// FunctionCall —— 函数调用描述
|
|
277
|
+
type FunctionCall = {
|
|
278
|
+
name: string; // 函数名;为空时标题 fallback 为 toolCall.id
|
|
279
|
+
arguments: string; // 调用参数(通常为 JSON 字符串)
|
|
280
|
+
description?: string; // 工具描述;为空时"描述"区块保留但内容为空白
|
|
281
|
+
mcpName?: string; // MCP 服务名;有值时头部改为"调用 MCP:",标题格式变为 "{mcpName} / {name}"
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
// ToolMessage —— 工具返回消息
|
|
285
|
+
interface ToolMessage {
|
|
286
|
+
role: 'tool';
|
|
287
|
+
content: string; // 返回内容(通常为 JSON 字符串)
|
|
288
|
+
status: MessageStatus;
|
|
289
|
+
duration: number; // 调用耗时(毫秒),被 ToolcallRender 自动读取
|
|
290
|
+
error?: string; // 错误信息(仅当 content 为空时由 ToolMessage 展示)
|
|
291
|
+
toolCallId: string; // 对应 ToolCall.id
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## 关联组件
|
|
296
|
+
|
|
297
|
+
- [DescPanel](../atomic/desc-panel.md) — 描述与参数面板
|
|
298
|
+
- [HighlightKeyword](../atomic/highlight-keyword.md) — 标题高亮
|
|
299
|
+
- [ToolMessage](./tool-message.md) — 内联工具返回
|