or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

agents.mderrors.mdguardrails.mdhandoffs.mdindex.mdmcp.mdmodels.mdrealtime.mdsessions.mdtools.mdtracing.md
tile.json

tools.mddocs/

Tool Integration

Create and integrate custom tools, built-in tools, and hosted tools for agent use.

Capabilities

Function Tools

Create custom function tools that agents can call during execution.

/**
 * Create a function tool for agent use
 * @param config - Tool configuration
 * @returns FunctionTool instance
 */
function tool<TParameters, TContext, TResult>(
  config: ToolConfig<TParameters, TContext, TResult>
): FunctionTool<TContext, TResult>;

interface ToolConfig<TParameters, TContext, TResult> {
  /** Tool identifier (defaults to function name) */
  name?: string;

  /** Description shown to the model */
  description: string;

  /** Zod schema or JSON schema for parameters */
  parameters: TParameters;

  /** Enable strict schema validation (default: true) */
  strict?: boolean;

  /** Function to execute when tool is called */
  execute: (
    input: z.infer<TParameters>,
    context?: RunContext<TContext>,
    details?: ToolCallDetails
  ) => TResult | Promise<TResult>;

  /** Custom error message generator */
  errorFunction?: (context: RunContext<TContext>, error: any) => string;

  /** Require approval before execution */
  needsApproval?: boolean | ((
    runContext: RunContext<TContext>,
    input: any,
    callId?: string
  ) => Promise<boolean>);

  /** Conditionally enable/disable tool */
  isEnabled?: boolean | ((options: {
    runContext: RunContext<TContext>;
    agent: Agent;
  }) => boolean | Promise<boolean>);
}

interface ToolCallDetails {
  /** Unique call identifier */
  callId: string;

  /** Tool name */
  toolName: string;
}

class FunctionTool<TContext = any, TResult = any> {
  /** Tool name */
  name: string;

  /** Tool description */
  description: string;

  /** Parameter schema */
  parametersSchema: JsonObjectSchema;

  /** Execute the tool */
  execute(
    input: any,
    context: RunContext<TContext>,
    details: ToolCallDetails
  ): Promise<TResult>;

  /** Check if tool is enabled */
  isEnabled(options: {
    runContext: RunContext<TContext>;
    agent: Agent;
  }): Promise<boolean>;

  /** Check if tool needs approval */
  needsApproval(
    runContext: RunContext<TContext>,
    input: any,
    callId?: string
  ): Promise<boolean>;

  /** Convert to JSON representation */
  toJSON(): any;
}

Usage Examples:

import { z } from 'zod';
import { Agent, run, tool } from '@openai/agents';

// Basic tool
const getWeatherTool = tool({
  name: 'get_weather',
  description: 'Get the current weather for a given city',
  parameters: z.object({
    city: z.string(),
    units: z.enum(['celsius', 'fahrenheit']).optional(),
  }),
  execute: async (input) => {
    // Fetch weather data
    return `The weather in ${input.city} is sunny and 72°F`;
  },
});

const agent = new Agent({
  name: 'WeatherAgent',
  instructions: 'You are a weather assistant',
  tools: [getWeatherTool],
});

const result = await run(agent, 'What is the weather in Tokyo?');

// Tool with context
const getUserDataTool = tool({
  name: 'get_user_data',
  description: 'Get data for the current user',
  parameters: z.object({}),
  execute: async (input, context) => {
    // Access user context
    const userId = context.context.userId;
    return `User data for ${userId}`;
  },
});

const result2 = await run(agent, 'Get my data', {
  context: { userId: '12345' },
});

// Tool with approval
const deleteTool = tool({
  name: 'delete_file',
  description: 'Delete a file from the system',
  parameters: z.object({
    path: z.string(),
  }),
  needsApproval: true,
  execute: async (input) => {
    // Delete the file
    return `Deleted ${input.path}`;
  },
});

const deleteAgent = new Agent({
  name: 'FileManager',
  instructions: 'You manage files',
  tools: [deleteTool],
});

const deleteResult = await run(deleteAgent, 'Delete config.json');

// Handle approval
if (deleteResult.interruptions.length > 0) {
  const approval = deleteResult.interruptions[0];
  await deleteResult.state.runContext.approveTool(approval);

  // Resume with approval
  const resumed = await run(deleteAgent, deleteResult.state);
}

