Add setEditorText/getEditorText to hook UI context, improve custom() API

- Add setEditorText() and getEditorText() to HookUIContext for prompt generator pattern
- custom() now accepts async factories for fire-and-forget work
- Add CancellableLoader component to tui package
- Add BorderedLoader component for hooks with cancel UI
- Export HookAPI, HookContext, HookFactory from main package
- Update all examples to import from packages instead of relative paths
- Update hooks.md and custom-tools.md documentation

fixes #350
This commit is contained in:
Mario Zechner 2026-01-01 00:04:56 +01:00
parent 02d0d6e192
commit 6f7c10e323
39 changed files with 477 additions and 163 deletions

View file

@ -198,6 +198,29 @@ async execute(toolCallId, params, onUpdate, ctx, signal) {
}
```
### Error Handling
**Throw an error** when the tool fails. Do not return an error message as content.
```typescript
async execute(toolCallId, params, onUpdate, ctx, signal) {
const { path } = params as { path: string };
// Throw on error - pi will catch it and report to the LLM
if (!fs.existsSync(path)) {
throw new Error(`File not found: ${path}`);
}
// Return content only on success
return { content: [{ type: "text", text: "Success" }] };
}
```
Thrown errors are:
- Reported to the LLM as tool errors (with `isError: true`)
- Emitted to hooks via `tool_result` event (hooks can inspect `event.isError`)
- Displayed in the TUI with error styling
## CustomToolContext
The `execute` and `onSession` callbacks receive a `CustomToolContext`: