Skip to content

Module System Integration

Learn how to use the enhanced Plugin-Module-Separation architecture in Robota SDK.

Overview

The Robota SDK now features a comprehensive Plugin-Module-Separation architecture that provides:

  • Enhanced Plugin System: Classification, priorities, and module event subscription
  • Module Infrastructure: BaseModule, ModuleRegistry, and ModuleTypeRegistry
  • Event-Driven Communication: Loose coupling between modules and plugins
  • Backward Compatibility: All existing plugins work without modification

Plugin Classification System

Plugin Categories and Priorities

typescript
import {
  Robota,
  LoggingPlugin,
  PerformancePlugin,
  UsagePlugin,
  PluginCategory,
  PluginPriority,
} from '@robota-sdk/agent-core';

// Plugins are automatically classified with categories and priorities
const plugins = [
  new LoggingPlugin({
    // [LOGGING/HIGH]
    level: 'info',
    moduleEvents: ['module.initialize.complete', 'module.execution.complete'],
  }),
  new PerformancePlugin({
    // [MONITORING/NORMAL]
    moduleEvents: ['module.execution.start', 'module.execution.complete'],
  }),
  new UsagePlugin({
    // [MONITORING/NORMAL]
    moduleEvents: ['module.execution.complete'],
  }),
];

// Create agent with enhanced plugins
const agent = new Robota({
  name: 'ClassifiedAgent',
  model: 'gpt-4',
  provider: 'openai',
  aiProviders: { openai: openaiProvider },
  plugins,
  systemMessage: 'You are an AI agent with enhanced monitoring capabilities.',
});

Module Event Subscription

Plugins can now subscribe to module lifecycle events:

typescript
// LoggingPlugin will automatically log module activities
const loggingPlugin = new LoggingPlugin({
  level: 'info',
  // Subscribe to specific module events
  moduleEvents: [
    'module.initialize.start',
    'module.initialize.complete',
    'module.execution.start',
    'module.execution.complete',
    'module.execution.error',
    'module.dispose.complete',
  ],
  // Or subscribe to all module events
  subscribeToAllModuleEvents: false,
});

// PerformancePlugin will track module performance
const performancePlugin = new PerformancePlugin({
  moduleEvents: ['module.execution.start', 'module.execution.complete'],
});

// UsagePlugin will track module usage statistics
const usagePlugin = new UsagePlugin({
  moduleEvents: ['module.execution.complete'],
});

Creating Custom Modules

Basic Module Implementation

typescript
import { BaseModule, ModuleExecutionContext, ModuleExecutionResult } from '@robota-sdk/agent-core';

class StorageModule extends BaseModule {
  readonly name = 'StorageModule';
  readonly version = '1.0.0';
  readonly moduleType = 'storage';

  private storage: Map<string, any> = new Map();

  constructor(options: any, eventEmitter?: EventEmitter) {
    super(options, eventEmitter);

    // Declare module capabilities
    this.capabilities = ['data-storage', 'data-retrieval'];
    this.dependencies = []; // No dependencies for this module
  }

  async initialize(): Promise<void> {
    this.emitModuleEvent('initialize.start', {
      moduleName: this.name,
      moduleType: this.moduleType,
      executionId: this.generateExecutionId(),
    });

    // Initialize storage
    this.storage.clear();
    console.log('Storage module initialized');

    this.emitModuleEvent('initialize.complete', {
      moduleName: this.name,
      moduleType: this.moduleType,
      executionId: this.lastExecutionId,
      duration: Date.now() - this.startTime,
    });
  }

  async execute<T>(context: ModuleExecutionContext): Promise<ModuleExecutionResult<T>> {
    this.emitModuleEvent('execution.start', {
      moduleName: this.name,
      moduleType: this.moduleType,
      executionId: this.generateExecutionId(),
      context,
    });

    try {
      const { operation, key, value } = context;
      let result: any;

      switch (operation) {
        case 'store':
          this.storage.set(key, value);
          result = { success: true, key, value };
          break;
        case 'retrieve':
          result = { success: true, key, value: this.storage.get(key) };
          break;
        case 'delete':
          const deleted = this.storage.delete(key);
          result = { success: deleted, key };
          break;
        default:
          throw new Error(`Unknown operation: ${operation}`);
      }

      this.emitModuleEvent('execution.complete', {
        moduleName: this.name,
        moduleType: this.moduleType,
        executionId: this.lastExecutionId,
        duration: Date.now() - this.startTime,
        success: true,
        result,
      });

      return { success: true, data: result as T };
    } catch (error) {
      this.emitModuleEvent('execution.error', {
        moduleName: this.name,
        moduleType: this.moduleType,
        executionId: this.lastExecutionId,
        duration: Date.now() - this.startTime,
        success: false,
        error: error.message,
      });

      return { success: false, error: error.message };
    }
  }

