Astreus - Docs

Plugin Registry

Plugins

Plugin Registry extends agent capabilities through a centralized plugin management system with automatic tool registration. The system provides specialized tools and functions with intelligent orchestration.

Plugin Registry Architecture

The Plugin Registry in Astreus provides:

  • Centralized Management: Global plugin registry with automatic tool registration
  • Tool Functions: Specific capabilities like sending emails, posting to social media
  • Agent Integration: Direct integration through agent.addTool() and plugin registry
  • Type Safety: Full TypeScript support with proper type definitions
  • Error Handling: Built-in error handling and validation
  • Configuration: Flexible configuration options for different use cases
  • Automatic Registration: Plugins automatically register with the global registry

Agent-Centric Plugin Usage

With the enhanced approach, plugins are managed directly through agents:

import { 
  createAgent, 
  createProvider, 
  createMemory, 
  createDatabase, 
  PluginRegistry 
} from '@astreus-ai/astreus';
import { ResendPlugin } from '@astreus-ai/resend-plugin';
import { WhatsAppPlugin } from '@astreus-ai/whatsapp-plugin';
import { XPlugin } from '@astreus-ai/x-plugin';

async function createAgentWithPlugins() {
  const db = await createDatabase();
  const memory = await createMemory({ database: db });
  const provider = createProvider({ type: 'openai', model: 'gpt-4o-mini' });

  const agent = await createAgent({
    name: 'MultiCapabilityAgent',
    provider: provider,
    memory: memory,
    systemPrompt: "You are a helpful assistant with email, WhatsApp, and social media capabilities."
  });

  // Create and initialize plugins
  const resendPlugin = new ResendPlugin({
    apiKey: process.env.RESEND_API_KEY,
    defaultFrom: 'noreply@company.com'
  });
  await resendPlugin.init();

  const whatsappPlugin = new WhatsAppPlugin({
    accountSid: process.env.TWILIO_ACCOUNT_SID,
    authToken: process.env.TWILIO_AUTH_TOKEN,
    phoneNumber: process.env.TWILIO_PHONE_NUMBER
  });
  await whatsappPlugin.init();

  const xPlugin = new XPlugin({
    apiKey: process.env.X_API_KEY,
    apiSecret: process.env.X_API_SECRET,
    accessToken: process.env.X_ACCESS_TOKEN,
    accessSecret: process.env.X_ACCESS_TOKEN_SECRET
  });
  await xPlugin.init();

  // Add all tools from plugins to agent
  resendPlugin.getTools().forEach(tool => agent.addTool(tool));
  whatsappPlugin.getTools().forEach(tool => agent.addTool(tool));
  xPlugin.getTools().forEach(tool => agent.addTool(tool));

  return agent;
}

// Use agent with plugins
const agent = await createAgentWithPlugins();

// Agent can now use all plugin capabilities
await agent.chat({
  stream: true,
  message: "Send an email to john@example.com about our meeting tomorrow",
  sessionId: "business-session",
  onChunk: (chunk) => console.log(chunk)
});

Available Plugins

Resend Plugin (Email)

Send emails through the Resend service:

import { ResendPlugin } from '@astreus-ai/resend-plugin';

const resendPlugin = new ResendPlugin({
  apiKey: process.env.RESEND_API_KEY,
  defaultFrom: 'support@company.com',
  defaultReplyTo: 'support@company.com'
});

// Initialize the plugin
await resendPlugin.init();

// Add tools to agent
resendPlugin.getTools().forEach(tool => agent.addTool(tool));

// Agent can now send emails
await agent.chat({
  message: "Send a welcome email to new-user@example.com",
  sessionId: "onboarding"
});

WhatsApp Plugin

Send WhatsApp messages via Twilio:

import { WhatsAppPlugin } from '@astreus-ai/whatsapp-plugin';

const whatsappPlugin = new WhatsAppPlugin({
  accountSid: process.env.TWILIO_ACCOUNT_SID,
  authToken: process.env.TWILIO_AUTH_TOKEN,
  phoneNumber: process.env.TWILIO_PHONE_NUMBER // Your Twilio WhatsApp number
});

// Initialize the plugin
await whatsappPlugin.init();

// Add tools to agent
whatsappPlugin.getTools().forEach(tool => agent.addTool(tool));

// Agent can now send WhatsApp messages
await agent.chat({
  message: "Send a WhatsApp message to +1234567890 saying 'Your order is ready!'",
  sessionId: "notifications"
});

X (Twitter) Plugin

Post to X (formerly Twitter):

import { XPlugin } from '@astreus-ai/x-plugin';

const xPlugin = new XPlugin({
  apiKey: process.env.X_API_KEY,
  apiSecret: process.env.X_API_SECRET_KEY,
  accessToken: process.env.X_ACCESS_TOKEN,
  accessSecret: process.env.X_ACCESS_TOKEN_SECRET
});

// Initialize the plugin
await xPlugin.init();

// Add tools to agent
xPlugin.getTools().forEach(tool => agent.addTool(tool));

// Agent can now post to X
await agent.chat({
  message: "Post a tweet about our new product launch",
  sessionId: "marketing"
});

Plugin Management

Manage plugins through agent methods:

// Get all available tool names
const availableToolNames = agent.getAvailableTools();
console.log('Available tools:', availableToolNames);

// Check if a specific tool is available
const hasEmailTool = availableToolNames.includes('resend_send_email');
console.log('Email capability:', hasEmailTool ? 'Available' : 'Not available');

// Get plugin information
const pluginInfo = resendPlugin.config;
console.log('Plugin name:', pluginInfo.name);
console.log('Plugin description:', pluginInfo.description);
console.log('Plugin tools:', pluginInfo.tools.map(tool => tool.name));

Creating Custom Plugins

Create your own plugins by implementing the tool interface:

import { Tool } from '@astreus-ai/astreus';

// Define a custom tool
const customTool: Tool = {
  name: 'get_weather',
  description: 'Get current weather information for a location',
  parameters: [
    {
      name: 'location',
      type: 'string',
      description: 'The city and country, e.g. "London, UK"',
      required: true
    },
    {
      name: 'units',
      type: 'string',
      description: 'Temperature units (celsius or fahrenheit)',
      required: false
    }
  ],
  execute: async (params: { location: string; units?: string }) => {
    try {
      // Implement your weather API call here
      const response = await fetch(`https://api.weather.com/v1/current?location=${params.location}&units=${params.units || 'celsius'}`);
      const data = await response.json();
      
      return {
        success: true,
        data: {
          location: params.location,
          temperature: data.temperature,
          condition: data.condition,
          humidity: data.humidity,
          units: params.units || 'celsius'
        }
      };
    } catch (error) {
      return {
        success: false,
        error: `Failed to get weather for ${params.location}: ${error.message}`
      };
    }
  }
};

// Add custom tool to agent
agent.addTool(customTool);

// Agent can now get weather information
await agent.chat({
  message: "What's the weather like in Tokyo?",
  sessionId: "weather-check"
});

Plugin Factory Pattern

Create reusable plugin factories:

