Plugin Registry
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
- Tool Naming: Use clear, descriptive names for tools (e.g.,
send_email
,get_weather
) - Parameter Validation: Validate all input parameters before processing
- Error Handling: Return structured error responses with helpful messages
- Documentation: Provide clear descriptions for tools and parameters
- Environment Variables: Store sensitive configuration in environment variables
- Type Safety: Use TypeScript for better development experience
- Testing: Test plugins thoroughly before adding to production agents
- Rate Limiting: Implement rate limiting for external API calls
- Logging: Add appropriate logging for debugging and monitoring
- Versioning: Version your plugins for better maintenance
How is this guide?