fix(coding-agent): emit rpc prompt response after preflight closes #3049

This commit is contained in:
Mario Zechner
2026-04-15 21:59:45 +02:00
parent b920622110
commit 441c12956a
6 changed files with 467 additions and 131 deletions

View File

@@ -41,7 +41,7 @@ In particular, Node `readline` is not protocol-compliant for RPC mode because it
#### prompt
Send a user prompt to the agent. Returns immediately; events stream asynchronously.
Send a user prompt to the agent. The command response is emitted after the prompt is accepted, queued, or handled. Events continue streaming asynchronously after acceptance.
```json
{"id": "req-1", "type": "prompt", "message": "Hello, world!"}
@@ -72,6 +72,8 @@ Response:
{"id": "req-1", "type": "response", "command": "prompt", "success": true}
```
`success: true` means the prompt was accepted, queued, or handled immediately. `success: false` means the prompt was rejected before acceptance. Failures after acceptance are reported through the normal event and message stream, not as a second `response` for the same request id.
The `images` field is optional. Each image uses `ImageContent` format: `{"type": "image", "data": "base64-encoded-data", "mimeType": "image/png"}`.
#### steer

View File

@@ -182,6 +182,25 @@ unsubscribe = session.subscribe(() => {});
### Prompting and Message Queueing
`PromptOptions` controls prompt expansion, queueing behavior while streaming, and prompt preflight notifications:
```typescript
interface PromptOptions {
expandPromptTemplates?: boolean;
images?: ImageContent[];
streamingBehavior?: "steer" | "followUp";
source?: InputSource;
preflightResult?: (success: boolean) => void;
}
```
`preflightResult` is called once per `prompt()` invocation:
- `true` when the prompt was accepted, queued, or handled immediately
- `false` when prompt preflight rejected before acceptance
It fires before `prompt()` resolves. `prompt()` still resolves only after the full accepted run finishes, including retries. Failures after acceptance are reported through the normal event and message stream, not through `preflightResult(false)`.
The `prompt()` method handles prompt templates, extension commands, and message sending:
```typescript
@@ -200,8 +219,10 @@ await session.prompt("After you're done, also check X", { streamingBehavior: "fo
**Behavior:**
- **Extension commands** (e.g., `/mycommand`): Execute immediately, even during streaming. They manage their own LLM interaction via `pi.sendMessage()`.
- **File-based prompt templates** (from `.md` files): Expanded to their content before sending/queueing.
- **File-based prompt templates** (from `.md` files): Expanded to their content before sending or queueing.
- **During streaming without `streamingBehavior`**: Throws an error. Use `steer()` or `followUp()` directly, or specify the option.
- **`preflightResult(true)`**: Means the prompt was accepted, queued, or handled immediately.
- **`preflightResult(false)`**: Means preflight rejected before acceptance.
For explicit queueing during streaming: