|  | 
|  | 1 | +import asyncio | 
|  | 2 | +import json | 
|  | 3 | + | 
|  | 4 | +from agents import ( | 
|  | 5 | +    Agent, | 
|  | 6 | +    Runner, | 
|  | 7 | +    ToolGuardrailFunctionOutput, | 
|  | 8 | +    ToolInputGuardrailData, | 
|  | 9 | +    ToolInputGuardrailTripwireTriggered, | 
|  | 10 | +    ToolOutputGuardrailData, | 
|  | 11 | +    ToolOutputGuardrailTripwireTriggered, | 
|  | 12 | +    function_tool, | 
|  | 13 | +    tool_input_guardrail, | 
|  | 14 | +    tool_output_guardrail, | 
|  | 15 | +) | 
|  | 16 | + | 
|  | 17 | + | 
|  | 18 | +@function_tool | 
|  | 19 | +def send_email(to: str, subject: str, body: str) -> str: | 
|  | 20 | +    """Send an email to the specified recipient.""" | 
|  | 21 | +    return f"Email sent to {to} with subject '{subject}'" | 
|  | 22 | + | 
|  | 23 | + | 
|  | 24 | +@function_tool | 
|  | 25 | +def get_user_data(user_id: str) -> dict[str, str]: | 
|  | 26 | +    """Get user data by ID.""" | 
|  | 27 | +    # Simulate returning sensitive data | 
|  | 28 | +    return { | 
|  | 29 | +        "user_id": user_id, | 
|  | 30 | +        "name": "John Doe", | 
|  | 31 | + | 
|  | 32 | +        "ssn": "123-45-6789",  # Sensitive data that should be blocked! | 
|  | 33 | +        "phone": "555-1234", | 
|  | 34 | +    } | 
|  | 35 | + | 
|  | 36 | + | 
|  | 37 | +@tool_input_guardrail | 
|  | 38 | +def block_sensitive_words(data: ToolInputGuardrailData) -> ToolGuardrailFunctionOutput: | 
|  | 39 | +    """Block tool calls that contain sensitive words in arguments.""" | 
|  | 40 | +    try: | 
|  | 41 | +        args = json.loads(data.tool_call.arguments) | 
|  | 42 | +    except json.JSONDecodeError: | 
|  | 43 | +        return ToolGuardrailFunctionOutput( | 
|  | 44 | +            tripwire_triggered=False, output_info="Invalid JSON arguments" | 
|  | 45 | +        ) | 
|  | 46 | + | 
|  | 47 | +    # Check for suspicious content | 
|  | 48 | +    sensitive_words = [ | 
|  | 49 | +        "password", | 
|  | 50 | +        "hack", | 
|  | 51 | +        "exploit", | 
|  | 52 | +        "malware", | 
|  | 53 | +        "orange", | 
|  | 54 | +    ]  # to mock sensitive words | 
|  | 55 | +    for key, value in args.items(): | 
|  | 56 | +        value_str = str(value).lower() | 
|  | 57 | +        for word in sensitive_words: | 
|  | 58 | +            if word in value_str: | 
|  | 59 | +                return ToolGuardrailFunctionOutput( | 
|  | 60 | +                    tripwire_triggered=True, | 
|  | 61 | +                    model_message=f"🚨 Tool call blocked: contains '{word}'", | 
|  | 62 | +                    output_info={"blocked_word": word, "argument": key}, | 
|  | 63 | +                ) | 
|  | 64 | + | 
|  | 65 | +    return ToolGuardrailFunctionOutput(tripwire_triggered=False, output_info="Input validated") | 
|  | 66 | + | 
|  | 67 | + | 
|  | 68 | +@tool_output_guardrail | 
|  | 69 | +def block_sensitive_output(data: ToolOutputGuardrailData) -> ToolGuardrailFunctionOutput: | 
|  | 70 | +    """Block tool outputs that contain sensitive data.""" | 
|  | 71 | +    output_str = str(data.output).lower() | 
|  | 72 | + | 
|  | 73 | +    # Check for sensitive data patterns | 
|  | 74 | +    if "ssn" in output_str or "123-45-6789" in output_str: | 
|  | 75 | +        return ToolGuardrailFunctionOutput( | 
|  | 76 | +            tripwire_triggered=True, | 
|  | 77 | +            model_message="🚨 Tool output blocked: contains sensitive data", | 
|  | 78 | +            output_info={"blocked_pattern": "SSN", "tool": data.tool_call.name}, | 
|  | 79 | +        ) | 
|  | 80 | + | 
|  | 81 | +    return ToolGuardrailFunctionOutput(tripwire_triggered=False, output_info="Output validated") | 
|  | 82 | + | 
|  | 83 | + | 
|  | 84 | +# Apply guardrails to tools | 
|  | 85 | +send_email.tool_input_guardrails = [block_sensitive_words] | 
|  | 86 | +get_user_data.tool_output_guardrails = [block_sensitive_output] | 
|  | 87 | + | 
|  | 88 | +agent = Agent( | 
|  | 89 | +    name="Secure Assistant", | 
|  | 90 | +    instructions="You are a helpful assistant with access to email and user data tools.", | 
|  | 91 | +    tools=[send_email, get_user_data], | 
|  | 92 | +) | 
|  | 93 | + | 
|  | 94 | + | 
|  | 95 | +async def main(): | 
|  | 96 | +    print("=== Tool Guardrails Example ===\n") | 
|  | 97 | + | 
|  | 98 | +    # Example 1: Normal operation - should work fine | 
|  | 99 | +    print("1. Normal email sending:") | 
|  | 100 | +    try: | 
|  | 101 | +        result = await Runner.run (agent , "Send a welcome email to [email protected]" ) | 
|  | 102 | +        print(f"✅ Success: {result.final_output}\n") | 
|  | 103 | +    except Exception as e: | 
|  | 104 | +        print(f"❌ Error: {e}\n") | 
|  | 105 | + | 
|  | 106 | +    # Example 2: Input guardrail triggers - should block suspicious content | 
|  | 107 | +    print("2. Attempting to send email with suspicious content:") | 
|  | 108 | +    try: | 
|  | 109 | +        result = await Runner.run( | 
|  | 110 | +            agent, "Send an email to [email protected] with the subject: orange" | 
|  | 111 | +        ) | 
|  | 112 | +        print(f"✅ Success: {result.final_output}\n") | 
|  | 113 | +    except ToolInputGuardrailTripwireTriggered as e: | 
|  | 114 | +        print(f"🚨 Input guardrail triggered: {e.output.model_message}") | 
|  | 115 | +        print(f"   Details: {e.output.output_info}\n") | 
|  | 116 | + | 
|  | 117 | +    # Example 3: Output guardrail triggers - should block sensitive data | 
|  | 118 | +    print("3. Attempting to get user data (contains SSN):") | 
|  | 119 | +    try: | 
|  | 120 | +        result = await Runner.run(agent, "Get the data for user ID user123") | 
|  | 121 | +        print(f"✅ Success: {result.final_output}\n") | 
|  | 122 | +    except ToolOutputGuardrailTripwireTriggered as e: | 
|  | 123 | +        print(f"🚨 Output guardrail triggered: {e.output.model_message}") | 
|  | 124 | +        print(f"   Details: {e.output.output_info}\n") | 
|  | 125 | + | 
|  | 126 | + | 
|  | 127 | +if __name__ == "__main__": | 
|  | 128 | +    asyncio.run(main()) | 
|  | 129 | + | 
|  | 130 | +""" | 
|  | 131 | +Example output: | 
|  | 132 | +
 | 
|  | 133 | +=== Tool Guardrails Example === | 
|  | 134 | +
 | 
|  | 135 | +1. Normal email sending: | 
|  | 136 | +✅ Success: I've sent a welcome email to [email protected] with an appropriate subject and greeting message. | 
|  | 137 | +
 | 
|  | 138 | +2. Attempting to send email with suspicious content: | 
|  | 139 | +🚨 Input guardrail triggered: 🚨 Tool call blocked: contains 'orange' | 
|  | 140 | +   Details: {'blocked_word': 'orange', 'argument': 'subject'} | 
|  | 141 | +
 | 
|  | 142 | +3. Attempting to get user data (contains SSN): | 
|  | 143 | +🚨 Output guardrail triggered: 🚨 Tool output blocked: contains sensitive data | 
|  | 144 | +   Details: {'blocked_pattern': 'SSN', 'tool': 'get_user_data'} | 
|  | 145 | +""" | 
0 commit comments