// Weather plugin factory
function createWeatherPlugin(config: { apiKey: string; defaultUnits?: string }) {
  const weatherTool: Tool = {
    name: 'get_weather',
    description: 'Get current weather information for a location',
    parameters: [
      {
        name: 'location',
        type: 'string',
        description: 'The city and country, e.g. "London, UK"',
        required: true
      },
      {
        name: 'units',
        type: 'string',
        description: 'Temperature units (celsius or fahrenheit)',
        required: false
      }
    ],
    execute: async (params: { location: string; units?: string }) => {
      const units = params.units || config.defaultUnits || 'celsius';
      
      try {
        const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${params.location}&appid=${config.apiKey}&units=${units === 'celsius' ? 'metric' : 'imperial'}`);
        const data = await response.json();
        
        if (!response.ok) {
          throw new Error(data.message || 'Weather API error');
        }
        
        return {
          success: true,
          data: {
            location: data.name,
            country: data.sys.country,
            temperature: Math.round(data.main.temp),
            condition: data.weather[0].description,
            humidity: data.main.humidity,
            windSpeed: data.wind.speed,
            units: units
          }
        };
      } catch (error) {
        return {
          success: false,
          error: `Failed to get weather for ${params.location}: ${error.message}`
        };
      }
    }
  };

  return {
    getTool: () => weatherTool,
    name: 'weather',
    version: '1.0.0'
  };
}

// Use the weather plugin
const weatherPlugin = createWeatherPlugin({
  apiKey: process.env.OPENWEATHER_API_KEY,
  defaultUnits: 'celsius'
});

agent.addTool(weatherPlugin.getTool());

Advanced Plugin Patterns

Multi-Tool Plugins

Create plugins that provide multiple related tools:

function createDatabasePlugin(config: { connectionString: string }) {
  const queryTool: Tool = {
    name: 'database_query',
    description: 'Execute a SQL query on the database',
    parameters: [
      {
        name: 'query',
        type: 'string',
        description: 'SQL query to execute',
        required: true
      },
      {
        name: 'params',
        type: 'array',
        description: 'Query parameters for prepared statements',
        required: false
      }
    ],
    execute: async (params: { query: string; params?: string[] }) => {
      // Implement database query logic
      return { success: true, data: [] };
    }
  };

  const insertTool: Tool = {
    name: 'database_insert',
    description: 'Insert data into a database table',
    parameters: [
      {
        name: 'table',
        type: 'string',
        description: 'Table name',
        required: true
      },
      {
        name: 'data',
        type: 'object',
        description: 'Data to insert',
        required: true
      }
    ],
    execute: async (params: { table: string; data: object }) => {
      // Implement database insert logic
      return { success: true, data: { id: 'new-record-id' } };
    }
  };

  return {
    getTools: () => [queryTool, insertTool],
    name: 'database',
    version: '1.0.0'
  };
}

// Add multiple tools from one plugin
const dbPlugin = createDatabasePlugin({
  connectionString: process.env.DATABASE_URL
});

dbPlugin.getTools().forEach(tool => agent.addTool(tool));

Stateful Plugins

Create plugins that maintain state across calls:

function createSessionPlugin() {
  const sessions = new Map<string, any>();

  const createSessionTool: Tool = {
    name: 'create_session',
    description: 'Create a new user session',
    parameters: [
      {
        name: 'userId',
        type: 'string',
        description: 'User ID',
        required: true
      },
      {
        name: 'data',
        type: 'object',
        description: 'Session data',
        required: false
      }
    ],
    execute: async (params: { userId: string; data?: object }) => {
      const sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
      sessions.set(sessionId, {
        userId: params.userId,
        data: params.data || {},
        createdAt: new Date(),
        lastAccessed: new Date()
      });
      
      return {
        success: true,
        data: { sessionId, userId: params.userId }
      };
    }
  };

  const getSessionTool: Tool = {
    name: 'get_session',
    description: 'Get session information',
    parameters: [
      {
        name: 'sessionId',
        type: 'string',
        description: 'Session ID',
        required: true
      }
    ],
    execute: async (params: { sessionId: string }) => {
      const session = sessions.get(params.sessionId);
      if (!session) {
        return {
          success: false,
          error: 'Session not found'
        };
      }

      session.lastAccessed = new Date();
      return {
        success: true,
        data: session
      };
    }
  };

  return {
    getTools: () => [createSessionTool, getSessionTool],
    getSessions: () => Array.from(sessions.entries()),
    clearSessions: () => sessions.clear(),
    name: 'session',
    version: '1.0.0'
  };
}

Plugin Configuration

Environment Variables

Configure plugins using environment variables:

// .env file
RESEND_API_KEY=your_resend_api_key
TWILIO_ACCOUNT_SID=your_twilio_account_sid
TWILIO_AUTH_TOKEN=your_twilio_auth_token
TWILIO_PHONE_NUMBER=whatsapp:+1234567890
X_API_KEY=your_x_api_key
X_API_SECRET=your_x_api_secret
X_ACCESS_TOKEN=your_x_access_token
X_ACCESS_TOKEN_SECRET=your_x_access_token_secret

// Plugin configuration
const plugins = {
  resend: createResendPlugin({
    apiKey: process.env.RESEND_API_KEY!,
    fromEmail: process.env.FROM_EMAIL || 'noreply@company.com'
  }),
  whatsapp: createWhatsAppPlugin({
    accountSid: process.env.TWILIO_ACCOUNT_SID!,
    authToken: process.env.TWILIO_AUTH_TOKEN!,
    phoneNumber: process.env.TWILIO_PHONE_NUMBER!
  }),
  x: createXPlugin({
    apiKey: process.env.X_API_KEY!,
    apiSecret: process.env.X_API_SECRET!,
    accessToken: process.env.X_ACCESS_TOKEN!,
    accessTokenSecret: process.env.X_ACCESS_TOKEN_SECRET!
  })
};

// Add all plugins to agent
Object.values(plugins).forEach(plugin => {
  agent.addTool(plugin.getTool());
});

Error Handling

Implement proper error handling in plugins:

const robustTool: Tool = {
  name: 'api_call',
  description: 'Make an API call with error handling',
  parameters: [
    {
      name: 'url',
      type: 'string',
      description: 'API endpoint URL',
      required: true
    },
    {
      name: 'method',
      type: 'string',
      description: 'HTTP method (GET, POST, PUT, DELETE)',
      required: false
    }
  ],
  execute: async (params: { url: string; method?: string }) => {
    try {
      const response = await fetch(params.url, {
        method: params.method || 'GET',
        signal: AbortSignal.timeout(10000) // 10 second timeout
      });

      if (!response.ok) {
        return {
          success: false,
          error: `HTTP ${response.status}: ${response.statusText}`
        };
      }

      const data = await response.json();
      return {
        success: true,
        data: data
      };
    } catch (error) {
      if (error.name === 'TimeoutError') {
        return {
          success: false,
          error: 'Request timed out'
        };
      }
      
      return {
        success: false,
        error: `Network error: ${error.message}`
      };
    }
  }
};

Best Practices

  1. Tool Naming: Use clear, descriptive names for tools (e.g., send_email, get_weather)
  2. Parameter Validation: Validate all input parameters before processing
  3. Error Handling: Return structured error responses with helpful messages
  4. Documentation: Provide clear descriptions for tools and parameters
  5. Environment Variables: Store sensitive configuration in environment variables
  6. Type Safety: Use TypeScript for better development experience
  7. Testing: Test plugins thoroughly before adding to production agents
  8. Rate Limiting: Implement rate limiting for external API calls
  9. Logging: Add appropriate logging for debugging and monitoring
  10. Versioning: Version your plugins for better maintenance

How is this guide?