feat(coding-agent): add input event for extension input interception (#761)

* feat(coding-agent): add input event for extension input interception

Extensions can now intercept, transform, or handle user input before the
agent processes it. Three result types: continue (pass through), transform
(modify text/images), handled (respond without LLM). Handlers chain
transforms and short-circuit on handled. Source field identifies origin.

* fix: make source public, use if/else over ternary

* fix: remove response field, extension handles own UI
This commit is contained in:
Nico Bailon 2026-01-15 17:41:56 -08:00 committed by GitHub
parent 012319e15a
commit 3e5d91f287
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 282 additions and 5 deletions

View file

@ -256,6 +256,7 @@ pi starts
user sends prompt ─────────────────────────────────────────┐
│ │
├─► input (can transform or handle completely) │
├─► before_agent_start (can inject message, modify system prompt)
├─► agent_start │
│ │
@ -574,6 +575,30 @@ pi.on("user_bash", (event, ctx) => {
**Examples:** [ssh.ts](../examples/extensions/ssh.ts), [interactive-shell.ts](../examples/extensions/interactive-shell.ts)
### Input Events
#### input
Fired when user input is received, before agent processing. Can transform or handle completely.
```typescript
pi.on("input", async (event, ctx) => {
// event.text, event.images, event.source ("interactive" | "rpc" | "extension")
if (event.text.startsWith("?quick "))
return { action: "transform", text: `Respond briefly: ${event.text.slice(7)}` };
if (event.text === "ping") {
ctx.ui.notify("pong", "info"); // Extension handles its own feedback
return { action: "handled" }; // Skip LLM
}
return { action: "continue" }; // Default: pass through
});
```
**Results:** `continue` (pass through), `transform` (modify text/images), `handled` (skip LLM). Transforms chain; first "handled" wins. See [input-transform.ts](../examples/extensions/input-transform.ts).
## ExtensionContext
Every handler receives `ctx: ExtensionContext`: