import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js"; import type { PublicToolDefinition, ToolModelOutput } from "#shared/tool-definition.js"; import type { SessionContext } from "#public/definitions/callback-context.js"; import type { JsonObject } from "#shared/json.js"; import type { AuthorizationDefinition, NonInteractiveAuthorizationDefinition, TokenResult } from "#runtime/connections/types.js"; import { type DynamicEvents, type DynamicSentinel } from "#shared/dynamic-tool-definition.js"; type ApprovalToolInput = TInput extends object ? Readonly : TInput; type ApprovalContextInput = unknown extends TInput ? Record : TInput; /** * Context passed to a tool's {@link ToolDefinition.needsApproval} function. * * `approvedTools` is the set of tool names (or compound approval keys) * already approved at least once in the current session. `toolName` is the * runtime name of the tool being evaluated. `toolInput` is the raw input the * model passed, available for input-aware decisions (e.g. per-connection scoping). */ export interface NeedsApprovalContext> { readonly approvedTools: ReadonlySet; readonly toolInput?: ApprovalToolInput; readonly toolName: string; } export type { ToolModelOutput } from "#shared/tool-definition.js"; /** * Authorization strategy declared on a {@link ToolDefinition} via the * `auth` field. Accepts the same shapes as a connection's `auth`: * - a `getToken`-only object (static API keys, pre-provisioned JWTs); * `principalType` may be omitted and defaults to `"app"`. * - a full interactive OAuth definition (e.g. `connect("okta")` from * `@vercel/connect/eve`, or {@link defineInteractiveAuthorization}). */ export type ToolAuthDefinition = (Omit & { readonly principalType?: NonInteractiveAuthorizationDefinition["principalType"]; }) | AuthorizationDefinition; /** * Authored tool context. Passed as the last argument to * {@link ToolDefinition.execute}. * * Extends {@link SessionContext} with token accessors. {@link getToken} and * {@link requireAuth} only do useful work when the tool declares `auth`; * calling them on a tool without `auth` throws. */ export type ToolContext = SessionContext & { /** * Resolves the bearer token for this tool's declared `auth`, * consulting the per-step token cache before invoking the authored * `getToken`. For interactive strategies a cache miss throws * `ConnectionAuthorizationRequiredError`; the runtime catches it, * suspends the turn on a framework-owned callback URL, shows a * "Sign in" affordance, and re-runs the tool after the OAuth * callback completes. * * Throws when the tool does not declare an `auth` strategy. */ getToken(): Promise; /** * Signals that the caller must complete this tool's authorization flow * before proceeding. Throws `ConnectionAuthorizationRequiredError`, which * the runtime converts into a consent prompt (for interactive strategies) * and re-runs the tool after sign-in. Use it to gate a tool on * authorization without resolving a token first. */ requireAuth(): never; }; /** * Public tool definition authored in `agent/tools/*.ts`. * * The tool's runtime name is the filename slug under `agent/tools/` without * the extension (`agent/tools/get_weather.ts` registers as `get_weather`). * Authored definitions have no `name` field; identity is path-derived. */ export type ToolDefinition = PublicToolDefinition & { execute(input: TInput, ctx: ToolContext): Promise | TOutput; /** * Optional authorization strategy. When set, the execute context gains a * working {@link ToolContext.getToken} / {@link ToolContext.requireAuth}, * and a thrown `ConnectionAuthorizationRequiredError` (implicit from * `getToken()` or explicit via `requireAuth()`) drives the framework's * interactive consent flow, the same machinery MCP connections use, scoped * to this tool's name. * * Use `connect("...")` from `@vercel/connect/eve` for Vercel * Connect-backed OAuth, {@link defineInteractiveAuthorization} for a * custom interactive flow, or a plain `{ getToken }` object for * static/pre-provisioned credentials. */ auth?: ToolAuthDefinition; /** * Optional per-tool approval gate. The return value determines whether * user approval is required before executing this tool. * * Use the helpers from `eve/tools/approval` for common cases: * - {@link always}: always require approval * - {@link never}: never require approval * - {@link once}: require approval only the first time per session */ needsApproval?: (ctx: NeedsApprovalContext>) => boolean; /** * Optional projection controlling what the model sees as the tool result. * Receives the full `TOutput` from {@link execute} and returns the * model-facing {@link ToolModelOutput}. * * When omitted, the model sees the full `execute` return value * (default AI SDK serialization). Channel event handlers * (`action.result`) always receive the full output regardless. */ toModelOutput?: (output: TOutput) => ToolModelOutput | Promise; }; /** * Defines a tool configuration, used both for static tools (default export * from `agent/tools/*.ts`) and as the entry wrapper inside `defineDynamic` * resolvers. * * For static tools, the runtime tool name is the filename slug. `defineTool` * stamps a brand that lifecycle code validates; it rejects raw object literals. */ export declare function defineTool, TOutputSchema extends StandardJSONSchemaV1>(definition: { description: ToolDefinition["description"]; inputSchema: TInputSchema; outputSchema: TOutputSchema; execute(input: StandardJSONSchemaV1.InferOutput, ctx: ToolContext): Promise> | StandardJSONSchemaV1.InferOutput; needsApproval?: ToolDefinition, unknown>["needsApproval"]; toModelOutput?: ToolDefinition>["toModelOutput"]; auth?: ToolAuthDefinition; }): ToolDefinition, StandardJSONSchemaV1.InferOutput>; export declare function defineTool, TOutput>(definition: { description: ToolDefinition["description"]; inputSchema: TSchema; outputSchema?: JsonObject; execute(input: StandardJSONSchemaV1.InferOutput, ctx: ToolContext): Promise | TOutput; needsApproval?: ToolDefinition, unknown>["needsApproval"]; toModelOutput?: ToolDefinition["toModelOutput"]; auth?: ToolAuthDefinition; }): ToolDefinition, TOutput>; export declare function defineTool>(definition: { description: ToolDefinition["description"]; inputSchema: JsonObject; outputSchema: TOutputSchema; execute(input: Record, ctx: ToolContext): Promise> | StandardJSONSchemaV1.InferOutput; needsApproval?: ToolDefinition, unknown>["needsApproval"]; toModelOutput?: ToolDefinition>["toModelOutput"]; auth?: ToolAuthDefinition; }): ToolDefinition, StandardJSONSchemaV1.InferOutput>; export declare function defineTool(definition: { description: ToolDefinition["description"]; inputSchema: JsonObject; outputSchema?: JsonObject; execute(input: Record, ctx: ToolContext): Promise | TOutput; needsApproval?: ToolDefinition, unknown>["needsApproval"]; toModelOutput?: ToolDefinition["toModelOutput"]; auth?: ToolAuthDefinition; }): ToolDefinition, TOutput>; export declare function defineTool(definition: ToolDefinition): ToolDefinition; /** * Defines a dynamic resolver evaluated at runtime from stream-event * handlers. It is shared across three slots, and the directory it is * authored in (not this function) decides what each handler must return * and which events are honored. The file's path-derived slug names the * single-entry case; a `Record` return names entries * `slug__key`. Return `null` to contribute nothing for that event. * * Per-slot return shape: * - `agent/tools/`: return a single `defineTool(...)`, a * `Record`, or `null`. * - `agent/skills/`: return a single `defineSkill(...)`, a * `Record`, or `null`. * - `agent/instructions/`: return a single `defineInstructions({ markdown })`, * which lowers to one `{ role: "system", content: markdown }` message, * or `null`. (Maps are not meaningful here.) * * Per-slot events: tools resolvers run at `session.started`, * `turn.started`, and `step.started`. Instructions and skills resolvers * contribute to the system prompt, so for cache stability they run only * at `session.started` and `turn.started`; the runtime never invokes a * handler keyed on `step.started` in those slots. * * ```ts * import { defineDynamic, defineTool } from "eve/tools"; * import { z } from "zod"; * * export default defineDynamic({ * events: { * "session.started": async (event, ctx) => ({ * export: defineTool({ * description: "Export data", * inputSchema: z.object({ format: z.string() }), * async execute(input) { * return doExport(input.format); * }, * }), * }), * }, * }); * ``` * * A single return is named after the file slug. A map names each entry by its * bare key — there is no automatic slug prefix, so namespace keys yourself * (e.g. `team__playbook`) when a bare name might collide. A dynamic tool/skill * whose name matches an authored one overrides it; two dynamic resolvers * emitting the same name is an error. */ export declare function defineDynamic(definition: { readonly events: DynamicEvents; }): DynamicSentinel; /** * Marker discriminator written into every {@link DisabledToolSentinel}. */ declare const DISABLED_TOOL_SENTINEL_KIND = "eve:disabled-tool"; /** * Marker value returned from {@link disableTool}. Export this as the default * export of a file in `agent/tools/` to remove the framework default whose * name matches the file's slug. */ export interface DisabledToolSentinel { readonly kind: typeof DISABLED_TOOL_SENTINEL_KIND; } /** * Returns a sentinel that disables the framework tool whose name matches the * containing file's slug. */ export declare function disableTool(): DisabledToolSentinel; /** * Type guard: returns whether `value` is a {@link DisabledToolSentinel} * produced by {@link disableTool}. */ export declare function isDisabledToolSentinel(value: unknown): value is DisabledToolSentinel; /** * Marker discriminator written into the {@link ExperimentalWorkflow} opt-in * sentinel. */ declare const ENABLE_WORKFLOW_TOOL_SENTINEL_KIND = "eve:enable-workflow-tool"; /** * Marker value re-exported as the default export of a file in `agent/tools/` * (conventionally `agent/tools/workflow.ts`) to enable the framework `Workflow` * orchestration tool. The tool is off unless this marker is present, * mirroring the {@link disableTool} opt-out in reverse. */ export interface EnableWorkflowToolSentinel { readonly kind: typeof ENABLE_WORKFLOW_TOOL_SENTINEL_KIND; } /** * Opt-in marker for the framework `Workflow` tool, a code-mode sandbox whose * only callable operations are this agent's subagents and remote agents, for * orchestrating them from model-authored JavaScript. Re-export it as the * default export of `agent/tools/workflow.ts`: * * ```ts * export { ExperimentalWorkflow as default } from "eve/tools"; * ``` * * The capability is experimental. The resulting model-facing tool is still * called `Workflow`. */ export declare const ExperimentalWorkflow: EnableWorkflowToolSentinel; /** * Type guard: returns whether `value` is the {@link ExperimentalWorkflow} * opt-in sentinel. */ export declare function isEnableWorkflowToolSentinel(value: unknown): value is EnableWorkflowToolSentinel;