export declare const UNSET: unique symbol; export type FuncParam = { name: string; hasDefault: boolean; defaultValue: unknown; variadic: boolean; /** * True when the parameter's declared type is (or contains) a function type * — e.g. `block: () => void`, a union with a function arm, or a variadic * whose element type is a function. Set by the codegen from the static * `isFunctionTyped` predicate; consumed by `validateToolForLLM`. * * Defaults to false on legacy/handcrafted FuncParam values so the runtime * backstop fails open (i.e. doesn't block valid tools). */ isFunctionTyped?: boolean; /** * False when the parameter's declared type does NOT accept Result values — * i.e. it is not `Result`/`Result<...>`, not explicit `any`, and not a * union containing either. Set by codegen from the static * `paramAcceptsFailure` predicate (lib/typeChecker/utils.ts); consumed by * the failure-propagation check in invoke(). * * Absent on legacy/handcrafted FuncParam values, and absence fails OPEN * (the param accepts failures) — same convention as `isFunctionTyped`. */ acceptsResult?: boolean; boundValue?: unknown; isBound?: boolean; }; export type CallType = { type: "positional"; args: unknown[]; } | { type: "named"; positionalArgs: unknown[]; namedArgs: Record; /** Trailing-block argument from `f(name: val) as { ... }` syntax. * * In the positional case the block is simply appended to `args` * (it's always the next positional slot), so no separate field * is needed. In the named case earlier params may be filled by * name and intermediate params may need UNSET padding, so the * block must be bound by NAME to the last non-variadic * parameter — appending it as positional[N] would mis-fill * parameter N. resolveNamed synthesizes it into namedArgs under * the last param's name so the rest of fill logic treats it * uniformly. Without this, `f(name: val) as { ... }` silently * dropped the block. */ blockArg?: unknown; }; export type ToolDefinition = { name: string; description: string; schema: unknown; }; /** Retry-safety markers carried on a registered tool. Inline shape so the * runtime stays decoupled from the compiler's AST types. */ export type ToolMarkers = { destructive?: boolean; idempotent?: boolean; }; export type AgencyFunctionOpts = { name: string; module: string; fn: (...args: any[]) => any; params: FuncParam[]; toolDefinition: ToolDefinition | null; exported?: boolean; markers?: ToolMarkers; isPreapproved?: boolean; registeredName?: string; }; export declare class AgencyFunction { readonly __agencyFunction = true; readonly name: string; readonly module: string; readonly params: FuncParam[]; readonly toolDefinition: ToolDefinition | null; private readonly _fn; private readonly _unboundParams; private readonly _nonVariadicUnbound; private readonly _hasVariadic; private readonly _isBound; private readonly _checksFailures; readonly exported: boolean; readonly markers: ToolMarkers; private readonly _isPreapproved; /** The key this function's registered ancestor is stored under in the * function registry. `.rename()` changes `name` but not this, and the * other derivations carry it forward — `.partial()` and `.preapprove()` * directly, `.describe()` via `withToolDefinition()` — so a serialized * ref to any derived copy can find its registry entry again. Equal to * `name` for functions never renamed. */ readonly registeredName: string; constructor(opts: AgencyFunctionOpts); get isPreapproved(): boolean; get description(): string; get boundArgs(): { indices: number[]; values: unknown[]; originalParams: FuncParam[]; } | null; withToolDefinition(toolDefinition: ToolDefinition | null): AgencyFunction; getOriginalParams(): FuncParam[]; getUnboundParams(): FuncParam[]; invoke(descriptor: CallType): Promise; partial(bindings: Record): AgencyFunction; preapprove(): AgencyFunction; describe(description: string): AgencyFunction; /** * Return a copy of this function with a new name. The name is BOTH what the * LLM sees as the tool name and what tool-call dispatch matches against * (`prompt.ts` looks up the handler by `fn.name`), so `name` and * `toolDefinition.name` are updated together. * * `.partial()` and `.describe()` deliberately preserve the base name, so * deriving several tools from one function (e.g. `read.partial(dir)` as * `skillsDir` does) produces several tools that all share that base name. * Passing such a list to `llm({ tools })` is rejected by providers that * require unique tool names (Anthropic returns a 400). `.rename(...)` gives * each derived tool a distinct name. */ rename(newName: string): AgencyFunction; private mergeWithBound; private resolveArgs; private resolvePositional; private resolveNamed; /** * Runtime backstop invoked once per tool by `runPrompt` immediately before * issuing the LLM request. Throws if any required function-typed param is * unbound — duplicating (intentionally) the type checker's check at the * `llm(...)` site so dynamically-assembled tool arrays (`tools: [...base, * x]`) are also covered. The error wording uses the same builder as the * compile-time diagnostic so users see one consistent message. */ validateForLLM(): void; static isAgencyFunction(value: unknown): value is AgencyFunction; static create(opts: AgencyFunctionOpts, registry: Record): AgencyFunction; }