import type { AgencyFunction, ToolDefinition } from "./agencyFunction.js"; import type { StateStack } from "./state/stateStack.js"; import type { MessageThread } from "./state/messageThread.js"; import type { StatelogClient } from "../statelogClient.js"; /** What one intrinsic call sees. Deliberately narrow: an intrinsic * manipulates the RUN (frames, drafts), not the outside world, so it * gets the call, the stack, and the threaded schema — nothing else. * Widen this type only when a new intrinsic genuinely needs more. */ export type IntrinsicCall = { toolCall: { id: string; name: string; arguments: Record; }; stateStack: StateStack; /** Zod schema threaded by the llm() codegen (saveDraft's value * type); undefined when the call site had none. */ draftSchema: unknown; }; /** A tool the tool loop handles ITSELF, inline in the ordered pass, * instead of dispatching into the concurrent pool. The loop owns all * the generic bookkeeping — resume idempotency, statelog events, * callbacks, the tool-result message — so `handle` is just the * semantics and must be fast, synchronous, and interrupt-free. * The registry is CLOSED: intrinsics touch run state, which is * exactly what user tools must never do, so additions are code * changes here, not a user-facing extension point. */ export type IntrinsicTool = { /** Identity check against a tools-array entry (name+module pair, * never object identity — the prelude auto-import means modules * hold their own wrapper objects). */ matches: (fn: AgencyFunction) => boolean; /** The provider-facing definition, replacing the def's own. Receives * the matched function so a renamed tool advertises its renamed * name — the name the model calls and dispatch matches against. */ buildDefinition: (ctx: { draftSchema: unknown; fn: AgencyFunction; }) => ToolDefinition; /** Handle one call; the return value is the tool-result text. * Contract note: EVERY call must produce a tool-result message * (providers reject a tool_use with no result), and for now that * result is plain text — every intrinsic is a state write plus an * acknowledgment. If a future intrinsic needs a richer result * (attachments, structured content), widen this return type then; * the loop's plumbing is the only consumer. */ handle: (call: IntrinsicCall) => string; }; export declare function findIntrinsic(fn: AgencyFunction): IntrinsicTool | undefined; /** One round's calls, split once, declaratively: intrinsic entries * (with their original call-list index, for stable step keys) and * everything else, which dispatches concurrently as always. The loop * never re-derives membership — these two lists are the answer. */ export declare function partitionIntrinsicCalls; }>(toolCalls: T[], toolFunctions: AgencyFunction[]): { intrinsicCalls: { toolCall: T; callIndex: number; intrinsic: IntrinsicTool; }[]; dispatchCalls: T[]; }; /** * Run one intrinsic call: the handler plus every piece of generic * bookkeeping a dispatched tool would get — the toolExecution span, * the toolCallStart/toolCall statelog events, the onToolCallStart/End * hooks, and the tool-result message push. The tool loop's ordered * pass calls this inside a `pr.step` (resume idempotency stays with * the loop). The lifecycle mirrors the real dispatch path's events * inside one span so span-pairing consumers see intrinsic calls too; * deliberate differences from that path: one step instead of * per-phase branch steps (there is no branch), and timeTaken 0 (an * inline state write has no meaningful duration). */ export declare function runIntrinsicCall(opts: { intrinsic: IntrinsicTool; toolCall: { id: string; name: string; arguments: Record; }; stateStack: StateStack; draftSchema: unknown; statelogClient: StatelogClient; ctx: unknown; model: unknown; messages: MessageThread; }): Promise;