/ examples / js / tools / custom-tool.ts
custom-tool.ts
  1  /**
  2   * Custom Tool Example
  3   * Demonstrates creating custom tools using BaseTool class (plugin pattern)
  4   */
  5  
  6  import { BaseTool, createTool, tool, ToolRegistry } from 'praisonai';
  7  
  8  // Method 1: Extend BaseTool class (recommended for complex tools)
  9  class WeatherTool extends BaseTool<{ location: string; units?: string }, { temp: number; condition: string }> {
 10    name = 'get_weather';
 11    description = 'Get current weather for a location';
 12    parameters = {
 13      type: 'object' as const,
 14      properties: {
 15        location: { type: 'string', description: 'City name' },
 16        units: { type: 'string', description: 'celsius or fahrenheit', default: 'celsius' }
 17      },
 18      required: ['location']
 19    };
 20  
 21    async run(params: { location: string; units?: string }): Promise<{ temp: number; condition: string }> {
 22      // Simulate API call
 23      console.log(`Getting weather for ${params.location} in ${params.units || 'celsius'}`);
 24      return { temp: 22, condition: 'sunny' };
 25    }
 26  }
 27  
 28  // Method 2: Use createTool function (quick inline tools)
 29  const calculatorTool = createTool({
 30    name: 'calculator',
 31    description: 'Evaluate a math expression',
 32    parameters: {
 33      type: 'object',
 34      properties: {
 35        expression: { type: 'string', description: 'Math expression to evaluate' }
 36      },
 37      required: ['expression']
 38    },
 39    run: (params: { expression: string }) => {
 40      try {
 41        // Only allow safe numeric math characters
 42        if (!/^[0-9+\-*/.() ]+$/.test(params.expression)) {
 43          return 'Error: Only basic math expressions are allowed';
 44        }
 45        const result = new Function(`"use strict"; return (${params.expression})`)();
 46        if (typeof result !== 'number' || !isFinite(result)) return 'Error: Invalid result';
 47        return result;
 48      } catch {
 49        return 'Error: Invalid expression';
 50      }
 51    }
 52  });
 53  
 54  // Method 3: Use tool() function with config object
 55  const greeterTool = tool({
 56    name: 'greeter',
 57    description: 'Generate a personalized greeting',
 58    parameters: {
 59      type: 'object',
 60      properties: {
 61        name: { type: 'string', description: 'Name to greet' },
 62        style: { type: 'string', description: 'Greeting style: formal or casual' }
 63      },
 64      required: ['name']
 65    },
 66    execute: async (params: { name: string; style?: string }) => {
 67      if (params.style === 'formal') {
 68        return `Good day, ${params.name}. How may I assist you?`;
 69      }
 70      return `Hey ${params.name}! What's up?`;
 71    }
 72  });
 73  
 74  async function main() {
 75    console.log('=== Custom Tool Examples ===\n');
 76  
 77    // Test WeatherTool (class-based)
 78    console.log('--- WeatherTool (class-based) ---');
 79    const weather = new WeatherTool();
 80    console.log('Name:', weather.name);
 81    console.log('Description:', weather.description);
 82    
 83    const weatherResult = await weather.run({ location: 'New York' });
 84    console.log('Result:', weatherResult);
 85    
 86    // Safe execution with error handling
 87    const safeResult = await weather.safeRun({ location: 'London' });
 88    console.log('Safe result:', safeResult);
 89  
 90    // Get OpenAI schema
 91    console.log('OpenAI Schema:', JSON.stringify(weather.getSchema(), null, 2));
 92  
 93    // Test calculatorTool (createTool)
 94    console.log('\n--- Calculator Tool (createTool) ---');
 95    const calcResult = await calculatorTool.run({ expression: '10 * 5 + 2' });
 96    console.log('10 * 5 + 2 =', calcResult);
 97  
 98    // Test greeterTool (tool function)
 99    console.log('\n--- Greeter Tool (tool function) ---');
100    const greeting1 = await greeterTool.execute({ name: 'Alice' });
101    console.log('Casual:', greeting1);
102    
103    const greeting2 = await greeterTool.execute({ name: 'Mr. Smith', style: 'formal' });
104    console.log('Formal:', greeting2);
105  
106    // Register tools in registry
107    console.log('\n--- Tool Registry ---');
108    const registry = new ToolRegistry();
109    registry.register(greeterTool);
110    
111    console.log('Registered tools:', registry.list().map(t => t.name));
112    console.log('OpenAI tools format:', registry.toOpenAITools().length, 'tools');
113  
114    // Validate tool
115    console.log('\n--- Validation ---');
116    console.log('WeatherTool valid:', weather.validate());
117  }
118  
119  main().catch(console.error);