Skip to main content
Learn how to integrate tools with AG-Kit agents to create powerful AI workflows that can interact with the external world through a comprehensive toolkit.

Basic Agent Integration

Simple Tool Integration

The most basic form of agent integration involves creating a custom tool and providing it to an agent. This allows the agent to perform specific operations beyond its base language capabilities. Key components of agent integration:
  • Model Provider: Configure the LLM provider (OpenAI, Anthropic, etc.)
  • Tool Definition: Create tools with clear schemas and error handling
  • Agent Configuration: Set up the agent with instructions, tools, and model settings
  • Execution: Run the agent with natural language inputs

Multiple Tool Integration

For more complex workflows, you can integrate multiple tools and toolkits with a single agent. This creates powerful assistants capable of handling diverse tasks across different domains. This approach allows agents to:
  • Read and write files using the filesystem toolkit
  • Execute code in secure sandboxed environments
  • Run command line operations for system interactions
  • Perform calculations with custom tools

Advanced Integration Patterns

Intelligent Tool Selection

Advanced agents can be configured with multiple specialized tools and intelligent selection strategies. The agent will automatically choose the most appropriate tool based on the task context and user requirements.
// Create specialized tools for different data formats
const dataProcessingTools = [
  tool(
    async ({ filePath, operation }) => {
      // Implementation details...
      return { success: true, data: { processed: true, operation } };
    },
    {
      name: 'csv_processor',
      description: 'Process CSV data files and perform data analysis',
      schema: z.object({ 
        filePath: z.string(),
        operation: z.enum(['parse', 'analyze', 'transform'])
      })
    }
  ),
  tool(
    async ({ url, method, headers }) => {
      // Implementation details...
      return { success: true, data: { status: 200, response: 'API response' } };
    },
    {
      name: 'http_client',
      description: 'Make HTTP requests to external APIs',
      schema: z.object({ 
        url: z.string(),
        method: z.enum(['GET', 'POST', 'PUT', 'DELETE']).default('GET'),
        headers: z.record(z.string()).optional()
      })
    }
  )
];

// Create agent with multiple specialized tools
const smartAgent = /* Agent initialization */ {
  /* ... */
  tools: [...dataProcessingTools, ...filesystemToolkit.getTools()],
  /* ... */
};
Benefits of intelligent tool selection:
  • Automatic tool routing based on task requirements
  • Contextual decision making for optimal tool usage
  • Extensible architecture for adding new specialized tools
  • Clear reasoning about tool selection choices

Error Handling and Resilience

Graceful Error Recovery

Building resilient agents that can handle tool failures gracefully is crucial for production applications. AG-Kit provides several mechanisms for error handling and recovery.
// Create resilient agent with error handling
const resilientAgent = /* Agent initialization */ {
  /* ... */
  tools: [
    ...filesystemToolkit.getTools(),
    new BuiltInCodeExecutor()
  ],
  /* controlFlow: { errorRetryLimit: 2, maxSteps: 10 } */
};

// Handle errors in usage
try {
  const response = await resilientAgent.run('Process this complex request');
  console.log('Success:', response);
} catch (error) {
  console.error('Agent error:', error.message);
  // Implement fallback strategies or user notification
}

Input Validation and Security

