docs/API.md: 补权限档位端点与字段(dsh 反馈的文档缺口)

dsh 在鸿蒙计划反馈中指出 API.md 未收录权限档位相关:
- PUT /sessions/{id}/permission 端点
- GET /sessions/{id} 返回的 permission_mode/permission_enforcement
- 发信请求体的 permission_mode 字段
- new_mail SSE 事件的档位字段

补:
- 会话端点清单加 PUT /sessions/{id}/permission
- 会话对象字段表(permission_mode 三档 + permission_enforcement native/advisory)
- 新增「权限档位」节:三档语义、新建/续谈均可设定、Agent 继承约束
- 发信请求体 JSON 示例加 permission_mode + 说明(两种情形都生效)
- new_mail SSE payload 示例补档位字段(含 from_human/to_human/in_reply_to)

注:后端只有 PUT 没有 GET /sessions/{id}/permission,文档已注明读取走会话详情。
This commit is contained in:
2026-09-07 07:32:00 +08:00
parent 314c3224ce
commit bf32369ebd

View File

@ -87,7 +87,8 @@ POST /me/mail/{id}/forward 转发(引用原文 + 附件随行)
"reply_to": "<mail_id>",
"session_alias": "fix-leak",
"attachment_ids": ["<attachment_id>"],
"max_rounds": 3
"max_rounds": 3,
"permission_mode": "workspace"
}
```
@ -95,6 +96,9 @@ POST /me/mail/{id}/forward 转发(引用原文 + 附件随行)
(即本次投递新建会话)时生效 —— 续谈已有会话时若也接受这两个字段,
每封新信都会悄悄改掉对方正在遵守的约定。
`permission_mode` 则**两种情形都生效**:新建会话时声明初始档位;
续谈已有会话时显式改档(人是权限的源头,可任改三档)。详见「权限档位」节。
### 对话树
```
@ -142,8 +146,8 @@ GET /mail/{id}/thread?dir=down&offset=40&limit=40 继续往下
### 会话
```
GET /me/sessions 我参与的会话(含 max_rounds/used_rounds
GET /sessions/{id} 会话详情 + 会话内邮件(含附件)
GET /me/sessions 我参与的会话(含 max_rounds/used_rounds/permission_mode/permission_enforcement
GET /sessions/{id} 会话详情 + 会话内邮件(含附件 + 档位字段
GET /sessions/{id}/mails 会话内邮件(含附件)
PUT /sessions/{id}/alias 改会话别名(冲突 409
@ -152,8 +156,37 @@ POST /sessions/{id}/rename-proposal/dismiss 驳回建议
GET /sessions/{id}/budget 本任务的往返预算
PUT /sessions/{id}/budget 改预算 {max_rounds?, reset?}
PUT /sessions/{id}/permission 改档位 {permission_mode}(读取走会话详情,无需独立 GET
```
会话对象带两个档位字段(`GET /sessions/{id}` / `GET /me/sessions` 均返回):
| 字段 | 含义 | 取值 |
|---|---|---|
| `permission_mode` | 本任务允许 Agent 动手到什么程度 | `plan` / `workspace` / `full` |
| `permission_enforcement` | 该档位在收件平台**实际**被强制到什么程度 | `native`(真沙箱) / `advisory`(仅提示词告知) |
### 权限档位
人在派活时声明「这条任务允许 Agent 动手到什么程度」,插件把它翻译成平台原生的
沙箱/审批配置。三档:
| 档位 | 语义 | 权限询问 |
|---|---|---|
| `plan` | 只读:查资料、读代码、出方案,一个字都不许写 | **不产生** —— 直接拒绝,模型把方案写在回信里 |
| `workspace` | 本目录内可动,越界要问人(**默认档** | 越界时产生 |
| `full` | 自动放行 | **不产生** —— 已声明全权,再问是噪音 |
- 新建会话时在发信请求体里带 `permission_mode` 声明初始档位(省略 = `workspace`
- **续谈已有会话时带该字段也会生效**:人是权限的源头,可以任改三档(不受继承约束)
- Agent 侧派子任务不能自行抬档:`SendMail` 走继承,子会话档位 = `min(父档, 请求档)`
plan 档派不出 full 档子任务,约束沿链条传递)
- 对话页里随时改:`PUT /sessions/{id}/permission`(前端对话页右上角档位编辑器)
两次读路径(`ListInbox` / `GetMailByID` / `GetSessionMails` / `ListSentBy`)也返回
`permission_mode` / `permission_enforcement` —— 列表页档位徽标靠它们。
### 往返预算
配额的语义是「这件事值得多少个来回」—— 那是**任务**的属性,不是 Agent 的属性。
@ -463,7 +496,11 @@ GET /events/stream
{
"mail_id": "...", "session_id": "...", "from_name": "admin",
"subject": "...", "mail_type": "normal", "role": "to",
"to_workspace": "/home/program/agentmail"
"to_workspace": "/home/program/agentmail",
"from_human": false, "to_human": false,
"in_reply_to": "...", "reply_address": "...",
"permission_mode": "workspace",
"permission_enforcement": "native"
}
```
@ -471,6 +508,9 @@ GET /events/stream
不是主收件人的)。插件应当用它作为会话的工作目录 —— 自己拼一个临时目录会让
平台按 cwd 分组时把所有邮件会话归进「未分组」。
`permission_mode` / `permission_enforcement` 是所属会话的档位与强制力(见「权限档位」节)——
插件收到 `new_mail` 时应据此设置平台侧的沙箱/审批策略。
`permission_decision` 的 payload 含 `relay_key`(上游权限询问的 id
`session_id`:前者让插件对上平台侧那条待决询问,后者是插件重启丢了内存映射时
的兜底 —— 那种情况下决策会被当作一封普通通知投进会话。