import type { ModelMessage } from "ai"; import type { PublicToolInputSchema, PublicToolOutputSchema, ToolModelOutput } from "#shared/tool-definition.js"; import type { SessionContext } from "#public/definitions/callback-context.js"; import type { NeedsApprovalContext } from "#public/definitions/tool.js"; import type { SessionAuth } from "#context/keys.js"; import type { HandleMessageStreamEvent } from "#protocol/message.js"; type ToolContext = SessionContext; /** * Stream event types allowed for dynamic tool resolvers. Dispatch * supports any event; this extract restricts the public surface until * more events are validated. */ export type DynamicToolEventName = Extract; export declare const ALLOWED_DYNAMIC_TOOL_EVENTS: ReadonlySet; /** * Instructions and skills are restricted to session/turn boundaries. * They feed the system prompt, the most cache-sensitive position in the * wire format; keeping them stable across steps within a turn maximizes * cache hits. */ export declare const ALLOWED_DYNAMIC_INSTRUCTION_EVENTS: ReadonlySet; export declare const ALLOWED_DYNAMIC_SKILL_EVENTS: ReadonlySet; /** * Context passed to a dynamic resolver's event handler (tools and skills). * * Exposes read-only session identity, auth, and channel metadata. State * is not exposed here; resolvers read it through `defineState` handles or * the session context inside tool `execute` functions. */ export interface DynamicResolveContext { readonly session: { readonly id: string; readonly auth: SessionAuth; }; /** Channel metadata for the request that triggered this resolve. */ readonly channel: { /** Channel type that produced the request (e.g. `"slack"`, `"http"`), when known. */ readonly kind?: string; /** Channel-owned resume handle for the conversation, when the channel supplies one. */ readonly continuationToken?: string; /** Free-form channel-specific metadata attached to the request. */ readonly metadata?: Readonly>; }; /** Conversation history visible at this resolve point, oldest first. */ readonly messages: readonly ModelMessage[]; } /** * A single tool entry within a resolved dynamic tool set. * * Identity comes from context: a single returned entry is named after * the file slug; entries in a returned `Record` * are each named `slug__key`. * * `TInput` defaults to `Record` but is inferred when * `inputSchema` is a Standard Schema (e.g. Zod) via the `defineTool` * wrapper. `TOutput` defaults to `any`; provide an `outputSchema` * (Standard Schema) to infer and check the executor return type. */ export interface DynamicToolEntry, TOutput = any> { readonly description: string; readonly inputSchema: PublicToolInputSchema; readonly outputSchema?: PublicToolOutputSchema; execute(input: TInput, ctx: ToolContext): TOutput | Promise; readonly toModelOutput?: (output: TOutput) => ToolModelOutput | Promise; /** * Optional per-call approval gate, mirroring the authored-tool * `needsApproval` contract: return `true` to require user approval * before the call executes. Only honored for step-scoped dynamic * tools, whose live `execute` closures survive into the harness; * session/turn-scoped tools replay from durable metadata and cannot * carry a function across replay. */ readonly needsApproval?: (ctx: NeedsApprovalContext) => boolean; } /** * A resolved tool set: keys are entry identifiers, values are * {@link DynamicToolEntry} objects created via `defineTool` inside a * resolver. Entry type params are `any` so entries with differing * schemas stay assignable to one Record; `defineTool` captures each * entry's concrete types before this widened container. */ export type DynamicToolSet = Readonly>>; /** * Return type for a `defineDynamic` event handler: a single tool entry * (named after the file slug), a map of entries (named `slug__key`), or * `null` for no tools. */ export type DynamicToolResult = DynamicToolEntry | DynamicToolSet | null; /** * Strongly-typed tool-handler map: each key is a supported event name, * each value a resolver that takes the stream event and resolve context * and returns a {@link DynamicToolResult}. `defineDynamic` accepts the * wider {@link DynamicEvents} (handlers return `unknown`) because the * slot directory (tools/ vs skills/) decides the expected return at * runtime. Reference `DynamicToolEvents` to check the tool-specific * return type at authoring time. */ export type DynamicToolEvents = { readonly [K in DynamicToolEventName]?: (event: unknown, ctx: DynamicResolveContext) => DynamicToolResult | Promise; }; /** * Base event handler map accepted by `defineDynamic`. Intentionally * wide so it accepts both tool-returning and skill-returning handlers: * the slot directory (tools/ vs skills/) determines the required return, * validated at runtime by the respective resolver. */ export type DynamicEvents = { readonly [K in DynamicToolEventName]?: (event: unknown, ctx: DynamicResolveContext) => unknown | Promise; }; /** * Marker discriminator for a `defineDynamic({ events })` export. */ export declare const DYNAMIC_SENTINEL_KIND: "eve:dynamic"; /** * Return value of `defineDynamic`: the runtime shape of a * `defineDynamic({ events })` export, stamped with a sentinel kind the * compiler/normalizer detects. */ export interface DynamicSentinel { readonly kind: typeof DYNAMIC_SENTINEL_KIND; readonly events: DynamicEvents; } export declare function isDynamicSentinel(value: unknown): value is DynamicSentinel; /** * Symbol-based brand stamped by `defineTool` on every entry. Invisible * in IntelliSense, checked at runtime to enforce the wrapper and to * distinguish a single entry from a map of entries. */ export declare const TOOL_BRAND: unique symbol; /** * Returns true if `value` carries the `defineTool` brand symbol. Used * to detect single entry vs map of entries and to validate that entries * are properly wrapped. */ export declare function isBrandedToolEntry(value: unknown): boolean; /** * Symbol-based brand stamped by `defineInstructions` on every entry. * Invisible in IntelliSense, checked at runtime to validate that dynamic * instruction resolver returns are properly wrapped. */ export declare const INSTRUCTIONS_BRAND: unique symbol; /** * Returns true if `value` carries the `defineInstructions` brand symbol. * Used to validate that dynamic instruction entries are properly wrapped. */ export declare function isBrandedInstructionsEntry(value: unknown): boolean; /** * Symbol-based brand stamped by `defineSkill` on every entry. Invisible * in IntelliSense, checked at runtime to detect single-entry vs * map-of-entries return shapes in dynamic skill resolvers. */ export declare const SKILL_BRAND: unique symbol; /** * Returns true if `value` carries the `defineSkill` brand symbol. Used * to detect single entry vs map of entries and to validate that entries * are properly wrapped. */ export declare function isBrandedSkillEntry(value: unknown): boolean; export {};