// Extension hook registry: transform user input, and intercept tool calls (deny / rewrite args / // post-process results). Extensions register a ToolHooks object; the agent runs them in order. import type { ToolResult } from "./tools.ts"; export interface ToolHooks { onUserMessage?(text: string): string | undefined | Promise; beforeTool?( name: string, args: Record, ): { deny?: string; args?: Record } | void | Promise<{ deny?: string; args?: Record } | void>; afterTool?(name: string, args: Record, result: ToolResult): ToolResult | undefined | Promise; } const hooks: ToolHooks[] = []; export function addHook(h: ToolHooks): void { hooks.push(h); } export async function transformInput(text: string): Promise { for (const h of hooks) if (h.onUserMessage) text = (await h.onUserMessage(text)) ?? text; return text; } export async function beforeTool(name: string, args: Record): Promise<{ deny?: string; args: Record }> { let cur = args; for (const h of hooks) { if (!h.beforeTool) continue; const r = await h.beforeTool(name, cur); if (r?.deny) return { deny: r.deny, args: cur }; if (r?.args) cur = r.args; } return { args: cur }; } export async function afterTool(name: string, args: Record, result: ToolResult): Promise { for (const h of hooks) if (h.afterTool) result = (await h.afterTool(name, args, result)) ?? result; return result; }