UNPKG

@mastra/core

Version:

Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.

267 lines 11.2 kB
import type { Mastra } from '../mastra/index.js'; import type { PublicSchema, StandardSchemaWithJSON, InferPublicSchema } from '../schema/index.js'; import type { McpMetadata, MCPToolProperties, ToolAction, ToolExecutionContext, ToolPayloadTransform } from './types.js'; /** * Marker to identify Mastra tools even when `instanceof` fails. * This can happen in environments like Vite SSR where the same module * may be loaded multiple times, creating different class instances. * Uses Symbol.for() so the same symbol is shared across module copies. * Follows the naming convention: <org>.<product>.<category>.<className> */ export declare const MASTRA_TOOL_MARKER: unique symbol; /** * A type-safe tool that agents and workflows can call to perform specific actions. * * @template TSchemaIn - Input schema type * @template TSchemaOut - Output schema type * @template TSuspendSchema - Suspend operation schema type * @template TResumeSchema - Resume operation schema type * @template TContext - Execution context type * * @example Basic tool with validation * ```typescript * const weatherTool = createTool({ * id: 'get-weather', * description: 'Get weather for a location', * inputSchema: z.object({ * location: z.string(), * units: z.enum(['celsius', 'fahrenheit']).optional() * }), * execute: async (inputData) => { * return await fetchWeather(inputData.location, inputData.units); * } * }); * ``` * * @example Tool requiring approval * ```typescript * const deleteFileTool = createTool({ * id: 'delete-file', * description: 'Delete a file', * requireApproval: true, * inputSchema: z.object({ filepath: z.string() }), * execute: async (inputData) => { * await fs.unlink(inputData.filepath); * return { deleted: true }; * } * }); * ``` * * @example Tool with Mastra integration * ```typescript * const saveTool = createTool({ * id: 'save-data', * description: 'Save data to storage', * inputSchema: z.object({ key: z.string(), value: z.any() }), * execute: async (inputData, context) => { * const storage = context?.mastra?.getStorage(); * await storage?.set(inputData.key, inputData.value); * return { saved: true }; * } * }); * ``` */ export declare class Tool<TSchemaIn = unknown, TSchemaOut = unknown, TSuspendSchema = unknown, TResumeSchema = unknown, TContext extends ToolExecutionContext<TSuspendSchema, TResumeSchema, any> = ToolExecutionContext<TSuspendSchema, TResumeSchema>, TId extends string = string, TRequestContext extends Record<string, any> | unknown = unknown> implements ToolAction<TSchemaIn, TSchemaOut, TSuspendSchema, TResumeSchema, TContext, TId, TRequestContext> { /** Unique identifier for the tool */ id: TId; /** Description of what the tool does */ description: string; /** Schema for validating input parameters */ inputSchema?: StandardSchemaWithJSON<TSchemaIn>; /** Schema for validating output structure */ outputSchema?: StandardSchemaWithJSON<TSchemaOut>; /** Schema for suspend operation data */ suspendSchema?: StandardSchemaWithJSON<TSuspendSchema>; /** Schema for resume operation data */ resumeSchema?: StandardSchemaWithJSON<TResumeSchema>; /** * Schema for validating request context values. * When provided, the request context will be validated against this schema before tool execution. */ requestContextSchema?: PublicSchema<TRequestContext>; /** * Tool execution function * @param inputData - The raw, validated input data * @param context - Optional execution context with metadata * @returns Promise resolving to tool output or a ValidationError if input validation fails */ execute?: ToolAction<TSchemaIn, TSchemaOut, TSuspendSchema, TResumeSchema, TContext, TId, TRequestContext>['execute']; /** Parent Mastra instance for accessing shared resources */ mastra?: Mastra; /** * Whether the tool requires explicit user approval before execution. * Accepts a boolean for static behavior, or a function evaluated per-call * for conditional approval. * @example * ```typescript * // Static * requireApproval: true * * // Conditional — only require approval for non-dry-run calls * requireApproval: async ({ isDryRun }) => !isDryRun * ``` */ requireApproval?: ToolAction<TSchemaIn, TSchemaOut, TSuspendSchema, TResumeSchema, TContext, TId, TRequestContext>['requireApproval']; /** * Enables strict tool input generation for providers that support it. */ strict?: boolean; /** * Provider-specific options passed to the model when this tool is used. * Keys are provider names (e.g., 'anthropic', 'openai'), values are provider-specific configs. * @example * ```typescript * providerOptions: { * anthropic: { * cacheControl: { type: 'ephemeral' } * } * } * ``` */ providerOptions?: Record<string, Record<string, unknown>>; /** * Optional function to transform the tool's raw output before sending it to the model. * The raw result is still available for application logic; only the model sees the transformed version. */ toModelOutput?: (output: TSchemaOut) => unknown; /** * Optional target-aware transform for display and transcript payloads. */ transform?: ToolPayloadTransform<TSchemaIn, TSchemaOut>; /** * Optional MCP-specific properties including annotations and metadata. * Only relevant when the tool is being used in an MCP context. * @example * ```typescript * mcp: { * annotations: { * title: 'Weather Lookup', * readOnlyHint: true, * destructiveHint: false * }, * _meta: { * version: '1.0.0', * author: 'team@example.com' * } * } * ``` */ mcp?: MCPToolProperties; onInputStart?: ToolAction<TSchemaIn, TSchemaOut, TSuspendSchema, TResumeSchema, TContext, TId, TRequestContext>['onInputStart']; onInputDelta?: ToolAction<TSchemaIn, TSchemaOut, TSuspendSchema, TResumeSchema, TContext, TId, TRequestContext>['onInputDelta']; onInputAvailable?: ToolAction<TSchemaIn, TSchemaOut, TSuspendSchema, TResumeSchema, TContext, TId, TRequestContext>['onInputAvailable']; onOutput?: ToolAction<TSchemaIn, TSchemaOut, TSuspendSchema, TResumeSchema, TContext, TId, TRequestContext>['onOutput']; /** * Examples of valid tool inputs passed through to the AI SDK. */ inputExamples?: Array<{ input: Record<string, unknown>; }>; /** * Metadata identifying this tool as originating from an MCP server. * Set automatically by the MCP client when creating tools. */ mcpMetadata?: McpMetadata; /** * Creates a new Tool instance with input validation wrapper. * * @param opts - Tool configuration and execute function * @example * ```typescript * const tool = new Tool({ * id: 'my-tool', * description: 'Does something useful', * inputSchema: z.object({ name: z.string() }), * execute: async (inputData) => ({ greeting: `Hello ${inputData.name}` }) * }); * ``` */ constructor(opts: ToolAction<TSchemaIn, TSchemaOut, TSuspendSchema, TResumeSchema, TContext, TId, TRequestContext>); } /** * Creates a type-safe tool with automatic input validation. * * @template TSchemaIn - Input schema type * @template TSchemaOut - Output schema type * @template TSuspendSchema - Suspend operation schema type * @template TResumeSchema - Resume operation schema type * @template TContext - Execution context type * @template TExecute - Execute function type * * @param opts - Tool configuration including schemas and execute function * @returns Type-safe Tool instance with conditional typing based on schemas * * @example Simple tool * ```typescript * const greetTool = createTool({ * id: 'greet', * description: 'Say hello', * execute: async () => ({ message: 'Hello!' }) * }); * ``` * * @example Tool with input validation * ```typescript * const calculateTool = createTool({ * id: 'calculate', * description: 'Perform calculations', * inputSchema: z.object({ * operation: z.enum(['add', 'subtract']), * a: z.number(), * b: z.number() * }), * execute: async (inputData) => { * const result = inputData.operation === 'add' * ? inputData.a + inputData.b * : inputData.a - inputData.b; * return { result }; * } * }); * ``` * * @example Tool with output schema * ```typescript * const userTool = createTool({ * id: 'get-user', * description: 'Get user data', * inputSchema: z.object({ userId: z.string() }), * outputSchema: z.object({ * id: z.string(), * name: z.string(), * email: z.string() * }), * execute: async (inputData) => { * return await fetchUser(inputData.userId); * } * }); * ``` * * @example Tool with external API * ```typescript * const weatherTool = createTool({ * id: 'weather', * description: 'Get weather data', * inputSchema: z.object({ * city: z.string(), * units: z.enum(['metric', 'imperial']).default('metric') * }), * execute: async (inputData) => { * const response = await fetch( * `https://api.weather.com/v1/weather?q=${inputData.city}&units=${inputData.units}` * ); * return response.json(); * } * }); * ``` */ type SchemaLike = PublicSchema<any> | undefined; type InferSchema<T extends SchemaLike> = T extends PublicSchema<any> ? InferPublicSchema<T> : unknown; type CreateToolOpts<TId extends string, TInputSchema extends SchemaLike, TOutputSchema extends SchemaLike, TSuspendSchema extends SchemaLike, TResumeSchema extends SchemaLike, TRequestContext, TContext extends ToolExecutionContext<InferSchema<TSuspendSchema>, InferSchema<TResumeSchema>, TRequestContext>> = Omit<ToolAction<InferSchema<TInputSchema>, InferSchema<TOutputSchema>, InferSchema<TSuspendSchema>, InferSchema<TResumeSchema>, TContext, TId, TRequestContext>, 'inputSchema' | 'outputSchema' | 'suspendSchema' | 'resumeSchema'> & { inputSchema?: TInputSchema; outputSchema?: TOutputSchema; suspendSchema?: TSuspendSchema; resumeSchema?: TResumeSchema; }; export declare function createTool<TId extends string = string, TInputSchema extends SchemaLike = undefined, TOutputSchema extends SchemaLike = undefined, TSuspendSchema extends SchemaLike = undefined, TResumeSchema extends SchemaLike = undefined, TRequestContext extends Record<string, any> | unknown = unknown, TContext extends ToolExecutionContext<InferSchema<TSuspendSchema>, InferSchema<TResumeSchema>, TRequestContext> = ToolExecutionContext<InferSchema<TSuspendSchema>, InferSchema<TResumeSchema>, TRequestContext>>(opts: CreateToolOpts<TId, TInputSchema, TOutputSchema, TSuspendSchema, TResumeSchema, TRequestContext, TContext>): Tool<InferSchema<TInputSchema>, InferSchema<TOutputSchema>, InferSchema<TSuspendSchema>, InferSchema<TResumeSchema>, TContext, TId, TRequestContext>; export {}; //# sourceMappingURL=tool.d.ts.map