/** * Extension points for the Agent lifecycle. * * Each extension point is a hook that gets called at a specific phase. * Extensions are always optional and failures are isolated — a failing * extension never aborts the agent run. * * Plugins register extensions via `PluginAPI.extensions`, not by * directly importing this module. The Agent calls the registry in * order at each phase. */ import type { RunResult, UserInputPayload } from '../core/agent.js'; import type { Context } from '../core/context.js'; import type { ToolUseBlock } from '../types/blocks.js'; import type { Request, Response } from '../types/provider.js'; import type { ToolExecutionOutput } from '../types/tool-executor.js'; /** * Called before Agent.run() begins the main iteration loop. * Returns `false` or throws to prevent the run from starting. */ export type BeforeRunHook = (ctx: Context, input: UserInputPayload) => void | Promise; /** * Called after Agent.run() completes (or fails/aborts). * Receives the final RunResult, always called regardless of outcome. */ export type AfterRunHook = (ctx: Context, result: RunResult) => void | Promise; /** * Called right before each iteration of the agent loop. * The context is live (messages, signal, etc.) and can be inspected. * Modifications to ctx (e.g. ctx.messages, ctx.model) take effect * for the upcoming iteration. */ export type BeforeIterationHook = (ctx: Context, iterationIndex: number) => void | Promise; /** * Called after each iteration completes (tool results appended, * compaction done, but before the next loop iteration check). */ export type AfterIterationHook = (ctx: Context, iterationIndex: number) => void | Promise; /** * Called when the agent encounters an error during the provider call * or tool execution phase. The hook can return a modified context * or signal that recovery should be attempted. * * Return `{ action: 'retry', model?: string | undefined }` to retry the turn * (possibly with a different model). * Return `{ action: 'fail' }` to propagate the error. * Return `{ action: 'continue' }` to skip and continue the loop. */ export type OnErrorHook = (ctx: Context, err: unknown, phase: 'provider' | 'tool' | 'agent', iterationIndex: number) => { action: 'retry'; model?: string | undefined; } | { action: 'fail'; } | { action: 'continue'; } | void | Promise<{ action: 'retry'; model?: string | undefined; } | { action: 'fail'; } | { action: 'continue'; } | void>; /** * The default provider runner function signature — what the Agent's * built-in provider runner looks like. Extensions that wrap the provider * runner receive this as the `inner` parameter they can delegate to. */ export type ProviderRunnerFn = (ctx: Context, request: Request) => Promise; /** * Wrap or replace the provider call in the agent loop. * * The `inner` function is the default provider runner (with retries). * The extension can call it, modify the request/response, add caching, * or bypass it entirely. */ export type ProviderRunnerWrapper = (ctx: Context, request: Request, inner: ProviderRunnerFn) => Promise; /** * Called before a batch of tools is executed. Can modify or reject * the tool list. Return the (possibly filtered/modified) tool uses. */ export type BeforeToolExecutionHook = (ctx: Context, toolUses: ToolUseBlock[]) => ToolUseBlock[] | Promise; /** * Called after a batch of tools has been executed and results * are available. The extension can inspect or transform results * before they're appended to context. */ export type AfterToolExecutionHook = (ctx: Context, outputs: ToolExecutionOutput[]) => void | Promise; /** * An extension registered by a plugin or the host application. * * Every hook is optional — implement only the phases you need. * Hooks are called in registration order. A hook failure is * caught, logged, and does not prevent subsequent hooks from running. * * @example * ```ts * const myExt: AgentExtension = { * name: 'my-plugin-ext', * beforeIteration: async (ctx, idx) => { * console.log('Starting iteration', idx); * }, * }; * api.extensions.register(myExt); * ``` */ export interface AgentExtension { /** Unique name for this extension. Used in diagnostics and logging. */ name: string; /** Optional owner tag (plugin name or host identifier). */ owner?: string | undefined; beforeRun?: BeforeRunHook | undefined; afterRun?: AfterRunHook | undefined; beforeIteration?: BeforeIterationHook | undefined; afterIteration?: AfterIterationHook | undefined; onError?: OnErrorHook | undefined; wrapProviderRunner?: ProviderRunnerWrapper | undefined; beforeToolExecution?: BeforeToolExecutionHook | undefined; afterToolExecution?: AfterToolExecutionHook | undefined; } //# sourceMappingURL=extension-points.d.ts.map