Tools
Create type-safe tools that give agents the ability to interact with external systems.
Overview
Tools enable agents to take actions -- call APIs, read files, execute code, query databases. Cogitator tools are defined with Zod schemas for full type safety and automatic JSON Schema generation for LLM function calling.
import { tool } from '@cogitator-ai/core';
import { z } from 'zod';
const getWeather = tool({
name: 'get_weather',
description: 'Get the current weather for a city',
parameters: z.object({
city: z.string().describe('City name'),
units: z.enum(['celsius', 'fahrenheit']).default('celsius'),
}),
execute: async ({ city, units }) => {
const response = await fetch(`https://api.weather.com/${city}?units=${units}`);
return response.json();
},
});The tool() Factory
function tool<TParams, TResult>(config: ToolConfig<TParams, TResult>): Tool<TParams, TResult>;ToolConfig
| Field | Type | Description |
|---|---|---|
name | string | Unique tool name (used in LLM function calling) |
description | string | What the tool does (sent to the LLM) |
parameters | ZodType | Zod schema defining accepted parameters |
execute | (params, context?) => Promise<TResult> | Implementation function |
category | string | Optional grouping category |
tags | string[] | Optional tags for filtering |
sideEffects | string[] | Declare side effects ('network', 'filesystem', 'external') |
requiresApproval | boolean | Require human approval before execution |
timeout | number | Per-call timeout in milliseconds |
sandbox | SandboxConfig | Run in isolated environment |
Parameter Schemas
The parameters field accepts any Zod schema. Cogitator converts it to JSON Schema (OpenAPI 3.0 format) before sending it to the LLM.
const createIssue = tool({
name: 'create_github_issue',
description: 'Create a new issue in a GitHub repository',
parameters: z.object({
repo: z.string().describe('Repository in owner/repo format'),
title: z.string().max(256).describe('Issue title'),
body: z.string().describe('Issue description in markdown'),
labels: z.array(z.string()).optional().describe('Labels to apply'),
priority: z.enum(['low', 'medium', 'high']).default('medium'),
}),
execute: async ({ repo, title, body, labels, priority }) => {
const issue = await github.createIssue(repo, { title, body, labels, priority });
return { issueNumber: issue.number, url: issue.html_url };
},
});Use .describe() on each field -- these descriptions are sent to the LLM and significantly improve tool call accuracy.
Tool Results
The execute function can return any serializable value. Cogitator converts the result to JSON and feeds it back to the LLM as a tool response:
const calculator = tool({
name: 'calculator',
description: 'Evaluate a mathematical expression',
parameters: z.object({
expression: z.string().describe('Math expression to evaluate'),
}),
execute: async ({ expression }) => {
const result = eval(expression);
return { result, expression };
},
});If the execute function throws, the error message is sent back to the LLM so it can retry or adjust its approach.
Built-in Tools
Cogitator ships with ready-to-use tools:
import {
calculator,
datetime,
uuid,
fileRead,
fileWrite,
fileList,
fileExists,
fileDelete,
httpRequest,
exec,
webSearch,
webScrape,
sqlQuery,
vectorSearch,
sendEmail,
githubApi,
jsonParse,
jsonStringify,
regexMatch,
regexReplace,
hash,
base64Encode,
base64Decode,
sleep,
randomNumber,
randomString,
} from '@cogitator-ai/core';Use them directly:
const agent = new Agent({
name: 'file-assistant',
model: 'openai/gpt-4o',
instructions: 'You help users manage files.',
tools: [fileRead, fileWrite, fileList, fileDelete],
});Tool Registry
The ToolRegistry class manages collections of tools and provides lookup by name:
import { ToolRegistry } from '@cogitator-ai/core';
const registry = new ToolRegistry();
registry.register(getWeather);
registry.register(createIssue);
registry.registerMany([calculator, datetime]);
const weatherTool = registry.get('get_weather');
const allNames = registry.getNames();
const schemas = registry.getSchemas();The Cogitator runtime uses ToolRegistry internally to resolve tool calls from the LLM.
Tool Schema Conversion
Under the hood, toolToSchema() converts a Zod-based tool into the JSON Schema format that LLM providers expect:
import { toolToSchema } from '@cogitator-ai/core';
const schema = toolToSchema(getWeather);
// {
// name: 'get_weather',
// description: 'Get the current weather for a city',
// parameters: {
// type: 'object',
// properties: {
// city: { type: 'string', description: 'City name' },
// units: { type: 'string', enum: ['celsius', 'fahrenheit'], default: 'celsius' }
// },
// required: ['city']
// }
// }Sandboxed Execution
Tools that execute untrusted code can declare a sandbox:
const runCode = tool({
name: 'run_code',
description: 'Execute Python code in a sandboxed environment',
parameters: z.object({
code: z.string().describe('Python code to execute'),
}),
execute: async ({ code }) => ({ code }),
sandbox: { type: 'docker', image: 'python:3.12-slim' },
});When sandbox is configured, the tool's execute function runs inside an isolated container managed by the Cogitator runtime.
Tool Caching
Wrap tools with withCache to avoid repeated expensive calls:
import { withCache } from '@cogitator-ai/core';
const cachedWeather = withCache(getWeather, {
ttl: '5m',
strategy: 'exact',
});See Tool Caching for TTL strategies, semantic matching, and Redis-backed storage.