Define a Tool
Create type-safe tools with defineTool() — Zod schemas, execution, and configuration.
Basic Usage
import { defineTool } from '@ahzan-agentforge/core';
import { z } from 'zod';
const calculator = defineTool({
name: 'calculator',
description: 'Perform arithmetic calculations',
input: z.object({
expression: z.string().describe('Math expression to evaluate'),
}),
output: z.object({
result: z.number(),
}),
execute: async ({ expression }) => {
const result = eval(expression); // Use a safe evaluator in production
return { result };
},
});from agentforge import define_tool
from pydantic import BaseModel, Field
class CalcInput(BaseModel):
expression: str = Field(description="Math expression to evaluate")
class CalcOutput(BaseModel):
result: float
calculator = define_tool(
name="calculator",
description="Perform arithmetic calculations",
input=CalcInput,
output=CalcOutput,
execute=lambda inp: CalcOutput(result=eval(inp.expression)),
)ToolConfig
interface ToolConfig<TInput, TOutput> {
name: string; // Tool name (used by LLM)
description: string; // What the tool does (sent to LLM)
input: ZodSchema<TInput>; // Input validation schema
output: ZodSchema<TOutput>; // Output validation schema
execute: (input: TInput) => Promise<TOutput>;
// Optional
timeout?: number; // Execution timeout in ms (default: 30000)
tags?: string[]; // Categorization tags
cacheable?: boolean; // Enable result caching (default: false)
retry?: RetryConfig; // Retry configuration
compensate?: ((input: TInput, output: TOutput) => Promise<void>) | 'irreversible';
version?: string; // Tool version string
}Tool Object
defineTool() returns a Tool object with resolved defaults:
interface Tool<TInput, TOutput> {
name: string;
description: string;
inputSchema: ZodSchema<TInput>;
outputSchema: ZodSchema<TOutput>;
execute: (input: TInput) => Promise<TOutput>;
timeout: number; // Default: 30000
tags: string[]; // Default: []
cacheable: boolean; // Default: false
retry: Required<RetryConfig>; // Default: { maxAttempts: 3, backoff: 'exponential', baseDelay: 1000 }
compensate?: ((input: TInput, output: TOutput) => Promise<void>) | 'irreversible';
}Schema Descriptions
Add .describe() to Zod fields — these become the tool's parameter descriptions sent to the LLM:
const searchTool = defineTool({
name: 'search',
description: 'Search a knowledge base',
input: z.object({
query: z.string().describe('Search query'),
limit: z.number().optional().describe('Max results to return'),
category: z.enum(['docs', 'api', 'blog']).describe('Category to search'),
}),
output: z.object({
results: z.array(z.object({
title: z.string(),
snippet: z.string(),
url: z.string(),
})),
}),
execute: async (input) => {
// ...
},
});Timeout
Tools have a 30-second default timeout. Override per-tool:
const slowTool = defineTool({
name: 'generate-report',
description: 'Generate a detailed report (slow)',
input: z.object({ topic: z.string() }),
output: z.object({ report: z.string() }),
execute: async ({ topic }) => { /* ... */ },
timeout: 120_000, // 2 minutes
});Next Steps
- Validation — input/output validation details
- Retry — automatic retry with backoff
- Caching — cache tool results
- Compensating Actions — rollback support