docs: document standalone AskUserQuestion channel and CCR forwarding
Browse files
docs/architecture/safety-and-permissions.md
CHANGED
|
@@ -865,3 +865,35 @@ headless agent 模式下,超出限制直接终止 agent(`permissions.ts:1023
|
|
| 865 |
│ └─ 用户确认对话框 │
|
| 866 |
└──────────────────────────────────────┘
|
| 867 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 865 |
│ └─ 用户确认对话框 │
|
| 866 |
└──────────────────────────────────────┘
|
| 867 |
```
|
| 868 |
+
|
| 869 |
+
---
|
| 870 |
+
|
| 871 |
+
## 附录:AskUserQuestion 独立问答通道
|
| 872 |
+
|
| 873 |
+
`AskUserQuestion` 用于向用户提出多选题(澄清需求、在方案间做选择)。它**不再借道权限系统的 `ask` 流程**,而是走一条独立的问答通道,与权限确认队列解耦。
|
| 874 |
+
|
| 875 |
+
### 与权限 `ask` 的区别
|
| 876 |
+
|
| 877 |
+
| 维度 | 权限式 `ask`(早期实现) | 独立问答通道(当前实现) |
|
| 878 |
+
|------|----------------------|----------------------|
|
| 879 |
+
| `checkPermissions` 返回 | `behavior: 'ask'` | `behavior: 'allow'` |
|
| 880 |
+
| 阻塞方式 | 权限回调回填 `answers` | `call` 内 `await questionService.ask(...)` |
|
| 881 |
+
| 本地渲染 | 进 `toolUseConfirmQueue`,由 `PermissionRequest` 渲染 | 独立 overlay(`QuestionPrompt`),与 `toolPermissionOverlay` 并列 |
|
| 882 |
+
| 焦点协调 | `tool-permission` 对话框 | `question` 对话框 + `useRegisterOverlay('question')` |
|
| 883 |
+
|
| 884 |
+
### 运行时组件
|
| 885 |
+
|
| 886 |
+
- **`src/services/question/questionService.ts`** — 独立问答通道。`ask(questions)` 存入 `pending: Map<id, ...>` 并返回 Promise;`reply` / `reject` 解析对应 Promise;通过 EventEmitter 广播 `asked` / `replied` / `rejected`。
|
| 887 |
+
- **`src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx`** — `call` 内 `await questionService.ask(...)`,再把结果按题映射为 `answers`。
|
| 888 |
+
- **`src/components/question/QuestionPrompt.tsx`** — 独立 overlay,复用 `QuestionView` / `SubmitQuestionsView` / `use-multiple-choice-state` 渲染,并用 `useKeybindings`(`Tabs` 上下文)绑定多题切换。
|
| 889 |
+
- **`src/screens/REPL.tsx`** — 订阅 `asked` 弹出 overlay;订阅 `replied` / `rejected` 关闭 overlay。
|
| 890 |
+
|
| 891 |
+
### 桥接 / CCR 远程转发
|
| 892 |
+
|
| 893 |
+
桥接(`BRIDGE_MODE`)连接时,`asked` 事件会**同时**把问题作为 `can_use_tool` control_request 转发给远程用户(claude.ai),与本地 overlay 竞速:
|
| 894 |
+
|
| 895 |
+
- 远程 `allow` 且带 `updatedInput.answers` → 按题映射后 `questionService.reply(...)`;通用 `allow`(无 answers)降级为每题选第一个选项。
|
| 896 |
+
- 远程 `deny` → `questionService.reject(...)`。
|
| 897 |
+
- 任一端先应答,都会清掉本地 overlay 并 `cancelRequest` 另一端的 prompt,避免残留。
|
| 898 |
+
|
| 899 |
+
> 注:因 `checkPermissions` 现返回 `allow`,AskUserQuestion 不再进入 `handleInteractivePermission`,故不会与桥接路径重复转发。
|
docs/remote-bridge/overview.md
CHANGED
|
@@ -150,6 +150,16 @@ SDK 消息格式转换器。将 CCR 发送的 SDK 格式消息(`SDKMessage`)
|
|
| 150 |
|
| 151 |
在远程会话中处理权限请求桥接(位于 `src/hooks/useSSHSession.ts`、`useRemoteSession.ts`、`useDirectConnect.ts`),将远程权限提示通过 WebSocket 转发给用户。
|
| 152 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
---
|
| 154 |
|
| 155 |
## 认证机制
|
|
|
|
| 150 |
|
| 151 |
在远程会话中处理权限请求桥接(位于 `src/hooks/useSSHSession.ts`、`useRemoteSession.ts`、`useDirectConnect.ts`),将远程权限提示通过 WebSocket 转发给用户。
|
| 152 |
|
| 153 |
+
### AskUserQuestion 远程转发
|
| 154 |
+
|
| 155 |
+
`AskUserQuestion` 走独立问答通道(详见 `docs/architecture/safety-and-permissions.md` 附录),桥接连接时会把问题作为 `can_use_tool` control_request 转发给远程用户(claude.ai),与本地 overlay 竞速应答:
|
| 156 |
+
|
| 157 |
+
- 远程 `allow` + `updatedInput.answers` → 按题映射回填;通用 `allow` 降级为每题首个选项。
|
| 158 |
+
- 远程 `deny` → 拒绝该问题。
|
| 159 |
+
- 任一端先应答即 `cancelRequest` 另一端,避免残留 prompt。
|
| 160 |
+
|
| 161 |
+
实现位于 `src/screens/REPL.tsx` 对 `questionService` 事件(`asked` / `replied` / `rejected`)的订阅。
|
| 162 |
+
|
| 163 |
---
|
| 164 |
|
| 165 |
## 认证机制
|
docs/tools/tool-reference.md
CHANGED
|
@@ -117,7 +117,7 @@
|
|
| 117 |
|
| 118 |
| 工具名称 | 分类 | 用途描述 | 关键参数 |
|
| 119 |
|----------|------|----------|----------|
|
| 120 |
-
| **AskUserQuestion** (AskUserQuestionTool) | 特殊 | 向用户提出需
|
| 121 |
| **Config** (ConfigTool) | 特殊 | 读取或修改 Claude Code 配置设置(ant 内部版本) | `setting` (必填), `value` (可选) |
|
| 122 |
| **Sleep** (SleepTool) | 特殊 | 让代理休眠一段时间。用于延迟执行或等待条件成熟 | 取决于实现 |
|
| 123 |
| **CronCreate** (CronCreateTool) | 特殊 | 创建定时触发任务(cron 调度) | 取决于实现 |
|
|
|
|
| 117 |
|
| 118 |
| 工具名称 | 分类 | 用途描述 | 关键参数 |
|
| 119 |
|----------|------|----------|----------|
|
| 120 |
+
| **AskUserQuestion** (AskUserQuestionTool) | 特殊 | 向用户提出 1-4 个多选题以澄清需求或做决策。走独立问答通道(不占用权限确认队列),本地 TUI 弹独立 overlay,桥接模式下同时转发给远程用户(claude.ai)竞速应答 | `questions` (必填, 1-4 个, 每题含 `question`/`header`/`options[{label,description,preview?}]` 2-4 个/`multiSelect`) |
|
| 121 |
| **Config** (ConfigTool) | 特殊 | 读取或修改 Claude Code 配置设置(ant 内部版本) | `setting` (必填), `value` (可选) |
|
| 122 |
| **Sleep** (SleepTool) | 特殊 | 让代理休眠一段时间。用于延迟执行或等待条件成熟 | 取决于实现 |
|
| 123 |
| **CronCreate** (CronCreateTool) | 特殊 | 创建定时触发任务(cron 调度) | 取决于实现 |
|