@glodon-aiot/bot-client-ui
Version:
aiot libembeds
452 lines (382 loc) • 17.1 kB
Markdown
# 安装依赖
## npm
`npm install @glodon-aiot/bot-client-ui`
## yarn
`yarn add @glodon-aiot/bot-client-ui`
安装后即可使用,**无需**再单独安装 `react`、`react-dom`、`antd` 等依赖(默认入口已内置于构建产物中)。
无论宿主是 React、Vue 还是原生 JS,**接入方式完全一致**:导入类并 `new` 实例化,组件会渲染到 `getContainer()` 返回的 DOM 节点中,与宿主框架无关。默认入口会打包底层依赖(含 React),适合开箱即用。
若你的宿主工程对 bundle 体积敏感,并且已统一管理 `@glodon-aiot/agent-cli-ui` / React 依赖,可使用去重版入口:
```javascript
import BotClientUI from '@glodon-aiot/bot-client-ui/external';
```
## 入口选型建议
- 默认推荐:`@glodon-aiot/bot-client-ui`
- 适合 Vue / 原生 JS / 多技术栈宿主,开箱即用、零额外构建配置。
- 依赖已内置,宿主不需要单独处理 `react` / `react-dom` 解析。
- 体积优先:`@glodon-aiot/bot-client-ui/external`
- 适合大型 React 宿主(或微前端主应用)希望与现有依赖统一去重。
- 该入口会外置 `@glodon-aiot/agent-cli-ui`,最终体积取决于宿主的依赖管理与打包策略。
## 从 cdn 引入 cjs 文件
一些项目无法处理 esm,请使用以下方式引入依赖。BotClientUI 将被注册在 window 对象上。
`<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>`
# 快速开始
## 初始化
```javascript
import BotClientUI from '@glodon-aiot/bot-client-ui';
new BotClientUI({
token: 'aiot_resource_token_goes_here',
getContainer: () => document.getElementById('client-ui'),
errorHandlers: {
token: (error) => {
console.error(error);
},
},
});
```
## 在线预览:
- 对话型应用 Demo [https://code.juejin.cn/pen/7494170871938940966](https://code.juejin.cn/pen/7494170871938940966)
- Agent Demo [https://code.juejin.cn/pen/7372449505322467363](https://code.juejin.cn/pen/7372449505322467363)
# BotClientUI 构造配置
## 通用配置
| 名称 | 类型 | 必填 | 默认值 | 说明 | 适用应用类型 | 支持版本 |
| -------------- | ----------------------------- | ------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | ---------- |
| token | string | 是 | - | aiot 行业 AI 平台的 AI 应用的 resource token。详情查看[认证说明](https://glodon-cv-help.yuque.com/lzh2bp/eszzb5/evk1gvh3pqaexe74?singleDoc#%20《认证说明》)。 | 全部 | |
| apiUrl | string | 否 | `https://copilot.glodon.com/api/cvforce` | 拼接规则:`${origin}/api/cvforce`,其中`origin`是部署服务的源地址。 | 全部 | 3.0.8 |
| getContainer | () => Element | 否 | () => document.body | 容器元素获取方法,默认在 document.body 中渲染 | 全部 | |
| sessionId | string | 否 | - | 默认加载的会话 ID | Agent/对话 | |
| mode | `'float' \| 'inlay'` | 否 | 'float' | 悬浮按钮模式,或者嵌入模式 | Agent/对话 | |
| header | `Element \| string \| boolean` | 否 | - | 应用名称 | Agent/对话 | |
| footer | `Element \| string \| boolean` | 否 | - | 页脚内容 | Agent/对话 | |
| sider | boolean | 否 | | inlay 模式可用。 是否展示左侧会话列表 | Agent/对话 | |
| icon | string | 否 | | 影响 greeting 和 triggerButton 的 icon | Agent/对话 | 3.3.1 |
| size | [SizeConfig](#GbxmJ) | 否 | {width: 450} | float 模式下:窗体大小 | 全部 | |
| open | boolean | 否 | false | float 模式下:默认打开状态 | Agent/对话 | |
| triggerButton | [TriggerButtonConfig](#djhoc) | 否 | {visible: true} | triggerButton 设置 | Agent/对话 | |
| features | [Features](#uIpxC) | 否 | FEATURE_DEFAULT | 功能配置 | Agent/对话 | |
| debug | boolean | 否 | false | 打开 debug 模式时:<br/>1. 控制 log 输出。 2. promptValues 变为非必填项; 3. Agent 类型应用下,控制 ws 连接是否开启,debug 模式,由于收到权限限制,可能会配置失败。 | Agent/对话 | |
| eventListeners | [EventListeners](#IhvdK) | | | 事件监听器配置 | Agent/对话 | |
| errorHandlers | [ErrorHandlers](#VTONU) | 否 | - | errorHandlers.token 是 token 验证失败后的处理器; errorHandlers.promptValues 非 debug 模式下,检测空值 | 全部 | |
## 只适用于 Agent 应用的配置
| 名称 | 类型 | 必填 | 默认值 | 说明 |
| ------- | ------------- | ---- | ------ | ----------------------------------------------------------------------------------------------------------------- |
| plugins | PluginsConfig | 否 | - | Agent 应用适用。<br/>插件列表,`pluginCode`与`functionCode`要与平台中注册的插件标识和 API 名称保持一致 |
| mcp | McpConfig | 否 | - | Agent 应用适用。<br/>这里注册的 MCP 作用到每个会话中。<br/>如果希望特定会话才可注册 MCP,则在会话加载后动态注册。 |
# BotClientUI 实例 API
| 名称 | 类型 | 说明 |
| -------------- | -------------------------------------------- | ------------------ |
| reload | `() => void` | |
| activeSession | `Session` | 当前活跃的会话信息 |
| input | `(message:string) => void` | 填充输入框内容 |
| getMessageList | `(sessionId?: string) => Promise<Message[]>` | 获取历史对话列表 |
# 类型定义
## 基础类型
```typescript
interface SizeConfig {
width?: number | string;
height?: number | string;
maxWidth?: number | string;
maxHeight?: number | string;
minWidth?: number | string;
minHeight?: number | string;
}
interface TriggerButtonConfig {
style: string;
visible: boolean;
}
interface SessionInfo {
id: string;
name: string;
}
interface Message {
messageId: string;
content: string;
role: ChatMessageRole;
sessionId: string;
reference: IReference[];
searchReference: ISearchRefernce[];
messageTime: string;
}
enum ChatMessageRole {
Robot = 1,
User = 2,
System = 3,
}
interface IReference {
text: string;
docId: string;
fileId: string;
fileName: string;
knowledgeId: string;
knowledgeName: string;
score: number;
nickname: string;
knowledgeSourceName: string;
}
interface ISearchRefernce {
link: string;
title: string;
snippet: string;
}
interface SessionPrompt {
id?: string;
key: string;
name?: string;
value: string;
status?: PromptStatus;
}
interface Knowledge {
id: string;
}
```
## 功能配置
```typescript
interface Feature {
// 问候
greeting?:
| boolean
| {
icon?: string;
text?: string; // 问候语
questions?: boolean; // 推荐问题
layoutBreakpoints?: number[]; // 布局断点数组
};
// toolbar中的"会话历史记录"
sessionList?: boolean;
// toolbar中的"新会话"
newSession?: boolean; // dialog only
// toolbar中的"上传文件"
fileUpload?: boolean; // dialog only
// toolbar中的"上传图片"
imageUpload?: boolean; // agent only
// 问题气泡
userMessageBox?: {
// dialog only
copy?: boolean;
editAgain?: boolean;
};
// 回答气泡
botMessageBox?: {
// dialog only
// 参考列表前置
referenceFirst?: boolean;
// 参考列表元素设置
reference?: {
// 是否可查看参考源文件
file?: boolean;
// 是否展开参考内容
itemExpanded?: boolean;
};
// 是否展示相关问题
relatedQuesions: boolean;
// 回答气泡底部设置
footer: {
items: {
componentName: 'AnswerAgain' | 'Copy' | 'Comments';
position: 'left' | 'right';
}[];
};
};
prompts?: boolean;
// toolbar中的网络访问
connectNetwork?:
| boolean
| { visible: boolean; default?: boolean; disabled?: boolean };
// 参考知识库设置
knowledges?:
| boolean
| { visible: boolean; default: Knowledge[]; disabled?: boolean };
// 用户指令变量设置
promptVariables?: boolean | { visible: boolean; default: SessionPrompt[] };
// 支持自定义问答内容markdown的超链接元素的点击事件
markdown?: {
componentProps?: {
a?: {
onClick?: (e: { nativeEvent: PointerEvent }) => void;
};
};
};
}
```
## 事件与错误处理
```typescript
interface EventListeners {
comment: (payload: {
applicationId: string;
sessionId: string;
comment: Comment;
}) => void;
sessionload: (payload: {
applicationId: string;
sessionId: string;
session: SessionInfo;
sessionInstance: Session;
}) => void;
message: (payload: {
applicationId: string;
sessionId: string;
message: Message;
}) => void;
beforemessagesend: (payload: {
applicationId: string;
sessionId: string;
message: Message;
}) => boolean | Partil<Message> | Promise<boolean | Partil<Message>>;
}
interface ErrorHandlers {
token: (error: any) => void;
promptValues?: (error: any, values: { key: string; value: string }[]) => void;
}
```
## Agent 应用配置
### 插件配置
```typescript
interface PluginsConfig {
[pluginCode: string]: {
[functionCode: string]: Function;
};
}
interface McpServer {
type: 'sse';
url: string;
headers?: Record<string, string>;
}
interface McpConfig {
mcpServers: {
[key: string]: McpServer;
};
}
```
### MCP 配置
```typescript
interface McpServer {
type: 'sse';
url: string;
headers?: Record<string, string>;
}
interface McpConfig {
mcpServers: {
[key: string]: McpServer;
};
}
```
# Agent 类型应用的特别说明
## 客户端插件使用
由于该类型应用一般被当作某个软件的助手使用,需要主体软件在浏览器上注册一些方法,作为与浏览器交互的桥梁。
例如,有客户端`Plugin A`,注册插件如下代码。
其中,`pluginACode`是插件标识,可以在[行业 AI 平台](https://copilot.glodon.com/)的【插件管理 - 插件详情】中获得,不支持自定义。`functionCode`对应的是`API名称`,可自定义。
```javascript
window.pluginACode = {
functionCode1: (params, cb) => {
console.log(
`模拟pluginA function1 执行\n执行入参\n${JSON.stringify(arguments)}`
);
setTimeout(() => {
console.log(`模拟pluginA function1 执行完成`);
cb({
code: 0,
message: 'function1运行成功',
data: {
a: 'a',
b: 2,
},
});
}, 5000);
},
functionCode2: (params, cb) => {
console.log(
`模拟pluginA function2 执行\n执行入参\n${JSON.stringify(arguments)}`
);
setTimeout(() => {
console.log(`模拟pluginA function2 执行完成`);
cb({
code: 0,
message: 'function2运行成功',
data: {
a: 'a',
b: 2,
},
});
}, 10000);
},
};
```
创建 Agent 应用 UI 的时候,配置`plugins`属性。完整代码如下:
```javascript
import BotClientUI from '@glodon-aiot/bot-client-ui';
new BotClientUI({
token: 'aiot_resource_token_goes_here',
getContainer: () => document.getElementById('agent-ui'),
mode: 'inlay',
plugins: {
pluginACode: window.pluginACode,
},
errorHandlers: {
token: (error) => {
console.error(error);
},
},
});
```
## MCP 注册
MCP Server 信息可以在[行业 AI 平台](https://copilot.glodon.com/)的【MCP 管理 - MCP 详情】中获得。
### 全局作用的 MCP 注册
全局作用的 MCP 注册的完整代码如下:
```javascript
import BotClientUI from '@glodon-aiot/bot-client-ui';
new BotClientUI({
token: 'aiot_resource_token_goes_here',
getContainer: () => document.getElementById('agent-ui'),
mode: 'inlay',
mcp: {
mcpServers: {
mcpServer_ID: {
type: 'sse',
url: 'https://copilot.glodon.com/proxy/XXXX/mcp/XXXX/mcp-mcpServer_ID/XXXX/sse',
},
},
},
errorHandlers: {
token: (error) => {
console.error(error);
},
},
});
```
### 为当前会话注册 MCP
为当前会话注册 MCP 的完整代码如下:
```javascript
import BotClientUI from '@glodon-aiot/bot-client-ui';
const botClientUI = new BotClientUI({
token: 'aiot_resource_token_goes_here',
getContainer: () => document.getElementById('agent-ui'),
mode: 'inlay',
errorHandlers: {
token: (error) => {
console.error(error);
},
},
eventListeners: {
sessionload: ({ sessionInstance }) => {
if (sessionInstance) {
// MCP注册方法
const addMCP = () => {
sessionInstance.addMcpServer({
mcpServers: {
mcpServer_ID: {
type: 'sse',
url: 'https://copilot.glodon.com/proxy/XXXX/mcp/XXXX/mcp-mcpServer_ID/XXXX/sse',
},
},
});
};
// 只能在ready事件发生后才可以注册MCP
sessionInstance.addEventListener('ready', addMCP);
// session不活跃之后移除事件监听
sessionInstance.addEventListener('inactivated', () =>
sessionInstance.removeEventListener('ready', addMCP)
);
}
},
},
});
```