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

guardrails.mddocs/

Input and Output Guardrails

Validate inputs and outputs for safety and reliability.

Capabilities

Input Guardrails

Check and validate inputs before agent execution.

/**
 * Input guardrail for validating inputs before agent execution
 */
interface InputGuardrail<TContext = any> {
  /** Guardrail identifier */
  name: string;

  /**
   * Execute the guardrail check
   * @param args - Guardrail execution arguments
   * @returns Guardrail result with tripwire status
   */
  execute: (args: {
    agent: Agent;
    input: AgentInputItem[];
    context: RunContext<TContext>;
  }) => Promise<GuardrailFunctionOutput>;

  /** Run this guardrail in parallel with others (default: false) */
  runInParallel?: boolean;
}

interface GuardrailFunctionOutput {
  /** Whether the guardrail was triggered/violated */
  tripwireTriggered: boolean;

  /** Additional information about the check */
  outputInfo: any;
}

interface InputGuardrailResult {
  /** Guardrail name */
  name: string;

  /** Whether tripwire was triggered */
  tripwireTriggered: boolean;

  /** Output information from the check */
  outputInfo: any;

  /** Error if guardrail execution failed */
  error?: Error;
}

Usage Examples:

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

// Basic input guardrail
const profanityGuardrail: InputGuardrail = {
  name: 'profanity_check',
  execute: async ({ input, context }) => {
    const text = input
      .map(item => item.type === 'user_message' ? item.content : '')
      .join(' ');

    const hasProfanity = /\b(bad|word|list)\b/i.test(text);

    return {
      tripwireTriggered: hasProfanity,
      outputInfo: { filtered: hasProfanity },
    };
  },
};

const agent = new Agent({
  name: 'SafeAgent',
  instructions: 'You are a helpful assistant',
  inputGuardrails: [profanityGuardrail],
});

try {
  const result = await run(agent, 'Hello there!');
  console.log(result.finalOutput);
} catch (error) {
  if (error instanceof InputGuardrailTripwireTriggered) {
    console.log('Input was blocked by guardrail');
  }
}

// Context-aware guardrail
const rateLimitGuardrail: InputGuardrail = {
  name: 'rate_limit',
  execute: async ({ context }) => {
    const userId = context.context.userId;
    const requestCount = await getRequestCount(userId);

    return {
      tripwireTriggered: requestCount > 100,
      outputInfo: { requestCount },
    };
  },
};

const rateLimitedAgent = new Agent({
  name: 'RateLimitedAgent',
  instructions: 'You are helpful',
  inputGuardrails: [rateLimitGuardrail],
});

const result2 = await run(rateLimitedAgent, 'Hello', {
  context: { userId: 'user123' },
});

// Multiple guardrails
const lengthGuardrail: InputGuardrail = {
  name: 'max_length',
  execute: async ({ input }) => {
    const text = input
      .map(item => item.type === 'user_message' ? item.content : '')
      .join(' ');

    return {
      tripwireTriggered: text.length > 10000,
      outputInfo: { length: text.length },
    };
  },
};

const languageGuardrail: InputGuardrail = {
  name: 'language_check',
  execute: async ({ input }) => {
    // Check if input is in allowed languages
    const allowedLanguages = ['en', 'es', 'fr'];
    const language = detectLanguage(input);

    return {
      tripwireTriggered: !allowedLanguages.includes(language),
      outputInfo: { detectedLanguage: language },
    };
  },
};

const multiGuardAgent = new Agent({
  name: 'MultiGuardAgent',
  instructions: 'You are helpful',
  inputGuardrails: [
    profanityGuardrail,
    lengthGuardrail,
    languageGuardrail,
  ],
});

// Parallel execution guardrails
const fastGuardrail: InputGuardrail = {
  name: 'fast_check',
  runInParallel: true, // Run concurrently with other parallel guardrails
  execute: async ({ input }) => {
    // Fast validation
    return {
      tripwireTriggered: false,
      outputInfo: {},
    };
  },
};

