> ## Documentation Index
> Fetch the complete documentation index at: https://docs.core-ai.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# defineTool()

> Define tools that language models can call

## Overview

The `defineTool()` function defines tools (functions) that language models can call during generation. Tools enable models to access external data, perform calculations, or trigger actions beyond text generation.

## Function signature

```typescript theme={null}
export function defineTool(
    options: ToolDefinition
): ToolDefinition

type ToolDefinition = {
    name: string;
    description: string;
    parameters: z.ZodType;
};
```

## Parameters

<ParamField path="name" type="string" required>
  The unique name of the tool. This is what the model uses to identify and call the tool.

  Should be descriptive and follow snake\_case convention (e.g., `get_weather`, `search_database`).
</ParamField>

<ParamField path="description" type="string" required>
  A clear description of what the tool does. This helps the model understand when and how to use it.

  Should explain the tool's purpose, expected inputs, and what it returns.
</ParamField>

<ParamField path="parameters" type="z.ZodType" required>
  Zod schema defining the tool's input parameters. The model will generate arguments matching this schema.
</ParamField>

## Return value

Returns the same `ToolDefinition` object that was passed in. This is a type-safe helper that provides IDE autocompletion and validation.

## Examples

### Basic tool definition

```typescript theme={null}
import { defineTool } from '@core-ai/core-ai';
import { z } from 'zod';

const weatherTool = defineTool({
  name: 'get_weather',
  description: 'Get the current weather for a location',
  parameters: z.object({
    location: z.string().describe('City name or zip code')
  })
});
```

### Tool with multiple parameters

```typescript theme={null}
const searchTool = defineTool({
  name: 'search_database',
  description: 'Search the product database with filters',
  parameters: z.object({
    query: z.string().describe('Search query'),
    category: z.string().optional().describe('Product category filter'),
    maxResults: z.number().min(1).max(100).default(10)
      .describe('Maximum number of results to return')
  })
});
```

### Using tools with generate()

```typescript theme={null}
import { generate, defineTool } from '@core-ai/core-ai';
import { createOpenAI } from '@core-ai/openai';
import { z } from 'zod';

const openai = createOpenAI();
const model = openai.chatModel('gpt-5-mini');

const calculatorTool = defineTool({
  name: 'calculate',
  description: 'Perform mathematical calculations',
  parameters: z.object({
    expression: z.string().describe('Math expression to evaluate')
  })
});

const result = await generate({
  model,
  messages: [
    { role: 'user', content: 'What is 142 * 89?' }
  ],
  tools: {
    calculate: calculatorTool
  }
});

if (result.toolCalls.length > 0) {
  const toolCall = result.toolCalls[0];
  console.log('Tool:', toolCall.name);
  console.log('Arguments:', toolCall.arguments);
  // Output: { expression: '142 * 89' }
}
```

### Tool execution loop

```typescript theme={null}
const tools = {
  get_weather: defineTool({
    name: 'get_weather',
    description: 'Get weather for a location',
    parameters: z.object({
      location: z.string()
    })
  }),
  get_time: defineTool({
    name: 'get_time',
    description: 'Get current time in a timezone',
    parameters: z.object({
      timezone: z.string().describe('IANA timezone name')
    })
  })
};

// Implement tool handlers
const toolHandlers = {
  get_weather: async (args: { location: string }) => {
    // Call weather API
    return `The weather in ${args.location} is sunny, 72°F`;
  },
  get_time: async (args: { timezone: string }) => {
    const time = new Date().toLocaleString('en-US', { 
      timeZone: args.timezone 
    });
    return `Current time in ${args.timezone}: ${time}`;
  }
};

const messages = [
  { role: 'user' as const, content: 'What\'s the weather in Tokyo?' }
];

let result = await generate({
  model: model,
  messages,
  tools
});

// Execute tools and continue conversation
while (result.toolCalls.length > 0) {
  messages.push({
    role: 'assistant',
    parts: result.parts
  });

  for (const toolCall of result.toolCalls) {
    const handler = toolHandlers[toolCall.name as keyof typeof toolHandlers];
    const toolResult = await handler(toolCall.arguments as any);

    messages.push({
      role: 'tool',
      toolCallId: toolCall.id,
      content: toolResult
    });
  }
  
  result = await generate({
    model: model,
    messages,
    tools
  });
}

console.log(result.content);
// Output: "The weather in Tokyo is sunny, 72°F"
```

### Complex parameters with nested objects

