# Embed SDK(Web 嵌入式对话组件)技术方案 > 状态:**已实现并上线**(产物 `desktop/public/embed/mao-chat.js`)。本文档为设计依据;实现细节以源码 `sdk/embed/` 为准,行为差异见 `docs/plan/2026-09-04-embed-sdk-review.md`。 ## 1. 需求背景 Mao 的 agent 对话能力目前已覆盖 desktop(Electron / Web)、android 壳、agent-cli(mao-agent)、weixin / feishu bot。但内部 Web 业务系统想把 agent 对话能力嵌入自己的页面时,没有任何轻量途径——要么引导用户跳转 Mao,要么整页复制 desktop。 本需求提供 **Web Embed SDK**:内部 Web 系统引入一个脚本文件、调用一次 `MaoChat.init()`,页面即出现浮动入口按钮,点击展开对话浮窗,终端用户可与 Mao agent 就当前页面内容进行完整对话(含流式输出、思考过程、工具执行状态、追问回答、手动停止;工具审批仅 LOCAL 链路存在,embed 会话默认 CLOUD,无审批环节)。 ### 已否决的备选方案 - **iframe 浮窗方案**(desktop 加 `/embed/chat` 路由 + 引导脚本):实现最省,但 SDK 无法沉淀为独立交付物与公开 API 契约,后继向任意第三方站开放时宿主侧要推倒重来。已否决,但 iframe 方案的 `getToken()` / `context()` API 设计被本方案继承。 - **Headless SDK**(只输出协议与状态,宿主自绘 UI):维护成本转嫁给每个接入方,不符合"一行接入"目标。已否决。 ## 2. 需求描述 ### 2.1 宿主接入形态(长期契约) ```html ``` ### 2.2 功能范围 - 浮动按钮:右下角固定,展示运行状态(空闲 / 执行中转圈 / 需要处理红点)。 - 对话浮窗:Shadow DOM 挂载,含消息流(用户气泡 / 助手正文平铺、Markdown 渲染、思考过程折叠、工具调用状态卡片)、文本输入框、发送、**手动停止执行**、"新对话"按钮、错误与重连提示。 - 视觉语言对齐 Mao 桌面端(`desktop/src/style.css`):默认主色 `#0066cc`,发丝级描边 + 分层柔和阴影 + 8/10/14/16px 圆角阶梯。`theme.primary` 覆写后 hover 色、浅底色、聚焦环由 `color-mix` 按主色重算(不支持 `color-mix` 的浏览器落回静态默认值)。动效遵循 `prefers-reduced-motion`。 - 注:工具审批仅存在于 LOCAL 执行链路(Electron 客户端弹窗处理),embed 会话默认 CLOUD、服务端执行工具,无审批环节,浮窗不提供审批 UI。 - 追问卡片:`ask_user_questions` 事件驱动,浮窗内作答并回传。 - 页面上下文:`context()` 返回值做变更检测,变化时以引用块前缀拼入下一条用户消息;宿主页面选中文本自动出现"讨论:xxx"引用 chip。 - 会话:每 (用户, agent) 一个常驻会话,sessionId 持久化于 localStorage,仅复用 SDK 自己创建的会话;desktop 端会话列表可见该会话并可继续(共享列表作为跨端连续性 feature 保留)。 - 懒连接:首次展开浮窗才建立 WS;发送时若连接不在则走重连兜底(同 desktop `sendReliable` 语义)。 ### 2.3 身份与集成约定 - 终端用户即 Mao 账号用户,**复用 Mao JWT**,SDK 不新增鉴权体系。 - **refresh token 不进浏览器**:宿主后端持有 Mao 凭据(或代登录 `/api/v1/auth/login`),仅向页面发放短期 access token;SDK 只通过 `getToken()` 取值,内存持有,401 / WS 鉴权失败时重新调用 `getToken()`,**不落 localStorage / sessionStorage**。 - token 生命周期、续期、注销责任在宿主;SDK 无状态。 ## 3. 技术选型 | 项 | 选型 | 理由 | |---|---|---| | UI 框架 | Vue 3(SDK 内置 runtime)+ Shadow DOM | 复用 desktop 渲染层经验;Vue 3 对 Shadow DOM 支持成熟 | | 构建 | Vite lib mode,产物 IIFE 单文件 + ESM 双格式,样式构建期内联注入 Shadow DOM | 与 desktop 工具链一致;`