const anotherFastGuardrail: InputGuardrail = {
  name: 'another_fast_check',
  runInParallel: true,
  execute: async ({ input }) => {
    // Another fast validation
    return {
      tripwireTriggered: false,
      outputInfo: {},
    };
  },
};

const parallelAgent = new Agent({
  name: 'ParallelGuardAgent',
  instructions: 'You are helpful',
  inputGuardrails: [fastGuardrail, anotherFastGuardrail],
});

// Helper function for example
async function getRequestCount(userId: string): Promise<number> {
  return 50; // Mock implementation
}

function detectLanguage(input: any[]): string {
  return 'en'; // Mock implementation
}

Output Guardrails

Check and validate outputs after agent generation.

/**
 * Output guardrail for validating outputs after agent execution
 */
interface OutputGuardrail<TOutput = any, TContext = any> {
  /** Guardrail identifier */
  name: string;

  /**
   * Execute the guardrail check
   * @param args - Guardrail execution arguments
   * @returns Guardrail result with tripwire status
   */
  execute: (args: {
    agent: Agent;
    agentOutput: TOutput;
    context: RunContext<TContext>;
    details?: {
      rawOutput: AgentOutputItem[];
    };
  }) => Promise<GuardrailFunctionOutput>;
}

interface OutputGuardrailResult {
  /** Guardrail name */
  name: string;

  /** Whether tripwire was triggered */
  tripwireTriggered: boolean;

  /** Output information from the check */
  outputInfo: any;

  /** Error if guardrail execution failed */
  error?: Error;
}

/**
 * Helper function to define output guardrails with type safety
 * @param config - Output guardrail configuration
 * @returns OutputGuardrail instance
 */
function defineOutputGuardrail<TOutput = any, TContext = any>(
  config: OutputGuardrailConfig<TOutput, TContext>
): OutputGuardrail<TOutput, TContext>;

interface OutputGuardrailConfig<TOutput, TContext> {
  /** Guardrail identifier */
  name: string;

  /**
   * Execute the guardrail check
   */
  execute: (args: {
    agent: Agent;
    agentOutput: TOutput;
    context: RunContext<TContext>;
    details?: {
      rawOutput: AgentOutputItem[];
    };
  }) => Promise<GuardrailFunctionOutput>;
}

Usage Examples:

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

// Basic output guardrail
const toxicityGuardrail: OutputGuardrail = {
  name: 'toxicity_check',
  execute: async ({ agentOutput }) => {
    const outputText = String(agentOutput);
    const isToxic = await checkToxicity(outputText);

    return {
      tripwireTriggered: isToxic,
      outputInfo: { toxicityScore: 0.2 },
    };
  },
};

const agent = new Agent({
  name: 'SafeAgent',
  instructions: 'You are a helpful assistant',
  outputGuardrails: [toxicityGuardrail],
});

try {
  const result = await run(agent, 'Tell me a story');
  console.log(result.finalOutput);
} catch (error) {
  if (error instanceof OutputGuardrailTripwireTriggered) {
    console.log('Output was blocked by guardrail');
  }
}

// Using defineOutputGuardrail helper
const piiGuardrail = defineOutputGuardrail({
  name: 'pii_detection',
  execute: async ({ agentOutput }) => {
    const text = String(agentOutput);

    // Check for PII patterns
    const hasPII =
      /\b\d{3}-\d{2}-\d{4}\b/.test(text) || // SSN
      /\b\d{16}\b/.test(text); // Credit card

    return {
      tripwireTriggered: hasPII,
      outputInfo: { piiDetected: hasPII },
    };
  },
});

const piiAgent = new Agent({
  name: 'PIIAwareAgent',
  instructions: 'You are helpful',
  outputGuardrails: [piiGuardrail],
});

// Structured output guardrail
import { z } from 'zod';