// Conditional approval
const sensitiveDataTool = tool({
  name: 'access_sensitive_data',
  description: 'Access sensitive customer data',
  parameters: z.object({
    customerId: z.string(),
  }),
  needsApproval: async (runContext, input) => {
    // Only require approval for certain customers
    return input.customerId.startsWith('VIP');
  },
  execute: async (input) => {
    return `Sensitive data for ${input.customerId}`;
  },
});

// Conditional tool enablement
const premiumTool = tool({
  name: 'premium_feature',
  description: 'Access premium features',
  parameters: z.object({}),
  isEnabled: ({ runContext }) => {
    // Only enable for premium users
    return runContext.context.isPremium === true;
  },
  execute: async () => {
    return 'Premium feature accessed';
  },
});

// Custom error handling
const externalApiTool = tool({
  name: 'call_external_api',
  description: 'Call an external API',
  parameters: z.object({
    endpoint: z.string(),
  }),
  execute: async (input) => {
    const response = await fetch(input.endpoint);
    if (!response.ok) {
      throw new Error(`API returned ${response.status}`);
    }
    return await response.json();
  },
  errorFunction: (context, error) => {
    return `Failed to call API: ${error.message}. Please try again later.`;
  },
});

Computer Use Tool

Create tools for computer automation and UI interaction.

/**
 * Create a computer use tool for UI automation
 * @param computer - Computer interface implementation
 * @returns ComputerTool instance
 */
function computerTool(computer: Computer): ComputerTool;

interface Computer {
  /** Operating environment */
  environment: 'mac' | 'windows' | 'ubuntu' | 'browser';

  /** Screen dimensions [width, height] */
  dimensions: [number, number];

  /** Capture screenshot */
  screenshot(): string | Promise<string>;

  /** Click at coordinates */
  click(x: number, y: number, button: 'left' | 'right' | 'middle'): void | Promise<void>;

  /** Double-click at coordinates */
  doubleClick(x: number, y: number): void | Promise<void>;

  /** Scroll at coordinates */
  scroll(x: number, y: number, scrollX: number, scrollY: number): void | Promise<void>;

  /** Type text */
  type(text: string): void | Promise<void>;

  /** Move cursor */
  move(x: number, y: number): void | Promise<void>;

  /** Press keys */
  keypress(keys: string[]): void | Promise<void>;

  /** Drag along path */
  drag(path: Array<[number, number]>): void | Promise<void>;

  /** Wait/pause */
  wait(): void | Promise<void>;
}

class ComputerTool {
  /** Tool name (always 'computer') */
  name: 'computer';

  /** Tool description */
  description: string;

  /** Execute computer action */
  execute(input: ComputerAction, context: RunContext): Promise<string>;
}

type ComputerAction =
  | { action: 'screenshot' }
  | { action: 'click'; x: number; y: number; button?: 'left' | 'right' | 'middle' }
  | { action: 'double_click'; x: number; y: number }
  | { action: 'scroll'; x: number; y: number; scroll_x: number; scroll_y: number }
  | { action: 'type'; text: string }
  | { action: 'move'; x: number; y: number }
  | { action: 'keypress'; keys: string[] }
  | { action: 'drag'; path: Array<[number, number]> }
  | { action: 'wait' };

Usage Examples:

import { Agent, run, computerTool } from '@openai/agents';

// Implement Computer interface
const myComputer = {
  environment: 'mac' as const,
  dimensions: [1920, 1080] as [number, number],

  async screenshot() {
    // Capture and return base64 screenshot
    return 'data:image/png;base64,...';
  },

  async click(x: number, y: number, button: string) {
    console.log(`Clicking at (${x}, ${y}) with ${button} button`);
    // Execute click
  },

  async doubleClick(x: number, y: number) {
    console.log(`Double-clicking at (${x}, ${y})`);
    // Execute double-click
  },

  async scroll(x: number, y: number, scrollX: number, scrollY: number) {
    console.log(`Scrolling at (${x}, ${y}) by (${scrollX}, ${scrollY})`);
    // Execute scroll
  },

  async type(text: string) {
    console.log(`Typing: ${text}`);
    // Type text
  },

  async move(x: number, y: number) {
    console.log(`Moving cursor to (${x}, ${y})`);
    // Move cursor
  },

  async keypress(keys: string[]) {
    console.log(`Pressing keys: ${keys.join('+')}`);
    // Press keys
  },

  async drag(path: Array<[number, number]>) {
    console.log(`Dragging along path with ${path.length} points`);
    // Execute drag
  },

  async wait() {
    console.log('Waiting...');
    // Pause execution
  },
};

