@glodon-aiot/bot-client-ui 0.0.0-20251106104234
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 +432 -0
- package/dist/es/index.mjs +14 -0
- package/dist/es/style.less.mjs +4 -0
- package/dist/lib/index.js +2 -0
- package/dist/src/index.d.ts +8 -0
- package/package.json +86 -0
package/README.md
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
# 安装依赖
|
|
2
|
+
|
|
3
|
+
## npm
|
|
4
|
+
|
|
5
|
+
`npm install @glodon-aiot/bot-client-ui`
|
|
6
|
+
|
|
7
|
+
## yarn
|
|
8
|
+
|
|
9
|
+
`yarn add @glodon-aiot/bot-client-ui`
|
|
10
|
+
|
|
11
|
+
## 从 cdn 引入 cjs 文件
|
|
12
|
+
|
|
13
|
+
一些项目无法处理 esm,请使用以下方式引入依赖。BotClientUI 将被注册在 window 对象上。
|
|
14
|
+
`<script src="https://cv-cdn.obs.cn-north-4.myhuaweicloud.com/glodon/libs/bot-client-ui/3.3.0/bot-client-ui.umd.cjs"></script>`
|
|
15
|
+
|
|
16
|
+
# 快速开始
|
|
17
|
+
|
|
18
|
+
## 初始化
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
import BotClientUI from '@glodon-aiot/bot-client-ui';
|
|
22
|
+
|
|
23
|
+
new BotClientUI({
|
|
24
|
+
token: 'aiot_resource_token_goes_here',
|
|
25
|
+
getContainer: () => document.getElementById('client-ui'),
|
|
26
|
+
errorHandlers: {
|
|
27
|
+
token: (error) => {
|
|
28
|
+
console.error(error);
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 在线预览:
|
|
35
|
+
|
|
36
|
+
- 对话型应用 Demo [https://code.juejin.cn/pen/7494170871938940966](https://code.juejin.cn/pen/7494170871938940966)
|
|
37
|
+
- Agent Demo [https://code.juejin.cn/pen/7372449505322467363](https://code.juejin.cn/pen/7372449505322467363)
|
|
38
|
+
|
|
39
|
+
# BotClientUI 构造配置
|
|
40
|
+
|
|
41
|
+
## 通用配置
|
|
42
|
+
|
|
43
|
+
| 名称 | 类型 | 必填 | 默认值 | 说明 | 适用应用类型 | 支持版本 |
|
|
44
|
+
| -------------- | ----------------------------- | ------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | ---------- | ---------- | --- |
|
|
45
|
+
| token | string | 是 | - | aiot 行业 AI 平台的 AI 应用的 resource token。详情查看[认证说明](https://glodon-cv-help.yuque.com/lzh2bp/eszzb5/evk1gvh3pqaexe74?singleDoc#%20《认证说明》)。 | 全部 | |
|
|
46
|
+
| apiUrl | string | 否 | `https://copilot.glodon.com/api/cvforce` | 拼接规则:`${origin}/api/cvforce`,其中`origin`是部署服务的源地址。 | 全部 | 3.0.8 |
|
|
47
|
+
| getContainer | () => Element | 否 | () => document.body | 容器元素获取方法,默认在 document.body 中渲染 | 全部 | |
|
|
48
|
+
| sessionId | string | 否 | - | 默认加载的会话 ID | Agent/对话 | |
|
|
49
|
+
| mode | 'float' | 'inlay' | 否 | 'float' | 悬浮按钮模式,或者嵌入模式 | Agent/对话 | |
|
|
50
|
+
| header | Element | string | boolean | 否 | 应用名称 | 应用名称 | Agent/对话 | |
|
|
51
|
+
| footer | Element | string | boolean | 否 | | | Agent/对话 | |
|
|
52
|
+
| sider | boolean | 否 | | inlay 模式可用。 是否展示左侧会话列表 | Agent/对话 | |
|
|
53
|
+
| icon | string | 否 | | 影响 greeting 和 triggerButton 的 icon | Agent/对话 | 3.3.1 |
|
|
54
|
+
| size | [SizeConfig](#GbxmJ) | 否 | {width: 450} | float 模式下:窗体大小 | 全部 | |
|
|
55
|
+
| open | boolean | 否 | false | float 模式下:默认打开状态 | Agent/对话 | |
|
|
56
|
+
| triggerButton | [TriggerButtonConfig](#djhoc) | 否 | {visible: true} | triggerButton 设置 | Agent/对话 | |
|
|
57
|
+
| features | [Features](#uIpxC) | 否 | FEATURE_DEFAULT | 功能配置 | Agent/对话 | |
|
|
58
|
+
| debug | boolean | 否 | false | 打开 debug 模式时:<br/>1. 控制 log 输出。 2. promptValues 变为非必填项; 3. Agent 类型应用下,控制 ws 连接是否开启,debug 模式,由于收到权限限制,可能会配置失败。 | Agent/对话 | |
|
|
59
|
+
| eventListeners | [EventListeners](#IhvdK) | | | 事件监听器配置 | Agent/对话 | |
|
|
60
|
+
| errorHandlers | [ErrorHandlers](#VTONU) | 否 | - | errorHandlers.token 是 token 验证失败后的处理器; errorHandlers.promptValues 非 debug 模式下,检测空值 | 全部 | |
|
|
61
|
+
|
|
62
|
+
## 只适用于 Agent 应用的配置
|
|
63
|
+
|
|
64
|
+
| 名称 | 类型 | 必填 | 默认值 | 说明 |
|
|
65
|
+
| ------- | ------------- | ---- | ------ | ----------------------------------------------------------------------------------------------------------------- |
|
|
66
|
+
| plugins | PluginsConfig | 否 | - | Agent 应用适用。<br/>插件列表,`pluginCode`与`functionCode`要与平台中注册的插件标识和 API 名称保持一致 |
|
|
67
|
+
| mcp | McpConfig | 否 | - | Agent 应用适用。<br/>这里注册的 MCP 作用到每个会话中。<br/>如果希望特定会话才可注册 MCP,则在会话加载后动态注册。 |
|
|
68
|
+
|
|
69
|
+
# BotClientUI 实例 API
|
|
70
|
+
|
|
71
|
+
| 名称 | 类型 | 说明 |
|
|
72
|
+
| -------------- | -------------------------------------------- | ------------------ |
|
|
73
|
+
| reload | `() => void` | |
|
|
74
|
+
| activeSession | `Session` | 当前活跃的会话信息 |
|
|
75
|
+
| input | `(message:string) => void` | 填充输入框内容 |
|
|
76
|
+
| getMessageList | `(sessionId?: string) => Promise<Message[]>` | 获取历史对话列表 |
|
|
77
|
+
|
|
78
|
+
# 类型定义
|
|
79
|
+
|
|
80
|
+
## 基础类型
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
interface SizeConfig {
|
|
84
|
+
width?: number | string;
|
|
85
|
+
height?: number | string;
|
|
86
|
+
maxWidth?: number | string;
|
|
87
|
+
maxHeight?: number | string;
|
|
88
|
+
minWidth?: number | string;
|
|
89
|
+
minHeight?: number | string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
interface TriggerButtonConfig {
|
|
93
|
+
style: string;
|
|
94
|
+
visible: boolean;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface SessionInfo {
|
|
98
|
+
id: string;
|
|
99
|
+
name: string;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
interface Message {
|
|
103
|
+
messageId: string;
|
|
104
|
+
content: string;
|
|
105
|
+
role: ChatMessageRole;
|
|
106
|
+
sessionId: string;
|
|
107
|
+
reference: IReference[];
|
|
108
|
+
searchReference: ISearchRefernce[];
|
|
109
|
+
messageTime: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
enum ChatMessageRole {
|
|
113
|
+
Robot = 1,
|
|
114
|
+
User = 2,
|
|
115
|
+
System = 3,
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface IReference {
|
|
119
|
+
text: string;
|
|
120
|
+
docId: string;
|
|
121
|
+
fileId: string;
|
|
122
|
+
fileName: string;
|
|
123
|
+
knowledgeId: string;
|
|
124
|
+
knowledgeName: string;
|
|
125
|
+
score: number;
|
|
126
|
+
nickname: string;
|
|
127
|
+
knowledgeSourceName: string;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
interface ISearchRefernce {
|
|
131
|
+
link: string;
|
|
132
|
+
title: string;
|
|
133
|
+
snippet: string;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
interface SessionPrompt {
|
|
137
|
+
id?: string;
|
|
138
|
+
key: string;
|
|
139
|
+
name?: string;
|
|
140
|
+
value: string;
|
|
141
|
+
status?: PromptStatus;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
interface Knowledge {
|
|
145
|
+
id: string;
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## 功能配置
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
interface Feature {
|
|
153
|
+
// 问候
|
|
154
|
+
greeting?:
|
|
155
|
+
| boolean
|
|
156
|
+
| {
|
|
157
|
+
icon?: string;
|
|
158
|
+
text?: string; // 问候语
|
|
159
|
+
questions?: boolean; // 推荐问题
|
|
160
|
+
layoutBreakpoints?: number[]; // 布局断点数组
|
|
161
|
+
};
|
|
162
|
+
// toolbar中的"会话历史记录"
|
|
163
|
+
sessionList?: boolean;
|
|
164
|
+
// toolbar中的"新会话"
|
|
165
|
+
newSession?: boolean; // dialog only
|
|
166
|
+
// toolbar中的"上传文件"
|
|
167
|
+
fileUpload?: boolean; // dialog only
|
|
168
|
+
// toolbar中的"上传图片"
|
|
169
|
+
imageUpload?: boolean; // agent only
|
|
170
|
+
// 问题气泡
|
|
171
|
+
userMessageBox?: {
|
|
172
|
+
// dialog only
|
|
173
|
+
copy?: boolean;
|
|
174
|
+
editAgain?: boolean;
|
|
175
|
+
};
|
|
176
|
+
// 回答气泡
|
|
177
|
+
botMessageBox?: {
|
|
178
|
+
// dialog only
|
|
179
|
+
// 参考列表前置
|
|
180
|
+
referenceFirst?: boolean;
|
|
181
|
+
// 参考列表元素设置
|
|
182
|
+
reference?: {
|
|
183
|
+
// 是否可查看参考源文件
|
|
184
|
+
file?: boolean;
|
|
185
|
+
// 是否展开参考内容
|
|
186
|
+
itemExpanded?: boolean;
|
|
187
|
+
};
|
|
188
|
+
// 是否展示相关问题
|
|
189
|
+
relatedQuesions: boolean;
|
|
190
|
+
// 回答气泡底部设置
|
|
191
|
+
footer: {
|
|
192
|
+
items: {
|
|
193
|
+
componentName: 'AnswerAgain' | 'Copy' | 'Comments';
|
|
194
|
+
position: 'left' | 'right';
|
|
195
|
+
}[];
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
prompts?: boolean;
|
|
199
|
+
// toolbar中的网络访问
|
|
200
|
+
connectNetwork?:
|
|
201
|
+
| boolean
|
|
202
|
+
| { visible: boolean; default?: boolean; disabled?: boolean };
|
|
203
|
+
// 参考知识库设置
|
|
204
|
+
knowledges?:
|
|
205
|
+
| boolean
|
|
206
|
+
| { visible: boolean; default: Knowledge[]; disabled?: boolean };
|
|
207
|
+
// 用户指令变量设置
|
|
208
|
+
promptVariables?: boolean | { visible: boolean; default: SessionPrompt[] };
|
|
209
|
+
// 支持自定义问答内容markdown的超链接元素的点击事件
|
|
210
|
+
markdown?: {
|
|
211
|
+
componentProps?: {
|
|
212
|
+
a?: {
|
|
213
|
+
onClick?: (e: { nativeEvent: PointerEvent }) => void;
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## 事件与错误处理
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
interface EventListeners {
|
|
224
|
+
comment: (payload: {
|
|
225
|
+
applicationId: string;
|
|
226
|
+
sessionId: string;
|
|
227
|
+
comment: Comment;
|
|
228
|
+
}) => void;
|
|
229
|
+
sessionload: (payload: {
|
|
230
|
+
applicationId: string;
|
|
231
|
+
sessionId: string;
|
|
232
|
+
session: SessionInfo;
|
|
233
|
+
sessionInstance: Session;
|
|
234
|
+
}) => void;
|
|
235
|
+
message: (payload: {
|
|
236
|
+
applicationId: string;
|
|
237
|
+
sessionId: string;
|
|
238
|
+
message: Message;
|
|
239
|
+
}) => void;
|
|
240
|
+
beforemessagesend: (payload: {
|
|
241
|
+
applicationId: string;
|
|
242
|
+
sessionId: string;
|
|
243
|
+
message: Message;
|
|
244
|
+
}) => boolean | Partil<Message> | Promise<boolean | Partil<Message>>;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
interface ErrorHandlers {
|
|
248
|
+
token: (error: any) => void;
|
|
249
|
+
promptValues?: (error: any, values: { key: string; value: string }[]) => void;
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Agent 应用配置
|
|
254
|
+
|
|
255
|
+
### 插件配置
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
interface PluginsConfig {
|
|
259
|
+
[pluginCode: string]: {
|
|
260
|
+
[functionCode: string]: Function;
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
interface McpServer {
|
|
265
|
+
type: 'sse';
|
|
266
|
+
url: string;
|
|
267
|
+
headers?: Record<string, string>;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
interface McpConfig {
|
|
271
|
+
mcpServers: {
|
|
272
|
+
[key: string]: McpServer;
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### MCP 配置
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
interface McpServer {
|
|
281
|
+
type: 'sse';
|
|
282
|
+
url: string;
|
|
283
|
+
headers?: Record<string, string>;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
interface McpConfig {
|
|
287
|
+
mcpServers: {
|
|
288
|
+
[key: string]: McpServer;
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
# Agent 类型应用的特别说明
|
|
294
|
+
|
|
295
|
+
## 客户端插件使用
|
|
296
|
+
|
|
297
|
+
由于该类型应用一般被当作某个软件的助手使用,需要主体软件在浏览器上注册一些方法,作为与浏览器交互的桥梁。
|
|
298
|
+
|
|
299
|
+
例如,有客户端`Plugin A`,注册插件如下代码。
|
|
300
|
+
|
|
301
|
+
其中,`pluginACode`是插件标识,可以在[行业 AI 平台](https://copilot.glodon.com/)的【插件管理 - 插件详情】中获得,不支持自定义。`functionCode`对应的是`API名称`,可自定义。
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
window.pluginACode = {
|
|
305
|
+
functionCode1: (params, cb) => {
|
|
306
|
+
console.log(
|
|
307
|
+
`模拟pluginA function1 执行\n执行入参\n${JSON.stringify(arguments)}`
|
|
308
|
+
);
|
|
309
|
+
setTimeout(() => {
|
|
310
|
+
console.log(`模拟pluginA function1 执行完成`);
|
|
311
|
+
cb({
|
|
312
|
+
code: 0,
|
|
313
|
+
message: 'function1运行成功',
|
|
314
|
+
data: {
|
|
315
|
+
a: 'a',
|
|
316
|
+
b: 2,
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
}, 5000);
|
|
320
|
+
},
|
|
321
|
+
functionCode2: (params, cb) => {
|
|
322
|
+
console.log(
|
|
323
|
+
`模拟pluginA function2 执行\n执行入参\n${JSON.stringify(arguments)}`
|
|
324
|
+
);
|
|
325
|
+
setTimeout(() => {
|
|
326
|
+
console.log(`模拟pluginA function2 执行完成`);
|
|
327
|
+
cb({
|
|
328
|
+
code: 0,
|
|
329
|
+
message: 'function2运行成功',
|
|
330
|
+
data: {
|
|
331
|
+
a: 'a',
|
|
332
|
+
b: 2,
|
|
333
|
+
},
|
|
334
|
+
});
|
|
335
|
+
}, 10000);
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
创建 Agent 应用 UI 的时候,配置`plugins`属性。完整代码如下:
|
|
341
|
+
|
|
342
|
+
```javascript
|
|
343
|
+
import BotClientUI from '@glodon-aiot/bot-client-ui';
|
|
344
|
+
|
|
345
|
+
new BotClientUI({
|
|
346
|
+
token: 'aiot_resource_token_goes_here',
|
|
347
|
+
getContainer: () => document.getElementById('agent-ui'),
|
|
348
|
+
mode: 'inlay',
|
|
349
|
+
plugins: {
|
|
350
|
+
pluginACode: window.pluginACode,
|
|
351
|
+
},
|
|
352
|
+
errorHandlers: {
|
|
353
|
+
token: (error) => {
|
|
354
|
+
console.error(error);
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## MCP 注册
|
|
361
|
+
|
|
362
|
+
MCP Server 信息可以在[行业 AI 平台](https://copilot.glodon.com/)的【MCP 管理 - MCP 详情】中获得。
|
|
363
|
+
|
|
364
|
+
### 全局作用的 MCP 注册
|
|
365
|
+
|
|
366
|
+
全局作用的 MCP 注册的完整代码如下:
|
|
367
|
+
|
|
368
|
+
```javascript
|
|
369
|
+
import BotClientUI from '@glodon-aiot/bot-client-ui';
|
|
370
|
+
|
|
371
|
+
new BotClientUI({
|
|
372
|
+
token: 'aiot_resource_token_goes_here',
|
|
373
|
+
getContainer: () => document.getElementById('agent-ui'),
|
|
374
|
+
mode: 'inlay',
|
|
375
|
+
mcp: {
|
|
376
|
+
mcpServers: {
|
|
377
|
+
mcpServer_ID: {
|
|
378
|
+
type: 'sse',
|
|
379
|
+
url: 'https://copilot.glodon.com/proxy/XXXX/mcp/XXXX/mcp-mcpServer_ID/XXXX/sse',
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
errorHandlers: {
|
|
384
|
+
token: (error) => {
|
|
385
|
+
console.error(error);
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
});
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### 为当前会话注册 MCP
|
|
392
|
+
|
|
393
|
+
为当前会话注册 MCP 的完整代码如下:
|
|
394
|
+
|
|
395
|
+
```javascript
|
|
396
|
+
import BotClientUI from '@glodon-aiot/bot-client-ui';
|
|
397
|
+
|
|
398
|
+
const botClientUI = new BotClientUI({
|
|
399
|
+
token: 'aiot_resource_token_goes_here',
|
|
400
|
+
getContainer: () => document.getElementById('agent-ui'),
|
|
401
|
+
mode: 'inlay',
|
|
402
|
+
errorHandlers: {
|
|
403
|
+
token: (error) => {
|
|
404
|
+
console.error(error);
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
eventListeners: {
|
|
408
|
+
sessionload: ({ sessionInstance }) => {
|
|
409
|
+
if (sessionInstance) {
|
|
410
|
+
// MCP注册方法
|
|
411
|
+
const addMCP = () => {
|
|
412
|
+
sessionInstance.addMcpServer({
|
|
413
|
+
mcpServers: {
|
|
414
|
+
mcpServer_ID: {
|
|
415
|
+
type: 'sse',
|
|
416
|
+
url: 'https://copilot.glodon.com/proxy/XXXX/mcp/XXXX/mcp-mcpServer_ID/XXXX/sse',
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
// 只能在ready事件发生后才可以注册MCP
|
|
423
|
+
sessionInstance.addEventListener('ready', addMCP);
|
|
424
|
+
// session不活跃之后移除事件监听
|
|
425
|
+
sessionInstance.addEventListener('inactivated', () =>
|
|
426
|
+
sessionInstance.removeEventListener('ready', addMCP)
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
});
|
|
432
|
+
```
|