UNPKG

@glodon-aiot/bot-client-ui

Version:

aiot libembeds

452 lines (382 loc) 17.1 kB
# 安装依赖 ## 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) ); } }, }, }); ```