@polybiouslabs/polybious
Version:
Polybius is a next-generation intelligent agent framework built for adaptability across diverse domains. It merges contextual awareness, multi-agent collaboration, and predictive reasoning to deliver dynamic, self-optimizing performance.
197 lines (196 loc) • 7.38 kB
JavaScript
import { logger } from '../config/logger';
import { v4 as uuidv4 } from 'uuid';
// Built-in tools
import { ImageGenerationTool } from './builtin/image-generation';
import { SentimentAnalysisTool } from './builtin/sentiment-analysis';
import { DataAnalysisTool } from './builtin/data-analysis';
import { ContentEnhancementTool } from './builtin/content-enhancement';
import { SchedulingTool } from './builtin/scheduling';
import { WebhookTool } from './builtin/webhook';
export class ToolRegistryManager {
registry = {};
executionHistory = new Map();
enabledTools;
constructor(enabledTools = []) {
this.enabledTools = enabledTools;
this.initializeBuiltinTools();
}
initializeBuiltinTools() {
const availableTools = [
{ name: 'image_generation', class: ImageGenerationTool },
{ name: 'sentiment_analysis', class: SentimentAnalysisTool },
{ name: 'data_analysis', class: DataAnalysisTool },
{ name: 'content_enhancement', class: ContentEnhancementTool },
{ name: 'scheduling', class: SchedulingTool },
{ name: 'webhook', class: WebhookTool },
];
const toolsToInit = this.enabledTools.length > 0
? availableTools.filter(tool => this.enabledTools.includes(tool.name))
: availableTools;
const builtinTools = toolsToInit.map(tool => new tool.class());
for (const tool of builtinTools) {
this.registerTool(tool.getConfig(), tool);
}
logger.info(`Initialized ${builtinTools.length} built-in tools`, {
enabled: toolsToInit.map(t => t.name)
});
}
registerTool(config, handler) {
if (this.registry[config.name]) {
logger.warn(`Tool ${config.name} already registered, overwriting`);
}
this.registry[config.name] = {
config,
handler,
usage: {
totalCalls: 0,
successRate: 1.0,
avgDuration: 0,
lastUsed: new Date(),
errorCount: 0,
},
};
logger.info(`Registered tool: ${config.name}`);
}
async executeTool(toolName, parameters) {
const tool = this.registry[toolName];
if (!tool) {
throw new Error(`Tool ${toolName} not found in registry`);
}
if (!tool.config.enabled) {
throw new Error(`Tool ${toolName} is disabled`);
}
// Rate limiting check
if (tool.config.rateLimited) {
const recentCalls = this.getRecentCalls(toolName, tool.config.rateLimited.timeWindow);
if (recentCalls >= tool.config.rateLimited.maxCalls) {
throw new Error(`Rate limit exceeded for tool ${toolName}`);
}
}
// Validate parameters
if (tool.handler.validate && !tool.handler.validate(parameters)) {
throw new Error(`Invalid parameters for tool ${toolName}`);
}
const executionId = uuidv4();
const startTime = Date.now();
try {
logger.info(`Executing tool: ${toolName}`, { executionId, parameters });
let result = await tool.handler.execute(parameters);
// Transform result if transformer exists
if (tool.handler.transform) {
result = tool.handler.transform(result);
}
const duration = Date.now() - startTime;
// Update usage stats
this.updateUsageStats(toolName, true, duration);
// Record execution
this.recordExecution(toolName, {
id: executionId,
toolName,
parameters,
result,
timestamp: new Date(),
duration,
success: true,
});
logger.info(`Tool execution completed: ${toolName}`, {
executionId,
duration: `${duration}ms`
});
return result;
}
catch (error) {
const duration = Date.now() - startTime;
// Update usage stats
this.updateUsageStats(toolName, false, duration);
// Record execution
this.recordExecution(toolName, {
id: executionId,
toolName,
parameters,
result: null,
timestamp: new Date(),
duration,
success: false,
error: error instanceof Error ? error.message : String(error),
});
logger.error(`Tool execution failed: ${toolName}`, {
executionId,
error: error instanceof Error ? error.message : error,
duration: `${duration}ms`
});
throw error;
}
}
updateUsageStats(toolName, success, duration) {
const tool = this.registry[toolName];
if (!tool)
return;
const stats = tool.usage;
stats.totalCalls++;
stats.lastUsed = new Date();
if (!success) {
stats.errorCount++;
}
stats.successRate = (stats.totalCalls - stats.errorCount) / stats.totalCalls;
stats.avgDuration = (stats.avgDuration + duration) / 2;
}
recordExecution(toolName, execution) {
if (!this.executionHistory.has(toolName)) {
this.executionHistory.set(toolName, []);
}
const history = this.executionHistory.get(toolName);
history.unshift(execution);
// Keep only last 100 executions per tool
if (history.length > 100) {
history.splice(100);
}
}
getRecentCalls(toolName, timeWindowMinutes) {
const history = this.executionHistory.get(toolName) || [];
const cutoff = new Date(Date.now() - timeWindowMinutes * 60 * 1000);
return history.filter(exec => exec.timestamp > cutoff).length;
}
getAvailableTools() {
return Object.keys(this.registry).filter(name => this.registry[name].config.enabled);
}
getToolConfig(toolName) {
return this.registry[toolName]?.config || null;
}
getToolStats(toolName) {
return this.registry[toolName]?.usage || null;
}
getAllStats() {
const stats = {};
for (const [name, tool] of Object.entries(this.registry)) {
stats[name] = tool.usage;
}
return stats;
}
getExecutionHistory(toolName, limit = 10) {
const history = this.executionHistory.get(toolName) || [];
return history.slice(0, limit);
}
enableTool(toolName) {
if (this.registry[toolName]) {
this.registry[toolName].config.enabled = true;
logger.info(`Enabled tool: ${toolName}`);
}
}
disableTool(toolName) {
if (this.registry[toolName]) {
this.registry[toolName].config.enabled = false;
logger.info(`Disabled tool: ${toolName}`);
}
}
clearHistory(toolName) {
if (toolName) {
this.executionHistory.delete(toolName);
logger.info(`Cleared execution history for tool: ${toolName}`);
}
else {
this.executionHistory.clear();
logger.info('Cleared all execution history');
}
}
}