const dataAgent = new Agent({
  name: 'DataAgent',
  instructions: 'Extract data',
  outputType: z.object({
    name: z.string(),
    age: z.number(),
    email: z.string(),
  }),
  outputGuardrails: [
    defineOutputGuardrail<{ name: string; age: number; email: string }>({
      name: 'age_validation',
      execute: async ({ agentOutput }) => {
        return {
          tripwireTriggered: agentOutput.age < 0 || agentOutput.age > 150,
          outputInfo: { age: agentOutput.age },
        };
      },
    }),
  ],
});

// Context-aware output guardrail
const complianceGuardrail = defineOutputGuardrail({
  name: 'compliance_check',
  execute: async ({ agentOutput, context }) => {
    const userRegion = context.context.region;
    const outputText = String(agentOutput);

    // Region-specific compliance check
    const isCompliant = await checkRegionCompliance(outputText, userRegion);

    return {
      tripwireTriggered: !isCompliant,
      outputInfo: { region: userRegion, compliant: isCompliant },
    };
  },
});

const complianceAgent = new Agent({
  name: 'ComplianceAgent',
  instructions: 'You provide information',
  outputGuardrails: [complianceGuardrail],
});

await run(complianceAgent, 'Give me information', {
  context: { region: 'EU' },
});

// Access raw output items
const detailedGuardrail = defineOutputGuardrail({
  name: 'detailed_check',
  execute: async ({ agentOutput, details }) => {
    // Access raw output items for detailed inspection
    const hasRefusal = details?.rawOutput.some(
      item => item.type === 'refusal'
    );

    return {
      tripwireTriggered: hasRefusal,
      outputInfo: { refusalDetected: hasRefusal },
    };
  },
});

// Helper functions for examples
async function checkToxicity(text: string): Promise<boolean> {
  return false; // Mock implementation
}

async function checkRegionCompliance(text: string, region: string): Promise<boolean> {
  return true; // Mock implementation
}

Global Guardrails

Apply guardrails to all agents using Runner configuration.

interface RunnerConfig<TContext = any> {
  /** Global input guardrails applied to all agents */
  inputGuardrails?: InputGuardrail[];

  /** Global output guardrails applied to all agents */
  outputGuardrails?: OutputGuardrail[];
}

Usage Examples:

import { Agent, Runner, InputGuardrail, OutputGuardrail } from '@openai/agents';

// Define global guardrails
const globalInputGuardrail: InputGuardrail = {
  name: 'global_input_check',
  execute: async ({ input }) => {
    console.log('Global input check');
    return {
      tripwireTriggered: false,
      outputInfo: {},
    };
  },
};

const globalOutputGuardrail: OutputGuardrail = {
  name: 'global_output_check',
  execute: async ({ agentOutput }) => {
    console.log('Global output check');
    return {
      tripwireTriggered: false,
      outputInfo: {},
    };
  },
};

// Create runner with global guardrails
const runner = new Runner({
  inputGuardrails: [globalInputGuardrail],
  outputGuardrails: [globalOutputGuardrail],
});

const agent1 = new Agent({
  name: 'Agent1',
  instructions: 'You are agent 1',
});

const agent2 = new Agent({
  name: 'Agent2',
  instructions: 'You are agent 2',
});

// Global guardrails apply to all agents
await runner.run(agent1, 'Hello');
await runner.run(agent2, 'Hi there');

// Combine global and agent-specific guardrails
const specificGuardrail: InputGuardrail = {
  name: 'agent_specific',
  execute: async ({ input }) => {
    console.log('Agent-specific check');
    return {
      tripwireTriggered: false,
      outputInfo: {},
    };
  },
};

const agent3 = new Agent({
  name: 'Agent3',
  instructions: 'You are agent 3',
  inputGuardrails: [specificGuardrail], // Added to global guardrails
});

