Add ask_user_question interaction tool

This commit is contained in:
Yichen Jiang
2026-06-25 22:51:38 +08:00
parent 329371a529
commit 08fc8467bc
31 changed files with 1083 additions and 16 deletions

View File

@@ -50,6 +50,7 @@ Dependency rule: **extension** plugins depend on interface packages, never on `d
| `ctx.sessionPersistence` | `SessionPersistence` (abstract) | dsh-session-persistence | durable persistence seam: create/append/load/list sessions |
| `ctx.systemPrompt` | `SystemPrompt` | dsh-system-prompt | ordered sections + tool schemas → `assemble()` |
| `ctx.tools` | `ToolRegistry` | dsh-tools | tool definitions; `execute()` through waterfall |
| `ctx.userInteraction` | `UserInteractionService` | dsh-user-interaction | UI-backed human question/answer seam for tools and permission flows |
| `ctx.agents` | `AgentRegistry` | dsh-agent | live `Agent` handles + the create/resume factory seam (returns an `AgentHandle` = `{ agent, dispose() }` for owned per-agent teardown) |
| `ctx.agentLoop` | `AgentLoop` | dsh-agent-loop | creates `ReactLoopAgent`s and drives their loops |
| `ctx.bash` | `BashExecutor` (abstract) | dsh-bash | bash execution seam: foreground runs + background tasks |
@@ -198,7 +199,7 @@ Every MVP feature (including the TODO-marked ones), with the mechanism that impl
| Built-in tools (Read/Write/Edit/Bash/…) | `ctx.tools.register()`; schemas flow into the assembly automatically. **Bash: implemented**`dsh-bash` (seam) + `dsh-bash-local` (subprocesses) + `dsh-tool-bash` (`bash`/`bash_output`/`bash_kill`, incl. background tasks) |
| ToolSearch / progressive disclosure | wrap `agent/request`, filter `req.tools` |
| Tool sandbox (landlock / sandbox-exec) | wrap `tools/execute`, or implement a sandboxing `BashExecutor` (the dsh-bash seam) |
| Permission system / AskUserQuestion | wrap `tools/execute` (veto or ask); register an ask tool |
| Permission system / AskUserQuestion | `dsh-user-interaction` provides `ctx.userInteraction`; `dsh-tool-ask-user` registers `ask_user_question`; permission plugins can also wrap `tools/execute` and ask before delegating |
| Plan mode | wrap `tools/execute` (deny writes) + `agent/request` (inject mode prompt) |
| Sub-agents (spawn / fork / steer) | TODO seam on `AgentLoop.create()`; fork = seed Session with parent events; `steer()` on the child handle |
| MCP | one plugin per server: discover tools → `ctx.tools.register()` |

View File

@@ -301,7 +301,7 @@ Source: [`packages/core/tools/src/index.ts:43`](../../packages/core/tools/src/in
## Services
The 9 `ctx.<key>` services the harness provides. An abstract seam (e.g. `ctx.bash`) is implemented by a separate package; the interface is what consumers code against.
The 10 `ctx.<key>` services the harness provides. An abstract seam (e.g. `ctx.bash`) is implemented by a separate package; the interface is what consumers code against.
### `ctx.agentLoop` — `AgentLoop`
@@ -454,6 +454,17 @@ Types: [ToolDefinition](../core-data-structures/tools.md) · [ToolExecution](../
Source: [`packages/core/tools/src/index.ts:277`](../../packages/core/tools/src/index.ts)
### `ctx.userInteraction` — `UserInteractionService`
`ctx.userInteraction`: one active UI provider plus an `ask()` surface.
```ts cordis-catalog
registerProvider(provider: UserInteractionProvider): () => void
async ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>
```
Source: [`packages/core/user-interaction/src/index.ts:72`](../../packages/core/user-interaction/src/index.ts)
## Inherited tier (cordis core + loader/hmr/timer)
The framework surface every plugin inherits, beyond the harness vocabulary above. This is pinned vendor source ([vendoring policy](../../vendor/README.md)); it is summarized here so the catalog is a complete picture of what `ctx` and the event bus offer, without elevating framework internals to the harness tier's prominence.

View File

@@ -31,9 +31,7 @@ graph TD
tools --> agent
tools --> llm
tools --> system-prompt
ui-stdio --> agent
ui-stdio --> llm
ui-stdio --> session
user-interaction --> agent
acp --> agent
acp --> llm
acp --> session
@@ -48,10 +46,16 @@ graph TD
subagent --> agent
subagent --> llm
subagent --> tools
tool-ask-user --> agent
tool-ask-user --> tools
tool-ask-user --> user-interaction
tool-bash --> agent
tool-bash --> bash
tool-bash --> llm
tool-bash --> tools
ui-stdio --> agent
ui-stdio --> session
ui-stdio --> user-interaction
agent-core --> agent
agent-core --> agent-loop
agent-core --> invariants
@@ -81,7 +85,9 @@ graph TD
stdio-agent --> agent-core
stdio-agent --> session
stdio-agent --> session-persistence-jsonl
stdio-agent --> tool-ask-user
stdio-agent --> ui-stdio
stdio-agent --> user-interaction
subagent-fork --> agent
subagent-fork --> session
subagent-fork --> subagent
@@ -107,17 +113,19 @@ graph TD
| `session-persistence-jsonl` | `session`, `session-persistence` |
| `session-persistence-sqlite` | `session`, `session-persistence` |
| `tools` | `agent`, `llm`, `system-prompt` |
| `ui-stdio` | `agent`, `llm`, `session` |
| `user-interaction` | `agent` |
| `acp` | `agent`, `llm`, `session`, `session-persistence`, `tools` |
| `agent-loop` | `agent`, `llm`, `session`, `session-persistence`, `system-prompt`, `tools` |
| `subagent` | `agent`, `llm`, `tools` |
| `tool-ask-user` | `agent`, `tools`, `user-interaction` |
| `tool-bash` | `agent`, `bash`, `llm`, `tools` |
| `ui-stdio` | `agent`, `session`, `user-interaction` |
| `agent-core` | `agent`, `agent-loop`, `invariants`, `llm`, `session`, `system-prompt`, `tool-bash`, `tools` |
| `subagent-acp` | `agent`, `llm`, `subagent` |
| `subagent-inprocess` | `agent`, `llm`, `session`, `subagent` |
| `subagent-mock` | `agent`, `llm`, `subagent` |
| `tool-subagent` | `agent`, `llm`, `subagent`, `tools` |
| `acp-agent` | `acp`, `agent-core`, `session-persistence-jsonl` |
| `stdio-agent` | `agent`, `agent-core`, `session`, `session-persistence-jsonl`, `ui-stdio` |
| `stdio-agent` | `agent`, `agent-core`, `session`, `session-persistence-jsonl`, `tool-ask-user`, `ui-stdio`, `user-interaction` |
| `subagent-fork` | `agent`, `session`, `subagent`, `subagent-inprocess` |
| `subagent-spawn` | `subagent`, `subagent-inprocess` |