09-admin-ui.md 14 KB

09 管理后台与 Playground

1. 总体布局:VS Code 工作台风格

整个后台仿照 VS Code 工作台:左侧活动栏(Activity Bar)放图标导航,侧栏(Side Bar)放列表,主区域(Editor Area)放详情,底部状态栏(Status Bar)显示服务状态。Playground 的对话面板对齐 Claude VS Code 插件。

┌──┬──────────────┬──────────────────────────────────────────────┐
│◉ │ SESSIONS   + │  ┌ Playground ─────────────────────────────┐ │
│▤ │ ▸ 销售分析…   │  │                                         │ │
│⚙ │ ▸ 资料整理…   │  │       (对话面板,见 §3)                 │ │
│⌘ │ ▸ …          │  │                                         │ │
│☰ │              │  └─────────────────────────────────────────┘ │
│  │              │                                              │
├──┴──────────────┴──────────────────────────────────────────────┤
│ ● claude 已登录  ● codex 已登录  运行中 1/4  排队 0        v0.1.0 │
└────────────────────────────────────────────────────────────────┘

2. 页面清单

活动栏按使用场景分组(2026-10-27 起),组内有多个页面时在主区域顶部以页签切换;页面地址不变,点击组时回到这组里上次看的页面:

活动栏 页签
💬 Playground —
👥 工作组 Bot Playground · 机器人 · 回归用例(13-bot-teams)
📊 概览 —
🕘 运行记录 会话记录 · 定时任务(14-schedules)· 后台调用(15-background-calls)· 审计日志
🧩 能力 Profiles · 技能与插件 · MCP 服务 · 资料库
🗃 文件管理 —
🔑 接入 API Keys · API 协议
⚙ 设置(底部) —

各页面的内容:

活动栏 侧栏 主区域
💬 Playground 会话列表(搜索、按引擎/使用者筛选) 对话面板 + 右侧可收起的调试面板
📊 概览 — 运行中任务、今日用量、7 天趋势、错误列表、凭证状态
🗂 会话 全部会话(所有平台/使用者) 只读回放(时间线 + 原始事件 + 文件),可"在 Playground 中继续"
🧩 Profiles Profile 列表 表单编辑:引擎、模型(下拉选择当前引擎的模型)、提示词(Monaco 编辑器)、权限、工具、技能、资料库、第三方 MCP 服务、Codex 插件(仅 Codex,默认不开放,ADR-0018 修订)、文件访问策略(模式、可读/可写/禁止路径,右侧显示合并后的生效预览,见 06 §4.3);版本历史
📚 资料库 资料目录列表 名称、路径(带目录选择器)、说明、读写属性、启用;可见性检测结果;被哪些 Profile 使用;索引状态(M3)
🗃 文件管理 位置 + 常用目录(各资料库、本地技能目录、已安装技能、Python 运行环境、服务数据、日志) 以管理员身份浏览与管理文件:会话工作区与资料库可写(新建文件/目录、上传与拖放、重命名/移动、删除、目录打包下载);整个服务目录(/srv/agent-server:程序、运行环境、技能、数据、日志、引擎 home)只读浏览。文本文件用 Monaco 编辑或查看(Ctrl/⌘+S 保存,打开后被改动则拒绝覆盖),图片预览,其他文件下载。登录凭证与密钥(内置全局禁止项中的 ~/.claude/.credentials.json、~/.codex/auth.json、~/.ssh 等)不显示;数据库及其备份能看到但不能读取或下载(含 MCP 服务密钥等只写不读的配置)。路径不能越出位置,外部符号链接不跟随;会话目录本身不能在这里删除或移动;修改会话文件后同步该会话的文件记录。实现:apps/server/src/services/file-manager.ts、/admin/v1/fs/*
🔑 引擎状态 Claude / Codex 登录状态、账户摘要、额度、CLI 路径与版本、生效的工具清单(用于确认个人插件已被禁用);未登录时提示在终端执行 claude / codex login
🗝 API Keys Key 列表 签发(明文只显示一次)、吊销、最近使用时间
🔌 MCP 服务 — 内置工具(只读展示);第三方服务:添加远程 HTTP 或本地进程(沙箱)服务、测试连接、刷新工具、逐个工具设置策略(直接调用 / 跟随权限模式 / 总是审批 / 关闭)、后台执行、查看与覆盖工具提示(只读、破坏性、幂等)、启停、删除;工具标出结构化输出、长任务;服务标出提供资源、提示模板;远程服务可以启用 OAuth(填写或自动注册客户端,"授权"在新窗口中完成,可以清除);密钥只写不读;显示使用它的 Profile 与连接状态(ADR-0021、ADR-0025)
📖 API 协议 右侧:调试身份 + 目录(随滚动高亮) 对外接口(/v1)的完整协议:由 apps/server/src/api-reference/reference.ts 生成(测试保证与实际路由一致),跟随亮/暗主题。每个接口可以调试:填写参数与请求体后以"后台管理员"或某个平台的身份调用(平台身份由服务端签发 10 分钟的浏览器令牌,API Key 不离开服务端,记入审计),写操作发送前确认,发送消息会提示消耗订阅额度;事件流实时显示(最多 2 分钟 / 200 条,可停止);响应中的 ID 自动预填到其他接口的路径参数。下载 PDF 由服务端无头 Chrome 生成(A4,服务器没有 Chrome 时改用浏览器打印)
🔌 连接器 (暂缓) —
📜 审计 筛选条件 命令执行、连接器调用、审批、后台操作
⚙ 设置 分组:路径 / 安全 / 网络 / 限制 / 引擎 路径:工作区根目录、技能目录、Python 环境、matplotlibrc;安全:全局禁止路径(内置项锁定)、新建 Profile 的默认文件访问模式;网络:域名白名单、私网拦截;限制:并发、交互超时、上传大小、保留期;后台调用 / 脚本调用工具 / 定时任务 / 工作组限额:各项上限(脚本:调用次数、并发、运行时长,见 17-run-script);引擎:CLI 路径、默认模型、Codex 配置覆盖项。所有路径输入都做实时校验

3. Playground

3.1 结构(对齐 Claude VS Code 插件)

┌ 顶栏 ─────────────────────────────────────────────────────────┐
│ [会话标题 ▾ 历史]                    [+ 新会话] [⚙ 配置] [⋯]      │
├ 时间线(居中,max-width 680px)──────────────────┬ 调试面板 ──────┤
│ ┌──────────────────────────────┐               │ 事件 | JSON |   │
│ │ 分析附件里的 Q3 销售数据 📎x2   │  ← 用户消息    │ 文件 | 用量     │
│ └──────────────────────────────┘    (带边框的框) │               │
│ │                                              │ #12 tool.start │
│ ● 先看看数据结构。                  ← 助手文本     │ #13 tool.done  │
│ │                                              │ ...            │
│ ● Read  uploads/sales.xlsx        ← 工具行       │               │
│ │  ┌ IN  │ {...}           ┐    (点击展开)     │               │
│ │  └ OUT │ 1,204 rows…     ┘                   │               │
│ ● Bash  python analyze.py         ● 绿=成功       │               │
│ ● 需要你的确认                     ● 红=失败       │               │
│ │ ┌ 允许运行此命令? ───────────┐  ● 黄=待处理     │               │
│ │ │ pip install ...            │                 │               │
│ │ │ [1 允许] [2 本会话允许] [3 拒绝…]│             │               │
│ │ └────────────────────────────┘                 │               │
│ ● 📄 outputs/Q3报告.docx  [预览][下载]            │               │
├────────────────────────────────────────────────┤               │
│ ┌ 输入框(圆角 8px,聚焦时 Claude 橙色光圈)──────┐ │               │
│ │ [📎 sales.xlsx ×] [🖼 截图.png ×]             │ │               │
│ │ 描述你想分析的问题…                            │ │               │
│ │ [Claude ▾][Sonnet ▾][需审批 ▾][📎]        [➤] │ │               │
│ └──────────────────────────────────────────────┘ │               │
└────────────────────────────────────────────────┴───────────────┘

3.2 组件规范(来自插件样式的实测值,见 research 文档)

组件 规范
时间线 消息左侧留 30px;左边距 12px 处画一条 1px 竖线(--app-primary-border-color);每条消息前有一个 7px 圆点(距左 9px);圆点颜色:默认 --app-secondary-foreground,成功 #74c991,失败 #c74e39,待处理/警告 #e1c08d
用户消息 1px 边框(--app-input-border)、6px 圆角、背景 --app-input-background、内边距 4px 6px;保留换行
助手文本 无气泡,直接排版 Markdown;行内代码用 --app-inline-code-background
工具行 工具名加粗,参数摘要用等宽字体、0.85em、次要色;点击展开 IN/OUT 两行网格:标签列等宽字体、0.5 透明度,内容默认最高 60px 并带渐隐遮罩,点击展开全文
工具结果 背景 --app-code-background,white-space: pre,可横向滚动
思考过程 <details> 折叠,摘要为斜体、次要色、0.8 透明度,悬停时变为 1
交互卡片(审批/提问) 背景 --app-input-secondary-background、1px 边框、8px 圆角、8px 内边距;标题加粗;按钮纵向排列并带数字快捷键(1/2/3),第 3 项"拒绝"可以展开输入拒绝理由;聚焦时边框为 --app-input-active-border 65%
输入框 1px 边框、8px 圆角、轻阴影 0 1px 2px #0000001a;聚焦时边框变为 Claude 橙 #d97757,外圈 3px 的 12% 橙色光晕;文本区内边距 10px 36px 10px 14px,最高 200px
发送按钮 26×26px,5px 圆角,背景 #c6613f(clay),图标色 #faf9f5(ivory);禁用时 0.4 透明度;运行中变为停止按钮
底部工具条 引擎、模型、权限模式做成药丸按钮(背景为前景色 10% 混合,悬停 18%)
状态徽标 4px 圆角,4px 8px 内边距,500 字重:已连接为绿,失败为红,需登录为黄
间距刻度 4 / 8 / 12 / 16px;圆角 4 / 6 / 8px
字体 UI 用系统字体(-apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif)13px;等宽字体 "JetBrains Mono", Menlo, Consolas, monospace 12px

3.3 交互行为

  • 键盘:Enter 发送、Shift+Enter 换行、Esc 中断;交互卡片出现时自动获得焦点,数字键选择选项
  • 新内容到达时自动滚动到底部;用户向上滚动后暂停自动滚动,并显示"↓ 回到最新"按钮
  • 用户消息在滚动时吸顶(sticky),对应插件的 stickyHeader 行为
  • 工具调用默认折叠,失败的工具默认展开
  • 产出文件以卡片形式展示,点击在右侧调试面板的"文件"页签中预览

3.4 配置抽屉(⚙)

引擎、模型、Profile(选择后填充默认值)、权限模式(需审批 / 自动 / 只读)、系统提示词追加、启用的资料库和技能、文件访问策略的临时调整。底部有"另存为 Profile"按钮。

3.5 调试面板(Playground 特有,插件里没有)

  • 事件:带 seq、类型、耗时的事件列表,点击跳转到时间线对应位置
  • JSON:原始事件(AgentEvent),可以切换查看引擎原始消息(适配前的数据,仅调试模式下记录)
  • 文件:工作区文件树,支持预览和下载
  • 用量:token、耗时、预估费用、订阅限额剩余(引擎支持时显示)

3.6 回归用例

在 Playground 中可以把一个会话的首条输入和 Profile 保存为"用例",引擎升级后一键批量重放,人工比对结果(M3)。

4. 主题

  • 亮/暗两套令牌:默认跟随系统,可手动切换。暗色取 VS Code Dark Modern 的配色,亮色取 Light Modern 的配色(见 research 文档的令牌表)。
  • 令牌集中放在 packages/ui-tokens(UnoCSS preset + CSS 变量),后台和业务平台共用,业务平台也可以只引入 chat-ui 加令牌。
  • 只复刻视觉规范(颜色、间距、布局),不拷贝插件的源码、图标和字体资源;图标用开源的 @vscode/codicons。

5. 技术实现

  • Vue 3 <script setup> + TS;Pinia 管理会话和事件状态(applyEvent 是纯函数,由事件流增量构建视图模型)
  • packages/chat-ui 导出 <AgentChat>(完整面板)以及 <Timeline>、<ToolCall>、<InteractionCard>、<Composer> 等细粒度组件
  • Markdown:markdown-it + Shiki(亮/暗主题)+ 表格、KaTeX(数据分析常用)
  • 图表产出(png/svg/html)内联预览;html 用 sandbox iframe 隔离
  • 后台以静态资源形式由 Fastify 托管在 /admin/,同源部署,不需要处理 CORS