  async dispose(): Promise<void> {
    this.storage.clear();
    console.log('Storage module disposed');

    this.emitModuleEvent('dispose.complete', {
      moduleName: this.name,
      moduleType: this.moduleType,
      executionId: this.generateExecutionId(),
    });
  }

  getStats() {
    return {
      executionCount: this.executionCount,
      averageExecutionTime: this.averageExecutionTime,
      lastExecution: this.lastExecution,
      storageSize: this.storage.size,
    };
  }
}

Advanced Module with Dependencies

typescript
class ProcessingModule extends BaseModule {
  readonly name = 'ProcessingModule';
  readonly version = '1.0.0';
  readonly moduleType = 'processing';

  constructor(options: any, eventEmitter?: EventEmitter) {
    super(options, eventEmitter);

    this.capabilities = ['data-processing', 'transformation'];
    this.dependencies = ['StorageModule']; // Depends on storage module
  }

  async initialize(): Promise<void> {
    this.emitModuleEvent('initialize.start', {
      moduleName: this.name,
      moduleType: this.moduleType,
      executionId: this.generateExecutionId(),
    });

    // Initialize processing resources
    console.log('Processing module initialized');

    this.emitModuleEvent('initialize.complete', {
      moduleName: this.name,
      moduleType: this.moduleType,
      executionId: this.lastExecutionId,
      duration: Date.now() - this.startTime,
    });
  }

  async execute<T>(context: ModuleExecutionContext): Promise<ModuleExecutionResult<T>> {
    this.emitModuleEvent('execution.start', {
      moduleName: this.name,
      moduleType: this.moduleType,
      executionId: this.generateExecutionId(),
      context,
    });

    try {
      const { data, operation } = context;

      // Process data based on operation
      const processedData = await this.processData(data, operation);

      this.emitModuleEvent('execution.complete', {
        moduleName: this.name,
        moduleType: this.moduleType,
        executionId: this.lastExecutionId,
        duration: Date.now() - this.startTime,
        success: true,
        result: processedData,
      });

      return { success: true, data: processedData as T };
    } catch (error) {
      this.emitModuleEvent('execution.error', {
        moduleName: this.name,
        moduleType: this.moduleType,
        executionId: this.lastExecutionId,
        error: error.message,
      });

      return { success: false, error: error.message };
    }
  }

  private async processData(data: any, operation: string): Promise<any> {
    // Simulate data processing
    switch (operation) {
      case 'transform':
        return { ...data, processed: true, timestamp: Date.now() };
      case 'validate':
        return { valid: true, data };
      default:
        return data;
    }
  }
}

Module Registry Usage

Setting Up Module Registry

typescript
import { ModuleRegistry, ModuleTypeRegistry } from '@robota-sdk/agent-core';

class ModularAgent extends Robota {
  private moduleRegistry: ModuleRegistry;

  constructor() {
    // Create monitoring plugins
    const loggingPlugin = new LoggingPlugin({
      level: 'info',
      moduleEvents: ['module.initialize.complete', 'module.execution.complete'],
    });

    const performancePlugin = new PerformancePlugin({
      moduleEvents: ['module.execution.start', 'module.execution.complete'],
    });

    super({
      name: 'ModularAgent',
      model: 'gpt-4',
      provider: 'openai',
      aiProviders: { openai: openaiProvider },
      plugins: [loggingPlugin, performancePlugin],
      systemMessage: 'You are a modular AI agent with enhanced capabilities.',
    });

    // Initialize module registry with shared EventEmitter
    this.moduleRegistry = new ModuleRegistry(this.eventEmitter);

    this.setupModules();
  }

  private async setupModules(): Promise<void> {
    // Register modules
    const storageModule = new StorageModule(
      {
        enabled: true,
        config: { maxSize: 1000 },
      },
      this.eventEmitter,
    );

    const processingModule = new ProcessingModule(
      {
        enabled: true,
        config: { maxConcurrency: 5 },
      },
      this.eventEmitter,
    );

    await this.moduleRegistry.registerModule(storageModule);
    await this.moduleRegistry.registerModule(processingModule);

    // Initialize all modules (dependency order is handled automatically)
    await this.moduleRegistry.initializeModules();
  }

  async storeData(key: string, value: any): Promise<any> {
    return this.moduleRegistry.executeModule('StorageModule', {
      operation: 'store',
      key,
      value,
    });
  }