const agent = new Agent({
  name: 'AutomationAgent',
  instructions: 'You can control the computer to automate tasks',
  tools: [computerTool(myComputer)],
});

const result = await run(
  agent,
  'Open the calculator app and calculate 25 + 37'
);

Shell Tool

Create tools for executing shell commands.

/**
 * Create a shell command execution tool
 * @param shell - Shell interface implementation
 * @returns ShellTool instance
 */
function shellTool(shell: Shell): ShellTool;

interface Shell {
  /** Execute a shell command */
  execute(action: ShellAction): Promise<ShellResult>;
}

interface ShellAction {
  /** Command to execute */
  command: string;

  /** Working directory */
  workingDirectory?: string;

  /** Shell to use (e.g., 'bash', 'zsh', 'powershell') */
  shell?: string;
}

interface ShellResult {
  /** Command output (stdout + stderr) */
  output: string;

  /** Exit code */
  exitCode: number;
}

class ShellTool {
  /** Tool name (always 'shell') */
  name: 'shell';

  /** Tool description */
  description: string;

  /** Execute shell command */
  execute(input: ShellAction, context: RunContext): Promise<string>;
}

Usage Examples:

import { Agent, run, shellTool } from '@openai/agents';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

// Implement Shell interface
const myShell = {
  async execute(action) {
    try {
      const { stdout, stderr } = await execAsync(action.command, {
        cwd: action.workingDirectory,
        shell: action.shell || '/bin/bash',
      });

      return {
        output: stdout + stderr,
        exitCode: 0,
      };
    } catch (error: any) {
      return {
        output: error.stdout + error.stderr,
        exitCode: error.code || 1,
      };
    }
  },
};

const agent = new Agent({
  name: 'DevOpsAgent',
  instructions: 'You can execute shell commands to manage systems',
  tools: [shellTool(myShell)],
});

const result = await run(
  agent,
  'List all files in the current directory and show their sizes'
);

// With working directory
const result2 = await run(
  agent,
  'Check the git status of the project in /home/user/myproject'
);

Apply Patch Tool

Create tools for applying unified diff patches to files.

/**
 * Create a file editing tool using unified diffs
 * @param editor - Editor interface implementation
 * @returns ApplyPatchTool instance
 */
function applyPatchTool(editor: Editor): ApplyPatchTool;

interface Editor {
  /** Apply a unified diff patch */
  applyPatch(operation: ApplyPatchOperation): Promise<ApplyPatchResult>;
}

interface ApplyPatchOperation {
  /** Unified diff patch content */
  patch: string;

  /** Working directory for relative paths */
  workingDirectory?: string;
}

interface ApplyPatchResult {
  /** Whether patch was successfully applied */
  success: boolean;

  /** Success or error message */
  message?: string;
}

class ApplyPatchTool {
  /** Tool name (always 'apply_patch') */
  name: 'apply_patch';

  /** Tool description */
  description: string;

  /** Execute patch application */
  execute(input: ApplyPatchOperation, context: RunContext): Promise<string>;
}

Usage Examples:

import { Agent, run, applyPatchTool } from '@openai/agents';
import { applyDiff } from '@openai/agents/utils';
import * as fs from 'fs/promises';
import * as path from 'path';

// Implement Editor interface
const myEditor = {
  async applyPatch(operation) {
    try {
      const workingDir = operation.workingDirectory || process.cwd();

      // Parse patch to extract file paths
      const lines = operation.patch.split('\n');
      const filePaths = new Set<string>();

      for (const line of lines) {
        if (line.startsWith('--- ') || line.startsWith('+++ ')) {
          const filePath = line.split('\t')[0].substring(4);
          if (filePath !== '/dev/null') {
            filePaths.add(path.join(workingDir, filePath));
          }
        }
      }

      // Apply patch using utility function
      const result = applyDiff(operation.patch, workingDir);

      return {
        success: true,
        message: `Successfully applied patch to ${filePaths.size} file(s)`,
      };
    } catch (error: any) {
      return {
        success: false,
        message: `Failed to apply patch: ${error.message}`,
      };
    }
  },
};

