chenbhao commited on
Commit
0f215fe
·
1 Parent(s): 044c1b2

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 调度) | 取决于实现 |