Implementing proper input validation and security measures in tools is essential for safe agent operations, especially when dealing with file systems or external APIs.
const validatedTool = tool(
  async ({ filePath, operation }) => {
    try {
      const fs = await import('fs/promises');
      
      // Pre-execution validation
      try {
        await fs.access(filePath);
        const stats = await fs.stat(filePath);
        if (stats.size > 10 * 1024 * 1024) { // 10MB limit
          return { 
            success: false, 
            error: 'File too large (max 10MB)', 
            error_type: 'validation' 
          };
        }
      } catch {
        return { 
          success: false, 
          error: 'File does not exist', 
          error_type: 'validation' 
        };
      }
      
      // Execute operation with proper error handling
      const operations = {
        read: async () => ({ content: await fs.readFile(filePath, 'utf-8') }),
        analyze: async () => {
          const content = await fs.readFile(filePath, 'utf-8');
          return { 
            lines: content.split('\n').length,
            characters: content.length,
            words: content.split(/\s+/).length
          };
        },
        transform: async () => ({ message: 'Transform operation completed' })
      };
      
      const result = await operations[operation]();
      
      // Post-execution validation
      if (!result || typeof result !== 'object') {
        return {
          success: false,
          error: 'Invalid processing result',
          error_type: 'execution'
        };
      }
      
      return { success: true, data: result };
      
    } catch (error) {
      return { 
        success: false, 
        error: error.message, 
        error_type: 'execution' 
      };
    }
  },
  {
    name: 'validated_file_processor',
    description: 'Process files with comprehensive validation and security checks',
    schema: z.object({
      filePath: z.string().refine(
        (path) => !path.includes('..') && !path.startsWith('/'),
        'File path must be relative and safe'
      ),
      operation: z.enum(['read', 'analyze', 'transform'])
    })
  }
);

// Use validated tool with agent
const secureAgent = /* Agent initialization */ {
  /* ... */
  tools: [validatedTool],
  /* ... */
};
Key validation practices:
  • Input sanitization to prevent path traversal attacks
  • File size limits to prevent resource exhaustion
  • Pre and post-execution validation for data integrity
  • Structured error responses with appropriate error types

Streaming and Real-time Integration

Streaming Tool Responses

For long-running operations or real-time data processing, AG-Kit supports streaming responses that provide progress updates and intermediate results to users.
import { EventEmitter } from 'events';

// Create streaming tool for long-running operations
const streamingTool = tool(
  async ({ dataset, batchSize }) => {
    const stream = new EventEmitter();
    
    // Simulate streaming processing with progress updates
    [25, 50, 75, 100].forEach((progress, index) => {
      setTimeout(() => {
        const event = progress === 100 ? 'complete' : 'progress';
        stream.emit(event, { 
          progress, 
          message: `Processing batch ${index + 1}`,
          timestamp: new Date().toISOString()
        });
      }, (index + 1) * 1000);
    });
    
    return {
      success: true,
      stream,
      data: { 
        message: 'Streaming processing started', 
        batchSize,
        estimatedDuration: '4 seconds'
      }
    };
  },
  {
    name: 'streaming_processor',
    description: 'Process large datasets with real-time progress updates',
    schema: z.object({
      dataset: z.string(),
      batchSize: z.number().default(100)
    })
  }
);

// Create streaming agent
const streamingAgent = /* Agent initialization */ {
  /* ... */
  tools: [streamingTool],
  /* ... */
};

// Usage with streaming enabled
const response = await streamingAgent.run(
  'Process the large dataset with real-time progress updates',
  /* state, options */
);

// Handle streaming response
if (response.stream) {
  response.stream.subscribe({
    next: (chunk) => {
      console.log('Streaming chunk:', chunk);
      // Update UI with progress information
    },
    error: (error) => {
      console.error('Stream error:', error);
      // Handle streaming errors
    },
    complete: () => {
      console.log('Stream completed');
      // Finalize UI updates
    }
  });
}
Streaming capabilities enable:
  • Real-time progress tracking for long-running operations
  • Intermediate result delivery for better user experience
  • Responsive UI updates during processing
  • Early error detection and handling

Performance Optimization

Parallel Tool Execution

AG-Kit agents can automatically execute independent tool calls in parallel, significantly improving performance for operations that don’t depend on each other.
// Create agent with parallel execution capabilities
const parallelAgent = /* Agent initialization */ {
  /* ... */
  tools: [
    calculatorTool,
    ...filesystemToolkit.getTools()
  ],
  /* ... */
};

// The agent will automatically execute independent tool calls in parallel
const response = await parallelAgent.run(
  'Calculate 15 * 23, read the config.json file, and check if package.json exists'
);
Performance benefits:
  • Reduced execution time for independent operations
  • Better resource utilization through concurrent processing
  • Improved user experience with faster response times
  • Automatic optimization without manual coordination

Next Steps