const agent = new Agent({
  name: 'CodeEditor',
  instructions: 'You can edit files using unified diffs',
  tools: [applyPatchTool(myEditor)],
});

const result = await run(
  agent,
  'Add a new function called "greet" to the file utils.ts that takes a name and returns a greeting'
);

Hosted MCP Tool

Create tools that execute on OpenAI's servers using Model Context Protocol.

/**
 * Create a hosted MCP tool for server-side execution
 * @param config - Hosted MCP tool configuration
 * @returns HostedTool instance
 */
function hostedMcpTool(config: HostedMcpToolConfig): HostedTool;

interface HostedMcpToolConfig {
  /** Server label/identifier (required) */
  serverLabel: string;

  /** Server URL (required if connectorId not provided) */
  serverUrl?: string;

  /** Connector ID (required if serverUrl not provided) */
  connectorId?: string;

  /** Authorization token */
  authorization?: string;

  /** Additional HTTP headers */
  headers?: Record<string, string>;

  /** Filter allowed tools */
  allowedTools?: string[] | { toolNames?: string[] };

  /** Tool approval requirements */
  requireApproval?: 'never' | 'always' | {
    never?: { toolNames: string[] };
    always?: { toolNames: string[] };
  };

  /** Approval callback */
  onApproval?: (
    context: RunContext,
    data: { toolName: string; arguments: any }
  ) => Promise<{ approve: boolean; reason?: string }>;
}

class HostedTool {
  /** Tool type (always 'hosted_mcp_tool') */
  type: 'hosted_mcp_tool';

  /** Server configuration */
  serverConfig: HostedMcpToolConfig;

  /** Convert to JSON representation */
  toJSON(): any;
}

Usage Examples:

import { Agent, run, hostedMcpTool } from '@openai/agents';

// Basic hosted MCP tool
const mcpTool = hostedMcpTool({
  serverLabel: 'my-mcp-server',
  serverUrl: 'https://mcp.example.com',
  authorization: 'Bearer token123',
});

const agent = new Agent({
  name: 'MCPAgent',
  instructions: 'You can use MCP tools',
  tools: [mcpTool],
});

// With tool filtering
const filteredMcpTool = hostedMcpTool({
  serverLabel: 'filtered-server',
  serverUrl: 'https://mcp.example.com',
  allowedTools: ['search', 'calculate', 'weather'],
});

// With approval requirements
const approvalMcpTool = hostedMcpTool({
  serverLabel: 'secure-server',
  serverUrl: 'https://mcp.example.com',
  requireApproval: {
    always: { toolNames: ['delete', 'modify'] },
    never: { toolNames: ['read', 'list'] },
  },
  onApproval: async (context, data) => {
    // Custom approval logic
    if (data.toolName === 'delete') {
      return {
        approve: false,
        reason: 'Deletion not allowed in this context',
      };
    }
    return { approve: true };
  },
});

// With connector ID
const connectorMcpTool = hostedMcpTool({
  serverLabel: 'connector-server',
  connectorId: 'conn_abc123',
  headers: {
    'X-Custom-Header': 'value',
  },
});

OpenAI Hosted Tools

Pre-built hosted tools provided by OpenAI.

/**
 * Create a web search tool
 * @param options - Web search configuration
 * @returns HostedTool instance
 */
function webSearchTool(options?: WebSearchOptions): HostedTool;

interface WebSearchOptions {
  /** Maximum number of results */
  maxResults?: number;

  /** Require approval before searching */
  requireApproval?: boolean;
}

/**
 * Create a vector store file search tool
 * @param vectorStoreIds - Vector store IDs to search
 * @param options - File search configuration
 * @returns HostedTool instance
 */
function fileSearchTool(
  vectorStoreIds: string[],
  options?: FileSearchOptions
): HostedTool;

interface FileSearchOptions {
  /** Maximum number of results */
  maxResults?: number;

  /** Ranking options */
  rankingOptions?: {
    ranker?: 'auto' | 'default_2024_08_21';
    scoreThreshold?: number;
  };

  /** Require approval before searching */
  requireApproval?: boolean;
}

/**
 * Create a code interpreter tool
 * @param options - Code interpreter configuration
 * @returns HostedTool instance
 */
function codeInterpreterTool(options?: CodeInterpreterOptions): HostedTool;

interface CodeInterpreterOptions {
  /** File IDs to make available to code interpreter */
  fileIds?: string[];

