import type { CostEstimate, MessageJSON, ModelName, PromptResult, TokenUsage, ToolCallJSON, UserContentInput } from "smoltalk"; import type { LLMRetryReason } from "./llmRetry.js"; import type { RuntimeContext } from "./state/context.js"; import type { StateStack } from "./state/stateStack.js"; import type { TraceEvent } from "./trace/types.js"; import type { RunNodeResult } from "./types.js"; export type CallbackMap = { onAgentStart: { nodeName: string; args: Record; messages: MessageJSON[]; cancel: (reason?: string) => void; }; onAgentEnd: { nodeName: string; result: RunNodeResult; }; onNodeStart: { nodeName: string; }; onNodeEnd: { nodeName: string; data: any; }; onLLMCallStart: { prompt: string | UserContentInput; tools: { name: string; description?: string; schema: any; }[]; model: ModelName | undefined; messages: MessageJSON[]; }; onLLMCallEnd: { model: string; result: PromptResult; usage: TokenUsage | undefined; cost: CostEstimate | undefined; timeTaken: number; messages: MessageJSON[]; }; onFunctionStart: { functionName: string; args: Record; moduleId: string; }; onFunctionEnd: { functionName: string; timeTaken: number; }; onToolCallStart: { toolName: string; args: Record; }; onToolCallEnd: { toolName: string; result: any; timeTaken: number; }; onLLMRetry: { attempt: number; maxRetries: number; delayMs: number; reason: LLMRetryReason; detail: string; }; onLLMTimeout: { limitMs: number; attempt: number; }; onStream: { type: "text"; text: string; } | { type: "tool_call"; toolCall: ToolCallJSON; } | { type: "done"; result: PromptResult; } | { type: "error"; error: any; }; onTrace: TraceEvent; onOAuthRequired: { serverName: string; authUrl: string; complete: Promise; cancel: () => void; }; onEmit: unknown; onThreadStart: { threadId: string; threadType: "thread" | "subthread"; parentThreadId?: string; label?: string; isResumption?: boolean; }; onThreadEnd: { threadId: string; label?: string; eagerSummarize: boolean; messages: MessageJSON[]; }; }; /** All callbacks (scoped + top-level + TS-passed) return `void`. Callback * bodies cannot raise interrupts — that is enforced statically by the * typechecker (see `checkCallbackBodyInterrupts`). A callback that * throws a JS error is caught and logged by `fireWithGuard`. */ export type CallbackReturn = void; export type AgencyCallbacks = { [K in keyof CallbackMap]?: (data: CallbackMap[K]) => void | Promise; }; export declare function registerGlobalHook(name: K, fn: (data: CallbackMap[K]) => void | Promise): void; /** Gather every callback registered for `name`, in fire order. `stack` is * the stack to walk for scoped callbacks — pass `ctx.stateStack` from * top-level call sites, or a branch's own stack from inside a fork branch * (otherwise scoped callbacks registered inside the branch's frame chain * are missed). */ export declare function gatherCallbacks(ctx: RuntimeContext, name: K, stack: StateStack): any[]; /** Whether any consumer is registered for `name` across all sources a fire * would reach: global hooks, scoped callbacks on `stack`, top-level * registrations, and a TS-passed callback. Mirrors what `invokeCallbacks` * actually fires, so callers can branch on "is anyone listening?" without * reaching into `ctx.callbacks` directly (which only sees the TS-passed * slot — the bug that made streaming ignore `callback("onStream")`). */ export declare function hasCallbackConsumer(ctx: RuntimeContext, name: K, stateStack?: StateStack): boolean; /** Fire every callback registered for `name`, sequentially. When * `stateStack` is supplied, callbacks run on that stack (so scoped * callbacks registered inside a branch's frame chain are found). When * `stateStack` is omitted, behaviour is identical to today's `callHook`: * scoped callbacks are walked from `ctx.stateStack` and the callback * frame pushes onto `ctx.stateStack`. * * Used directly by sites that fire inside a fork/tool branch (e.g. the * per-tool `onToolCallStart` / `onToolCallEnd` in `prompt.ts`). The * public `callHook` is now a thin wrapper that omits `stateStack`. * * `ctx` is optional — when omitted, it's resolved from the active ALS * frame via `getRuntimeContext()`. Every codegen-emitted `callHook(...)` * site omits it. Within this repo, the remaining explicit-ctx callers * are all in runtime code where an ALS frame *is* installed and the * param is redundant: * - `node.ts` — `onAgentStart` (inside `runInBootstrapFrame`) and * `onAgentEnd` (inside `agencyStore.run` with the real threads). * - `prompt.ts` — `onLLMCallStart`/`End` and the per-tool * `onToolCallStart`/`End`, all called from inside a * `Runner.runInScope` frame seeded by the generated node body. * Those sites pass `ctx` defensively (predating the ALS migration) * and could be tightened in a follow-up by dropping the param and * making it required-via-ALS again. The slot stays optional so * external callers that have a ctx but no ALS frame still work. */ export declare function invokeCallbacks(args: { ctx?: RuntimeContext; name: K; data: CallbackMap[K]; stateStack?: StateStack; }): Promise; /** Today's call sites that fire on the top-level stack. Thin wrapper over * `invokeCallbacks` with no `stateStack` override. */ export declare function callHook(args: { ctx?: RuntimeContext; name: K; data: CallbackMap[K]; }): Promise;