@blueking/chat-x 0.0.43 → 0.0.45-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.
- package/README.md +1 -1
- package/dist/ag-ui/types/constants.d.ts +16 -0
- package/dist/ag-ui/types/contents.d.ts +0 -3
- package/dist/ag-ui/types/index.d.ts +2 -0
- package/dist/ag-ui/types/interrupt.d.ts +107 -0
- package/dist/ag-ui/types/messages.d.ts +2 -0
- package/dist/ag-ui/types/schema.d.ts +42 -0
- package/dist/components/ai-buttons/tool-btn/tool-btn.vue.d.ts +1 -11
- package/dist/components/ai-questions/questions-container.vue.d.ts +3 -0
- package/dist/components/ai-questions/selection-question.vue.d.ts +3 -0
- package/dist/components/chat-content/flow-agent-content/flow-agent-content.vue.d.ts +0 -1
- package/dist/components/chat-content/flow-agent-content/flow-agent-node-detail.vue.d.ts +0 -2
- package/dist/components/chat-input/ai-slash-input/ai-slash-input.vue.d.ts +1 -3
- package/dist/components/chat-input/chat-input.vue.d.ts +10 -9
- package/dist/components/chat-input/input-attachment/input-attachment.vue.d.ts +1 -0
- package/dist/components/chat-input/{ai-slash-input/ai-skill-list/ai-skill-list.vue.d.ts → input-info-alert.vue.d.ts} +1 -3
- package/dist/components/chat-message/interrupt-message/index.d.ts +2 -0
- package/dist/components/chat-message/interrupt-message/interrupt-message.vue.d.ts +17 -0
- package/dist/components/chat-message/interrupt-message/tool-approval-card.vue.d.ts +8 -0
- package/dist/components/chat-message/interrupt-message/user-question/index.d.ts +5 -0
- package/dist/components/chat-message/interrupt-message/user-question/use-user-question.d.ts +35 -0
- package/dist/components/chat-message/interrupt-message/user-question/user-question-answered-card.vue.d.ts +25 -0
- package/dist/components/chat-message/interrupt-message/user-question/user-question-card.vue.d.ts +25 -0
- package/dist/components/chat-message/interrupt-message/user-question/user-question-choice.vue.d.ts +13 -0
- package/dist/components/chat-message/interrupt-message/user-question/user-question-option.vue.d.ts +17 -0
- package/dist/components/chat-message/message-container/message-container.vue.d.ts +14 -7
- package/dist/components/chat-message/message-render/message-render.vue.d.ts +4 -0
- package/dist/components/index.d.ts +2 -6
- package/dist/composables/index.d.ts +0 -1
- package/dist/composables/use-common.d.ts +1 -1
- package/dist/composables/use-custom-tab.d.ts +1 -1
- package/dist/composables/use-message-group.d.ts +2004 -227
- package/dist/icons/execution.d.ts +0 -3
- package/dist/icons/index.d.ts +1 -1
- package/dist/icons/interrupt.d.ts +24 -0
- package/dist/index.css +1 -1
- package/dist/index.js +5059 -4674
- package/dist/index.js.map +1 -1
- package/dist/lang/lang.d.ts +33 -5
- package/dist/mcp/generated/docs/activity-layout.md +138 -0
- package/dist/mcp/generated/docs/activity-message.md +18 -28
- package/dist/mcp/generated/docs/ai-image.md +9 -4
- package/dist/mcp/generated/docs/ai-loading.md +11 -6
- package/dist/mcp/generated/docs/ai-prompt-list.md +42 -0
- package/dist/mcp/generated/docs/ai-selection.md +10 -5
- package/dist/mcp/generated/docs/ai-slash-editor.md +43 -0
- package/dist/mcp/generated/docs/ai-slash-input.md +43 -0
- package/dist/mcp/generated/docs/ai-slash-menu.md +42 -0
- package/dist/mcp/generated/docs/animation-text.md +9 -4
- package/dist/mcp/generated/docs/assistant-message.md +10 -5
- package/dist/mcp/generated/docs/chat-container.md +144 -93
- package/dist/mcp/generated/docs/chat-input.md +45 -9
- package/dist/mcp/generated/docs/cite-content.md +8 -3
- package/dist/mcp/generated/docs/code-content.md +9 -4
- package/dist/mcp/generated/docs/common-error-content.md +10 -5
- package/dist/mcp/generated/docs/constants.md +68 -3
- package/dist/mcp/generated/docs/content-render.md +10 -5
- package/dist/mcp/generated/docs/delete-tool.md +9 -4
- package/dist/mcp/generated/docs/desc-panel.md +9 -4
- package/dist/mcp/generated/docs/detail-section.md +93 -0
- package/dist/mcp/generated/docs/execution-summary.md +10 -5
- package/dist/mcp/generated/docs/file-content.md +9 -4
- package/dist/mcp/generated/docs/file-upload-btn.md +11 -6
- package/dist/mcp/generated/docs/flow-agent-content.md +212 -0
- package/dist/mcp/generated/docs/flow-agent-node-detail.md +240 -0
- package/dist/mcp/generated/docs/highlight-keyword.md +10 -5
- package/dist/mcp/generated/docs/image-content.md +9 -4
- package/dist/mcp/generated/docs/image-preview-group.md +9 -4
- package/dist/mcp/generated/docs/image-preview.md +10 -5
- package/dist/mcp/generated/docs/info-message.md +7 -2
- package/dist/mcp/generated/docs/input-attachment.md +43 -0
- package/dist/mcp/generated/docs/input-info-alert.md +42 -0
- package/dist/mcp/generated/docs/interrupt-message.md +204 -0
- package/dist/mcp/generated/docs/interrupt.md +282 -0
- package/dist/mcp/generated/docs/key-value-content.md +9 -4
- package/dist/mcp/generated/docs/knowledge-rag-content.md +126 -0
- package/dist/mcp/generated/docs/latex-content.md +9 -4
- package/dist/mcp/generated/docs/loading-message.md +11 -6
- package/dist/mcp/generated/docs/markdown-container.md +1 -1
- package/dist/mcp/generated/docs/markdown-content.md +13 -31
- package/dist/mcp/generated/docs/markdown-latex.md +3 -3
- package/dist/mcp/generated/docs/markdown-mermaid.md +3 -3
- package/dist/mcp/generated/docs/mermaid-content.md +9 -4
- package/dist/mcp/generated/docs/message-container.md +70 -12
- package/dist/mcp/generated/docs/message-loading.md +120 -0
- package/dist/mcp/generated/docs/message-render.md +21 -9
- package/dist/mcp/generated/docs/message-tools.md +13 -8
- package/dist/mcp/generated/docs/messages.md +75 -11
- package/dist/mcp/generated/docs/overflow-tips.md +4 -4
- package/dist/mcp/generated/docs/preview-toolbar.md +42 -0
- package/dist/mcp/generated/docs/questions-container.md +88 -0
- package/dist/mcp/generated/docs/reasoning-message.md +10 -5
- package/dist/mcp/generated/docs/reference-content.md +10 -5
- package/dist/mcp/generated/docs/reference-doc-content.md +112 -0
- package/dist/mcp/generated/docs/schema.md +93 -0
- package/dist/mcp/generated/docs/scroll-btn.md +8 -3
- package/dist/mcp/generated/docs/selection-footer.md +9 -4
- package/dist/mcp/generated/docs/selection-question.md +91 -0
- package/dist/mcp/generated/docs/shortcut-btn.md +10 -5
- package/dist/mcp/generated/docs/shortcut-btns.md +10 -5
- package/dist/mcp/generated/docs/shortcut-render.md +11 -10
- package/dist/mcp/generated/docs/simple-table.md +103 -0
- package/dist/mcp/generated/docs/text-content.md +9 -4
- package/dist/mcp/generated/docs/theme.md +3 -3
- package/dist/mcp/generated/docs/tool-approval-card.md +148 -0
- package/dist/mcp/generated/docs/tool-btn.md +15 -41
- package/dist/mcp/generated/docs/tool-message.md +10 -5
- package/dist/mcp/generated/docs/toolcall-render.md +10 -5
- package/dist/mcp/generated/docs/use-animation-text.md +4 -4
- package/dist/mcp/generated/docs/use-clipboard.md +3 -3
- package/dist/mcp/generated/docs/use-command-selection.md +1 -1
- package/dist/mcp/generated/docs/use-custom-tab.md +1 -1
- package/dist/mcp/generated/docs/use-global-config.md +1 -1
- package/dist/mcp/generated/docs/use-menu-keydown.md +1 -1
- package/dist/mcp/generated/docs/use-message-group.md +40 -9
- package/dist/mcp/generated/docs/use-observer-visible-list.md +1 -1
- package/dist/mcp/generated/docs/user-feedback.md +8 -3
- package/dist/mcp/generated/docs/user-message.md +10 -5
- package/dist/mcp/generated/docs/user-question-answered-card.md +106 -0
- package/dist/mcp/generated/docs/user-question-card.md +211 -0
- package/dist/mcp/generated/docs/user-question-choice.md +108 -0
- package/dist/mcp/generated/docs/user-question-option.md +42 -0
- package/dist/mcp/generated/docs/vnode-renderer.md +126 -0
- package/dist/mcp/generated/index.json +1062 -551
- package/dist/mcp/index.js +0 -0
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/list-components.d.ts +7 -6
- package/dist/mcp/tools/list-components.js +23 -29
- package/dist/mcp/tools/list-components.js.map +1 -1
- package/dist/mcp/tools/search-docs.js +1 -1
- package/dist/mcp/tools/search-docs.js.map +1 -1
- package/dist/mcp/utils/doc-loader.d.ts +1 -1
- package/dist/plugins/index.d.ts +0 -1
- package/dist/types/custom.d.ts +0 -1
- package/dist/types/editor.d.ts +0 -6
- package/dist/types/input.d.ts +1 -1
- package/dist/types/tool.d.ts +3 -3
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/utils.d.ts +0 -1
- package/package.json +23 -21
- package/dist/components/chat-content/flow-agent-content/flow-agent-state.d.ts +0 -34
- package/dist/components/chat-content/flow-agent-content/use-flow-agent.d.ts +0 -47
- package/dist/components/chat-content/flow-agent-content/use-flow-tab.d.ts +0 -18
- package/dist/composables/use-full-screen.d.ts +0 -17
- package/dist/icons/screen.d.ts +0 -6
- package/dist/mcp/generated/docs/use-full-screen.md +0 -114
- package/dist/plugins/markdown-bk-inline-style.d.ts +0 -20
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<!-- AI SUMMARY -->
|
|
2
|
+
## 快速了解
|
|
3
|
+
|
|
4
|
+
FlowAgent 节点详情中的轻量表格展示组件。 源码位置:src/components/chat-content/flow-agent-content/simple-table.vue。
|
|
5
|
+
|
|
6
|
+
### 关联组件
|
|
7
|
+
- **flow-agent-node-detail** — 节点详情中用于展示输入参数、插件输出定义和结构化输出
|
|
8
|
+
- **detail-section** — 通常放在详情分段容器内使用
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
<!-- FULL DOC -->
|
|
12
|
+
|
|
13
|
+
# SimpleTable 简易表格
|
|
14
|
+
|
|
15
|
+
> **能力域**:Agent 能力
|
|
16
|
+
|
|
17
|
+
`SimpleTable` 是 FlowAgent 节点详情中的轻量只读表格,用于展示参数名、参数值、插件输出定义等结构化信息。组件只根据 `columns` 和 `data` 渲染表格,不提供排序、筛选、分页或编辑能力。
|
|
18
|
+
|
|
19
|
+
通常不需要单独使用,主要由 `FlowAgentNodeDetail` 内部组合。
|
|
20
|
+
|
|
21
|
+
## 源码事实
|
|
22
|
+
|
|
23
|
+
- **源码位置**:`src/components/chat-content/flow-agent-content/simple-table.vue`
|
|
24
|
+
- **能力说明**:FlowAgent 节点详情中的轻量表格展示组件。
|
|
25
|
+
|
|
26
|
+
## 核心能力
|
|
27
|
+
|
|
28
|
+
- **列驱动渲染**:通过 `columns` 决定表头、字段读取 key 和单元格换行策略
|
|
29
|
+
- **空值兜底**:单元格值为 `null` 或 `undefined` 时显示 `--`,`0` 会正常显示为 `0`
|
|
30
|
+
- **空数据占位**:`data` 为空数组时渲染一行 `--`,`colspan` 等于列数
|
|
31
|
+
- **长文本换行**:列配置 `breakAll: true` 后,该列单元格添加 `is-break-all` 样式,适合展示 JSON 或长字符串
|
|
32
|
+
|
|
33
|
+
## 基础用法
|
|
34
|
+
|
|
35
|
+
```vue
|
|
36
|
+
<template>
|
|
37
|
+
<SimpleTable
|
|
38
|
+
:columns="columns"
|
|
39
|
+
:data="data"
|
|
40
|
+
/>
|
|
41
|
+
</template>
|
|
42
|
+
|
|
43
|
+
<script setup lang="ts">
|
|
44
|
+
import SimpleTable from '@blueking/chat-x/src/components/chat-content/flow-agent-content/simple-table.vue';
|
|
45
|
+
|
|
46
|
+
const columns = [
|
|
47
|
+
{ key: 'key', label: '参数名' },
|
|
48
|
+
{ breakAll: true, key: 'value', label: '参数值' },
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const data = [
|
|
52
|
+
{ key: 'bk_host_id', value: '10001' },
|
|
53
|
+
{ key: 'metadata', value: '{"source":"cmdb","scope":"production"}' },
|
|
54
|
+
];
|
|
55
|
+
</script>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**渲染效果**
|
|
59
|
+
|
|
60
|
+
## 空数据
|
|
61
|
+
|
|
62
|
+
当 `data.length === 0` 时,组件渲染一行居中的 `--`,用于表示当前分段没有可展示数据。
|
|
63
|
+
|
|
64
|
+
## API
|
|
65
|
+
|
|
66
|
+
### Props
|
|
67
|
+
|
|
68
|
+
| 属性名 | 类型 | 必填 | 默认值 | 说明 |
|
|
69
|
+
| ------- | ------------------------ | ---- | ------ | ---------------------------- |
|
|
70
|
+
| columns | `SimpleTableColumn[]` | 是 | — | 表格列配置 |
|
|
71
|
+
| data | `Record<string, unknown>[]` | 是 | — | 表格行数据,按列 `key` 取值 |
|
|
72
|
+
|
|
73
|
+
### Emits
|
|
74
|
+
|
|
75
|
+
- 无。
|
|
76
|
+
|
|
77
|
+
### Slots
|
|
78
|
+
|
|
79
|
+
- 无。
|
|
80
|
+
|
|
81
|
+
### Expose
|
|
82
|
+
|
|
83
|
+
- 无。
|
|
84
|
+
|
|
85
|
+
## 类型定义
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
export interface SimpleTableColumn {
|
|
89
|
+
breakAll?: boolean; // 是否对该列单元格启用 word-break: break-all
|
|
90
|
+
key: string; // 从 data 行对象中读取的字段名
|
|
91
|
+
label: string; // 表头文案
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## 使用建议
|
|
96
|
+
|
|
97
|
+
- 适合详情面板中的短表格,不适合承载复杂数据表能力。
|
|
98
|
+
- 需要展示对象值时,建议在传入前先序列化为字符串;`FlowAgentNodeDetail` 内部会对对象值执行 `JSON.stringify`。
|
|
99
|
+
|
|
100
|
+
## 关联组件
|
|
101
|
+
|
|
102
|
+
- [FlowAgentNodeDetail](./flow-agent-node-detail.md) — 节点详情主体。
|
|
103
|
+
- [DetailSection](./detail-section.md) — 表格常放置在详情分段内。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- AI SUMMARY -->
|
|
2
2
|
## 快速了解
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
渲染纯文本内容。 源码位置:src/components/chat-content/text-content/text-content.vue。
|
|
5
5
|
|
|
6
6
|
### 关联组件
|
|
7
7
|
- **markdown-content** — 需要富文本时的替代方案
|
|
@@ -11,8 +11,13 @@ TextContent 用 Vue 文本插值渲染纯文本气泡,不解析 HTML,适合
|
|
|
11
11
|
<!-- FULL DOC -->
|
|
12
12
|
|
|
13
13
|
# TextContent 文本内容
|
|
14
|
+
## 源码事实
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
- **源码位置**:`src/components/chat-content/text-content/text-content.vue`
|
|
17
|
+
- **能力域**:内容渲染
|
|
18
|
+
- **能力说明**:渲染纯文本内容。
|
|
19
|
+
|
|
20
|
+
> **能力域**:内容渲染
|
|
16
21
|
|
|
17
22
|
纯文本气泡组件,使用 Vue 文本插值渲染 `content`,天然防 XSS。
|
|
18
23
|
|
|
@@ -70,5 +75,5 @@ div.text-content
|
|
|
70
75
|
|
|
71
76
|
## 关联组件
|
|
72
77
|
|
|
73
|
-
- [MarkdownContent](
|
|
74
|
-
- [UserMessage](
|
|
78
|
+
- [MarkdownContent](/components/rendering/markdown-content) — 富文本替代
|
|
79
|
+
- [UserMessage](/components/message/user-message) — 用户消息气泡
|
|
@@ -383,6 +383,6 @@ $selection-z-index: $shortcut-menu-z-index + 1;
|
|
|
383
383
|
|
|
384
384
|
## 关联组件
|
|
385
385
|
|
|
386
|
-
- [ChatContainer](../components/
|
|
387
|
-
- [ChatInput](../components/
|
|
388
|
-
- [MessageContainer](../components/
|
|
386
|
+
- [ChatContainer](../components/setup/chat-container) — 布局与主题根节点
|
|
387
|
+
- [ChatInput](../components/input/chat-input) — 输入区变量与类名
|
|
388
|
+
- [MessageContainer](../components/setup/message-container) — 消息列表区域
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
<!-- AI SUMMARY -->
|
|
2
|
+
## 快速了解
|
|
3
|
+
|
|
4
|
+
渲染 AIDevToolApproval 中断的审批信息与取消操作。 源码位置:src/components/chat-message/interrupt-message/tool-approval-card.vue。
|
|
5
|
+
|
|
6
|
+
### 关联组件
|
|
7
|
+
- **interrupt-message** — InterruptMessageRender 按 reason 派发渲染
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
<!-- FULL DOC -->
|
|
11
|
+
|
|
12
|
+
# ToolApprovalCard 审批卡片
|
|
13
|
+
## 源码事实
|
|
14
|
+
|
|
15
|
+
- **源码位置**:`src/components/chat-message/interrupt-message/tool-approval-card.vue`
|
|
16
|
+
- **能力域**:Agent 能力
|
|
17
|
+
- **能力说明**:渲染 AIDevToolApproval 中断的审批信息与取消操作。
|
|
18
|
+
|
|
19
|
+
> **能力域**:Agent 能力
|
|
20
|
+
|
|
21
|
+
AI Dev 第三方工具审批(`InterruptReason.AIDevToolApproval`)专用卡片,由 [InterruptMessageRender](/components/agent/interrupt-message) 按 `reason` 动态挂载。
|
|
22
|
+
|
|
23
|
+
> **通常不需要单独引入**;仅在需要独立预览卡片样式时使用。
|
|
24
|
+
|
|
25
|
+
## 渲染结构
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
ToolApprovalCard
|
|
29
|
+
├── 标题栏:左侧色条 + 单据标题 + 复制图标 + 状态徽章(评审中/已通过/已拒绝/已撤销等)
|
|
30
|
+
├── 字段区:单据编号、提交时间
|
|
31
|
+
├── 处理人:当前处理人(overflow-tips 省略)
|
|
32
|
+
└── 操作区:查看单据详情(新窗口打开 url)、取消审批(仅 pending / draft)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
状态徽章样式:
|
|
36
|
+
|
|
37
|
+
| `ticket.status` | 视觉 |
|
|
38
|
+
| --------------------------------------- | -------- |
|
|
39
|
+
| `pending`、`draft` | 蓝色评审中 |
|
|
40
|
+
| `approved` | 绿色通过 |
|
|
41
|
+
| `rejected`、`cancelled`、`expired`、`abandoned` | 红色终态 |
|
|
42
|
+
| `revoked` | 橙色已撤销 |
|
|
43
|
+
|
|
44
|
+
## 基础用法(待审批)
|
|
45
|
+
|
|
46
|
+
> `ToolApprovalCard` 为 `InterruptMessageRender` 内部子组件,**未从 `@blueking/chat-x` 包入口导出**。业务侧通过构造 `InterruptMessage` 触发渲染即可;下方为类型与数据结构参考。
|
|
47
|
+
|
|
48
|
+
```vue
|
|
49
|
+
<template>
|
|
50
|
+
<!-- 业务侧推荐:由 MessageRender / MessageContainer 自动渲染 -->
|
|
51
|
+
<InterruptMessageRender
|
|
52
|
+
:content="interruptMessage.content"
|
|
53
|
+
role="interrupt"
|
|
54
|
+
:status="interruptMessage.status"
|
|
55
|
+
:on-interrupt-resume="handleInterruptResume"
|
|
56
|
+
/>
|
|
57
|
+
</template>
|
|
58
|
+
|
|
59
|
+
<script setup lang="ts">
|
|
60
|
+
import {
|
|
61
|
+
InterruptMessageRender,
|
|
62
|
+
APPROVAL_STATUS,
|
|
63
|
+
InterruptReason,
|
|
64
|
+
MessageRole,
|
|
65
|
+
MessageStatus,
|
|
66
|
+
type InterruptMessage,
|
|
67
|
+
type AIDevToolApprovalInterrupt,
|
|
68
|
+
} from '@blueking/chat-x';
|
|
69
|
+
|
|
70
|
+
const interrupt: AIDevToolApprovalInterrupt = {
|
|
71
|
+
id: 'interrupt_1',
|
|
72
|
+
reason: InterruptReason.AIDevToolApproval,
|
|
73
|
+
toolCallId: 'tool_call_1',
|
|
74
|
+
metadata: {
|
|
75
|
+
ticket: {
|
|
76
|
+
approvers: ['张三', '李四'],
|
|
77
|
+
sn: 'REV-2026-04-24-001',
|
|
78
|
+
status: APPROVAL_STATUS.PENDING,
|
|
79
|
+
submit_time: '2026-04-24 14:30:15',
|
|
80
|
+
title: '算法方案评审单',
|
|
81
|
+
url: 'https://example.com/tickets/001',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const interruptMessage: InterruptMessage = {
|
|
87
|
+
id: 'msg_1',
|
|
88
|
+
messageId: 'msg_1',
|
|
89
|
+
role: MessageRole.Interrupt,
|
|
90
|
+
status: MessageStatus.Pending,
|
|
91
|
+
content: {
|
|
92
|
+
outcome: { type: 'interrupt', interrupts: [interrupt] },
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const handleInterruptResume = async (payload, interrupt) => {
|
|
97
|
+
console.log(payload, interrupt.id);
|
|
98
|
+
};
|
|
99
|
+
</script>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**渲染效果**(文档站直接挂载 `ToolApprovalCard` 预览卡片 UI)
|
|
103
|
+
|
|
104
|
+
## 已通过 / 已拒绝 / 已撤销
|
|
105
|
+
|
|
106
|
+
```vue
|
|
107
|
+
<div>
|
|
108
|
+
<InterruptMessageRender
|
|
109
|
+
:content="{ outcome: { type: 'interrupt', interrupts: [approvedInterrupt] } }"
|
|
110
|
+
role="interrupt"
|
|
111
|
+
/>
|
|
112
|
+
<InterruptMessageRender
|
|
113
|
+
:content="{ outcome: { type: 'interrupt', interrupts: [rejectedInterrupt] } }"
|
|
114
|
+
role="interrupt"
|
|
115
|
+
/>
|
|
116
|
+
<InterruptMessageRender
|
|
117
|
+
:content="{ outcome: { type: 'interrupt', interrupts: [revokedInterrupt] } }"
|
|
118
|
+
role="interrupt"
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**渲染效果**
|
|
124
|
+
|
|
125
|
+
## API
|
|
126
|
+
|
|
127
|
+
### Props
|
|
128
|
+
|
|
129
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
130
|
+
| ----------------- | ---------------------------- | ------ | -------------------------------------------- |
|
|
131
|
+
| interrupt | `AIDevToolApprovalInterrupt` | — | **必填**,含 `metadata.ticket` |
|
|
132
|
+
| onInterruptResume | `OnInterruptResume` | — | 取消审批时触发,签名为 `(payload, interrupt)`,payload 为 `{ action: 'cancel' }` |
|
|
133
|
+
|
|
134
|
+
### Events / Slots / Expose
|
|
135
|
+
|
|
136
|
+
无。打开链接、复制剪贴板在组件内部完成;取消审批通过 `onInterruptResume({ action: 'cancel' }, interrupt)` 通知业务侧处理。
|
|
137
|
+
|
|
138
|
+
## 依赖
|
|
139
|
+
|
|
140
|
+
- `bkui-vue`:`Button`、`Loading`
|
|
141
|
+
- `useClipboard` — 复制单据
|
|
142
|
+
- `v-overflow-tips` — 处理人超长省略
|
|
143
|
+
|
|
144
|
+
## 关联组件
|
|
145
|
+
|
|
146
|
+
- [InterruptMessage 中断消息](/components/agent/interrupt-message)
|
|
147
|
+
- [中断类型 Interrupt](../../types/interrupt.md)
|
|
148
|
+
- [常量枚举 Constants](../../types/constants.md) — `APPROVAL_STATUS`、`APPROVAL_STATUS_MAP`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- AI SUMMARY -->
|
|
2
2
|
## 快速了解
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
工具栏图标按钮。 源码位置:src/components/ai-buttons/tool-btn/tool-btn.vue。
|
|
5
5
|
|
|
6
6
|
### 关联组件
|
|
7
7
|
- **message-tools** — 父级组装多个工具按钮与交互
|
|
@@ -11,8 +11,13 @@ ToolBtn 为消息工具栏提供单个操作入口:内置常用 id 与 SVG 图
|
|
|
11
11
|
<!-- FULL DOC -->
|
|
12
12
|
|
|
13
13
|
# ToolBtn 工具按钮
|
|
14
|
+
## 源码事实
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
- **源码位置**:`src/components/ai-buttons/tool-btn/tool-btn.vue`
|
|
17
|
+
- **能力域**:工具与反馈
|
|
18
|
+
- **能力说明**:工具栏图标按钮。
|
|
19
|
+
|
|
20
|
+
> **能力域**:工具与反馈
|
|
16
21
|
|
|
17
22
|
消息工具栏中的单个操作按钮,内置 SVG 图标映射、Tippy 悬浮提示、激活态与禁用态,通常由 `MessageTools` 管理,一般不需要手动使用。
|
|
18
23
|
|
|
@@ -25,9 +30,8 @@ div.ai-tool-btn(v-tippy,flex,min-width: 20px,height: 20px,border-radiu
|
|
|
25
30
|
disabled=true → .is-disabled(color: #979ba5; cursor: not-allowed)
|
|
26
31
|
:not(.is-disabled):hover → color: #4d4f56; background: #eaebf0
|
|
27
32
|
│
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
└── [其他] → <div>{{ name }}</div>(文本回退,XSS 安全)
|
|
33
|
+
├── [id in ToolIconsMap] → <component :is="ToolIconsMap[id]" />(SVG 图标,font-size: 16px 控制大小)
|
|
34
|
+
└── [id not in ToolIconsMap] → <div>{{ name }}</div>(文本回退,XSS 安全)
|
|
31
35
|
|
|
32
36
|
Tippy:content=description, theme='ai-chat-box', disabled=true 时 onShow 返回 false 不显示
|
|
33
37
|
click 事件:disabled=true 时被 JS 拦截,不触发 emit
|
|
@@ -52,7 +56,7 @@ click 事件:disabled=true 时被 JS 拦截,不触发 emit
|
|
|
52
56
|
| `activeLike` | 点赞(实心) | 激活态填充图标 |
|
|
53
57
|
| `activeUnLike` | 不满意(实心) | 激活态填充图标 |
|
|
54
58
|
|
|
55
|
-
>
|
|
59
|
+
> `id` 不在上表时,组件渲染 `<div>{{ name }}</div>` 作为文本回退。此时 `id` 的 TypeScript 类型会报错(`keyof typeof ToolIconsMap`),建议优先使用预置 ID。
|
|
56
60
|
|
|
57
61
|
## 基础用法
|
|
58
62
|
|
|
@@ -188,31 +192,7 @@ click 事件:disabled=true 时被 JS 拦截,不触发 emit
|
|
|
188
192
|
|
|
189
193
|
## 未知 ID 的文本回退
|
|
190
194
|
|
|
191
|
-
`id` 不在 `ToolIconsMap` 时渲染 `name`
|
|
192
|
-
|
|
193
|
-
## 自定义插槽内容
|
|
194
|
-
|
|
195
|
-
通过默认插槽可完全替换内置图标/文本,适用于预置 `ToolIconsMap` 未覆盖的图标场景(如侧栏全屏按钮):
|
|
196
|
-
|
|
197
|
-
```vue
|
|
198
|
-
<template>
|
|
199
|
-
<ToolBtn
|
|
200
|
-
description="全屏"
|
|
201
|
-
:tippy-options="{ content: '全屏' }"
|
|
202
|
-
@click="handleFullScreen"
|
|
203
|
-
>
|
|
204
|
-
<FullScreenIcon />
|
|
205
|
-
</ToolBtn>
|
|
206
|
-
</template>
|
|
207
|
-
|
|
208
|
-
<script setup lang="ts">
|
|
209
|
-
import { ToolBtn, FullScreenIcon } from '@blueking/chat-x';
|
|
210
|
-
|
|
211
|
-
const handleFullScreen = () => {
|
|
212
|
-
// 进入全屏逻辑
|
|
213
|
-
};
|
|
214
|
-
</script>
|
|
215
|
-
```
|
|
195
|
+
`id` 不在 `ToolIconsMap` 时渲染 `name` 文本,适用于自定义扩展场景(注意 TypeScript 会报类型错误):
|
|
216
196
|
|
|
217
197
|
## API
|
|
218
198
|
|
|
@@ -220,7 +200,7 @@ click 事件:disabled=true 时被 JS 拦截,不触发 emit
|
|
|
220
200
|
|
|
221
201
|
| 属性名 | 类型 | 必填 | 默认值 | 说明 |
|
|
222
202
|
| ------------ | -------------------------------------------------------------------------- | ---- | ------ | ------------------------------------------------------------------------------------------------------------------ |
|
|
223
|
-
| id | `keyof typeof ToolIconsMap` |
|
|
203
|
+
| id | `keyof typeof ToolIconsMap` | 是 | — | 按钮标识;在 `ToolIconsMap` 中时渲染对应 SVG 图标,否则渲染 `name` 文本 |
|
|
224
204
|
| name | `string` | 否 | — | 按钮名称;`id` 无对应图标时作为文本内容渲染 |
|
|
225
205
|
| description | `string` | 否 | — | Tippy tooltip 内容;`disabled=true` 时不显示 tooltip |
|
|
226
206
|
| active | `boolean` | 否 | — | 激活态;`true` 时追加 `.is-active`(字色由 `id` 决定:`like`/`activeLike` 为蓝色 `#3a84ff`,其他为红色 `#E71818`) |
|
|
@@ -233,18 +213,12 @@ click 事件:disabled=true 时被 JS 拦截,不触发 emit
|
|
|
233
213
|
| ------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
|
234
214
|
| click | `(data: IToolBtn & { active?: boolean; disabled?: boolean }, event: MouseEvent)` | 点击时触发;`data` 为组件当前全量 props(含 `active`/`disabled`);`disabled=true` 时不触发 |
|
|
235
215
|
|
|
236
|
-
### Slots
|
|
237
|
-
|
|
238
|
-
| 插槽名 | 说明 |
|
|
239
|
-
| ------- | ------------------------------------------------------------------------------------------ |
|
|
240
|
-
| default | 按钮内容;传入时替换默认的图标/文本渲染逻辑,常用于自定义 SVG 图标(如全屏、退出全屏按钮) |
|
|
241
|
-
|
|
242
216
|
## 类型定义
|
|
243
217
|
|
|
244
218
|
```typescript
|
|
245
219
|
// 来自 @blueking/chat-x 导出
|
|
246
220
|
interface IToolBtn {
|
|
247
|
-
id
|
|
221
|
+
id: keyof typeof ToolIconsMap; // 限定为预置 ID
|
|
248
222
|
name?: string;
|
|
249
223
|
description?: string;
|
|
250
224
|
}
|
|
@@ -281,5 +255,5 @@ type ToolIcons =
|
|
|
281
255
|
|
|
282
256
|
## 关联组件
|
|
283
257
|
|
|
284
|
-
- [MessageTools](
|
|
285
|
-
- [DeleteTool](
|
|
258
|
+
- [MessageTools](/components/feedback/message-tools) — 工具栏容器
|
|
259
|
+
- [DeleteTool](/components/feedback/delete-tool) — 删除确认内嵌触发
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- AI SUMMARY -->
|
|
2
2
|
## 快速了解
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
渲染工具返回内容,JSON 场景交给 DescPanel 展示。 源码位置:src/components/chat-message/tool-message/tool-message.vue。
|
|
5
5
|
|
|
6
6
|
### 关联组件
|
|
7
7
|
- **assistant-message** — 结果常作为 assistant 消息中 toolCall.toolMessage 内联展示
|
|
@@ -12,8 +12,13 @@ ToolMessage 展示工具(Function Call)执行返回,内部用 DescPanel
|
|
|
12
12
|
<!-- FULL DOC -->
|
|
13
13
|
|
|
14
14
|
# ToolMessage 工具消息
|
|
15
|
+
## 源码事实
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
- **源码位置**:`src/components/chat-message/tool-message/tool-message.vue`
|
|
18
|
+
- **能力域**:消息系统
|
|
19
|
+
- **能力说明**:渲染工具返回内容,JSON 场景交给 DescPanel 展示。
|
|
20
|
+
|
|
21
|
+
> **能力域**:消息系统
|
|
17
22
|
|
|
18
23
|
工具(Function Call)执行结果展示组件。内部通过 `DescPanel` 渲染,标题固定为"返回内容",支持将 JSON 自动解析为 key-value 列表。
|
|
19
24
|
|
|
@@ -212,6 +217,6 @@ interface ToolMessage {
|
|
|
212
217
|
|
|
213
218
|
## 关联组件
|
|
214
219
|
|
|
215
|
-
- [AssistantMessage](
|
|
216
|
-
- [MessageRender](
|
|
217
|
-
- [DescPanel](
|
|
220
|
+
- [AssistantMessage](/components/message/assistant-message) — toolCall.toolMessage 内联场景
|
|
221
|
+
- [MessageRender](/components/message/message-render) — 独立 tool 消息派发
|
|
222
|
+
- [DescPanel](/components/rendering/desc-panel) — 返回内容面板
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- AI SUMMARY -->
|
|
2
2
|
## 快速了解
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
渲染 assistant toolCalls,展示工具调用状态、参数和结果。 源码位置:src/components/tool-call/toolcall-render/toolcall-render.vue。
|
|
5
5
|
|
|
6
6
|
### 关联组件
|
|
7
7
|
- **desc-panel** — 详情区展示参数与描述文本
|
|
@@ -12,8 +12,13 @@ ToolcallRender 折叠展示一次工具/MCP 调用:头部显示名称、状态
|
|
|
12
12
|
<!-- FULL DOC -->
|
|
13
13
|
|
|
14
14
|
# ToolcallRender 工具调用渲染器
|
|
15
|
+
## 源码事实
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
- **源码位置**:`src/components/tool-call/toolcall-render/toolcall-render.vue`
|
|
18
|
+
- **能力域**:Agent 能力
|
|
19
|
+
- **能力说明**:渲染 assistant toolCalls,展示工具调用状态、参数和结果。
|
|
20
|
+
|
|
21
|
+
> **能力域**:Agent 能力
|
|
17
22
|
|
|
18
23
|
展示 AI 调用外部工具/函数过程与结果的渲染组件。由**可折叠头部**和**详情面板**组成,根据 `status` 自动切换颜色和状态文案,支持 MCP 调用识别和内联结果展示。
|
|
19
24
|
|
|
@@ -294,6 +299,6 @@ interface ToolMessage {
|
|
|
294
299
|
|
|
295
300
|
## 关联组件
|
|
296
301
|
|
|
297
|
-
- [DescPanel](
|
|
298
|
-
- [HighlightKeyword](
|
|
299
|
-
- [ToolMessage](
|
|
302
|
+
- [DescPanel](/components/rendering/desc-panel) — 描述与参数面板
|
|
303
|
+
- [HighlightKeyword](/components/helper/highlight-keyword) — 标题高亮
|
|
304
|
+
- [ToolMessage](/components/message/tool-message) — 内联工具返回
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- AI SUMMARY -->
|
|
2
2
|
## 快速了解
|
|
3
3
|
|
|
4
|
-
useAnimationText 接收 MaybeRef<string> 与可选 AnimationConfig(fadeDuration、easing),返回 chunks 与 animationStyle。 监听文本变化:前缀追加则增量拆分为新 chunk 并触发动画,否则重置为单 chunk,适合流式输出逐段淡入。 全局样式已含 ai-markdown-fade-in。AnimationText
|
|
4
|
+
useAnimationText 接收 MaybeRef<string> 与可选 AnimationConfig(fadeDuration、easing),返回 chunks 与 animationStyle。 监听文本变化:前缀追加则增量拆分为新 chunk 并触发动画,否则重置为单 chunk,适合流式输出逐段淡入。 全局样式已含 ai-markdown-fade-in。AnimationText 组件内部封装同一逻辑。
|
|
5
5
|
|
|
6
6
|
### 关联组件
|
|
7
7
|
- **animation-text** — 封装 chunks 与样式渲染
|
|
@@ -126,7 +126,7 @@ useAnimationText 接收 MaybeRef<string> 与可选 AnimationConfig(fadeDuratio
|
|
|
126
126
|
</script>
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
-
> 详见 [AnimationText 组件文档](/components/
|
|
129
|
+
> 详见 [AnimationText 组件文档](/components/rendering/animation-text)。
|
|
130
130
|
|
|
131
131
|
## API
|
|
132
132
|
|
|
@@ -194,5 +194,5 @@ function useAnimationText(
|
|
|
194
194
|
|
|
195
195
|
## 关联组件
|
|
196
196
|
|
|
197
|
-
- [AnimationText](../components/
|
|
198
|
-
- [MarkdownContent](../components/
|
|
197
|
+
- [AnimationText](../components/rendering/animation-text) — 默认封装组件
|
|
198
|
+
- [MarkdownContent](../components/rendering/markdown-content) — 富文本流式展示场景。
|
|
@@ -201,6 +201,6 @@ export const useClipboard = () => {
|
|
|
201
201
|
|
|
202
202
|
## 关联组件
|
|
203
203
|
|
|
204
|
-
- [CodeContent](../components/
|
|
205
|
-
- [MessageContainer](../components/
|
|
206
|
-
- [UserMessage](../components/
|
|
204
|
+
- [CodeContent](../components/rendering/code-content) — 代码块复制
|
|
205
|
+
- [MessageContainer](../components/setup/message-container) — 助手消息复制
|
|
206
|
+
- [UserMessage](../components/message/user-message) — 用户消息复制
|
|
@@ -122,4 +122,4 @@ export function injectGlobalConfig(): GlobalConfig | undefined;
|
|
|
122
122
|
|
|
123
123
|
## 关联组件
|
|
124
124
|
|
|
125
|
-
- [ChatContainer](../components/
|
|
125
|
+
- [ChatContainer](../components/setup/chat-container) — 调用 `useGlobalConfig` 注入 `supportUpload`
|
|
@@ -27,6 +27,8 @@ function useMessageGroup(options: {
|
|
|
27
27
|
}): {
|
|
28
28
|
messageGroups: Ref<MessageGroup[]>;
|
|
29
29
|
executionGroups: ComputedRef<MessageGroup[]>;
|
|
30
|
+
pendingApprovalCount: ComputedRef<number>;
|
|
31
|
+
pendingApprovalTipText: ComputedRef<string>;
|
|
30
32
|
isShareMode: ShallowRef<boolean>;
|
|
31
33
|
isAllSelected: ComputedRef<boolean>;
|
|
32
34
|
onToggleShareAll: (isAllSelected: boolean) => void;
|
|
@@ -113,6 +115,24 @@ const isExecutionMessage = (m: Message): boolean => {
|
|
|
113
115
|
| toolCall | `function.name`、`mcpName`、`description`、`arguments`、`id` |
|
|
114
116
|
| flow_agent | 各任务 `task_name`、各节点 `name` |
|
|
115
117
|
|
|
118
|
+
## 待审批统计
|
|
119
|
+
|
|
120
|
+
`useMessageGroup` 会统计消息列表中处于待审批状态的 AI Dev 审批中断:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const pendingApprovalStatusSet = new Set([APPROVAL_STATUS.PENDING, APPROVAL_STATUS.DRAFT]);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
当 `MessageRole.Interrupt` 消息的 `content.outcome.type === 'interrupt'`,且其中断项满足 `reason === InterruptReason.AIDevToolApproval`、`metadata.ticket.status` 为 `pending` 或 `draft` 时,计入 `pendingApprovalCount`。
|
|
127
|
+
|
|
128
|
+
`pendingApprovalTipText` 根据数量生成输入区提示文案:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
'当前会话有 {count} 个待审批单,如需继续,请先取消审批'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`ChatContainer` 会消费该返回值,向 `ChatInput` 传入 `sendDisabledTip` 并在输入区上方展示提示,从而阻止继续发送。
|
|
135
|
+
|
|
116
136
|
## 分享模式
|
|
117
137
|
|
|
118
138
|
`useMessageGroup` 提供完整的分享模式支持:
|
|
@@ -142,12 +162,21 @@ const keyword = shallowRef('');
|
|
|
142
162
|
const messages = computed(() => props.messages);
|
|
143
163
|
const selectedUserMessages = deepRef<Message[]>([]);
|
|
144
164
|
|
|
145
|
-
const {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
165
|
+
const {
|
|
166
|
+
messageGroups,
|
|
167
|
+
executionGroups,
|
|
168
|
+
pendingApprovalCount,
|
|
169
|
+
pendingApprovalTipText,
|
|
170
|
+
isShareMode,
|
|
171
|
+
isAllSelected,
|
|
172
|
+
onToggleShareAll,
|
|
173
|
+
onCancelShare,
|
|
174
|
+
onConfirmShare,
|
|
175
|
+
} = useMessageGroup({
|
|
176
|
+
keyword,
|
|
177
|
+
messages,
|
|
178
|
+
selectedUserMessages,
|
|
179
|
+
});
|
|
151
180
|
```
|
|
152
181
|
|
|
153
182
|
## 返回值说明
|
|
@@ -156,6 +185,8 @@ const { messageGroups, executionGroups, isShareMode, isAllSelected, onToggleShar
|
|
|
156
185
|
| ---------------- | ----------------------------- | --------------------------------------------------------------------------- |
|
|
157
186
|
| messageGroups | `Ref<MessageGroup[]>` | 完整消息分组列表 |
|
|
158
187
|
| executionGroups | `ComputedRef<MessageGroup[]>` | 仅包含执行类消息的分组(工具调用 + FlowAgent),自动提取 `userMessageTitle` |
|
|
188
|
+
| pendingApprovalCount | `ComputedRef<number>` | 当前消息中待审批 AI Dev 审批中断的数量 |
|
|
189
|
+
| pendingApprovalTipText | `ComputedRef<string>` | 待审批阻塞发送提示文案;无待审批时为空字符串 |
|
|
159
190
|
| isShareMode | `ShallowRef<boolean>` | 是否处于分享模式 |
|
|
160
191
|
| isAllSelected | `ComputedRef<boolean>` | 所有用户消息组是否全部选中 |
|
|
161
192
|
| onToggleShareAll | `(checked: boolean) => void` | 切换全选 |
|
|
@@ -181,6 +212,6 @@ interface MessageGroup {
|
|
|
181
212
|
|
|
182
213
|
## 关联组件
|
|
183
214
|
|
|
184
|
-
- [ChatContainer](../components/
|
|
185
|
-
- [MessageContainer](../components/
|
|
186
|
-
- [ExecutionSummary](../components/
|
|
215
|
+
- [ChatContainer](../components/setup/chat-container) — 调用 useMessageGroup 并下传分组
|
|
216
|
+
- [MessageContainer](../components/setup/message-container) — 渲染 messageGroups
|
|
217
|
+
- [ExecutionSummary](../components/agent/execution-summary) — 消费 executionGroups
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- AI SUMMARY -->
|
|
2
2
|
## 快速了解
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
用户反馈弹层,提交踩/反馈原因。 源码位置:src/components/message-tools/user-feedback/user-feedback.vue。
|
|
5
5
|
|
|
6
6
|
### 关联组件
|
|
7
7
|
- **message-tools** — 点赞/踩操作触发并收集反馈
|
|
@@ -10,8 +10,13 @@ UserFeedback 在点赞或踩之后展示原因收集面板:多选预设标签
|
|
|
10
10
|
<!-- FULL DOC -->
|
|
11
11
|
|
|
12
12
|
# MessageUserFeedback 用户反馈
|
|
13
|
+
## 源码事实
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
- **源码位置**:`src/components/message-tools/user-feedback/user-feedback.vue`
|
|
16
|
+
- **能力域**:工具与反馈
|
|
17
|
+
- **能力说明**:用户反馈弹层,提交踩/反馈原因。
|
|
18
|
+
|
|
19
|
+
> **能力域**:工具与反馈
|
|
15
20
|
|
|
16
21
|
AI 消息点赞/踩后收集用户具体反馈原因的弹出面板。支持多选预设原因标签、补充文字说明(textarea)、异步加载原因列表(骨架屏)。
|
|
17
22
|
|
|
@@ -226,4 +231,4 @@ loading=false,展示原因标签列表
|
|
|
226
231
|
|
|
227
232
|
## 关联组件
|
|
228
233
|
|
|
229
|
-
- [MessageTools](
|
|
234
|
+
- [MessageTools](/components/feedback/message-tools) — 点赞/踩入口与反馈联动
|