  /** Require approval before executing code */
  requireApproval?: boolean;
}

/**
 * Create an image generation tool
 * @param options - Image generation configuration
 * @returns HostedTool instance
 */
function imageGenerationTool(options?: ImageGenerationOptions): HostedTool;

interface ImageGenerationOptions {
  /** Image size */
  size?: '256x256' | '512x512' | '1024x1024' | '1792x1024' | '1024x1792';

  /** Image quality */
  quality?: 'standard' | 'hd';

  /** Image style */
  style?: 'natural' | 'vivid';

  /** Require approval before generating */
  requireApproval?: boolean;
}

Usage Examples:

import { Agent, run } from '@openai/agents';
import {
  webSearchTool,
  fileSearchTool,
  codeInterpreterTool,
  imageGenerationTool,
} from '@openai/agents';

// Web search
const searchAgent = new Agent({
  name: 'SearchAgent',
  instructions: 'You can search the web for information',
  tools: [webSearchTool({ maxResults: 5 })],
});

const searchResult = await run(
  searchAgent,
  'What are the latest AI developments?'
);

// File search
const fileAgent = new Agent({
  name: 'FileSearchAgent',
  instructions: 'You can search through uploaded documents',
  tools: [
    fileSearchTool(['vs_abc123', 'vs_def456'], {
      maxResults: 10,
      rankingOptions: {
        ranker: 'default_2024_08_21',
        scoreThreshold: 0.5,
      },
    }),
  ],
});

const fileResult = await run(
  fileAgent,
  'Find information about project timelines'
);

// Code interpreter
const codeAgent = new Agent({
  name: 'CodeAgent',
  instructions: 'You can write and execute Python code',
  tools: [
    codeInterpreterTool({
      fileIds: ['file_abc123'],
    }),
  ],
});

const codeResult = await run(
  codeAgent,
  'Analyze the CSV file and create a visualization'
);

// Image generation
const imageAgent = new Agent({
  name: 'ImageAgent',
  instructions: 'You can generate images',
  tools: [
    imageGenerationTool({
      size: '1024x1024',
      quality: 'hd',
      style: 'vivid',
    }),
  ],
});

const imageResult = await run(
  imageAgent,
  'Create an image of a futuristic city at sunset'
);

// Multiple hosted tools
const multiAgent = new Agent({
  name: 'MultiToolAgent',
  instructions: 'You have access to multiple tools',
  tools: [
    webSearchTool(),
    codeInterpreterTool(),
    imageGenerationTool(),
  ],
});

const multiResult = await run(
  multiAgent,
  'Search for data visualization techniques, write code to create a chart, and generate an image of the concept'
);

Agent as Tool

Transform an agent into a tool callable by other agents.

/**
 * Transform agent into a tool
 * @param options - Tool transformation options
 * @returns FunctionTool instance
 */
Agent.prototype.asTool(options?: AgentAsToolOptions): FunctionTool<TContext, Agent>;

interface AgentAsToolOptions {
  /** Override tool name */
  name?: string;

  /** Override tool description */
  description?: string;

  /** Input schema (defaults to text input) */
  inputType?: z.ZodType | JsonObjectSchema;
}

Usage Examples:

import { z } from 'zod';
import { Agent, run } from '@openai/agents';

// Create a specialist agent
const dataAnalyst = new Agent({
  name: 'DataAnalyst',
  instructions: 'You are an expert data analyst',
});

// Use as a tool
const mainAgent = new Agent({
  name: 'MainAgent',
  instructions: 'You coordinate different specialists',
  tools: [
    dataAnalyst.asTool({
      name: 'consult_data_analyst',
      description: 'Consult with the data analyst for analysis tasks',
    }),
  ],
});

const result = await run(
  mainAgent,
  'I need help analyzing sales data'
);

// With structured input
const calculatorAgent = new Agent({
  name: 'Calculator',
  instructions: 'You perform calculations',
});

const structuredTool = calculatorAgent.asTool({
  name: 'calculate',
  description: 'Perform a calculation',
  inputType: z.object({
    operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
    a: z.number(),
    b: z.number(),
  }),
});

const mathAgent = new Agent({
  name: 'MathAgent',
  instructions: 'You help with math',
  tools: [structuredTool],
});

const mathResult = await run(mathAgent, 'Calculate 15 times 24');