mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 07:03:25 +00:00
Add type guards for tool_result event narrowing
- Export isBashToolResult, isReadToolResult, etc. type guards - Update hooks.md with type guard usage examples - Document custom tool handling in hooks.md
This commit is contained in:
parent
3d9bad8fb6
commit
d353e5e219
5 changed files with 70 additions and 11 deletions
|
|
@ -11,6 +11,7 @@
|
||||||
- `ToolResultEventResult.result` renamed to `ToolResultEventResult.text` (removed), use `content` instead
|
- `ToolResultEventResult.result` renamed to `ToolResultEventResult.text` (removed), use `content` instead
|
||||||
- Hook handlers returning `{ result: "..." }` must change to `{ content: [{ type: "text", text: "..." }] }`
|
- Hook handlers returning `{ result: "..." }` must change to `{ content: [{ type: "text", text: "..." }] }`
|
||||||
- Built-in tool details types exported: `BashToolDetails`, `ReadToolDetails`, `GrepToolDetails`, `FindToolDetails`, `LsToolDetails`, `TruncationResult`
|
- Built-in tool details types exported: `BashToolDetails`, `ReadToolDetails`, `GrepToolDetails`, `FindToolDetails`, `LsToolDetails`, `TruncationResult`
|
||||||
|
- Type guards exported for narrowing: `isBashToolResult`, `isReadToolResult`, `isEditToolResult`, `isWriteToolResult`, `isGrepToolResult`, `isFindToolResult`, `isLsToolResult`
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -234,20 +234,26 @@ pi.on("tool_result", async (event, ctx) => {
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
The event type is a discriminated union based on `toolName`. TypeScript will narrow `details` to the correct type:
|
The event type is a discriminated union based on `toolName`. Use the provided type guards to narrow `details` to the correct type:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
pi.on("tool_result", async (event, ctx) => {
|
import { isBashToolResult, type HookAPI } from "@mariozechner/pi-coding-agent/hooks";
|
||||||
if (event.toolName === "bash") {
|
|
||||||
// event.details is BashToolDetails | undefined
|
export default function (pi: HookAPI) {
|
||||||
if (event.details?.truncation?.truncated) {
|
pi.on("tool_result", async (event, ctx) => {
|
||||||
// Access full output from temp file
|
if (isBashToolResult(event)) {
|
||||||
const fullPath = event.details.fullOutputPath;
|
// event.details is BashToolDetails | undefined
|
||||||
|
if (event.details?.truncation?.truncated) {
|
||||||
|
// Access full output from temp file
|
||||||
|
const fullPath = event.details.fullOutputPath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Available type guards: `isBashToolResult`, `isReadToolResult`, `isEditToolResult`, `isWriteToolResult`, `isGrepToolResult`, `isFindToolResult`, `isLsToolResult`.
|
||||||
|
|
||||||
#### Tool Details Types
|
#### Tool Details Types
|
||||||
|
|
||||||
Each built-in tool has a typed `details` field. Types are exported from `@mariozechner/pi-coding-agent`:
|
Each built-in tool has a typed `details` field. Types are exported from `@mariozechner/pi-coding-agent`:
|
||||||
|
|
@ -272,7 +278,18 @@ Common fields in details:
|
||||||
- `totalLines`, `totalBytes` - original size
|
- `totalLines`, `totalBytes` - original size
|
||||||
- `outputLines`, `outputBytes` - truncated size
|
- `outputLines`, `outputBytes` - truncated size
|
||||||
|
|
||||||
Custom tools use `CustomToolResultEvent` with `details: unknown`.
|
Custom tools use `CustomToolResultEvent` with `details: unknown`. You'll need to cast or validate:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
pi.on("tool_result", async (event, ctx) => {
|
||||||
|
if (event.toolName === "my-custom-tool") {
|
||||||
|
// Cast to your tool's details type
|
||||||
|
const details = event.details as MyCustomToolDetails;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Custom tools define their own details type in their `execute` function return value. The hook receives whatever the tool returned, but since the hook system doesn't know about custom tool types at compile time, it's typed as `unknown`.
|
||||||
|
|
||||||
**Note:** If you modify `content`, you should also update `details` accordingly. The TUI uses `details` (e.g., truncation info) for rendering, so inconsistent values will cause display issues.
|
**Note:** If you modify `content`, you should also update `details` accordingly. The TUI uses `details` (e.g., truncation info) for rendering, so inconsistent values will cause display issues.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,12 @@ export type {
|
||||||
TurnStartEvent,
|
TurnStartEvent,
|
||||||
WriteToolResultEvent,
|
WriteToolResultEvent,
|
||||||
} from "./types.js";
|
} from "./types.js";
|
||||||
|
export {
|
||||||
|
isBashToolResult,
|
||||||
|
isEditToolResult,
|
||||||
|
isFindToolResult,
|
||||||
|
isGrepToolResult,
|
||||||
|
isLsToolResult,
|
||||||
|
isReadToolResult,
|
||||||
|
isWriteToolResult,
|
||||||
|
} from "./types.js";
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,29 @@ export type ToolResultEvent =
|
||||||
| LsToolResultEvent
|
| LsToolResultEvent
|
||||||
| CustomToolResultEvent;
|
| CustomToolResultEvent;
|
||||||
|
|
||||||
|
// Type guards for narrowing ToolResultEvent to specific tool types
|
||||||
|
export function isBashToolResult(e: ToolResultEvent): e is BashToolResultEvent {
|
||||||
|
return e.toolName === "bash";
|
||||||
|
}
|
||||||
|
export function isReadToolResult(e: ToolResultEvent): e is ReadToolResultEvent {
|
||||||
|
return e.toolName === "read";
|
||||||
|
}
|
||||||
|
export function isEditToolResult(e: ToolResultEvent): e is EditToolResultEvent {
|
||||||
|
return e.toolName === "edit";
|
||||||
|
}
|
||||||
|
export function isWriteToolResult(e: ToolResultEvent): e is WriteToolResultEvent {
|
||||||
|
return e.toolName === "write";
|
||||||
|
}
|
||||||
|
export function isGrepToolResult(e: ToolResultEvent): e is GrepToolResultEvent {
|
||||||
|
return e.toolName === "grep";
|
||||||
|
}
|
||||||
|
export function isFindToolResult(e: ToolResultEvent): e is FindToolResultEvent {
|
||||||
|
return e.toolName === "find";
|
||||||
|
}
|
||||||
|
export function isLsToolResult(e: ToolResultEvent): e is LsToolResultEvent {
|
||||||
|
return e.toolName === "ls";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event data for branch event.
|
* Event data for branch event.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ export type {
|
||||||
ToolUIContext,
|
ToolUIContext,
|
||||||
} from "./core/custom-tools/index.js";
|
} from "./core/custom-tools/index.js";
|
||||||
export { discoverAndLoadCustomTools, loadCustomTools } from "./core/custom-tools/index.js";
|
export { discoverAndLoadCustomTools, loadCustomTools } from "./core/custom-tools/index.js";
|
||||||
// Hook system types
|
|
||||||
export type {
|
export type {
|
||||||
AgentEndEvent,
|
AgentEndEvent,
|
||||||
AgentStartEvent,
|
AgentStartEvent,
|
||||||
|
|
@ -62,6 +61,16 @@ export type {
|
||||||
TurnStartEvent,
|
TurnStartEvent,
|
||||||
WriteToolResultEvent,
|
WriteToolResultEvent,
|
||||||
} from "./core/hooks/index.js";
|
} from "./core/hooks/index.js";
|
||||||
|
// Hook system types and type guards
|
||||||
|
export {
|
||||||
|
isBashToolResult,
|
||||||
|
isEditToolResult,
|
||||||
|
isFindToolResult,
|
||||||
|
isGrepToolResult,
|
||||||
|
isLsToolResult,
|
||||||
|
isReadToolResult,
|
||||||
|
isWriteToolResult,
|
||||||
|
} from "./core/hooks/index.js";
|
||||||
export { messageTransformer } from "./core/messages.js";
|
export { messageTransformer } from "./core/messages.js";
|
||||||
export {
|
export {
|
||||||
type CompactionEntry,
|
type CompactionEntry,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue