Skip to main content
Tools allow models to interact with external systems or perform specific computations during generation.

defineTool()

Defines a tool that can be passed to models for automatic execution.
import { defineTool } from '@genkit-ai/ai';
import { z } from 'zod';

const weatherTool = defineTool(
  registry,
  {
    name: 'getWeather',
    description: 'Gets the current weather for a city',
    inputSchema: z.object({
      city: z.string(),
    }),
    outputSchema: z.object({
      temperature: z.number(),
      conditions: z.string(),
    }),
  },
  async (input) => {
    // Tool implementation
    return {
      temperature: 72,
      conditions: 'sunny',
    };
  }
);

Parameters

registry
Registry
required
The Genkit registry instance
config
ToolConfig
required
Tool configuration object
fn
ToolFn<I, O>
Implementation function for the toolFunction signature:
(input: z.infer<I>, ctx: ToolFnOptions & ToolRunOptions) => Promise<z.infer<O>>

Returns

ToolAction<I, O>
ToolAction
A tool action that can be passed to model generation requests

tool()

Defines a dynamic tool that is not registered in the Genkit registry.
import { tool } from '@genkit-ai/ai';
import { z } from 'zod';

const dynamicTool = tool(
  {
    name: 'dynamicWeather',
    description: 'Dynamic weather tool',
    inputSchema: z.object({ city: z.string() }),
    outputSchema: z.object({ temp: z.number() }),
  },
  async (input) => ({ temp: 72 })
);

Parameters

Same as defineTool() except without the registry parameter.

Returns

ToolAction<I, O>
ToolAction
A dynamic tool action (not registered)

Tool Interrupts (Beta)

Tools can interrupt execution to request user confirmation or additional input.

interrupt()

Creates an interrupt tool that pauses execution.
import { interrupt } from '@genkit-ai/ai';
import { z } from 'zod';

const confirmTool = interrupt({
  name: 'confirmAction',
  description: 'Requests user confirmation',
  inputSchema: z.object({ action: z.string() }),
  outputSchema: z.object({ confirmed: z.boolean() }),
  requestMetadata: { requiresConfirmation: true },
});

ToolAction.respond()

Responds to a tool interrupt with output data.
const toolResponse = myTool.respond(
  interruptRequest,
  { result: 'success' },
  { metadata: { userConfirmed: true } }
);
Parameters:
interrupt
ToolRequestPart
required
The interrupt tool request to respond to
outputData
z.infer<O>
required
Response data matching the tool’s output schema
options
object
metadata
Record<string, any>
Additional metadata for the response
Returns: ToolResponsePart

ToolAction.restart()

Restarts a tool request after an interrupt.
const restartRequest = myTool.restart(
  interruptRequest,
  { resumed: true },
  { replaceInput: { newParam: 'value' } }
);
Parameters:
interrupt
ToolRequestPart
required
The interrupt tool request to restart
resumedMetadata
any
Metadata to pass to the tool on restart (defaults to true)
options
object
replaceInput
z.infer<I>
New input to replace the original tool input
Returns: ToolRequestPart

Types

ToolAction

type ToolAction<I extends z.ZodTypeAny, O extends z.ZodTypeAny> = 
  Action<I, O, z.ZodTypeAny, ToolRunOptions> & 
  Resumable<I, O> & {
    __action: {
      metadata: {
        type: 'tool';
      };
    };
  };

ToolFnOptions

interface ToolFnOptions extends ActionFnArg<never> {
  interrupt: (metadata?: Record<string, any>) => never;
  context: ActionContext;
}

ToolRunOptions

interface ToolRunOptions extends ActionRunOptions<z.ZodTypeAny> {
  resumed?: boolean | Record<string, any>;
  metadata?: Record<string, any>;
}

Example: Complete Tool Definition

import { ai } from './genkit';
import { z } from 'zod';

const calculatorTool = ai.defineTool(
  {
    name: 'calculator',
    description: 'Performs basic arithmetic operations',
    inputSchema: z.object({
      operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
      a: z.number(),
      b: z.number(),
    }),
    outputSchema: z.object({
      result: z.number(),
    }),
  },
  async (input, ctx) => {
    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 { result };
  }
);

// Use in generation
const response = await ai.generate({
  model: gemini15Flash,
  prompt: 'What is 15 multiplied by 7?',
  tools: [calculatorTool],
});

Build docs developers (and LLMs) love