feat(mode): ask_user_question joins the plan allowlist; the section steers to the exit tool

Live-session feedback (a real Zed elicitation round-trip): the model
presented its finished plan as a plain reply and asked the USER to
switch modes — the exact reversal the roadmap warns about — because the
shipped section's 'present it with the exit_plan_mode tool' read as a
suggestion. The section now says a finished plan is delivered by
calling exit_plan_mode, preferred over pasting it as a plain reply or
asking the user to switch modes — firmer, without imperatives.

ask_user_question enters the shipped plan allowlist (asking is
read-only-safe), and the section points a blocked decision at it. The
plan-acp-agent example composes the bash family (default mode only —
plan's allowlist keeps excluding it, so the two modes now demo a real
difference) plus tool-ask-user; both recorded scenarios re-recorded:
the pin now shows plan = [ask_user_question, exit_plan_mode, read,
todo_write] and post-exit default = the full eight-tool surface.
This commit is contained in:
kingwl
2026-07-10 15:05:26 +08:00
parent 14f7976e3d
commit 02e0756b78
12 changed files with 1127 additions and 1029 deletions

View File

@@ -159,7 +159,7 @@ set(agent: Agent, mode: string): void
Types: [Agent](../core-data-structures/core.md)
Source: [`packages/mode/mode/src/index.ts:202`](../../packages/mode/mode/src/index.ts)
Source: [`packages/mode/mode/src/index.ts:205`](../../packages/mode/mode/src/index.ts)
## `ctx.sessionPersistence` — `SessionPersistence` (abstract seam)

View File

@@ -43,10 +43,10 @@ Mode definitions are validated plugin Config — per repo convention, changeable
section: |
You are in plan mode: explore and design, then present the
plan for approval through exit_plan_mode.
tools: [read, todo_write, web_search, web_fetch, exit_plan_mode]
tools: [read, todo_write, web_search, web_fetch, ask_user_question, exit_plan_mode]
```
`plan`'s shipped default allowlist is the read-only surface (`read`, `todo_write`, `web_search`/`web_fetch`, `exit_plan_mode`) with `bash` and `subagent` excluded until the sandbox family can actually confine them — a deployment that accepts the risk widens its own config today. `default` is reserved (the absence of policy) and rejected as a key; an unknown mode name fails validation loudly at `set()` time.
`plan`'s shipped default allowlist is the read-only surface (`read`, `todo_write`, `web_search`/`web_fetch`, `ask_user_question`, `exit_plan_mode`) with `bash` and `subagent` excluded until the sandbox family can actually confine them — a deployment that accepts the risk widens its own config today. `default` is reserved (the absence of policy) and rejected as a key; an unknown mode name fails validation loudly at `set()` time.
### In the terminal