Documentation Index
Fetch the complete documentation index at: https://docs.agenite.com/llms.txt
Use this file to discover all available pages before exploring further.
The Tool class provides a type-safe way to create tools that agents can use.
Constructor
new Tool<TInput>({
name: string;
description: string;
version?: string;
inputSchema?: z.ZodType<TInput> | JSONSchema;
execute: (params: {
input: TInput;
context?: ToolContext;
}) => Promise<ToolResponse>;
validate?: (input: TInput) => Promise<ValidationResult>;
})
Parameters
name (required): Unique identifier for the tool
description (required): Clear description of what the tool does
version: Semantic version number
inputSchema: Schema for input validation (Zod schema or JSON Schema)
execute (required): Function that performs the tool’s operation
validate: Custom validation function
Types
interface ToolResponse {
isError: boolean;
data: string | Array<ToolResponseBlock>;
error?: {
code: string;
message: string;
details?: unknown;
};
duration?: number;
tokenUsage?: TokenUsage;
}
interface ToolResponseBlock {
type: 'text' | 'image';
text?: string;
image?: {
type: 'base64';
media_type: string;
data: string;
};
}
ToolContext
interface ToolContext {
agentId?: string;
executionId?: string;
parentToolExecutionId?: string;
extraContext?: Record<string, unknown>;
metadata?: Record<string, unknown>;
}
JSONSchema
interface JSONSchema {
type: string;
properties?: Record<string, unknown>;
required?: string[];
[k: string]: unknown;
}
ValidationResult
interface ValidationResult {
isValid: boolean;
errors?: ValidationError[];
}
interface ValidationError {
field: string;
message: string;
}
Examples
import { Tool } from '@agenite/tool';
interface CalculatorInput {
operation: 'add' | 'subtract' | 'multiply' | 'divide';
a: number;
b: number;
}
const calculatorTool = new Tool<CalculatorInput>({
name: 'calculator',
description: 'Perform basic math operations',
version: '1.0.0',
inputSchema: {
type: 'object',
properties: {
operation: {
type: 'string',
enum: ['add', 'subtract', 'multiply', 'divide'],
},
a: { type: 'number' },
b: { type: 'number' },
},
required: ['operation', 'a', 'b'],
},
execute: async ({ input }) => {
try {
let result: number;
switch (input.operation) {
case 'add': result = input.a + input.b; break;
case 'subtract': result = input.a - input.b; break;
case 'multiply': result = input.a * input.b; break;
case 'divide':
if (input.b === 0) throw new Error('Division by zero');
result = input.a / input.b;
break;
}
return {
isError: false,
data: result.toString(),
};
} catch (error) {
return {
isError: true,
data: error.message,
error: {
code: 'CALC_ERROR',
message: error.message,
},
};
}
},
});
import { Tool } from '@agenite/tool';
import { z } from 'zod';
const weatherSchema = z.object({
location: z.object({
city: z.string(),
country: z.string().optional(),
coordinates: z.object({
lat: z.number(),
lon: z.number(),
}).optional(),
}),
units: z.enum(['metric', 'imperial']).default('metric'),
});
type WeatherInput = z.infer<typeof weatherSchema>;
const createWeatherTool = (apiKey: string) => {
const client = new WeatherAPI(apiKey);
return new Tool<WeatherInput>({
name: 'weather',
description: 'Get current weather for a location',
version: '1.0.0',
inputSchema: weatherSchema,
execute: async ({ input }) => {
try {
const weather = await client.getWeather(
input.location,
input.units
);
return {
isError: false,
data: JSON.stringify(weather),
};
} catch (error) {
return {
isError: true,
data: 'Failed to get weather data',
error: {
code: 'WEATHER_ERROR',
message: error.message,
},
};
}
},
});
};
import { Tool } from '@agenite/tool';
import { readFile } from 'fs/promises';
interface FileReadInput {
path: string;
format?: 'text' | 'base64';
}
const fileReaderTool = new Tool<FileReadInput>({
name: 'file-reader',
description: 'Read the contents of a file',
version: '1.0.0',
inputSchema: {
type: 'object',
properties: {
path: { type: 'string' },
format: {
type: 'string',
enum: ['text', 'base64'],
default: 'text',
},
},
required: ['path'],
},
execute: async ({ input }) => {
try {
const content = await readFile(input.path);
if (input.format === 'base64' && content.toString().endsWith('.jpg')) {
// Return image data for JPG files when base64 format is requested
return {
isError: false,
data: [
{
type: 'image',
image: {
type: 'base64',
media_type: 'image/jpeg',
data: content.toString('base64'),
},
},
{
type: 'text',
text: 'File read successfully',
},
],
};
}
// Default to text response
return {
isError: false,
data: content.toString('utf-8'),
};
} catch (error) {
return {
isError: true,
data: `Could not read file: ${error.message}`,
error: {
code: 'FILE_ERROR',
message: error.message,
},
};
}
},
});
import { Tool } from '@agenite/tool';
interface QueryInput {
sql: string;
parameters?: Record<string, unknown>;
}
const createDatabaseTool = (db: Database) => {
return new Tool<QueryInput>({
name: 'database-query',
description: 'Execute SQL queries against the database',
version: '1.0.0',
inputSchema: {
type: 'object',
properties: {
sql: { type: 'string' },
parameters: {
type: 'object',
additionalProperties: true,
},
},
required: ['sql'],
},
// Custom validation to prevent dangerous SQL operations
validate: async (input) => {
const dangerousKeywords = ['DROP', 'DELETE', 'TRUNCATE', 'ALTER'];
const sql = input.sql.toUpperCase();
for (const keyword of dangerousKeywords) {
if (sql.includes(keyword)) {
return {
isValid: false,
errors: [{
field: 'sql',
message: `Dangerous operation detected: ${keyword} is not allowed`,
}],
};
}
}
return { isValid: true };
},
execute: async ({ input }) => {
try {
const result = await db.query(input.sql, input.parameters);
return {
isError: false,
data: JSON.stringify(result),
};
} catch (error) {
return {
isError: true,
data: `Database error: ${error.message}`,
error: {
code: 'DB_ERROR',
message: error.message,
},
};
}
},
});
};
Best practices
- Type safety: Leverage TypeScript generics and Zod schemas for input validation
- Error handling: Use structured error responses with codes and details
- Schema validation: Use either JSON Schema or Zod for input validation
- Rich responses: Utilize text and image responses when appropriate
- Performance tracking: Monitor execution times and token usage
- Context utilization: Pass relevant context to tools for better integration
Next steps