```typescript theme={null}
const createEventTool = defineTool({
  name: 'create_calendar_event',
  description: 'Create a new calendar event',
  parameters: z.object({
    title: z.string().describe('Event title'),
    startTime: z.string().datetime().describe('ISO 8601 start time'),
    endTime: z.string().datetime().describe('ISO 8601 end time'),
    attendees: z.array(
      z.object({
        name: z.string(),
        email: z.string().email()
      })
    ).optional().describe('List of attendees'),
    location: z.string().optional(),
    reminders: z.object({
      email: z.boolean().default(true),
      popup: z.number().min(0).optional()
        .describe('Minutes before event for popup')
    }).optional()
  })
});
```

### Tool with enum parameters

```typescript theme={null}
const analyzeSentimentTool = defineTool({
  name: 'analyze_sentiment',
  description: 'Analyze the sentiment of text',
  parameters: z.object({
    text: z.string().describe('Text to analyze'),
    language: z.enum(['en', 'es', 'fr', 'de'])
      .default('en')
      .describe('Language of the text'),
    includeScore: z.boolean()
      .default(false)
      .describe('Include numerical sentiment score')
  })
});
```

### Multiple Tools in One Call

```typescript theme={null}
const tools = {
  search_web: defineTool({
    name: 'search_web',
    description: 'Search the web for information',
    parameters: z.object({
      query: z.string()
    })
  }),
  
  get_stock_price: defineTool({
    name: 'get_stock_price',
    description: 'Get current stock price',
    parameters: z.object({
      symbol: z.string().describe('Stock ticker symbol')
    })
  }),
  
  convert_currency: defineTool({
    name: 'convert_currency',
    description: 'Convert between currencies',
    parameters: z.object({
      amount: z.number(),
      from: z.string().describe('Source currency code'),
      to: z.string().describe('Target currency code')
    })
  })
};

const result = await generate({
  model: model,
  messages: [
    { role: 'user', content: 'What\'s Tesla\'s stock price in euros?' }
  ],
  tools
});

// Model might call get_stock_price then convert_currency
```

### Controlling Tool Usage

```typescript theme={null}
// Auto: Model decides whether to use tools
const result1 = await generate({
  model: model,
  messages: [{ role: 'user', content: 'Hello' }],
  tools: { get_weather: weatherTool },
  toolChoice: 'auto' // Default
});

// Required: Model must use a tool
const result2 = await generate({
  model: model,
  messages: [{ role: 'user', content: 'Get weather' }],
  tools: { get_weather: weatherTool },
  toolChoice: 'required'
});

// Force specific tool
const result3 = await generate({
  model: model,
  messages: [{ role: 'user', content: 'Get weather' }],
  tools: { 
    get_weather: weatherTool,
    get_time: timeTool
  },
  toolChoice: { type: 'tool', toolName: 'get_weather' }
});

// None: Disable tools
const result4 = await generate({
  model: model,
  messages: [{ role: 'user', content: 'Hello' }],
  tools: { get_weather: weatherTool },
  toolChoice: 'none'
});
```

## Type Safety

The tool definition is fully type-safe:

```typescript theme={null}
const userTool = defineTool({
  name: 'get_user',
  description: 'Get user information',
  parameters: z.object({
    userId: z.number(),
    includeProfile: z.boolean().optional()
  })
});

// TypeScript knows the parameter types
type ToolParams = z.infer<typeof userTool.parameters>;
// { userId: number; includeProfile?: boolean | undefined }

const handler = async (args: ToolParams) => {
  const userId: number = args.userId; // Type-safe
  const include: boolean | undefined = args.includeProfile; // Type-safe
  // Fetch and return user data
};
```

## Best Practices

<Tip>
  Use descriptive tool names that clearly indicate their purpose. Follow the `snake_case` convention.
</Tip>

<Tip>
  Write clear descriptions that explain what the tool does, when to use it, and what it returns. Good descriptions improve model accuracy.
</Tip>

<Tip>
  Use Zod's `.describe()` method on parameters to provide additional context to the model.
</Tip>

<Warning>
  Always validate tool results before passing them back to the model. Handle errors gracefully.
</Warning>

## Common Patterns

### 1. Database Queries

```typescript theme={null}
const queryTool = defineTool({
  name: 'query_database',
  description: 'Query the database for records',
  parameters: z.object({
    table: z.enum(['users', 'products', 'orders']),
    filters: z.record(z.unknown()).optional()
  })
});
```

### 2. API Calls

```typescript theme={null}
const apiTool = defineTool({
  name: 'call_api',
  description: 'Make an HTTP API request',
  parameters: z.object({
    endpoint: z.string(),
    method: z.enum(['GET', 'POST', 'PUT', 'DELETE']),
    body: z.record(z.unknown()).optional()
  })
});
```

### 3. File Operations

```typescript theme={null}
const fileTool = defineTool({
  name: 'read_file',
  description: 'Read contents of a file',
  parameters: z.object({
    path: z.string(),
    encoding: z.enum(['utf8', 'base64']).default('utf8')
  })
});
```
