Sessions

工具审批

在具体 Session 内查询、展示和处理 unrestricted 工具请求

工具审批

审批属于触发工具调用的 Session,不属于顶层 Agent。这保证多个 Session 并行运行时,审批不会被提交到错误的对话。

Shell 等工具请求额外权限时,当前 Assistant Message 中对应的 Tool Part 进入 approval-required 状态。

ready -> approval-required -> running -> completed
                         \-> failed

展示实时请求并提交决定

approval-required Tool Part 会携带完整审批快照。订阅只报告状态,不提供命令通道:

const unsubscribe = session.subscribe((mutation) => {
  if (
    mutation.variant !== "part" ||
    mutation.type !== "tool" ||
    mutation.part.state !== "approval-required" ||
    !mutation.part.approval
  ) {
    return;
  }

  show_approval_request(mutation.part.approval);
});

// 用户确认后:
await session.resolve_approval({
  approval_id,
  decision: "approved",
});

支持的决策只有 approveddeniedsubscribe() 始终保持为纯数据流,只在用户明确操作后调用 resolve_approval()。后续 Tool Part Mutation 才是最终状态依据。

先查询,后处理

后台审批页、恢复后的客户端或无法持续订阅的客户端,应使用 Session 方法:

const pending = await session.approvals();

for (const approval of pending) {
  render_approval({
    tool_name: approval.tool_name,
    command: approval.command,
    cwd: approval.cwd,
    reason: approval.reason,
    operation: approval.operation,
  });
}

await session.resolve_approval({
  approval_id: pending[0].approval_id,
  decision: "denied",
});

resolve_approval() 只处理当前 Session 的 pending 请求。请求不存在、已被其他客户端处理或属于其他 Session 时,结果的 successfalse,而不是越权处理它。

审批模式

const current = await session.approval_mode();

await session.set_approval_mode({
  mode: "always-allow",
});
模式行为
ask默认模式。每次 unrestricted 请求进入待审批队列。
always-allow该 Session 后续的新请求自动批准。

always-allow 不会改变 sandbox 类型,不会影响其他 Session,也不会自动处理已经 pending 的请求。产品应明确显示当前模式,并把高权限模式放在显式用户选择之后。

UI 实现要点

  • approval_id 作为审批卡片稳定 key,用 tool_call_id 关联 Tool Part。
  • 状态为 approval-required 时将工具输出区保持在等待状态,不能标记为完成。
  • 决策提交后等待下一个 Part Mutation 显示 runningcompletedfailed,不要在客户端伪造成功。
  • 同一个请求可以有多个订阅者,提交结果以 resolve_approval()success 为准。
  • Session 切换时清理旧会话的审批队列;不能把旧 Session 的 approval_id 发送给新 Session。

完整 Tool Part 状态与渲染方式见 实时订阅