Tool Calling
Agents that use Zod-validated function tools.
Basic Tool
typescript
import { Robota } from '@robota-sdk/agent-core';
import { createZodFunctionTool } from '@robota-sdk/agent-tools';
import { AnthropicProvider } from '@robota-sdk/agent-provider/anthropic';
import { z } from 'zod';
const provider = new AnthropicProvider({
apiKey: process.env.ANTHROPIC_API_KEY,
});
const calculatorTool = createZodFunctionTool(
'calculator',
'Evaluate a math expression',
z.object({
expression: z.string().describe('The math expression to evaluate'),
}),
async ({ expression }) => ({
data: String(eval(expression)),
}),
);
const agent = new Robota({
name: 'MathAgent',
aiProviders: [provider],
defaultModel: {
provider: 'anthropic',
model: 'claude-sonnet-4-6',
systemMessage: 'You are a math assistant. Use the calculator tool for calculations.',
},
tools: [calculatorTool],
});
const response = await agent.run('What is (42 * 17) + 256?');
console.log(response);
// The agent calls calculator({ expression: '(42 * 17) + 256' }) and reports the resultMultiple Tools
typescript
const fileSearchTool = createZodFunctionTool(
'search_files',
'Search for files by name pattern',
z.object({
pattern: z.string().describe('Glob pattern'),
}),
async ({ pattern }) => {
const { glob } = await import('fast-glob');
const files = await glob(pattern);
return { data: JSON.stringify(files) };
},
);
const readFileTool = createZodFunctionTool(
'read_file',
'Read the contents of a file',
z.object({
path: z.string().describe('File path to read'),
}),
async ({ path }) => {
const { readFileSync } = await import('fs');
return { data: readFileSync(path, 'utf-8') };
},
);
const agent = new Robota({
name: 'FileAgent',
aiProviders: [provider],
defaultModel: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
tools: [fileSearchTool, readFileTool],
});
// The agent may call search_files first, then read_file on the results
const response = await agent.run('Find all .ts files in src/ and show me the smallest one');Using Built-in Tools
typescript
import { bashTool, readTool, globTool, grepTool } from '@robota-sdk/agent-tools';
const agent = new Robota({
name: 'DevAgent',
aiProviders: [provider],
defaultModel: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
tools: [bashTool, readTool, globTool, grepTool],
});
const response = await agent.run('Find all TODO comments in the project');Sandbox-Aware Built-in Tools
Use factory exports when Bash or file tools should run inside a provider sandbox instead of the host workspace:
typescript
import {
E2BSandboxClient,
applyWorkspaceManifest,
createBashTool,
createEditTool,
createReadTool,
createWriteTool,
} from '@robota-sdk/agent-tools';
import { Sandbox } from 'e2b';
const sandbox = await Sandbox.create();
const sandboxClient = new E2BSandboxClient({ sandbox });
await applyWorkspaceManifest(sandboxClient, {
entries: {
'task.md': { type: 'file', content: 'Run the requested checks.\n' },
output: { type: 'dir' },
},
});
const agent = new Robota({
name: 'SandboxedDevAgent',
aiProviders: [provider],
defaultModel: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
tools: [
createBashTool({ sandboxClient }),
createReadTool({ sandboxClient }),
createWriteTool({ sandboxClient }),
createEditTool({ sandboxClient }),
],
});E2BSandboxClient is a structural adapter. Install and construct the concrete provider SDK in your application, then pass the adapter to Robota tools or InteractiveSession. Workspace manifests use the same sandbox port and prepare files/directories before the tools run. When a session store is present, snapshot-capable sandbox clients can persist a sandboxSnapshotId on shutdown and hydrate that workspace during non-fork resume.