kd-chatbot-ui-vue2 0.0.0-stage → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +554 -3
- package/dist/components/AgentEchartsBlock.vue.d.ts +7 -0
- package/dist/components/AgentMarkdown.vue.d.ts +7 -0
- package/dist/components/ChatBubble.vue.d.ts +21 -0
- package/dist/components/ChatSender.vue.d.ts +26 -0
- package/dist/components/KdChatAdaptPanel.vue.d.ts +57 -0
- package/dist/components/KdChatPanel.vue.d.ts +63 -0
- package/dist/components/KdChatView.vue.d.ts +20 -0
- package/dist/createAgentChatClient.d.ts +4 -0
- package/dist/index.d.ts +17 -0
- package/dist/kd-chatbot-ui.css +1 -0
- package/dist/kd-chatbot-ui.js +1354 -0
- package/dist/kd-chatbot-ui.js.map +1 -0
- package/dist/keys.d.ts +5 -0
- package/dist/requestParams.d.ts +12 -0
- package/dist/store.d.ts +375 -0
- package/dist/toValue.d.ts +5 -0
- package/dist/types.d.ts +230 -0
- package/dist/useAgentChat.d.ts +45 -0
- package/dist/utils/markdown.d.ts +23 -0
- package/dist/utils/streamReveal.d.ts +21 -0
- package/package.json +54 -6
package/README.md
CHANGED
|
@@ -1,3 +1,554 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# kd-chatbot-ui-vue2
|
|
2
|
+
|
|
3
|
+
Vue **2.7** 智能体会话组件库。与姊妹包 [`kd-chatbot-ui`](../kd-chatbot-ui)(Vue 3)接口契约对齐;请求鉴权由宿主传入 `request`,组件库不写死 token / baseURL。
|
|
4
|
+
|
|
5
|
+
本包位于 Monorepo:`agent-chat-components/packages/kd-chatbot-ui-vue2`。
|
|
6
|
+
|
|
7
|
+
| 模式 | 组件 | 适用场景 |
|
|
8
|
+
|------|------|----------|
|
|
9
|
+
| **适配(推荐)** | `AgentChatAdaptPanel` | 流程与 interpret 相近:组件内调接口;路径与入参由宿主配置 |
|
|
10
|
+
| **受控** | `AgentChatPanel` | 协议完全自定义:宿主自己调接口,用 props 传入 `sessions` |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
1. [与 Vue3 版差异](#0-与-vue3-版差异必读)
|
|
17
|
+
2. [安装与依赖](#1-安装与依赖)
|
|
18
|
+
3. [AgentChatAdaptPanel](#2-agentchatadaptpanel推荐)
|
|
19
|
+
4. [AgentChatPanel](#3-agentchatpanel受控模式)
|
|
20
|
+
5. [导出一览](#4-导出一览)
|
|
21
|
+
6. [开发与发布](#5-开发与发布)
|
|
22
|
+
7. [怎么选模式](#6-怎么选模式)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 0. 与 Vue3 版差异(必读)
|
|
27
|
+
|
|
28
|
+
| 项 | Vue3(`kd-chatbot-ui`) | Vue2(本包) |
|
|
29
|
+
|----|-------------------------|--------------|
|
|
30
|
+
| 包名 | `kd-chatbot-ui` | `kd-chatbot-ui-vue2` |
|
|
31
|
+
| Vue | `^3.5` | `^2.7`(不支持 2.6 及更早) |
|
|
32
|
+
| UI | Element Plus | Element UI `^2.15` |
|
|
33
|
+
| 状态 | Pinia `^3` | Pinia `^2.1` |
|
|
34
|
+
| 气泡 / 输入框 | `vue-element-plus-x` | 包内 `ChatBubble` / `ChatSender` |
|
|
35
|
+
| 历史栏双向绑定 | `v-model:history-open` | `:history-open.sync` |
|
|
36
|
+
| 插件安装 | `app.use(plugin)` | `Vue.use(plugin)` |
|
|
37
|
+
| 本地存储 key | `kdChatbotUi_v3` | `kdChatbotUi_vue2_v1`(与 Vue3 隔离) |
|
|
38
|
+
|
|
39
|
+
**接口契约相同**:`request` / `endpoints` / `requestParams` / `reloadKey` / `responseFields` / `theme` / `tips` 等与 Vue3 版一致。
|
|
40
|
+
**不要**在同一个 Vue 应用里同时安装两套包。
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 1. 安装与依赖
|
|
45
|
+
|
|
46
|
+
### 1.1 安装
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm i kd-chatbot-ui-vue2
|
|
50
|
+
# 或 yarn / pnpm
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
本地联调(指向 Monorepo 内本包):
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"kd-chatbot-ui-vue2": "link:../agent-chat-components/packages/kd-chatbot-ui-vue2"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
修改源码后,在 Monorepo 根目录执行:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pnpm build:vue2
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
宿主侧如未热更新到最新 `dist`,可再执行一次 `pnpm install` / 重启开发服务。
|
|
70
|
+
|
|
71
|
+
### 1.2 Peer 依赖
|
|
72
|
+
|
|
73
|
+
| 包 | 版本 |
|
|
74
|
+
|----|------|
|
|
75
|
+
| `vue` | `^2.7` |
|
|
76
|
+
| `vue-template-compiler` | 与 `vue` **同版本** |
|
|
77
|
+
| `pinia` | `^2.1`(配合 Vue 2.7) |
|
|
78
|
+
| `element-ui` | `^2.15` |
|
|
79
|
+
| `echarts` | `^5.5` |
|
|
80
|
+
| `marked` | `^15` / `^16` / `^18` |
|
|
81
|
+
| `dompurify` | `^3` |
|
|
82
|
+
|
|
83
|
+
### 1.3 宿主入口
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
import Vue from "vue";
|
|
87
|
+
import ElementUI from "element-ui";
|
|
88
|
+
import "element-ui/lib/theme-chalk/index.css";
|
|
89
|
+
import { createPinia, PiniaVuePlugin } from "pinia";
|
|
90
|
+
import KdChatbotUi from "kd-chatbot-ui-vue2";
|
|
91
|
+
import "kd-chatbot-ui-vue2/style.css";
|
|
92
|
+
|
|
93
|
+
Vue.use(ElementUI);
|
|
94
|
+
Vue.use(PiniaVuePlugin);
|
|
95
|
+
Vue.use(KdChatbotUi); // 可选:全局注册 KdChatPanel / KdChatAdaptPanel / KdChatView
|
|
96
|
+
|
|
97
|
+
const pinia = createPinia();
|
|
98
|
+
|
|
99
|
+
new Vue({
|
|
100
|
+
pinia,
|
|
101
|
+
render: h => h(App)
|
|
102
|
+
}).$mount("#app");
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
也可不 `Vue.use`,在页面内按需引入:
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
import { AgentChatAdaptPanel } from "kd-chatbot-ui-vue2";
|
|
109
|
+
import "kd-chatbot-ui-vue2/style.css";
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 2. `AgentChatAdaptPanel`(推荐)
|
|
115
|
+
|
|
116
|
+
组件内部完成:拉会话列表、创建会话、发问、轮询进度、取消、写 store。
|
|
117
|
+
宿主只需传:**请求函数**、**接口地址**、**传参映射**、**隔离维度**。
|
|
118
|
+
|
|
119
|
+
### 2.1 最小用法
|
|
120
|
+
|
|
121
|
+
```vue
|
|
122
|
+
<template>
|
|
123
|
+
<div class="agent-chat-page">
|
|
124
|
+
<AgentChatAdaptPanel
|
|
125
|
+
:request="request"
|
|
126
|
+
:theme="theme"
|
|
127
|
+
:endpoints="endpoints"
|
|
128
|
+
:request-params="requestParams"
|
|
129
|
+
:reload-key="reloadKey"
|
|
130
|
+
:tips="agentTips"
|
|
131
|
+
:show-open-in-browser="false"
|
|
132
|
+
/>
|
|
133
|
+
</div>
|
|
134
|
+
</template>
|
|
135
|
+
|
|
136
|
+
<script>
|
|
137
|
+
import { AgentChatAdaptPanel } from "kd-chatbot-ui-vue2";
|
|
138
|
+
import "kd-chatbot-ui-vue2/style.css";
|
|
139
|
+
import request from "@/utils/request";
|
|
140
|
+
|
|
141
|
+
export default {
|
|
142
|
+
name: "AgentChatPage",
|
|
143
|
+
components: { AgentChatAdaptPanel },
|
|
144
|
+
data() {
|
|
145
|
+
return {
|
|
146
|
+
request,
|
|
147
|
+
theme: "light",
|
|
148
|
+
/** 快捷提示(多项):value 文案 / content 发送内容 / type 提问类型 */
|
|
149
|
+
agentTips: [
|
|
150
|
+
{
|
|
151
|
+
id: "default_analysis",
|
|
152
|
+
value: "整体分析",
|
|
153
|
+
content: "请对动力学计算结果进行整体分析",
|
|
154
|
+
type: "default_analysis"
|
|
155
|
+
}
|
|
156
|
+
],
|
|
157
|
+
endpoints: {
|
|
158
|
+
createSession: "/ds-dynamics-alg-service/interpret/sessions",
|
|
159
|
+
listSessions: "/ds-dynamics-alg-service/interpret/sessions",
|
|
160
|
+
history: "/ds-dynamics-alg-service/interpret/history/:sessionId",
|
|
161
|
+
ask: "/ds-dynamics-alg-service/interpret/chat/ask",
|
|
162
|
+
cancel: "/ds-dynamics-alg-service/interpret/chat/cancel",
|
|
163
|
+
progress: "/ds-dynamics-alg-service/interpret/chat/progress"
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
},
|
|
167
|
+
computed: {
|
|
168
|
+
wellboreId() {
|
|
169
|
+
return String(this.$store?.state?.well?.wellboreId || "");
|
|
170
|
+
},
|
|
171
|
+
mainId() {
|
|
172
|
+
return String(this.$store?.state?.well?.mainId || "");
|
|
173
|
+
},
|
|
174
|
+
tripId() {
|
|
175
|
+
return String(this.$store?.state?.well?.tripId || "");
|
|
176
|
+
},
|
|
177
|
+
reloadKey() {
|
|
178
|
+
return `${this.wellboreId}|${this.mainId}|${this.tripId}`;
|
|
179
|
+
},
|
|
180
|
+
/**
|
|
181
|
+
* 各接口真实传参。
|
|
182
|
+
* - 主应用字段:在闭包里直接取(wellboreId 等)
|
|
183
|
+
* - 包内字段:用参数 runtime(sessionId / taskId / content / type / since)
|
|
184
|
+
*/
|
|
185
|
+
requestParams() {
|
|
186
|
+
const self = this;
|
|
187
|
+
return {
|
|
188
|
+
createSession: () => ({
|
|
189
|
+
body: {
|
|
190
|
+
wellbore_id: self.wellboreId,
|
|
191
|
+
main_id: self.mainId,
|
|
192
|
+
trip_id: self.tripId
|
|
193
|
+
}
|
|
194
|
+
}),
|
|
195
|
+
listSessions: () => ({
|
|
196
|
+
query: {
|
|
197
|
+
wellbore_id: self.wellboreId,
|
|
198
|
+
main_id: self.mainId,
|
|
199
|
+
trip_id: self.tripId
|
|
200
|
+
}
|
|
201
|
+
}),
|
|
202
|
+
history: runtime => ({
|
|
203
|
+
path: { sessionId: runtime.sessionId }
|
|
204
|
+
}),
|
|
205
|
+
ask: runtime => ({
|
|
206
|
+
body: {
|
|
207
|
+
wellbore_id: self.wellboreId,
|
|
208
|
+
main_id: self.mainId,
|
|
209
|
+
trip_id: self.tripId,
|
|
210
|
+
session_id: runtime.sessionId,
|
|
211
|
+
type: runtime.type,
|
|
212
|
+
content: runtime.content
|
|
213
|
+
}
|
|
214
|
+
}),
|
|
215
|
+
cancel: runtime => ({
|
|
216
|
+
body: { task_id: runtime.taskId }
|
|
217
|
+
}),
|
|
218
|
+
progress: runtime => ({
|
|
219
|
+
query: {
|
|
220
|
+
task_id: runtime.taskId,
|
|
221
|
+
since: runtime.since
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
</script>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
说明:
|
|
232
|
+
|
|
233
|
+
- 不必再传 `:context`;主应用字段写在 `requestParams` 闭包里即可。
|
|
234
|
+
- `endpoints` 已是完整路径(以 `/` 开头)时,不必再传 `base-url`。
|
|
235
|
+
- 宿主需已安装并注册 **Pinia**、**Element UI**。
|
|
236
|
+
|
|
237
|
+
### 2.2 Props
|
|
238
|
+
|
|
239
|
+
| 模板属性 | 类型 | 说明 |
|
|
240
|
+
|----------|------|------|
|
|
241
|
+
| `request` | `AgentChatRequestFn` | 宿主请求函数(带 token)。不传则用 `fetch`(无鉴权) |
|
|
242
|
+
| `base-url` | `string` | 可选统一前缀。`endpoints` 已给完整路径时可省略。模板写 `base-url`(不要写成 `baseURL`) |
|
|
243
|
+
| `endpoints` | `AgentChatEndpoints` | 各接口路径。以 `/` 开头视为站点绝对路径,不再拼 `base-url` |
|
|
244
|
+
| `request-params` | `AgentChatRequestParams` | 各接口传参映射(主应用字段 + 包内 runtime) |
|
|
245
|
+
| `reload-key` | `string \| number` | 井/趟等维度变化时重拉会话。建议 `` `${wellboreId}|${mainId}|${tripId}` `` |
|
|
246
|
+
| `response-fields` | `AgentChatResponseFields` | 响应字段名。默认 `session_id` / `task_id` / `code === "OK"` |
|
|
247
|
+
| `theme` | `"light" \| "dark" \| "gray" \| "white"` | 面板主题;`white` 按 `light` 处理 |
|
|
248
|
+
| `tips` | `AgentChatTip[]` | 底部快捷提示(多项)。每项:`value` 文案、`content` 发送内容、`type` 提问类型。不传则用默认「整体分析」 |
|
|
249
|
+
| `show-open-in-browser` | `boolean` | 是否显示「浏览器打开」,默认 `true` |
|
|
250
|
+
| `poll-interval-ms` | `number` | 进度轮询间隔,默认 `500` |
|
|
251
|
+
| `context` | `AgentChatContext` | **已不推荐**。仅兼容旧写法;新接入请用 `request-params` |
|
|
252
|
+
| `required-context` | `string[]` | 仅在仍使用 `context` 时做必填校验 |
|
|
253
|
+
|
|
254
|
+
### 2.3 Events
|
|
255
|
+
|
|
256
|
+
| 事件 | 说明 |
|
|
257
|
+
|------|------|
|
|
258
|
+
| `open-browser` | 点击「浏览器打开」。发送 / 切会话 / 取消由面板内部处理;新开页由宿主自行 `window.open` |
|
|
259
|
+
|
|
260
|
+
### 2.4 `tips` 快捷提示
|
|
261
|
+
|
|
262
|
+
```js
|
|
263
|
+
agentTips: [
|
|
264
|
+
{
|
|
265
|
+
id: "default_analysis",
|
|
266
|
+
value: "整体分析", // 按钮文案
|
|
267
|
+
content: "请对动力学计算结果进行整体分析", // 发送内容
|
|
268
|
+
type: "default_analysis" // ask.type
|
|
269
|
+
}
|
|
270
|
+
// 继续追加即可
|
|
271
|
+
]
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
也可:
|
|
275
|
+
|
|
276
|
+
```js
|
|
277
|
+
import { DEFAULT_AGENT_CHAT_TIPS } from "kd-chatbot-ui-vue2";
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 2.5 两套字段从哪里来
|
|
281
|
+
|
|
282
|
+
| 来源 | 例子 | 怎么写进请求 |
|
|
283
|
+
|------|------|----------------|
|
|
284
|
+
| **主应用** | `wellboreId`、`mainId`、`tripId` | 在 `requestParams` **闭包里直接取** |
|
|
285
|
+
| **包内 runtime** | `sessionId`、`taskId`、`content`、`type`、`since` | mapper 的参数 `runtime` |
|
|
286
|
+
|
|
287
|
+
`runtime` 由包在发请求前组装,宿主**不用**自己存 `sessionId`:
|
|
288
|
+
|
|
289
|
+
1. 创建会话 / 拉列表后,包从响应读出 `session_id`(字段名可由 `response-fields` 改)
|
|
290
|
+
2. 写入包内 store:`sessions[].id` + `activeId`
|
|
291
|
+
3. 用户发送时取出当前会话 id,连同 `content`、`type` 放进 `runtime`
|
|
292
|
+
4. 调用你写的 mapper,例如 `session_id: runtime.sessionId`
|
|
293
|
+
|
|
294
|
+
`taskId` 同理:来自 ask / history 响应,用于 cancel、progress。
|
|
295
|
+
|
|
296
|
+
### 2.6 `requestParams` 返回结构
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
type AgentChatParamMapper = (
|
|
300
|
+
runtime: AgentChatCallRuntime
|
|
301
|
+
) => {
|
|
302
|
+
path?: Record<string, unknown>; // 替换 URL 里的 :name / {name}
|
|
303
|
+
query?: Record<string, unknown>; // GET 查询参数
|
|
304
|
+
body?: Record<string, unknown>; // POST body
|
|
305
|
+
};
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
| 接口 key | 常用写法 |
|
|
309
|
+
|----------|----------|
|
|
310
|
+
| `createSession` | `body`:主应用隔离字段 |
|
|
311
|
+
| `listSessions` | `query`:主应用隔离字段 |
|
|
312
|
+
| `history` | `path: { sessionId: runtime.sessionId }` 填 `:sessionId` |
|
|
313
|
+
| `ask` | `body`:主应用字段 + `runtime.sessionId/type/content` |
|
|
314
|
+
| `cancel` | `body: { task_id: runtime.taskId }` |
|
|
315
|
+
| `progress` | `query: { task_id, since }` |
|
|
316
|
+
|
|
317
|
+
只写需要改的接口;未写的接口仍走包内默认 interpret 字段。
|
|
318
|
+
|
|
319
|
+
### 2.7 换项目时怎么改
|
|
320
|
+
|
|
321
|
+
**只换字段名:**
|
|
322
|
+
|
|
323
|
+
```js
|
|
324
|
+
ask: runtime => ({
|
|
325
|
+
body: {
|
|
326
|
+
wellId: this.wellId, // 你们自己的主应用字段
|
|
327
|
+
chatId: runtime.sessionId, // 包内 sessionId → 你们的 chatId
|
|
328
|
+
msg: runtime.content
|
|
329
|
+
}
|
|
330
|
+
})
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**路径占位也不同:**
|
|
334
|
+
|
|
335
|
+
```js
|
|
336
|
+
// endpoints
|
|
337
|
+
history: "/xxx/history/:conversationId"
|
|
338
|
+
|
|
339
|
+
// requestParams
|
|
340
|
+
history: runtime => ({
|
|
341
|
+
path: { conversationId: runtime.sessionId }
|
|
342
|
+
})
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**响应字段不同:**
|
|
346
|
+
|
|
347
|
+
```vue
|
|
348
|
+
<AgentChatAdaptPanel
|
|
349
|
+
:response-fields="{ sessionId: 'id', taskId: 'taskId', okValue: 0 }"
|
|
350
|
+
...
|
|
351
|
+
/>
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
包读出后仍放入 `runtime.sessionId` / `runtime.taskId`,后续映射不变。
|
|
355
|
+
|
|
356
|
+
### 2.8 `endpoints` 路径规则
|
|
357
|
+
|
|
358
|
+
- `http(s)://...`:原样使用
|
|
359
|
+
- 以 `/` 开头:站点绝对路径,**不拼** `base-url`
|
|
360
|
+
- 其它相对路径:拼在 `base-url` 后面
|
|
361
|
+
- `history` 支持 `:sessionId` 或 `{sessionId}`(或你在 `path` 里声明的其它占位名)
|
|
362
|
+
|
|
363
|
+
### 2.9 约定接口(未覆盖 `endpoints` 时)
|
|
364
|
+
|
|
365
|
+
相对 `base-url`:
|
|
366
|
+
|
|
367
|
+
| 方法 | 路径 | 说明 |
|
|
368
|
+
|------|------|------|
|
|
369
|
+
| `POST` | `/sessions` | 创建会话 |
|
|
370
|
+
| `GET` | `/sessions` | 会话列表 |
|
|
371
|
+
| `GET` | `/history/:sessionId` | 历史 |
|
|
372
|
+
| `POST` | `/chat/ask` | 提问(返回 `task_id`) |
|
|
373
|
+
| `POST` | `/chat/cancel` | 取消 |
|
|
374
|
+
| `GET` | `/chat/progress` | 轮询进度 |
|
|
375
|
+
|
|
376
|
+
默认成功码:`code === "OK"`。
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## 3. `AgentChatPanel`(受控模式)
|
|
381
|
+
|
|
382
|
+
宿主自己调接口,用 props 传入展示数据;用户操作通过事件抛回宿主。
|
|
383
|
+
|
|
384
|
+
### 3.1 Props / Events
|
|
385
|
+
|
|
386
|
+
| Props | 说明 |
|
|
387
|
+
|-------|------|
|
|
388
|
+
| `sessions` | `AgentSession[]` |
|
|
389
|
+
| `active-id` | 当前会话 id |
|
|
390
|
+
| `history-open` | 历史侧栏;用 **`:history-open.sync`**(不要用 `v-model:history-open`) |
|
|
391
|
+
| `is-replying` | 是否回复中 |
|
|
392
|
+
| `tips` / `theme` / `show-open-in-browser` | 同适配面板 |
|
|
393
|
+
|
|
394
|
+
| Events | 说明 |
|
|
395
|
+
|--------|------|
|
|
396
|
+
| `send` | `(payload: { text, type?, tip? })` |
|
|
397
|
+
| `select-session` | `(sessionId)` |
|
|
398
|
+
| `create-session` | 新建 |
|
|
399
|
+
| `cancel-reply` | 停止生成 |
|
|
400
|
+
| `clear-session` | 清空当前会话 |
|
|
401
|
+
| `update:historyOpen` | 切换历史栏(配合 `.sync`) |
|
|
402
|
+
| `open-browser` | 浏览器打开 |
|
|
403
|
+
|
|
404
|
+
### 3.2 示例
|
|
405
|
+
|
|
406
|
+
```vue
|
|
407
|
+
<template>
|
|
408
|
+
<AgentChatPanel
|
|
409
|
+
:sessions="sessions"
|
|
410
|
+
:active-id="activeId"
|
|
411
|
+
:history-open.sync="historyOpen"
|
|
412
|
+
:is-replying="isReplying"
|
|
413
|
+
@send="onSend"
|
|
414
|
+
@select-session="onSelect"
|
|
415
|
+
@create-session="onCreate"
|
|
416
|
+
@cancel-reply="onCancel"
|
|
417
|
+
@clear-session="onClear"
|
|
418
|
+
/>
|
|
419
|
+
</template>
|
|
420
|
+
|
|
421
|
+
<script>
|
|
422
|
+
import { AgentChatPanel } from "kd-chatbot-ui-vue2";
|
|
423
|
+
import "kd-chatbot-ui-vue2/style.css";
|
|
424
|
+
|
|
425
|
+
export default {
|
|
426
|
+
components: { AgentChatPanel },
|
|
427
|
+
data() {
|
|
428
|
+
return {
|
|
429
|
+
sessions: [],
|
|
430
|
+
activeId: "",
|
|
431
|
+
historyOpen: false,
|
|
432
|
+
isReplying: false
|
|
433
|
+
};
|
|
434
|
+
},
|
|
435
|
+
methods: {
|
|
436
|
+
async onSend({ text, type }) {
|
|
437
|
+
this.isReplying = true;
|
|
438
|
+
// 调你们自己的接口,写入 sessions
|
|
439
|
+
this.isReplying = false;
|
|
440
|
+
},
|
|
441
|
+
onSelect(id) {
|
|
442
|
+
this.activeId = id;
|
|
443
|
+
},
|
|
444
|
+
onCreate() {},
|
|
445
|
+
onCancel() {},
|
|
446
|
+
onClear() {}
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
</script>
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### 3.3 会话消息结构
|
|
453
|
+
|
|
454
|
+
```ts
|
|
455
|
+
interface AgentSession {
|
|
456
|
+
id: string;
|
|
457
|
+
title: string;
|
|
458
|
+
content: AgentMessage[];
|
|
459
|
+
pinned?: boolean;
|
|
460
|
+
badge?: number;
|
|
461
|
+
updatedAt?: number;
|
|
462
|
+
snippet?: string;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
interface AgentMessage {
|
|
466
|
+
type: "ask" | "answer";
|
|
467
|
+
placement: "start" | "end";
|
|
468
|
+
content: string;
|
|
469
|
+
segments?: { type: "reasoning" | "answer"; content: string }[];
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
流式回复:持续更新当前会话最后一条 `answer.segments`,再通过 `:sessions` 传入即可。
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
## 4. 导出一览
|
|
478
|
+
|
|
479
|
+
```ts
|
|
480
|
+
import {
|
|
481
|
+
AgentChatAdaptPanel,
|
|
482
|
+
AgentChatPanel,
|
|
483
|
+
AgentChatView,
|
|
484
|
+
useAgentChat,
|
|
485
|
+
useAgentChatStore,
|
|
486
|
+
createAgentChatClient,
|
|
487
|
+
buildInterpretContext,
|
|
488
|
+
INTERPRET_POLL_INTERVAL_MS,
|
|
489
|
+
DEFAULT_AGENT_CHAT_TIPS
|
|
490
|
+
} from "kd-chatbot-ui-vue2";
|
|
491
|
+
|
|
492
|
+
import type {
|
|
493
|
+
AgentChatEndpoints,
|
|
494
|
+
AgentChatRequestParams,
|
|
495
|
+
AgentChatRequestFn,
|
|
496
|
+
AgentChatCallRuntime,
|
|
497
|
+
AgentChatResponseFields,
|
|
498
|
+
AgentChatContext,
|
|
499
|
+
AgentSession,
|
|
500
|
+
AgentMessage,
|
|
501
|
+
AgentChatTip,
|
|
502
|
+
AgentChatSendPayload,
|
|
503
|
+
AgentChatTheme
|
|
504
|
+
} from "kd-chatbot-ui-vue2";
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
默认导出为 Vue 插件:`Vue.use(KdChatbotUi)`。
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
## 5. 开发与发布
|
|
512
|
+
|
|
513
|
+
本包在 Monorepo 内维护:
|
|
514
|
+
|
|
515
|
+
```text
|
|
516
|
+
agent-chat-components/
|
|
517
|
+
packages/
|
|
518
|
+
kd-chatbot-ui/ # Vue3
|
|
519
|
+
kd-chatbot-ui-vue2/ # 本包
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
# 在 agent-chat-components 根目录
|
|
524
|
+
pnpm install
|
|
525
|
+
pnpm build:vue2 # 只构建本包
|
|
526
|
+
pnpm build # Vue2 + Vue3 都构建
|
|
527
|
+
pnpm dev:vue2 # watch 构建
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
构建产物:`dist/kd-chatbot-ui.js`、`dist/kd-chatbot-ui.css`、类型声明。
|
|
531
|
+
|
|
532
|
+
发布(在本包目录或按你们的发包流程):
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
pnpm --filter kd-chatbot-ui-vue2 publish
|
|
536
|
+
# prepublishOnly 会先执行 build
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
---
|
|
540
|
+
|
|
541
|
+
## 6. 怎么选模式
|
|
542
|
+
|
|
543
|
+
- 后端仍是「会话 + ask + progress 轮询」,只是路径/字段名不同 → **`AgentChatAdaptPanel`** + `endpoints` + `requestParams`
|
|
544
|
+
- 协议完全不同,或宿主已有完整编排 → **`AgentChatPanel`**,自己管接口与 `sessions`
|
|
545
|
+
|
|
546
|
+
Vue 3 项目请用姊妹包 [`kd-chatbot-ui`](../kd-chatbot-ui),不要混用本包。
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## 版本
|
|
551
|
+
|
|
552
|
+
- 包名:`kd-chatbot-ui-vue2`
|
|
553
|
+
- 版本:见本目录 `package.json` 的 `version`
|
|
554
|
+
- License:MIT
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {
|
|
2
|
+
option: Record<string, any>;
|
|
3
|
+
$props: {
|
|
4
|
+
readonly option?: Record<string, any> | undefined;
|
|
5
|
+
};
|
|
6
|
+
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, Readonly<import('vue').ExtractPropTypes<{}>>, {}>;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {
|
|
2
|
+
content: string;
|
|
3
|
+
$props: {
|
|
4
|
+
readonly content?: string | undefined;
|
|
5
|
+
};
|
|
6
|
+
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, Readonly<import('vue').ExtractPropTypes<{}>>, {}>;
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
2
|
+
export default _default;
|
|
3
|
+
type __VLS_WithTemplateSlots<T, S> = T & (new () => {
|
|
4
|
+
$scopedSlots: S;
|
|
5
|
+
});
|
|
6
|
+
declare const __VLS_component: import('vue').DefineComponent<{}, {
|
|
7
|
+
content: string;
|
|
8
|
+
placement: string;
|
|
9
|
+
$props: {
|
|
10
|
+
readonly content?: string | undefined;
|
|
11
|
+
readonly placement?: string | undefined;
|
|
12
|
+
};
|
|
13
|
+
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, Readonly<import('vue').ExtractPropTypes<{}>>, {}>;
|
|
14
|
+
type __VLS_TemplateResult = {
|
|
15
|
+
attrs: Partial<{}>;
|
|
16
|
+
slots: {
|
|
17
|
+
content?(_: {}): any;
|
|
18
|
+
};
|
|
19
|
+
refs: {};
|
|
20
|
+
rootEl: HTMLDivElement;
|
|
21
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
2
|
+
export default _default;
|
|
3
|
+
type __VLS_WithTemplateSlots<T, S> = T & (new () => {
|
|
4
|
+
$scopedSlots: S;
|
|
5
|
+
});
|
|
6
|
+
declare const __VLS_component: import('vue').DefineComponent<{}, {
|
|
7
|
+
clear: () => void;
|
|
8
|
+
getModelValue: () => string;
|
|
9
|
+
$emit: (event: "input" | "submit", ...args: any[]) => void;
|
|
10
|
+
value: string;
|
|
11
|
+
placeholder: string;
|
|
12
|
+
$props: {
|
|
13
|
+
readonly value?: string | undefined;
|
|
14
|
+
readonly placeholder?: string | undefined;
|
|
15
|
+
};
|
|
16
|
+
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, Readonly<import('vue').ExtractPropTypes<{}>>, {}>;
|
|
17
|
+
type __VLS_TemplateResult = {
|
|
18
|
+
attrs: Partial<{}>;
|
|
19
|
+
slots: {
|
|
20
|
+
'action-list'?(_: {}): any;
|
|
21
|
+
};
|
|
22
|
+
refs: {
|
|
23
|
+
textareaRef: HTMLTextAreaElement;
|
|
24
|
+
};
|
|
25
|
+
rootEl: HTMLDivElement;
|
|
26
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { AgentChatContext, AgentChatEndpoints, AgentChatRequestFn, AgentChatRequestParams, AgentChatResponseFields, AgentChatTheme, AgentChatTip } from '../types';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
request?: AgentChatRequestFn;
|
|
4
|
+
/**
|
|
5
|
+
* 统一前缀。模板写 base-url。
|
|
6
|
+
* 不能命名为 baseURL,否则 Vue 会把它当成 base-u-r-l,base-url 绑不上。
|
|
7
|
+
*/
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
endpoints?: AgentChatEndpoints;
|
|
10
|
+
requestParams?: AgentChatRequestParams;
|
|
11
|
+
responseFields?: AgentChatResponseFields;
|
|
12
|
+
requiredContext?: string[];
|
|
13
|
+
reloadKey?: string | number;
|
|
14
|
+
/** @deprecated 主应用字段请写在 requestParams 闭包里 */
|
|
15
|
+
context?: AgentChatContext;
|
|
16
|
+
pollIntervalMs?: number;
|
|
17
|
+
/**
|
|
18
|
+
* 底部快捷提示(多项,均可动态)。
|
|
19
|
+
* 每项:value 文案、content 发送内容、type 提问类型。
|
|
20
|
+
*/
|
|
21
|
+
tips?: AgentChatTip[];
|
|
22
|
+
theme?: AgentChatTheme;
|
|
23
|
+
showOpenInBrowser?: boolean;
|
|
24
|
+
};
|
|
25
|
+
declare const _default: import('vue').DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
26
|
+
context: () => {};
|
|
27
|
+
theme: string;
|
|
28
|
+
showOpenInBrowser: boolean;
|
|
29
|
+
}>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
30
|
+
"open-browser": () => void;
|
|
31
|
+
}, string, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
32
|
+
context: () => {};
|
|
33
|
+
theme: string;
|
|
34
|
+
showOpenInBrowser: boolean;
|
|
35
|
+
}>>>, {
|
|
36
|
+
showOpenInBrowser: boolean;
|
|
37
|
+
theme: AgentChatTheme;
|
|
38
|
+
context: AgentChatContext;
|
|
39
|
+
}>;
|
|
40
|
+
export default _default;
|
|
41
|
+
type __VLS_WithDefaults<P, D> = {
|
|
42
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
|
|
43
|
+
default: D[K];
|
|
44
|
+
}> : P[K];
|
|
45
|
+
};
|
|
46
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
47
|
+
type __VLS_TypePropsToOption<T> = {
|
|
48
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
49
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
50
|
+
} : {
|
|
51
|
+
type: import('vue').PropType<T[K]>;
|
|
52
|
+
required: true;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
type __VLS_PrettifyLocal<T> = {
|
|
56
|
+
[K in keyof T]: T[K];
|
|
57
|
+
} & {};
|