// Both global and agent-specific guardrails run
await runner.run(agent3, 'Test');

Guardrail Results

Access guardrail execution results from RunResult.

interface RunResult<TOutput = any> {
  /** Input guardrail results */
  inputGuardrailResults: InputGuardrailResult[];

  /** Output guardrail results */
  outputGuardrailResults: OutputGuardrailResult[];
}

Usage Examples:

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

const inputGuardrail: InputGuardrail = {
  name: 'input_validator',
  execute: async ({ input }) => {
    return {
      tripwireTriggered: false,
      outputInfo: { validated: true },
    };
  },
};

const outputGuardrail: OutputGuardrail = {
  name: 'output_validator',
  execute: async ({ agentOutput }) => {
    return {
      tripwireTriggered: false,
      outputInfo: { score: 0.95 },
    };
  },
};

const agent = new Agent({
  name: 'GuardedAgent',
  instructions: 'You are helpful',
  inputGuardrails: [inputGuardrail],
  outputGuardrails: [outputGuardrail],
});

const result = await run(agent, 'Hello!');

// Check input guardrail results
for (const result of result.inputGuardrailResults) {
  console.log(`Input guardrail: ${result.name}`);
  console.log(`Triggered: ${result.tripwireTriggered}`);
  console.log(`Info: ${JSON.stringify(result.outputInfo)}`);
  if (result.error) {
    console.log(`Error: ${result.error.message}`);
  }
}

// Check output guardrail results
for (const result of result.outputGuardrailResults) {
  console.log(`Output guardrail: ${result.name}`);
  console.log(`Triggered: ${result.tripwireTriggered}`);
  console.log(`Info: ${JSON.stringify(result.outputInfo)}`);
  if (result.error) {
    console.log(`Error: ${result.error.message}`);
  }
}

// Check if any guardrails were triggered
const anyInputTriggered = result.inputGuardrailResults.some(
  r => r.tripwireTriggered
);
const anyOutputTriggered = result.outputGuardrailResults.some(
  r => r.tripwireTriggered
);

console.log(`Input blocked: ${anyInputTriggered}`);
console.log(`Output blocked: ${anyOutputTriggered}`);

Guardrail Errors

Handle guardrail-related errors.

/**
 * Base error for guardrail execution failures
 */
class GuardrailExecutionError extends AgentsError {
  /** Guardrail name */
  guardrailName: string;

  /** Original error */
  cause: Error;
}

/**
 * Error thrown when input guardrail tripwire is triggered
 */
class InputGuardrailTripwireTriggered extends AgentsError {
  /** Triggered guardrail results */
  guardrailResults: InputGuardrailResult[];
}

/**
 * Error thrown when output guardrail tripwire is triggered
 */
class OutputGuardrailTripwireTriggered extends AgentsError {
  /** Triggered guardrail results */
  guardrailResults: OutputGuardrailResult[];

  /** Agent output that was blocked */
  agentOutput: any;
}

Usage Examples:

import {
  Agent,
  run,
  InputGuardrail,
  OutputGuardrail,
  InputGuardrailTripwireTriggered,
  OutputGuardrailTripwireTriggered,
  GuardrailExecutionError,
} from '@openai/agents';

const strictInputGuardrail: InputGuardrail = {
  name: 'strict_input',
  execute: async ({ input }) => {
    return {
      tripwireTriggered: true, // Always trigger
      outputInfo: { reason: 'Input not allowed' },
    };
  },
};

const agent = new Agent({
  name: 'StrictAgent',
  instructions: 'You are strict',
  inputGuardrails: [strictInputGuardrail],
});

try {
  await run(agent, 'Hello');
} catch (error) {
  if (error instanceof InputGuardrailTripwireTriggered) {
    console.log('Input guardrail triggered');
    console.log('Triggered guardrails:');
    for (const result of error.guardrailResults) {
      console.log(`  - ${result.name}: ${JSON.stringify(result.outputInfo)}`);
    }
  }
}

