From 88cb98140494b06f88aa83a174ca81994bfa526d Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Thu, 6 Aug 2026 09:10:33 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20Agent=20=E5=B7=A5=E5=85=B7=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E6=9D=83=E9=99=90=E6=8E=A7=E5=88=B6=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: CodeFree --- .../2026-08-06-agent-tool-admin-only-design.md | 98 ++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-06-agent-tool-admin-only-design.md diff --git a/docs/superpowers/specs/2026-08-06-agent-tool-admin-only-design.md b/docs/superpowers/specs/2026-08-06-agent-tool-admin-only-design.md new file mode 100644 index 0000000..4cd7307 --- /dev/null +++ b/docs/superpowers/specs/2026-08-06-agent-tool-admin-only-design.md @@ -0,0 +1,98 @@ +# Agent 工具执行权限控制设计 + +## 背景 + +当前 Agent 工具框架中,所有 `enabled = 1` 的工具对任何登录用户都可见可调用。某些敏感工具(如 `fetch`,可发起外部 HTTP 请求)应限制为仅管理员可在 LLM 对话中调用,普通用户不应感知到这些工具的存在。 + +## 目标 + +- 在工具级别增加「仅管理员可用」开关 +- 普通用户对话时,admin-only 工具完全隐藏(不出现在工具列表中,LLM 不知道其存在) +- 管理员对话时,所有 enabled 工具正常可用 +- 管理后台显示权限标记,支持快速切换 + +## 设计 + +### 数据库变更 + +在 `agent_tools` 表新增 `admin_only` 字段: + +```typescript +adminOnly: integer("admin_only").default(0).notNull() +``` + +- `0`:所有登录用户可用(默认) +- `1`:仅管理员可在 LLM 对话中调用 + +需执行 `db:generate` + `db:migrate` 生成并应用迁移。 + +### Service 层变更(`server/service/agent-tool/index.ts`) + +1. **接口扩展**:`CreateAgentToolInput` 和 `UpdateAgentToolInput` 新增 `adminOnly?: boolean` 字段 + +2. **CRUD 函数**:`createAgentTool` 和 `updateAgentTool` 处理 `adminOnly` 字段(`boolean → 0/1`) + +3. **`getEnabledToolsForLlm(userId, userRole)`**: + - 新增 `userRole: UserRole | null` 参数 + - 查询 enabled=1 的工具后,若 `userRole !== "admin"`,过滤掉 `adminOnly = 1` 的工具 + - 过滤在内存中进行(数据量小,无需额外 DB 条件) + +4. **`getEnabledToolInfos(userRole)`**: + - 新增 `userRole: UserRole | null` 参数 + - 同理过滤 admin-only 工具 + +### API 层变更 + +1. **`server/api/llm/chat/index.post.ts`**: + - `getEnabledToolsForLlm(user.id)` → `getEnabledToolsForLlm(user.id, user.role)` + +2. **`server/api/llm/chat/tools.get.ts`**: + - 获取当前用户,`getEnabledToolInfos()` → `getEnabledToolInfos(user?.role ?? null)` + +3. **`server/api/agent-tools/index.post.ts`** 和 **`[id].put.ts`**: + - 请求体新增 `adminOnly` 字段透传到 service 层 + +### 前端变更 + +1. **`app/pages/admin/agent-tools/index.vue`**: + - `AgentToolRow` 接口新增 `adminOnly: number` + - 表格新增「权限」列,显示「仅管理员」或「所有人」标签 + - 新增 `handleToggleAdminOnly` 函数,快速切换 admin_only 状态 + +2. **`app/components/AgentToolFormModal.vue`**: + - `form` 新增 `adminOnly` 字段 + - 新增「仅管理员可用」复选框 + - 保存时 body 新增 `adminOnly` 字段 + +### 数据流 + +``` +管理员后台: 创建/编辑工具 → 勾选「仅管理员可用」→ adminOnly=1 存入 DB + +普通用户对话: /api/llm/chat → getEnabledToolsForLlm(userId, "user") + → 查询 enabled=1 → 过滤 adminOnly=1 → 普通用户不可见 + +管理员对话: /api/llm/chat → getEnabledToolsForLlm(userId, "admin") + → 查询 enabled=1 → 不过滤 → 管理员可用全部工具 +``` + +### 不改动的部分 + +- 工具 CRUD 管理 API 仍然是 admin-only(已有 `requireAdmin`) +- `executeAgentTool` 独立执行函数不加权限检查(仅在 admin 调试 API 中使用) +- `ToolContext` 不变(不需要传 role 到执行器层) +- `needsApproval` 审批机制不变(与 admin_only 正交:admin_only 控制可见性,needsApproval 控制执行确认) + +## 涉及文件清单 + +| 文件 | 变更类型 | +|------|----------| +| `packages/drizzle-pkg/lib/schema/agent-tool.ts` | 新增字段 | +| `server/service/agent-tool/index.ts` | 接口+函数扩展 | +| `server/api/llm/chat/index.post.ts` | 传参变更 | +| `server/api/llm/chat/tools.get.ts` | 传参变更 | +| `server/api/agent-tools/index.post.ts` | 透传字段 | +| `server/api/agent-tools/[id].put.ts` | 透传字段 | +| `app/pages/admin/agent-tools/index.vue` | 表格+切换 | +| `app/components/AgentToolFormModal.vue` | 表单字段 | +| 迁移文件(自动生成) | 新增 |