feat: ship enterprise control and desktop governance
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
# Codex Desktop 同线程消息镜像设计
|
||||
|
||||
目标:当用户在 Boss App 里对一个已绑定 `codexThreadRef` 的单线程会话发消息时,这条用户消息不仅进入 Boss 自己的项目账本和 `conversation_reply` 执行队列,也要被镜像进本机 Codex Desktop 的同一个线程历史里。这样用户稍后回到 Codex Desktop,看见的是同一个线程下连续的聊天记录,而不是 Boss 与 Desktop 两套割裂历史。
|
||||
|
||||
## 背景与现状
|
||||
|
||||
当前 Boss 的普通线程单聊主链是:
|
||||
|
||||
- Web / Android 调 `POST /api/v1/projects/[projectId]/messages`
|
||||
- 服务端写入 Boss 项目消息账本
|
||||
- 服务端排一个 `conversation_reply` 任务
|
||||
- 本机 `local-agent` 认领任务后调用 `codex exec resume <targetCodexThreadRef>`
|
||||
- Codex 线程完成后,再把线程回复回写到 Boss 项目账本
|
||||
|
||||
这条链现在已经能做到“Desktop 回复被 Boss 看见”,因为 heartbeat 扫描 `~/.codex/sessions/.../rollout-*.jsonl` 时,会把最近桌面 assistant 回复镜像回 Boss。缺口在反方向:
|
||||
|
||||
- Boss App 发起的用户消息只存在于 Boss 项目账本
|
||||
- `codex exec resume` 虽然会把 prompt 交给目标线程继续执行,但 Boss 发起的这条消息并不会先出现在 Desktop 线程历史
|
||||
- 结果就是用户在 APP 和 Desktop 里看到的“同一个线程”并不是同一份完整聊天记录
|
||||
|
||||
## 方案对比
|
||||
|
||||
### 方案 1:直接操控 Codex Desktop GUI 输入并发送
|
||||
|
||||
优点:
|
||||
|
||||
- 理论上最贴近“像用户在桌面端亲自发了一条消息”
|
||||
|
||||
缺点:
|
||||
|
||||
- 依赖窗口前台、焦点、输入法、系统权限
|
||||
- 极易被 Codex Desktop UI 更新打断
|
||||
- 无法稳定支持后台运行和多线程并发
|
||||
|
||||
不推荐作为主方案。
|
||||
|
||||
### 方案 2:直接把 Boss 用户消息写入对应 Codex rollout JSONL,再继续现有 `codex exec resume`
|
||||
|
||||
优点:
|
||||
|
||||
- 与当前 Desktop/CLI 共用的真实线程存储一致
|
||||
- 不需要操控 GUI
|
||||
- 可以保持现有 `local-agent -> codex exec resume` 主链不变
|
||||
- 能与现有 heartbeat 读取 rollout 的能力形成闭环
|
||||
|
||||
缺点:
|
||||
|
||||
- 需要谨慎贴合 Codex rollout 事件格式
|
||||
- 需要处理重复写入和 Desktop 刷新感知
|
||||
|
||||
这是本次推荐方案。
|
||||
|
||||
### 方案 3:单独给 Desktop 再建一条镜像线程
|
||||
|
||||
优点:
|
||||
|
||||
- 对现有线程文件侵入最小
|
||||
|
||||
缺点:
|
||||
|
||||
- 用户要的是“同一个线程”,不是“另一个镜像线程”
|
||||
- 历史会继续分叉
|
||||
|
||||
不满足目标。
|
||||
|
||||
## 本次设计
|
||||
|
||||
### 1. 保持 Boss 账本为移动端/UI 主真相
|
||||
|
||||
Boss 的项目消息账本、会话排序、未读数、主 Agent 协同逻辑继续基于现有 `boss-state.json`。这次不把 Boss UI 改成直接读取 `~/.codex`。
|
||||
|
||||
### 2. 对单线程 `conversation_reply` 任务增加“写入 Desktop 线程历史”的镜像步骤
|
||||
|
||||
当任务满足以下条件时,在 `local-agent` 侧做一次 rollout 镜像:
|
||||
|
||||
- `task.taskType === "conversation_reply"`
|
||||
- 存在 `targetCodexThreadRef`
|
||||
- 存在用户原始消息文本
|
||||
- 不属于 `relayViaMasterAgent === true` 的接管中转任务
|
||||
|
||||
镜像行为:
|
||||
|
||||
- 优先通过 `state_5.sqlite` 的 `threads.rollout_path` 定位目标 rollout 文件
|
||||
- 如果本机 Codex 因版本/迁移差异无法稳定解析 `state_5.sqlite`,则回退扫描 `~/.codex/sessions/**/rollout-*-<threadId>.jsonl`
|
||||
- 向该 rollout 文件追加一组 Codex 用户消息记录:`response_item / message(role=user)` 和 `event_msg / user_message`
|
||||
- 事件内容使用 Boss 原始用户消息文本,而不是执行 prompt
|
||||
- 事件时间优先使用 Boss 消息的 `sentAt`
|
||||
- 事件写入成功后,再继续现有 `codex exec resume`
|
||||
|
||||
### 3. 任务负载补齐“Boss 原始消息”字段
|
||||
|
||||
现在任务里只有:
|
||||
|
||||
- `requestMessageId`
|
||||
- `requestText`
|
||||
- `executionPrompt`
|
||||
|
||||
这还不够稳,因为后续去重和 Desktop 镜像需要区分:
|
||||
|
||||
- 哪条 Boss 用户消息已经镜像过
|
||||
- 这次镜像的真实显示文本是什么
|
||||
- 这条消息的原始时间戳是什么
|
||||
|
||||
因此为 `MasterAgentTask` 增加:
|
||||
|
||||
- `sourceMessageId?: string`
|
||||
- `sourceMessageBody?: string`
|
||||
- `sourceMessageSentAt?: string`
|
||||
- `mirrorBossUserMessageToCodexDesktop?: boolean`
|
||||
|
||||
对普通线程单聊:
|
||||
|
||||
- `sourceMessageId = message.id`
|
||||
- `sourceMessageBody = message.body`
|
||||
- `sourceMessageSentAt = message.sentAt`
|
||||
- `mirrorBossUserMessageToCodexDesktop = true`
|
||||
|
||||
对主 Agent 直聊、`@主Agent`、托管中转等不应写进子线程 Desktop 历史的场景,不开启这个标记。
|
||||
|
||||
### 4. 去重策略
|
||||
|
||||
同一条 Boss 消息可能因为:
|
||||
|
||||
- 任务重试
|
||||
- local-agent 重启
|
||||
- claim / complete 重放
|
||||
|
||||
而被多次处理。为避免在 Desktop 线程里重复写入同一条用户消息,本次采用“rollout 末尾去重”:
|
||||
|
||||
- 生成稳定镜像 key:`boss-user:<threadRef>:<sourceMessageId>`
|
||||
- 写入的 `event_msg` 中带上 `payload.metadata.bossSourceMessageId`
|
||||
- 写入前读取 rollout 尾部固定窗口,检查最近是否已经存在同一 `bossSourceMessageId`
|
||||
- 若存在,则跳过写入,仅继续 `codex exec resume`
|
||||
|
||||
这样不需要引入新的状态库,也能与 Codex 原始线程文件保持局部自洽。
|
||||
|
||||
### 5. 刷新感知
|
||||
|
||||
第一版只写 rollout 还不够稳,因为 Desktop 的线程列表排序和“最近活跃”判断通常还依赖 `threads.updated_at / updated_at_ms / has_user_event`。因此本次实现改为:
|
||||
|
||||
- rollout append 成功后,若 `state_5.sqlite` 可写且能命中该 thread,则同步刷新:
|
||||
- `updated_at`
|
||||
- `updated_at_ms`
|
||||
- `has_user_event = 1`
|
||||
- 如果当前机器上的 Codex 状态库不可用、字段不兼容或压根没有这条 thread 记录,则只保留 rollout 写入,不把整条消息链路判成失败
|
||||
|
||||
这样做的取舍是:
|
||||
|
||||
- 先保证 Boss -> Codex Desktop 同线程历史不丢
|
||||
- 再尽可能提升 Desktop 侧的列表刷新和最近活跃感知
|
||||
- 不引入 GUI 自动化,不依赖桌面窗口前台
|
||||
|
||||
## 涉及文件
|
||||
|
||||
- 新增 `local-agent/codex-thread-rollout-writer.mjs`
|
||||
- 修改 `local-agent/codex-task-runner.mjs`
|
||||
- 修改 `local-agent/server.mjs`
|
||||
- 修改 `src/lib/boss-data.ts`
|
||||
- 修改 `src/app/api/v1/projects/[projectId]/messages/route.ts`
|
||||
- 修改 `src/lib/boss-master-agent.ts`(如果当前普通线程任务创建逻辑在这里有共用 helper,也一起补齐)
|
||||
- 新增测试 `tests/local-agent-codex-rollout-writer.test.mjs`
|
||||
- 修改测试 `tests/local-agent-codex-task-runner.test.mjs`
|
||||
- 修改测试 `tests/single-thread-message-execution.test.ts`
|
||||
|
||||
## 边界
|
||||
|
||||
- 本次只处理“Boss App -> 已绑定 Codex Desktop 同线程”的用户消息镜像
|
||||
- 不处理群聊镜像到 Desktop
|
||||
- 不处理主 Agent 自己的回复写入 Desktop 子线程
|
||||
- 不做 Codex Desktop GUI 自动输入
|
||||
- 不把 Boss 会话列表直接改成读取 Desktop 原始线程文件
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 普通单线程会话发消息后,生成的 `conversation_reply` 任务带有完整 `sourceMessage*` 字段
|
||||
- local-agent 在执行 `codex exec resume` 前,能把这条 Boss 用户消息写进目标 rollout
|
||||
- 同一 `sourceMessageId` 重试时不会重复写入 rollout
|
||||
- 若状态库可用,镜像后会同步刷新 thread 的活跃时间和 `has_user_event`
|
||||
- 若状态库不可用或这台机器上的线程索引不完整,仍可通过 `sessions` 回退找到 rollout 并完成消息镜像
|
||||
- 现有普通线程回复链不回归,Boss 仍能收到 Codex 线程回复
|
||||
- 若目标线程缺失、只读或 cwd 不合法,仍保持现有 fail-closed 行为
|
||||
@@ -0,0 +1,399 @@
|
||||
# Boss 聊天统一电脑控制中枢设计
|
||||
|
||||
目标:让用户在 Boss App 里,无论是和 `主 Agent` 对话,还是和某个具体线程对话,都可以稳定驱动这台 Mac/Windows 设备完成三类事情:
|
||||
|
||||
- 项目开发与代码执行
|
||||
- 浏览器/桌面 GUI 操作
|
||||
- 普通产品讨论、调研和任务协同
|
||||
|
||||
并且这三类能力不再割裂成几条旁路,而是统一挂在 Boss 现有的聊天、执行底座和设备心跳体系下面。
|
||||
|
||||
## 背景与现状
|
||||
|
||||
当前 Boss 已经具备几条关键基础链路:
|
||||
|
||||
- `master-agent` 单聊可以通过 `local-agent -> codex exec` 真实产出回复
|
||||
- 普通单线程聊天已经可以排 `conversation_reply` 任务,并恢复到真实 Codex 线程执行
|
||||
- 群聊已有 `group_dispatch_plan -> dispatch_execution` 的编排链
|
||||
- 设备模型已经支持同一台机器的 `GUI + CLI` 双能力声明与默认执行模式切换
|
||||
- 本机 `local-agent` 已能做 Codex 线程发现、task claim、task complete、Desktop rollout 镜像
|
||||
|
||||
但目前缺的不是“再加一个按钮”,而是统一控制中枢:
|
||||
|
||||
- `conversation_reply` 只适合“把消息转给 Codex 线程继续聊”
|
||||
- `dispatch_execution` 主要面向群聊下发和线程编排
|
||||
- 还没有正式的“桌面控制 / 浏览器控制”任务类型
|
||||
- 主 Agent 也没有显式的能力路由模型,无法稳定判断当前消息应该走:
|
||||
- Codex 开发
|
||||
- Browser automation
|
||||
- Computer Use
|
||||
- 单纯讨论/总结
|
||||
|
||||
这会导致现在的体验像“能做一些事”,但还不是“可以靠 Boss 聊天控制电脑做事”。
|
||||
|
||||
## 目标边界
|
||||
|
||||
### 本次要达到的能力
|
||||
|
||||
1. 主 Agent 能把用户消息识别成四类执行意图:
|
||||
- `project_development`
|
||||
- `thread_collaboration`
|
||||
- `browser_control`
|
||||
- `desktop_control`
|
||||
|
||||
2. Boss 执行底座能显式表达这四类请求,并把它们路由到正确 runtime。
|
||||
|
||||
3. `local-agent` 增加两条新 runtime:
|
||||
- `browser-automation-runtime`
|
||||
- `computer-use-runtime`
|
||||
|
||||
4. Web / Android 前台至少能拿到任务执行方式和当前状态,知道这条消息是:
|
||||
- 交给 Codex 线程
|
||||
- 交给浏览器自动化
|
||||
- 交给桌面控制
|
||||
- 仅由主 Agent 直接回复
|
||||
|
||||
5. 对高风险桌面动作建立最小确认机制,避免“发一句话就直接在电脑上乱点/乱删”。
|
||||
|
||||
### 本次不做的事情
|
||||
|
||||
- 不做完整远控桌面产品
|
||||
- 不做视频流式屏幕回传
|
||||
- 不做跨设备键鼠镜像
|
||||
- 不把 Codex Desktop 自己纳入 Computer Use 自动点击目标
|
||||
- 不依赖 GUI 自动化去操控 Codex 自己的窗口
|
||||
|
||||
## 方案原则
|
||||
|
||||
### 原则 1:复用 Boss 现有执行底座,不另起一套“远控系统”
|
||||
|
||||
如果我们再单独造一层 `remote-control service`,会把:
|
||||
|
||||
- 会话账本
|
||||
- 任务队列
|
||||
- 权限与确认
|
||||
- 前台状态展示
|
||||
- 设备能力发现
|
||||
|
||||
全部再复制一遍。成本高,而且会和当前 Boss 的“聊天即控制入口”相冲突。
|
||||
|
||||
所以本次明确采用:
|
||||
|
||||
- 用户入口仍然是 Boss 聊天
|
||||
- 任务记录仍然是 `MasterAgentTask`
|
||||
- 路由仍然收敛进 `src/lib/execution`
|
||||
- 执行仍然由绑定设备上的 `local-agent` 落地
|
||||
|
||||
### 原则 2:先把“控制判断”标准化,再扩 runtime
|
||||
|
||||
现在最大的问题不是工具不够,而是没有统一的“这条消息该怎么执行”判断结果。
|
||||
|
||||
因此要先补一层执行意图:
|
||||
|
||||
- `discussion_only`
|
||||
- `thread_reply`
|
||||
- `browser_control`
|
||||
- `desktop_control`
|
||||
- `development_execution`
|
||||
|
||||
然后让不同后端只关心自己该执行哪一种。
|
||||
|
||||
### 原则 3:危险动作永远要显式分级
|
||||
|
||||
Boss 最终要能“做任何事”,但不能把“任何事”理解成“任何时候都自动执行”。
|
||||
|
||||
所以本次引入最小风险分级:
|
||||
|
||||
- `low`
|
||||
- 打开页面
|
||||
- 搜索信息
|
||||
- 读取项目文件
|
||||
- 运行只读检查
|
||||
- `medium`
|
||||
- 登录态网页操作
|
||||
- 浏览器表单提交
|
||||
- 桌面应用点击导航
|
||||
- 修改非代码业务内容
|
||||
- `high`
|
||||
- 删除/覆盖文件
|
||||
- 系统设置改动
|
||||
- 批量提交/发布
|
||||
- 不可逆外部操作
|
||||
|
||||
策略:
|
||||
|
||||
- `low`:默认直接执行
|
||||
- `medium`:默认轻确认,可在项目/会话级放行
|
||||
- `high`:必须明确确认
|
||||
|
||||
## 控制中枢设计
|
||||
|
||||
## 1. 新的执行意图模型
|
||||
|
||||
在当前 `ExecutionRequestKind` 基础上新增:
|
||||
|
||||
- `browser_control`
|
||||
- `desktop_control`
|
||||
|
||||
并补充一个统一意图字段,供主 Agent 和前台共用:
|
||||
|
||||
- `intentCategory`
|
||||
- `discussion_only`
|
||||
- `project_development`
|
||||
- `thread_collaboration`
|
||||
- `browser_control`
|
||||
- `desktop_control`
|
||||
|
||||
其中:
|
||||
|
||||
- `project_development` 继续优先走现有 Codex 线程 / CLI 执行链
|
||||
- `thread_collaboration` 继续走 `conversation_reply`
|
||||
- `browser_control` 新增浏览器自动化 runtime
|
||||
- `desktop_control` 新增 Computer Use runtime
|
||||
|
||||
## 2. 新的 runtime 层
|
||||
|
||||
### 2.1 browser-automation-runtime
|
||||
|
||||
用途:
|
||||
|
||||
- 打开网页
|
||||
- 登录指定后台
|
||||
- 提交表单
|
||||
- 抓取页面信息
|
||||
- 复现 Web bug
|
||||
|
||||
第一版实现直接复用现有 Playwright 能力,不重新造驱动协议。
|
||||
|
||||
建议协议:
|
||||
|
||||
- 输入:
|
||||
- `taskId`
|
||||
- `projectId`
|
||||
- `requestText`
|
||||
- `executionPrompt`
|
||||
- `targetUrl?`
|
||||
- `riskLevel`
|
||||
- 输出:
|
||||
- `status`
|
||||
- `replyBody`
|
||||
- `structuredResult?`
|
||||
- `artifacts?`
|
||||
|
||||
落地约束:
|
||||
|
||||
- `local-agent/browser-control-task-runner.mjs` 先收口成外部 runtime 桥,不把 Playwright 逻辑硬编码进 `server.mjs`
|
||||
- 通过 `browserControlEnabled / browserControlCommand / browserControlArgs / browserControlWorkdir / browserControlTimeoutMs` 配置启用
|
||||
- runtime 进程只需要遵守单行 JSON stdout 协议,后续可以平滑替换成真实 Playwright/OpenClaw/browser adapter
|
||||
|
||||
### 2.2 computer-use-runtime
|
||||
|
||||
用途:
|
||||
|
||||
- 打开本机应用
|
||||
- 在桌面 GUI 上点击、输入、切换
|
||||
- 配合浏览器外的桌面软件完成操作
|
||||
|
||||
第一版实现直接对接 Codex App 现有的 Computer Use 能力约束:
|
||||
|
||||
- 只能操作普通桌面应用
|
||||
- 需要系统 Screen Recording + Accessibility
|
||||
- 不把终端/Codex 自己当作自动点击目标
|
||||
|
||||
这意味着:
|
||||
|
||||
- 项目开发仍然优先走 Codex CLI/线程
|
||||
- Computer Use 负责 GUI 世界
|
||||
- 两者由主 Agent 在同一条聊天链里自动选择
|
||||
|
||||
落地约束:
|
||||
|
||||
- `local-agent/computer-use-task-runner.mjs` 同样先做成外部 runtime 桥
|
||||
- 通过 `computerUseEnabled / computerUseCommand / computerUseArgs / computerUseWorkdir / computerUseTimeoutMs` 配置启用
|
||||
- 先统一 Boss 与 runtime 的协议,再按设备情况接 Codex App Computer Use、OpenClaw 或其他 GUI runtime
|
||||
|
||||
## 3. MasterAgentTask 扩展
|
||||
|
||||
当前 `MasterAgentTaskType` 只有:
|
||||
|
||||
- `conversation_reply`
|
||||
- `attachment_analysis`
|
||||
- `group_dispatch_plan`
|
||||
- `dispatch_execution`
|
||||
- `device_import_resolution`
|
||||
|
||||
本次新增:
|
||||
|
||||
- `browser_control`
|
||||
- `desktop_control`
|
||||
|
||||
新增字段:
|
||||
|
||||
- `intentCategory?`
|
||||
- `runtimeKind?`
|
||||
- `riskLevel?`
|
||||
- `confirmationPolicy?`
|
||||
- `requiresUserConfirmation?`
|
||||
- `confirmationScopeKey?`
|
||||
|
||||
目的:
|
||||
|
||||
- 前台能展示“当前这条消息要走哪条执行链”
|
||||
- 服务端能统一处理确认/拦截
|
||||
- `local-agent` 能按 runtimeKind 正确分流
|
||||
|
||||
## 4. 主 Agent 路由逻辑
|
||||
|
||||
主 Agent 不再简单分成“自己答”或“排 conversation_reply”,而是多一步意图判断。
|
||||
|
||||
推荐判断顺序:
|
||||
|
||||
1. 如果是明显的项目讨论、总结、目标/版本记录、普通问答
|
||||
- `discussion_only`
|
||||
|
||||
2. 如果是“继续开发 / 改代码 / 跑测试 / 看项目状态 / 接手某线程”
|
||||
- `project_development` 或 `thread_collaboration`
|
||||
|
||||
3. 如果是“打开网站 / 点网页 / 查后台 / 提交表单 / 看页面”
|
||||
- `browser_control`
|
||||
|
||||
4. 如果是“打开电脑软件 / 操作桌面 / 系统 GUI / 非浏览器界面”
|
||||
- `desktop_control`
|
||||
|
||||
路由结果:
|
||||
|
||||
- `discussion_only`
|
||||
- 主 Agent 直接回复
|
||||
- `thread_collaboration`
|
||||
- 继续 `conversation_reply`
|
||||
- `project_development`
|
||||
- 优先真实 Codex 线程 / CLI
|
||||
- `browser_control`
|
||||
- 排 `browser_control` 任务
|
||||
- `desktop_control`
|
||||
- 排 `desktop_control` 任务
|
||||
|
||||
## 5. 设备能力模型
|
||||
|
||||
当前设备只有:
|
||||
|
||||
- `gui`
|
||||
- `cli`
|
||||
|
||||
这对“统一控制电脑”不够精确,所以建议在设备 heartbeat 能力里细化为:
|
||||
|
||||
- `cli`
|
||||
- `gui`
|
||||
- `browserAutomation`
|
||||
- `computerUse`
|
||||
|
||||
其中:
|
||||
|
||||
- `browserAutomation` 可由本机 Playwright/runtime 探测
|
||||
- `computerUse` 由本机配置和权限状态探测
|
||||
|
||||
这样前台与主 Agent 都能知道:
|
||||
|
||||
- 当前机器只能写代码
|
||||
- 还是也能控浏览器
|
||||
- 还是能做完整桌面 GUI 操作
|
||||
|
||||
## 6. 前台产品表现
|
||||
|
||||
### 会话页 / 聊天页
|
||||
|
||||
每条“触发执行”的用户消息,服务端返回时增加:
|
||||
|
||||
- `executionMode`
|
||||
- `discussion`
|
||||
- `thread`
|
||||
- `development`
|
||||
- `browser`
|
||||
- `desktop`
|
||||
- `riskLevel`
|
||||
- `requiresConfirmation`
|
||||
|
||||
前台展示原则:
|
||||
|
||||
- 不做厚重控制台 UI
|
||||
- 保持当前微信式聊天界面
|
||||
- 只在消息下方补一条轻状态:
|
||||
- `已交给主 Agent`
|
||||
- `正在调用浏览器自动化`
|
||||
- `正在调用桌面控制`
|
||||
- `等待你确认后执行`
|
||||
|
||||
### 会话信息 / 设备详情
|
||||
|
||||
补一个轻量能力区:
|
||||
|
||||
- `默认开发模式:CLI / GUI`
|
||||
- `浏览器自动化:可用 / 不可用`
|
||||
- `桌面控制:可用 / 不可用`
|
||||
|
||||
不把这些塞回聊天主界面。
|
||||
|
||||
## 7. 风险确认设计
|
||||
|
||||
### 会话级别
|
||||
|
||||
如果当前会话在某个项目下已经对中风险动作做过一次确认,则可以对这个项目保留:
|
||||
|
||||
- `禁止`
|
||||
- `允许本次`
|
||||
- `当前项目永久放行`
|
||||
|
||||
这和现有 GUI/CLI 并行冲突的项目级策略一致,避免用户多学一套规则。
|
||||
|
||||
### 任务级别
|
||||
|
||||
当主 Agent 判断为高风险时:
|
||||
|
||||
- 不直接执行
|
||||
- 先在聊天里给出极简确认卡
|
||||
- 用户点确认后再排任务
|
||||
|
||||
## 8. 本次实施顺序
|
||||
|
||||
### 第一批
|
||||
|
||||
- 写设计与计划文档
|
||||
- 扩展任务类型、执行请求类型、设备能力类型
|
||||
- 接入 `browser_control / desktop_control` 两类任务基础骨架
|
||||
- `local-agent` 增加 runtime 分流占位
|
||||
- 前台返回 `executionMode/riskLevel` 元数据
|
||||
|
||||
### 第二批
|
||||
|
||||
- 接入 browser automation 真执行
|
||||
- 接入 computer use 真执行
|
||||
- 完成确认链
|
||||
|
||||
### 第三批
|
||||
|
||||
- Android/Web 前台补状态展示
|
||||
- 真机回归
|
||||
- 文档回写
|
||||
|
||||
## 涉及文件
|
||||
|
||||
- 修改 `src/lib/execution/types.ts`
|
||||
- 修改 `src/lib/execution/tool-registry.ts`
|
||||
- 修改 `src/lib/execution/permission-policy.ts`
|
||||
- 修改 `src/lib/boss-data.ts`
|
||||
- 修改 `src/lib/boss-master-agent.ts`
|
||||
- 修改 `src/app/api/v1/projects/[projectId]/messages/route.ts`
|
||||
- 修改 `local-agent/codex-task-runner.mjs`
|
||||
- 修改 `local-agent/server.mjs`
|
||||
- 新增 `local-agent/browser-control-task-runner.mjs`
|
||||
- 新增 `local-agent/computer-use-task-runner.mjs`
|
||||
- 新增对应 tests
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 主 Agent 能把聊天输入稳定区分成讨论、开发、浏览器控制、桌面控制四类
|
||||
- `browser_control / desktop_control` 能以正式任务进入 Boss 队列
|
||||
- `local-agent` 能识别并分流这两类任务
|
||||
- 前台能看到当前消息是走哪条执行链
|
||||
- 中高风险动作不会静默直接执行
|
||||
- 现有 `conversation_reply / dispatch_execution` 主链不回归
|
||||
151
docs/superpowers/specs/2026-04-30-admin-backoffice-redesign.md
Normal file
151
docs/superpowers/specs/2026-04-30-admin-backoffice-redesign.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# Boss To B 总后台重构设计
|
||||
|
||||
日期:2026-04-30
|
||||
|
||||
## 背景
|
||||
|
||||
当前 `/admin` 已经具备最高管理员访问控制、总览聚合、账号授权、风险处理和 Skill 生命周期治理能力,但页面仍像“几个数据表拼在一起”。对于 To B 交付场景,平台侧需要的是一套能服务客户成功、运维值守和权限开通的 PC 总后台,而不是一个调试看板。
|
||||
|
||||
本次重构不新增大业务边界,优先重组现有 `/api/v1/admin/overview`、`/api/v1/admin/access`、`/api/v1/admin/risks/actions`、`/api/v1/admin/skills/requests` 数据和动作,把后台做成可用、可读、可处置的运营控制台。
|
||||
|
||||
## 目标
|
||||
|
||||
1. 最高管理员进入后台后,能在 10 秒内看出哪些客户、设备、主 Agent 任务或线程风险需要处理。
|
||||
2. 客户开通从“多个分散表单”收口成可理解的工作台:公司、老板账号、子账号、设备、项目、Skill 授权有清晰入口和状态。
|
||||
3. 风险处理从“表格按钮”升级为战情室:按严重程度、客户影响、负责人、SLA 和下一步动作组织。
|
||||
4. Skill 治理保留安全约束,但展示成可追踪的生命周期队列。
|
||||
5. UI 风格从移动端微信效率风改为 PC To B 管理后台:高密度、强层级、清晰状态、少装饰。
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不引入新的 Umi / Ant Design Pro 工程。
|
||||
- 不切换 PostgreSQL 或重写状态存储。
|
||||
- 不改 Android APP 端交互。
|
||||
- 不绕过 local-agent 的 Skill allowlist、checksum、备份和回滚约束。
|
||||
- 不把客户侧 Web 控制台和平台总后台混成一个产品。
|
||||
|
||||
## 信息架构
|
||||
|
||||
后台改为 4 个一级区:
|
||||
|
||||
1. `驾驶舱`:平台全局健康、关键风险、客户影响、在线设备、主 Agent 失败、待处理通知。
|
||||
2. `客户与账号`:公司列表、客户详情、账号开通、角色状态、登录与安全概览。
|
||||
3. `授权工作台`:设备、项目、Skill 授权,权限模板,过期授权,离职回收和审计。
|
||||
4. `风险与治理`:风险战情室、SLA、负责人、修复工单、风险时间线、Skill 生命周期请求。
|
||||
|
||||
现有 `账号与授权` 和 `Skill 治理` 不是删除,而是拆到更合理的上下文里:账号归客户,授权归权限,风险和 Skill 请求归治理。
|
||||
|
||||
## 页面设计
|
||||
|
||||
### 驾驶舱
|
||||
|
||||
顶部保留平台身份和刷新动作,但标题从“Boss 管理后台”升级为“平台运营驾驶舱”。主区域按优先级展示:
|
||||
|
||||
- `今日待处理`:关键风险数、超 SLA 通知、离线设备、主 Agent 失败。
|
||||
- `客户健康排行`:按开放风险、在线设备比例、合同/套餐状态排序。
|
||||
- `关键风险队列`:只展示最值得处理的风险,提供负责人、SLA、确认、关闭、工单动作。
|
||||
- `设备与节点健康`:GUI/CLI、Browser、Computer Use 能力状态集中展示。
|
||||
- `最近事件`:风险时间线和权限审计摘要。
|
||||
|
||||
驾驶舱默认不展示大分页表,避免用户一打开就被表格淹没。
|
||||
|
||||
### 客户与账号
|
||||
|
||||
采用左侧客户列表 + 右侧详情的结构:
|
||||
|
||||
- 客户列表显示公司名、套餐、账号数、设备数、开放风险、客户成功负责人。
|
||||
- 右侧详情显示老板账号、子账号、绑定设备、项目数量和最近风险。
|
||||
- 新建客户流程拆成三步:创建公司、创建老板账号、绑定设备/项目。
|
||||
- 子账号管理支持启用/停用、重置密码、MFA 状态和登录会话摘要。
|
||||
|
||||
这部分复用现有 `/api/v1/admin/access`,但前台从表单堆叠改成任务流。
|
||||
|
||||
### 授权工作台
|
||||
|
||||
授权页面按“给谁授权”而不是“授权类型”组织:
|
||||
|
||||
- 先选择账号或客户。
|
||||
- 再选择设备、项目、Skill。
|
||||
- 最后套用权限模板或手动勾选权限。
|
||||
|
||||
页面底部保留最近授权审计和过期授权提醒。高危动作继续二次确认。
|
||||
|
||||
### 风险与治理
|
||||
|
||||
风险页面采用“战情室”结构:
|
||||
|
||||
- 左侧风险队列:按 `critical / warning / info`、客户、负责人、SLA 筛选。
|
||||
- 中间风险详情:影响对象、错误摘要、最近时间线、建议动作。
|
||||
- 右侧处理面板:指派、设置 SLA、确认、关闭、创建工单。
|
||||
|
||||
Skill 生命周期治理放在同一区域的第二页签,展示为请求队列:
|
||||
|
||||
- 待认领、执行中、成功、失败分栏。
|
||||
- 每条请求展示设备、Skill、动作、来源、checksum、结果摘要。
|
||||
- 创建请求表单保留,但根据动作动态收敛字段。
|
||||
|
||||
## 组件边界
|
||||
|
||||
建议拆出以下组件,降低当前 `boss-admin-app.tsx` 的复杂度:
|
||||
|
||||
- `AdminShell`:PC 后台壳、顶部栏、一级导航。
|
||||
- `AdminDashboard`:驾驶舱。
|
||||
- `AdminCustomerWorkspace`:客户与账号工作台。
|
||||
- `AdminPermissionWorkspace`:授权工作台。
|
||||
- `AdminRiskCommandCenter`:风险战情室。
|
||||
- `AdminSkillGovernance`:Skill 生命周期治理,可复用并改造当前组件。
|
||||
- `AdminStatusBadge`、`AdminMetricCard`、`AdminActionRail`:统一状态、指标和动作区。
|
||||
|
||||
数据请求先继续使用现有 fetch,不强制引入新的客户端状态库。
|
||||
|
||||
## 数据和接口
|
||||
|
||||
第一批不要求新增后端字段,但前台应完整使用现有字段:
|
||||
|
||||
- `summary`
|
||||
- `companies`
|
||||
- `accounts`
|
||||
- `devices`
|
||||
- `risks`
|
||||
- `notifications`
|
||||
- `riskTimeline`
|
||||
- `grantsSummary`
|
||||
|
||||
如果发现页面需要客户健康分数,可先在前端由 `openRiskCount / onlineDeviceCount / deviceCount / status` 计算,不改状态 schema。
|
||||
|
||||
## 错误处理
|
||||
|
||||
- 后台总览读取失败时展示一张明确的恢复卡,提供重试按钮。
|
||||
- 风险动作失败时保留原行状态,不做乐观关闭。
|
||||
- 指派负责人和 SLA 不再使用 `window.prompt`,改成右侧处理面板或弹窗表单。
|
||||
- 空状态要表达下一步,例如“暂无风险,可以查看设备在线情况”,不要只写“暂无数据”。
|
||||
|
||||
## 测试策略
|
||||
|
||||
- 保留并更新 `tests/admin-refine-page.test.ts`,验证新的一级区和关键文案。
|
||||
- 增加组件 source 测试,确认不再使用 `window.prompt` 做风险指派和 SLA。
|
||||
- 复跑 `tests/admin-overview-route.test.ts`、`tests/admin-risk-actions-route.test.ts`、`tests/admin-skill-lifecycle-panel-source.test.ts`。
|
||||
- 最后跑 `npm run lint` 和相关 Node 测试。
|
||||
|
||||
## 分批落地
|
||||
|
||||
第一批直接做到可用:
|
||||
|
||||
1. 重构 `BossAdminApp` 外壳和一级导航。
|
||||
2. 做新版驾驶舱。
|
||||
3. 做风险战情室,替换 `window.prompt`。
|
||||
4. 账号授权和 Skill 治理先迁入新结构,并压缩视觉层级。
|
||||
|
||||
第二批再增强:
|
||||
|
||||
1. 客户详情抽屉。
|
||||
2. 新建客户三步流程。
|
||||
3. 风险筛选和搜索。
|
||||
4. 客户健康分数和趋势。
|
||||
|
||||
## 自检
|
||||
|
||||
- 无 TBD / TODO。
|
||||
- 范围聚焦 `/admin` PC 总后台,不触碰 APP。
|
||||
- 没有要求新增大后端能力,优先复用现有接口。
|
||||
- 关键交互从数据表改成工作台与战情室,解决“后台管理不太好”的主要问题。
|
||||
@@ -0,0 +1,75 @@
|
||||
# YuDao 风格企业后台独立化设计
|
||||
|
||||
日期:2026-04-30
|
||||
|
||||
## 背景
|
||||
|
||||
Boss 需要从“客户也能用的 Web 页面”升级为平台侧 To B 总后台。这个后台用于平台运营人员管理公司、老板账号、子账号、电脑节点、Skill 授权、风险告警和审计记录。现有 `/admin` 已能展示核心数据,但仍运行在 Next 主站内,信息架构不够像成熟企业后台,后续不适合承载更复杂的租户、权限和治理能力。
|
||||
|
||||
调研 `YunaiV/yudao-cloud` 后,结论是:不直接引入它的 Spring Cloud 微服务后端;借鉴它的租户、用户、角色、菜单、日志、工作台和独立前端思路。前端形态参考 YuDao 的 Vben/Vue 管理后台,数据仍由 Boss 现有状态账本和 Admin BFF 提供。
|
||||
|
||||
## 目标
|
||||
|
||||
第一批目标是完成企业后台独立化的可运行骨架:
|
||||
|
||||
- 新增独立 PC 后台工程 `apps/boss-admin-web`,使用 Vue + Vite + Ant Design Vue。
|
||||
- 新增 `/api/v1/admin/backoffice` 聚合接口,输出 YuDao 风格的菜单、工作台、租户、账号、角色权限、资源授权、风险和审计数据。
|
||||
- 保留现有 `/admin`,作为 Boss 主站内 fallback,不和独立后台互相替代。
|
||||
- 后台权限继续只允许 `highest_admin` 访问,不暴露密码哈希、MFA 密钥和会话令牌。
|
||||
- 新后台先复用 Boss Cookie 登录态,后续再接独立域名 `admin.boss.hyzq.net`。
|
||||
|
||||
## 非目标
|
||||
|
||||
- 不引入 YuDao Java 后端、MySQL 表结构或微服务网关。
|
||||
- 不在第一批替换所有现有后台 mutation 页面。
|
||||
- 不重新设计 Android APP。
|
||||
- 不改变当前 Boss 文件存储运行时。
|
||||
|
||||
## 架构
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Boss Admin Web\nVue + Ant Design Vue"] --> B["/api/v1/admin/backoffice\nAdmin BFF"]
|
||||
B --> C["boss-state.json\n当前状态账本"]
|
||||
B --> D["buildAdminOverview\n现有后台聚合"]
|
||||
B --> E["BOSS_PERMISSION_TEMPLATES\n权限模板"]
|
||||
F["现有 /admin\nNext fallback"] --> G["/api/v1/admin/overview"]
|
||||
```
|
||||
|
||||
`apps/boss-admin-web` 是独立前端工程。它只消费 BFF,不直接读取本地文件,也不复制业务规则。`/api/v1/admin/backoffice` 是企业后台的新契约层,负责把 Boss 当前状态翻译为更稳定的后台管理模型。
|
||||
|
||||
## 数据模型
|
||||
|
||||
第一批 BFF 返回:
|
||||
|
||||
- `menuTree`:工作台、租户管理、账号管理、角色权限、资源授权、Skill 中心、风险告警、审计日志、系统设置。
|
||||
- `workbench`:总览指标、客户健康、设备健康、风险摘要。
|
||||
- `tenants`:公司列表、套餐、负责人、账号数、设备数、风险数。
|
||||
- `users`:账号、昵称、角色、状态、公司、最近登录。
|
||||
- `roles`:内置角色和权限模板。
|
||||
- `resourceGroups`:设备、项目线程和 Skill 目录。
|
||||
- `audit`:风险、风险时间线和权限审计。
|
||||
- `yudaoMapping`:Boss 账本字段到后台概念的映射,便于后续迁移数据库或接 YuDao 风格模块。
|
||||
|
||||
## UI 方向
|
||||
|
||||
第一批 UI 只做高保真骨架,不新增业务动作:
|
||||
|
||||
- 左侧固定菜单,右侧工作区。
|
||||
- 顶部展示当前账号、后台说明和刷新入口。
|
||||
- 工作台使用指标卡、风险横幅、客户健康和节点表。
|
||||
- 租户、账号、角色、资源、风险、审计分别使用独立区块或表格。
|
||||
- Skill 中心聚合展示 Skill 目录、来源、设备数和治理状态,后续再接完整安装向导。
|
||||
|
||||
## 权限与安全
|
||||
|
||||
- 未登录返回 `401`。
|
||||
- 非 `highest_admin` 返回 `403`。
|
||||
- BFF 只返回安全账号字段,不返回 `passwordHash`、`mfaSecret`、`authSessions` 或任何 session token。
|
||||
- 所有返回头使用 `private, no-store`,避免后台数据被缓存。
|
||||
|
||||
## 验证
|
||||
|
||||
- 新增 BFF 路由测试,验证鉴权、菜单结构、数据聚合和敏感字段过滤。
|
||||
- 新增独立前端源代码测试,验证工程骨架、API 契约、核心页面模块和根工程隔离。
|
||||
- 跑 `npm run lint` 和 `npm run build`,确认不会破坏现有 Next 主站。
|
||||
Reference in New Issue
Block a user