  async retrieveData(key: string): Promise<any> {
    return this.moduleRegistry.executeModule('StorageModule', {
      operation: 'retrieve',
      key,
    });
  }

  async processData(data: any, operation: string): Promise<any> {
    return this.moduleRegistry.executeModule('ProcessingModule', {
      data,
      operation,
    });
  }

  getModuleStats(): any {
    return this.moduleRegistry.getStats();
  }
}

Complete Example

Full Integration Example

typescript
import {
  Robota,
  BaseModule,
  ModuleRegistry,
  LoggingPlugin,
  PerformancePlugin,
  UsagePlugin,
  ExecutionAnalyticsPlugin,
} from '@robota-sdk/agent-core';

// Create a comprehensive example
async function createModularAgent() {
  // Create monitoring plugins that will track module activities
  const loggingPlugin = new LoggingPlugin({
    level: 'info',
    moduleEvents: [
      'module.initialize.complete',
      'module.execution.complete',
      'module.execution.error',
    ],
  });

  const performancePlugin = new PerformancePlugin({
    moduleEvents: ['module.execution.start', 'module.execution.complete'],
  });

  const usagePlugin = new UsagePlugin({
    moduleEvents: ['module.execution.complete'],
  });

  const analyticsPlugin = new ExecutionAnalyticsPlugin({
    trackErrors: true,
    maxEntries: 1000,
  });

  // Create agent with all monitoring plugins
  const agent = new Robota({
    name: 'ComprehensiveModularAgent',
    model: 'gpt-4',
    provider: 'openai',
    aiProviders: { openai: openaiProvider },
    plugins: [loggingPlugin, performancePlugin, usagePlugin, analyticsPlugin],
    systemMessage: 'You are a comprehensive modular AI agent with full monitoring capabilities.',
  });

  // Initialize module registry with shared EventEmitter
  const moduleRegistry = new ModuleRegistry(agent.eventEmitter);

  // Create and register modules
  const storageModule = new StorageModule(
    {
      enabled: true,
      config: { maxSize: 1000 },
    },
    agent.eventEmitter,
  );

  const processingModule = new ProcessingModule(
    {
      enabled: true,
      config: { maxConcurrency: 5 },
    },
    agent.eventEmitter,
  );

  await moduleRegistry.registerModule(storageModule);
  await moduleRegistry.registerModule(processingModule);

  // Initialize modules
  await moduleRegistry.initializeModules();

  return { agent, moduleRegistry };
}

// Usage example
async function runExample() {
  const { agent, moduleRegistry } = await createModularAgent();

  // Store some data
  const storeResult = await moduleRegistry.executeModule('StorageModule', {
    operation: 'store',
    key: 'user_data',
    value: { name: 'John', age: 30 },
  });

  console.log('Store result:', storeResult);

  // Process some data
  const processResult = await moduleRegistry.executeModule('ProcessingModule', {
    data: { raw: 'data' },
    operation: 'transform',
  });

  console.log('Process result:', processResult);

  // Use the agent for conversation
  const response = await agent.run('Analyze the data processing capabilities');
  console.log('Agent response:', response);

  // Get comprehensive statistics
  console.log('Module stats:', moduleRegistry.getStats());
  console.log('Agent stats:', agent.getStats());

  // Get plugin statistics
  const plugins = agent.getPlugins();
  plugins.forEach((plugin) => {
    console.log(`${plugin.name} stats:`, plugin.getStats());
  });
}

// Run the example
runExample().catch(console.error);

Key Benefits

1. Event-Driven Architecture

  • Loose Coupling: Modules and plugins don't directly depend on each other
  • Automatic Monitoring: Plugins automatically monitor module activities
  • Extensibility: Easy to add new modules and plugins

2. Enhanced Plugin System

  • Classification: Plugins are categorized and prioritized
  • Module Awareness: Plugins can subscribe to module events
  • Backward Compatibility: All existing plugins work without changes

3. Type Safety

  • Complete TypeScript Support: Full type safety throughout the system
  • Generic Parameters: Flexible type system for custom modules and plugins
  • Runtime Validation: Type checking at runtime

4. Performance Monitoring

  • Comprehensive Metrics: Module execution times, success rates, error tracking
  • Plugin Statistics: Detailed plugin performance data
  • System Analytics: Overall system performance insights

Best Practices

  1. Module Design: Keep modules focused on single responsibilities
  2. Event Usage: Use module events for monitoring, not business logic
  3. Dependency Management: Declare dependencies explicitly
  4. Error Handling: Implement proper error handling in modules
  5. Performance: Monitor module performance and optimize as needed
  6. Testing: Write comprehensive tests for custom modules
  7. Documentation: Document module capabilities and usage patterns

Released under the MIT License.