Skip to main content

Tools

Give your bots capabilities by defining tools. A tool is a function the LLM can call during processing, with typed parameters and automatic schema generation.

Defining tools

Use the tool() helper. It takes a name, description, Zod schema, and function:

import { Baleybot, tool } from '@baleybots/core';
import { z } from 'zod';

// 1. Define the input schema
const WeatherInput = z.object({
city: z.string().describe('City name'),
});

// 2. Define the tool
const weatherTool = tool(
'get_weather',
'Get current weather for a city',
WeatherInput,
async ({ city }) => {
// Your weather API call here
return { temp: 72, condition: 'sunny', city };
},
);

// 3. Create the agent
const weatherBot = Baleybot.create({
name: 'weather-assistant',
goal: 'Help users with weather information',
tools: { weather: weatherTool },
});

const answer = await weatherBot.process(
"What's the weather in Tokyo?"
);

Parameters are automatically typed from the Zod schema. No manual type annotations needed.

Complex parameters

Zod handles all parameter shapes naturally:

// Object parameters — extract nested schemas
const UserInput = z.object({
name: z.string().describe('User name'),
age: z.number().optional().describe('User age'),
});

const createUser = tool(
'create_user',
'Creates a new user',
z.object({ user: UserInput }),
async ({ user }) => `Created user ${user.name}`,
);

// Array parameters
const SumInput = z.object({
numbers: z.array(z.number()).describe('Numbers to sum'),
});

const sumArray = tool(
'sum_array',
'Sums an array of numbers',
SumInput,
async ({ numbers }) => numbers.reduce((a, b) => a + b, 0),
);

// Enum parameters
const Color = z.enum(['red', 'green', 'blue']);

const setColor = tool(
'set_color',
'Sets the color',
z.object({ color: Color.describe('The color to set') }),
async ({ color }) => `Color set to ${color}`,
);

v6 features

Tools support AI SDK v6 features via an optional fifth argument:

Approval gating

Require user approval before a tool executes:

const deleteTool = tool(
'delete_file',
'Delete a file from the system',
z.object({ path: z.string() }),
async ({ path }) => {
// delete logic
return { deleted: true };
},
{ needsApproval: true }
);

You can also gate conditionally:

const WriteFileInput = z.object({
path: z.string(),
content: z.string(),
});

const writeTool = tool(
'write_file',
'Write content to a file',
WriteFileInput,
async ({ path, content }) => {
// write logic
return { written: true };
},
{
needsApproval: (params) =>
params.path.startsWith('/etc/') || params.path.includes('.env'),
},
);

Strict schema mode

Force the provider to enforce strict adherence to the schema, preventing hallucinated parameters:

const strictTool = tool(
'query_db',
'Query the database',
z.object({ sql: z.string() }),
async ({ sql }) => { /* ... */ },
{ strict: true }
);

Output transformation

Control what the model sees after a tool runs:

const searchTool = tool(
'search',
'Search the knowledge base',
z.object({ query: z.string() }),
async ({ query }) => {
const results = await search(query);
return results; // full results returned to your code
},
{
// model only sees a summary, not the full payload
toModelOutput: ({ output }) => ({
type: 'text',
value: `Found ${output.length} results. Top: ${output[0]?.title}`,
}),
}
);

You can also omit tool output from the model entirely:

{
toModelOutput: () => ({ type: 'omit' })
}

Streaming tool events

Baleybot handles tool execution internally. To observe tool calls in real-time, use onToken:

const result = await bot.process('What is 5 + 3?', {
onToken: (_name, event) => {
switch (event.type) {
case 'tool_call_stream_start':
console.log('Calling tool:', event.toolName);
break;
case 'tool_execution_output':
console.log('Tool result:', event.result);
break;
}
},
});

See the Streaming guide for all event types.

Alternative APIs

For most use cases, tool() is all you need. Two alternative APIs exist for specific situations:

defineZodTool() -- object-based syntax

Identical to tool() but uses an object instead of positional arguments. Use this if you prefer named properties or need to spread options:

import { defineZodTool } from '@baleybots/core';
import { z } from 'zod';

const AddInput = z.object({
a: z.number().describe('First number'),
b: z.number().describe('Second number'),
});

const addTool = defineZodTool({
name: 'add',
description: 'Adds two numbers',
inputSchema: AddInput,
function: (params) => params.a + params.b,
needsApproval: false,
strict: true,
});

Note: tool() calls defineZodTool() internally -- they produce identical results.

defineTool() -- raw JSON Schema

Use this only when you have a pre-existing JSON Schema and don't want to convert it to Zod:

import { defineTool } from '@baleybots/core';

const addTool = defineTool({
name: 'add',
description: 'Adds two numbers',
inputSchema: {
type: 'object',
properties: {
a: { type: 'number', description: 'First number' },
b: { type: 'number', description: 'Second number' },
},
required: ['a', 'b'],
},
function: ({ a, b }: { a: number; b: number }) => a + b,
});

Note: defineTool() does not support v6 features (needsApproval, strict, toModelOutput). Use tool() or defineZodTool() for those.

API reference

tool(name, description, inputSchema, fn, options?)

Quick inline tool definition using Zod schema.

  • name -- tool name
  • description -- what the tool does
  • inputSchema -- Zod schema for parameters
  • fn -- the function to execute (params automatically typed)
  • options? -- v6 features: needsApproval, strict, toModelOutput

defineZodTool(definition)

Object-based tool definition with Zod schema.

  • name -- tool name
  • description -- what the tool does
  • inputSchema -- Zod schema for parameters
  • function -- the function to execute
  • needsApproval? -- boolean or function for approval gating
  • strict? -- enable strict JSON schema mode
  • toModelOutput? -- transform output before sending to model

defineTool(definition)

Tool definition with raw JSON Schema.

  • name -- tool name
  • description -- what the tool does
  • inputSchema -- JSON Schema object for parameters
  • function -- the function to execute

Config options

  • tools? -- record of tool definitions
  • outputSchema? -- schema for structured output (when not using tools)