// Output guardrail error
const strictOutputGuardrail: OutputGuardrail = {
  name: 'strict_output',
  execute: async ({ agentOutput }) => {
    return {
      tripwireTriggered: true,
      outputInfo: { reason: 'Output not allowed' },
    };
  },
};

const outputAgent = new Agent({
  name: 'OutputAgent',
  instructions: 'You are helpful',
  outputGuardrails: [strictOutputGuardrail],
});

try {
  await run(outputAgent, 'Hello');
} catch (error) {
  if (error instanceof OutputGuardrailTripwireTriggered) {
    console.log('Output guardrail triggered');
    console.log('Blocked output:', error.agentOutput);
    console.log('Triggered guardrails:');
    for (const result of error.guardrailResults) {
      console.log(`  - ${result.name}: ${JSON.stringify(result.outputInfo)}`);
    }
  }
}

// Guardrail execution error
const faultyGuardrail: InputGuardrail = {
  name: 'faulty',
  execute: async () => {
    throw new Error('Guardrail crashed');
  },
};

const faultyAgent = new Agent({
  name: 'FaultyAgent',
  instructions: 'You are helpful',
  inputGuardrails: [faultyGuardrail],
});

try {
  await run(faultyAgent, 'Hello');
} catch (error) {
  if (error instanceof GuardrailExecutionError) {
    console.log('Guardrail execution failed');
    console.log('Guardrail name:', error.guardrailName);
    console.log('Error:', error.cause.message);
  }
}

Best Practices

Guardrail Design Guidelines:

import { Agent, run, InputGuardrail, OutputGuardrail, defineOutputGuardrail } from '@openai/agents';

// 1. Keep guardrails fast
const fastGuardrail: InputGuardrail = {
  name: 'fast_check',
  execute: async ({ input }) => {
    // Use efficient validation methods
    // Avoid expensive API calls or complex processing
    return {
      tripwireTriggered: false,
      outputInfo: {},
    };
  },
};

// 2. Use parallel execution for independent checks
const check1: InputGuardrail = {
  name: 'check_1',
  runInParallel: true,
  execute: async ({ input }) => {
    // Independent check
    return { tripwireTriggered: false, outputInfo: {} };
  },
};

const check2: InputGuardrail = {
  name: 'check_2',
  runInParallel: true,
  execute: async ({ input }) => {
    // Another independent check
    return { tripwireTriggered: false, outputInfo: {} };
  },
};

// 3. Provide meaningful outputInfo
const informativeGuardrail: OutputGuardrail = {
  name: 'content_policy',
  execute: async ({ agentOutput }) => {
    const violations = checkContentPolicy(String(agentOutput));

    return {
      tripwireTriggered: violations.length > 0,
      outputInfo: {
        violations,
        categories: violations.map(v => v.category),
        severity: violations.length > 0 ? 'high' : 'none',
      },
    };
  },
};

// 4. Use context for user-specific rules
const contextAwareGuardrail = defineOutputGuardrail({
  name: 'user_permissions',
  execute: async ({ agentOutput, context }) => {
    const userRole = context.context.userRole;
    const outputText = String(agentOutput);

    // Check if output is appropriate for user role
    const isAllowed = checkPermissions(outputText, userRole);

    return {
      tripwireTriggered: !isAllowed,
      outputInfo: { userRole, allowed: isAllowed },
    };
  },
});

// 5. Layer guardrails from fast to slow
const agent = new Agent({
  name: 'LayeredAgent',
  instructions: 'You are helpful',
  inputGuardrails: [
    fastGuardrail, // Run cheap checks first
    check1,
    check2,
    // More expensive checks last
  ],
});

// Helper functions
function checkContentPolicy(text: string): Array<{ category: string }> {
  return []; // Mock implementation
}

function checkPermissions(text: string, role: string): boolean {
  return true; // Mock implementation
}