UNPKG

codecrucible-synth

Version:

Production-Ready AI Development Platform with Multi-Voice Synthesis, Smithery MCP Integration, Enterprise Security, and Zero-Timeout Reliability

1,435 lines (1,258 loc) 40.3 kB
/** * Advanced Tool Orchestration System * Implements intelligent tool selection, parallel execution, dependency resolution, * and error recovery for complex AI agent workflows */ import { EventEmitter } from 'events'; import { Logger } from '../logger.js'; import { UnifiedModelClient } from '../../refactor/unified-model-client.js'; import { SecureToolFactory } from '../security/secure-tool-factory.js'; import { RBACSystem } from '../security/production-rbac-system.js'; import { SecurityAuditLogger } from '../security/security-audit-logger.js'; import { SecretsManager } from '../security/secrets-manager.js'; import { getErrorMessage } from '../../utils/error-utils.js'; import { getTelemetryProvider } from '../observability/observability-system.js'; // AI SDK v5.0 Streaming Interfaces export interface StreamChunk { type: | 'stream-start' | 'text-start' | 'text-delta' | 'text-end' | 'reasoning-start' | 'reasoning-delta' | 'reasoning-end' | 'tool-input-start' | 'tool-input-delta' | 'tool-input-end' | 'tool-call' | 'tool-result' | 'finish' | 'error'; id?: string; toolName?: string; toolCallId?: string; delta?: string; args?: any; result?: any; timestamp: number; error?: string; errorCode?: string; } export interface ToolExecutionDelta { type: 'input' | 'output' | 'progress' | 'error' | 'metadata'; content: string; progress?: number; metadata?: Record<string, any>; } // Core Tool Interfaces export interface Tool { id: string; name: string; description: string; category: ToolCategory; inputSchema: JSONSchema; outputSchema: JSONSchema; execute: (input: any, context: ToolContext) => Promise<ToolResult>; metadata: ToolMetadata; // Enhanced: Streaming support for modern tool execution patterns stream?: (input: any, context: ToolContext) => AsyncGenerator<ToolExecutionDelta>; validate?: (input: any) => { valid: boolean; errors: string[]; normalizedInput?: any }; } export interface ToolMetadata { version: string; author: string; tags: string[]; cost: number; // Relative cost factor latency: number; // Expected latency in ms reliability: number; // Reliability score 0-1 dependencies: string[]; // Tool IDs this tool depends on conflictsWith: string[]; // Tools that conflict with this one capabilities: ToolCapability[]; requirements: ToolRequirement[]; } export interface ToolCapability { type: 'read' | 'write' | 'execute' | 'network' | 'compute'; scope: string; permissions: string[]; } export interface ToolRequirement { type: 'environment' | 'dependency' | 'resource'; value: string; optional?: boolean; } export interface ToolContext { sessionId: string; userId?: string; environment: Record<string, any>; previousResults: ToolResult[]; constraints: ToolConstraints; security: SecurityContext; systemPrompt?: string; // Enhanced: System prompt for better tool decision making } export interface ToolConstraints { maxExecutionTime: number; maxMemoryUsage: number; allowedNetworkAccess: boolean; sandboxed: boolean; costLimit: number; } export interface SecurityContext { permissions: string[]; restrictions: string[]; auditLog: boolean; encryptionRequired: boolean; } export interface ToolResult { toolId: string; success: boolean; output?: any; error?: string; metadata: { executionTime: number; memoryUsed: number; cost: number; version: string; }; side_effects?: SideEffect[]; } export interface SideEffect { type: 'file_created' | 'file_modified' | 'network_request' | 'environment_changed'; description: string; reversible: boolean; undo?: () => Promise<void>; } export interface ToolCall { id: string; toolId: string; input: any; priority: number; retryPolicy: RetryPolicy; fallbackTools?: string[]; timeout?: number; dependsOn?: string[]; // Other tool call IDs } export interface RetryPolicy { maxAttempts: number; backoffStrategy: 'linear' | 'exponential' | 'fixed'; initialDelay: number; maxDelay: number; retryableErrors: string[]; } export interface ExecutionPlan { id: string; toolCalls: ToolCall[]; dependencies: Map<string, string[]>; executionOrder: string[][]; estimatedCost: number; estimatedTime: number; riskAssessment: RiskAssessment; } export interface RiskAssessment { overall: 'low' | 'medium' | 'high'; factors: RiskFactor[]; mitigations: string[]; } export interface RiskFactor { type: 'security' | 'reliability' | 'cost' | 'time'; severity: number; // 0-1 description: string; } export enum ToolCategory { FILE_SYSTEM = 'filesystem', NETWORK = 'network', COMPUTATION = 'computation', DATA_PROCESSING = 'data_processing', EXTERNAL_API = 'external_api', SYSTEM = 'system', CUSTOM = 'custom', } export interface JSONSchema { type: string; properties?: Record<string, any>; required?: string[]; additionalProperties?: boolean; } // Advanced Tool Orchestrator export class AdvancedToolOrchestrator extends EventEmitter { private logger: Logger; private modelClient: UnifiedModelClient; private toolRegistry: ToolRegistry; private executionEngine: ExecutionEngine; private dependencyResolver: DependencyResolver; private securityManager: SecurityManager; private costOptimizer: CostOptimizer; private performanceMonitor: PerformanceMonitor; private errorRecovery: ErrorRecoveryManager; private secureToolFactory!: SecureToolFactory; private telemetryProvider: any; // Enhanced: Telemetry integration for modern observability constructor(modelClient: UnifiedModelClient) { super(); this.logger = new Logger('AdvancedToolOrchestrator'); this.modelClient = modelClient; this.toolRegistry = new ToolRegistry(); this.executionEngine = new ExecutionEngine(this.toolRegistry); this.dependencyResolver = new DependencyResolver(); this.securityManager = new SecurityManager(); this.costOptimizer = new CostOptimizer(); this.performanceMonitor = new PerformanceMonitor(); this.errorRecovery = new ErrorRecoveryManager(); // Enhanced: Initialize telemetry provider for observability try { this.telemetryProvider = getTelemetryProvider(); } catch (error) { this.logger.warn('Telemetry provider not available, running without telemetry'); this.telemetryProvider = null; } // Initialize SecureToolFactory with required dependencies this.initializeSecureToolFactory(); this.initializeBuiltInTools(); } /** * Initialize SecureToolFactory with required dependencies */ private initializeSecureToolFactory(): void { try { const secretsManager = new SecretsManager(); // Note: Would need actual database instance in production const rbacSystem = new RBACSystem(null as any, secretsManager); const auditLogger = new SecurityAuditLogger(secretsManager, './audit-logs'); this.secureToolFactory = new SecureToolFactory(rbacSystem, auditLogger); } catch (error) { this.logger.error('Failed to initialize SecureToolFactory', error as Error); // Create a minimal implementation to prevent blocking this.secureToolFactory = null as any; } } /** * Enhanced: Execute tool call with AI SDK v5.0 streaming support */ async executeToolCallStreaming( toolCall: ToolCall, context: ToolContext, onChunk: (chunk: StreamChunk) => void ): Promise<ToolResult> { const startTime = Date.now(); const tool = this.toolRegistry.getTool(toolCall.toolId); if (!tool) { const error = `Tool ${toolCall.toolId} not found`; onChunk({ type: 'error', timestamp: Date.now(), error, errorCode: 'TOOL_NOT_FOUND', }); throw new Error(error); } try { // Send tool-input-start chunk onChunk({ type: 'tool-input-start', id: toolCall.id, toolName: tool.name, timestamp: Date.now(), }); // Stream tool input parameters if they exist if (toolCall.input && typeof toolCall.input === 'object') { const inputString = JSON.stringify(toolCall.input, null, 2); const chunks = this.tokenizeForStreaming(inputString, 50); for (const chunk of chunks) { onChunk({ type: 'tool-input-delta', id: toolCall.id, delta: chunk, timestamp: Date.now(), }); await this.delay(10); // Small delay for realistic streaming } } // Send tool-input-end chunk onChunk({ type: 'tool-input-end', id: toolCall.id, timestamp: Date.now(), }); // Validate input if tool supports validation if (tool.validate) { const validation = tool.validate(toolCall.input); if (!validation.valid) { const error = `Validation failed: ${validation.errors.join(', ')}`; onChunk({ type: 'error', timestamp: Date.now(), error, errorCode: 'VALIDATION_ERROR', }); throw new Error(error); } } // Send tool-call chunk onChunk({ type: 'tool-call', toolCallId: toolCall.id, toolName: tool.name, args: toolCall.input, timestamp: Date.now(), }); // Execute tool with streaming if supported let result: ToolResult; if (tool.stream) { // Use streaming execution const outputParts: string[] = []; for await (const delta of tool.stream(toolCall.input, context)) { if (delta.type === 'output') { outputParts.push(delta.content); onChunk({ type: 'text-delta', id: `${toolCall.id}_output`, delta: delta.content, timestamp: Date.now(), }); } } result = { toolId: tool.id, success: true, output: outputParts.join(''), metadata: { executionTime: Date.now() - startTime, memoryUsed: 0, cost: tool.metadata.cost, version: tool.metadata.version, }, }; } else { // Use regular execution result = await tool.execute(toolCall.input, context); result.metadata.executionTime = Date.now() - startTime; } // Send tool-result chunk onChunk({ type: 'tool-result', toolCallId: toolCall.id, result: result.output, timestamp: Date.now(), }); // Record telemetry if available if (this.telemetryProvider) { this.telemetryProvider.recordToolExecution( tool.name, result.metadata.executionTime, result.success ); } return result; } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); onChunk({ type: 'error', timestamp: Date.now(), error: errorMsg, errorCode: 'EXECUTION_ERROR', }); if (this.telemetryProvider) { this.telemetryProvider.recordToolExecution( tool.name, Date.now() - startTime, false, errorMsg ); } throw error; } } /** * Execute a complex tool orchestration plan */ async executePlan(toolCalls: ToolCall[], context: ToolContext): Promise<Map<string, ToolResult>> { const planId = this.generatePlanId(); this.logger.info(`Executing tool plan ${planId} with ${toolCalls.length} tools`); try { // Create execution plan const plan = await this.createExecutionPlan(toolCalls, context); this.emit('plan:created', { planId, plan }); // Security validation await this.securityManager.validatePlan(plan, context); // Cost optimization const optimizedPlan = await this.costOptimizer.optimizePlan(plan, context); // Execute plan const results = await this.executionEngine.execute(optimizedPlan, context); this.emit('plan:completed', { planId, results }); return results; } catch (error) { this.logger.error(`Plan execution failed:`, error); this.emit('plan:failed', { planId, error }); throw error; } } /** * Determine if a prompt requires tool usage */ shouldUseTools(prompt: string): boolean { const toolKeywords = [ 'analyze', 'read', 'file', 'directory', 'project', 'code', 'structure', 'write', 'create', 'generate', 'build', 'compile', 'test', 'run', 'search', 'find', 'list', 'show', 'display', 'check', 'scan', ]; const promptLower = prompt.toLowerCase(); return toolKeywords.some(keyword => promptLower.includes(keyword)); } /** * Process a prompt using appropriate tools */ async processWithTools( prompt: string, systemPrompt?: string, runtimeContext?: any ): Promise<string> { try { this.logger.info('Processing prompt with tools:', prompt.slice(0, 100) + '...'); // Create enhanced context with system prompt and runtime information const context: ToolContext = { sessionId: Date.now().toString(), userId: 'cli-user', environment: { mode: 'development', workingDirectory: runtimeContext?.workingDirectory || process.cwd(), timestamp: new Date().toISOString(), permissions: ['read', 'write', 'execute'], platform: runtimeContext?.platform || process.platform, isGitRepo: runtimeContext?.isGitRepo || false, currentBranch: runtimeContext?.currentBranch || 'main', modelId: runtimeContext?.modelId || 'unknown', }, previousResults: [], constraints: { maxExecutionTime: 30000, maxMemoryUsage: 1024 * 1024 * 100, // 100MB allowedNetworkAccess: false, sandboxed: true, costLimit: 1000, }, security: { permissions: ['read', 'write', 'execute'], restrictions: ['no-network', 'sandboxed'], auditLog: true, encryptionRequired: false, }, systemPrompt: systemPrompt, // Enhanced: Include system prompt for better tool decision making }; // Select appropriate tools for the objective const toolCalls = await this.selectTools(prompt, context); if (toolCalls.length === 0) { this.logger.info('No tools selected, falling back to AI model with system prompt'); // Enhanced: Use system prompt in fallback for consistent behavior if (systemPrompt) { const fullPrompt = `${systemPrompt}\n\nUser: ${prompt}`; return await this.modelClient.generateText(fullPrompt); } else { return await this.modelClient.generateText(prompt); } } // Execute the tools const results = await this.executePlan(toolCalls, context); // Synthesize results into a coherent response return await this.synthesizeToolResults(prompt, results); } catch (error) { this.logger.error('Tool processing failed:', error); // Fallback to direct AI model return await this.modelClient.generateText(prompt); } } /** * Synthesize tool results into a coherent response */ private async synthesizeToolResults( originalPrompt: string, results: Map<string, ToolResult> ): Promise<string> { const resultsArray = Array.from(results.entries()).map(([toolId, result]) => ({ tool: toolId, success: result.success, output: result.output, error: result.error, })); const synthesisPrompt = ` Original request: ${originalPrompt} Tool execution results: ${JSON.stringify(resultsArray, null, 2)} Please provide a clear, helpful response based on these tool results. If there were errors, acknowledge them and provide what information is available. `; return await this.modelClient.generateText(synthesisPrompt); } /** * Intelligent tool selection based on context and requirements */ async selectTools( objective: string, context: ToolContext, constraints?: ToolConstraints ): Promise<ToolCall[]> { this.logger.info(`Selecting tools for objective: ${objective}`); // Use AI to analyze objective and suggest tools const analysisPrompt = ` Analyze this objective and suggest the best tools to accomplish it: Objective: ${objective} Available tools: ${this.toolRegistry.getToolSummaries()} Context: ${JSON.stringify(context, null, 2)} Respond with a JSON array of tool calls including priorities and dependencies. `; const response = await this.modelClient.synthesize({ prompt: analysisPrompt, maxTokens: 2000, }); // Parse AI response and validate const suggestedCalls = this.parseToolSuggestions(response.content); // Apply constraint filtering const filteredCalls = constraints ? this.filterByConstraints(suggestedCalls, constraints) : suggestedCalls; // Optimize selection return this.optimizeToolSelection(filteredCalls, context); } /** * Register a new tool */ registerTool(tool: Tool): void { this.toolRegistry.register(tool); this.logger.info(`Registered tool: ${tool.name} (${tool.id})`); } /** * Create execution plan with dependency resolution */ private async createExecutionPlan( toolCalls: ToolCall[], context: ToolContext ): Promise<ExecutionPlan> { const planId = this.generatePlanId(); // Resolve dependencies const dependencies = this.dependencyResolver.resolveDependencies(toolCalls); const executionOrder = this.dependencyResolver.createExecutionOrder(dependencies); // Calculate estimates const estimatedCost = this.calculateEstimatedCost(toolCalls); const estimatedTime = this.calculateEstimatedTime(toolCalls, executionOrder); // Risk assessment const riskAssessment = await this.assessRisks(toolCalls, context); return { id: planId, toolCalls, dependencies, executionOrder, estimatedCost, estimatedTime, riskAssessment, }; } private parseToolSuggestions(aiResponse: string): ToolCall[] { try { // Extract JSON from AI response const jsonMatch = aiResponse.match(/\[[\s\S]*\]/); if (!jsonMatch) { throw new Error('No valid JSON found in AI response'); } const parsed = JSON.parse(jsonMatch[0]); return parsed.map((suggestion: any, index: number) => ({ id: `call_${index}`, toolId: suggestion.toolId, input: suggestion.input || {}, priority: suggestion.priority || 1, retryPolicy: suggestion.retryPolicy || this.getDefaultRetryPolicy(), fallbackTools: suggestion.fallbackTools || [], timeout: suggestion.timeout, dependsOn: suggestion.dependsOn || [], })); } catch (error) { this.logger.warn('Failed to parse AI tool suggestions, using fallback'); return []; } } private filterByConstraints(toolCalls: ToolCall[], constraints: ToolConstraints): ToolCall[] { return toolCalls.filter(call => { const tool = this.toolRegistry.getTool(call.toolId); if (!tool) return false; // Check cost constraint if (tool.metadata.cost > constraints.costLimit) return false; // Check timeout constraint if (tool.metadata.latency > constraints.maxExecutionTime) return false; // Check network access const needsNetwork = tool.metadata.capabilities.some(cap => cap.type === 'network'); if (needsNetwork && !constraints.allowedNetworkAccess) return false; return true; }); } private optimizeToolSelection(toolCalls: ToolCall[], context: ToolContext): ToolCall[] { // Sort by priority and reliability return toolCalls.sort((a, b) => { const toolA = this.toolRegistry.getTool(a.toolId); const toolB = this.toolRegistry.getTool(b.toolId); if (!toolA || !toolB) return 0; // Primary sort by priority if (a.priority !== b.priority) { return b.priority - a.priority; } // Secondary sort by reliability return toolB.metadata.reliability - toolA.metadata.reliability; }); } private calculateEstimatedCost(toolCalls: ToolCall[]): number { return toolCalls.reduce((total, call) => { const tool = this.toolRegistry.getTool(call.toolId); return total + (tool?.metadata.cost || 0); }, 0); } private calculateEstimatedTime(toolCalls: ToolCall[], executionOrder: string[][]): number { // Calculate time for parallel execution batches let totalTime = 0; for (const batch of executionOrder) { let maxBatchTime = 0; for (const callId of batch) { const call = toolCalls.find(c => c.id === callId); if (call) { const tool = this.toolRegistry.getTool(call.toolId); const toolTime = tool?.metadata.latency || 1000; maxBatchTime = Math.max(maxBatchTime, toolTime); } } totalTime += maxBatchTime; } return totalTime; } private async assessRisks(toolCalls: ToolCall[], context: ToolContext): Promise<RiskAssessment> { const riskFactors: RiskFactor[] = []; // Assess security risks const writeTools = toolCalls.filter(call => { const tool = this.toolRegistry.getTool(call.toolId); return tool?.metadata.capabilities.some(cap => cap.type === 'write'); }); if (writeTools.length > 0) { riskFactors.push({ type: 'security', severity: writeTools.length / toolCalls.length, description: `${writeTools.length} tools require write permissions`, }); } // Assess reliability risks const unreliableTools = toolCalls.filter(call => { const tool = this.toolRegistry.getTool(call.toolId); return (tool?.metadata.reliability || 1) < 0.8; }); if (unreliableTools.length > 0) { riskFactors.push({ type: 'reliability', severity: unreliableTools.length / toolCalls.length, description: `${unreliableTools.length} tools have low reliability scores`, }); } // Calculate overall risk const avgSeverity = riskFactors.reduce((sum, factor) => sum + factor.severity, 0) / riskFactors.length; const overall = avgSeverity > 0.7 ? 'high' : avgSeverity > 0.4 ? 'medium' : 'low'; return { overall, factors: riskFactors, mitigations: this.suggestMitigations(riskFactors), }; } private suggestMitigations(riskFactors: RiskFactor[]): string[] { const mitigations: string[] = []; for (const factor of riskFactors) { switch (factor.type) { case 'security': mitigations.push('Enable sandboxed execution', 'Require explicit permissions'); break; case 'reliability': mitigations.push('Implement retry mechanisms', 'Add fallback tools'); break; case 'cost': mitigations.push('Set cost limits', 'Use cheaper alternatives'); break; case 'time': mitigations.push('Set timeouts', 'Parallel execution where possible'); break; } } return [...new Set(mitigations)]; // Remove duplicates } private getDefaultRetryPolicy(): RetryPolicy { return { maxAttempts: 3, backoffStrategy: 'exponential', initialDelay: 1000, maxDelay: 10000, retryableErrors: ['TIMEOUT', 'NETWORK_ERROR', 'TEMPORARY_FAILURE'], }; } private generatePlanId(): string { return `plan_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } /** * Enhanced: Utility methods for streaming support */ private tokenizeForStreaming(content: string, chunkSize: number): string[] { const chunks: string[] = []; for (let i = 0; i < content.length; i += chunkSize) { chunks.push(content.slice(i, i + chunkSize)); } return chunks.length > 0 ? chunks : [content]; } private async delay(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } /** * Enhanced: Find tools suitable for a given task with modern matching */ async findToolsForTask( task: string, requirements?: { categories?: ToolCategory[]; capabilities?: string[]; maxCost?: number; maxLatency?: number; } ): Promise<Array<{ tool: Tool; confidence: number; reasoning: string }>> { const matches: Array<{ tool: Tool; confidence: number; reasoning: string }> = []; const taskLower = task.toLowerCase(); for (const tool of this.toolRegistry.getAllTools()) { // Apply requirement filters if (requirements?.categories && !requirements.categories.includes(tool.category)) { continue; } if (requirements?.maxCost && tool.metadata.cost > requirements.maxCost) { continue; } if (requirements?.maxLatency && tool.metadata.latency > requirements.maxLatency) { continue; } // Calculate confidence based on various factors let confidence = 0; const reasons: string[] = []; // Name match (highest priority) if ( tool.name.toLowerCase().includes(taskLower) || taskLower.includes(tool.name.toLowerCase()) ) { confidence += 0.4; reasons.push('tool name matches'); } // Description match if (tool.description.toLowerCase().includes(taskLower)) { confidence += 0.3; reasons.push('description contains keywords'); } // Tag matches const matchingTags = tool.metadata.tags.filter( tag => tag.toLowerCase().includes(taskLower) || taskLower.includes(tag.toLowerCase()) ); if (matchingTags.length > 0) { confidence += matchingTags.length * 0.1; reasons.push(`tags match: ${matchingTags.join(', ')}`); } // Capability matches if (requirements?.capabilities) { const hasRequiredCaps = requirements.capabilities.some(reqCap => tool.metadata.capabilities.some( toolCap => toolCap.type.includes(reqCap) || toolCap.scope.includes(reqCap) ) ); if (hasRequiredCaps) { confidence += 0.2; reasons.push('capabilities match requirements'); } } if (confidence > 0.1) { // Minimum threshold matches.push({ tool, confidence: Math.min(confidence, 1.0), reasoning: reasons.join('; ') || 'general relevance', }); } } // Sort by confidence and return top matches return matches.sort((a, b) => b.confidence - a.confidence).slice(0, 10); } private initializeBuiltInTools(): void { // Initialize secure tools using E2B-based factory this.registerTool(new FileReadTool()); this.registerTool(new FileWriteTool()); this.registerTool(new NetworkRequestTool()); // Create a secure code execution tool adapter const agentContext = { workingDirectory: process.cwd() }; // Basic context const secureCodeTool = this.secureToolFactory.createCodeExecutionTool(agentContext); // Create an adapter that implements the Tool interface const secureCodeToolAdapter = { id: 'secure_code_execution', name: 'Secure Code Executor', description: 'Execute code in sandboxed E2B environment', category: ToolCategory.COMPUTATION, inputSchema: { type: 'object', properties: { code: { type: 'string' }, language: { type: 'string' }, }, required: ['code', 'language'], }, outputSchema: { type: 'object', properties: { success: { type: 'boolean' }, output: { type: 'string' }, error: { type: 'string' }, }, }, execute: async (input: any, context: any) => { return await secureCodeTool.execute(input); }, metadata: { version: '1.0.0', author: 'system', tags: ['security', 'execution', 'e2b'], cost: 5, latency: 2000, reliability: 0.95, performance: 4, dependencies: [], conflictsWith: [], capabilities: [ { type: 'execute' as const, scope: 'sandboxed', permissions: ['code_execution'], }, ], requirements: [], }, }; this.registerTool(secureCodeToolAdapter); this.registerTool(new DataAnalysisTool()); this.logger.info('🔒 Initialized built-in tools with secure execution'); } // Public API methods public getAvailableTools(): Tool[] { return this.toolRegistry.getAllTools(); } public getToolsByCategory(category: ToolCategory): Tool[] { return this.toolRegistry.getToolsByCategory(category); } public getExecutionMetrics(): any { return this.performanceMonitor.getMetrics(); } } // Supporting Classes class ToolRegistry { private tools: Map<string, Tool> = new Map(); register(tool: Tool): void { // Validate tool this.validateTool(tool); this.tools.set(tool.id, tool); } getTool(id: string): Tool | undefined { return this.tools.get(id); } getAllTools(): Tool[] { return Array.from(this.tools.values()); } getToolsByCategory(category: ToolCategory): Tool[] { return this.getAllTools().filter(tool => tool.category === category); } getToolSummaries(): string { return this.getAllTools() .map(tool => `${tool.name}: ${tool.description}`) .join('\n'); } private validateTool(tool: Tool): void { if (!tool.id || !tool.name || !tool.execute) { throw new Error('Invalid tool: missing required fields'); } } } class ExecutionEngine { private logger: Logger; constructor(private toolRegistry: ToolRegistry) { this.logger = new Logger('ExecutionEngine'); } async execute(plan: ExecutionPlan, context: ToolContext): Promise<Map<string, ToolResult>> { const results = new Map<string, ToolResult>(); for (const batch of plan.executionOrder) { // Execute batch in parallel const batchPromises = batch.map(callId => this.executeToolCall(callId, plan, context, results) ); const batchResults = await Promise.allSettled(batchPromises); // Check for failures that should stop execution const failures = batchResults.filter(r => r.status === 'rejected'); if (failures.length > 0) { this.logger.error(`Batch execution failed: ${failures.length} failures`); break; } } return results; } private async executeToolCall( callId: string, plan: ExecutionPlan, context: ToolContext, results: Map<string, ToolResult> ): Promise<void> { const call = plan.toolCalls.find(c => c.id === callId); if (!call) { throw new Error(`Tool call ${callId} not found in plan`); } const tool = this.toolRegistry.getTool(call.toolId); if (!tool) { throw new Error(`Tool ${call.toolId} not found in registry`); } try { const startTime = Date.now(); const result = await tool.execute(call.input, context); const executionTime = Date.now() - startTime; result.metadata.executionTime = executionTime; results.set(callId, result); this.logger.info(`Tool ${tool.name} executed successfully in ${executionTime}ms`); } catch (error: unknown) { const errorResult: ToolResult = { toolId: call.toolId, success: false, error: getErrorMessage(error), metadata: { executionTime: 0, memoryUsed: 0, cost: 0, version: tool.metadata.version, }, }; results.set(callId, errorResult); this.logger.error(`Tool ${tool.name} execution failed:`, error); } } } class DependencyResolver { resolveDependencies(toolCalls: ToolCall[]): Map<string, string[]> { const dependencies = new Map<string, string[]>(); for (const call of toolCalls) { dependencies.set(call.id, call.dependsOn || []); } return dependencies; } createExecutionOrder(dependencies: Map<string, string[]>): string[][] { const order: string[][] = []; const visited = new Set<string>(); const visiting = new Set<string>(); // Topological sort with batch detection const visit = (nodeId: string): void => { if (visited.has(nodeId)) return; if (visiting.has(nodeId)) { throw new Error(`Circular dependency detected involving ${nodeId}`); } visiting.add(nodeId); const deps = dependencies.get(nodeId) || []; for (const dep of deps) { visit(dep); } visiting.delete(nodeId); visited.add(nodeId); }; // Visit all nodes for (const nodeId of dependencies.keys()) { visit(nodeId); } // Create execution batches const remaining = new Set(dependencies.keys()); while (remaining.size > 0) { const batch: string[] = []; for (const nodeId of remaining) { const deps = dependencies.get(nodeId) || []; const allDepsCompleted = deps.every(dep => !remaining.has(dep)); if (allDepsCompleted) { batch.push(nodeId); } } if (batch.length === 0) { throw new Error('Unable to resolve dependencies - possible circular reference'); } order.push(batch); batch.forEach(nodeId => remaining.delete(nodeId)); } return order; } } class SecurityManager { async validatePlan(plan: ExecutionPlan, context: ToolContext): Promise<void> { // Implement security validation logic // Check permissions, validate inputs, etc. } } class CostOptimizer { async optimizePlan(plan: ExecutionPlan, context: ToolContext): Promise<ExecutionPlan> { // Implement cost optimization logic return plan; } } class PerformanceMonitor { getMetrics(): any { return { totalExecutions: 0, averageExecutionTime: 0, successRate: 1.0, }; } } class ErrorRecoveryManager { // Implement error recovery logic } // Built-in Tool Implementations class FileReadTool implements Tool { id = 'file_read'; name = 'File Reader'; description = 'Read content from files'; category = ToolCategory.FILE_SYSTEM; inputSchema = { type: 'object', properties: { path: { type: 'string' }, }, required: ['path'], }; outputSchema = { type: 'object', properties: { content: { type: 'string' }, }, }; metadata: ToolMetadata = { version: '1.0.0', author: 'system', tags: ['file', 'read'], cost: 1, latency: 100, reliability: 0.95, dependencies: [], conflictsWith: [], capabilities: [{ type: 'read', scope: 'filesystem', permissions: ['read'] }], requirements: [], }; async execute(input: any, context: ToolContext): Promise<ToolResult> { // Implementation would go here return { toolId: this.id, success: true, output: { content: 'file content' }, metadata: { executionTime: 50, memoryUsed: 1024, cost: 1, version: this.metadata.version, }, }; } } class FileWriteTool implements Tool { id = 'file_write'; name = 'File Writer'; description = 'Write content to files'; category = ToolCategory.FILE_SYSTEM; inputSchema = { type: 'object', properties: { path: { type: 'string' }, content: { type: 'string' }, }, required: ['path', 'content'], }; outputSchema = { type: 'object', properties: { success: { type: 'boolean' }, }, }; metadata: ToolMetadata = { version: '1.0.0', author: 'system', tags: ['file', 'write'], cost: 2, latency: 150, reliability: 0.9, dependencies: [], conflictsWith: [], capabilities: [{ type: 'write', scope: 'filesystem', permissions: ['write'] }], requirements: [], }; async execute(input: any, context: ToolContext): Promise<ToolResult> { return { toolId: this.id, success: true, output: { success: true }, metadata: { executionTime: 75, memoryUsed: 512, cost: 2, version: this.metadata.version, }, side_effects: [ { type: 'file_created', description: `Created file at ${input.path}`, reversible: true, }, ], }; } } class NetworkRequestTool implements Tool { id = 'network_request'; name = 'Network Request'; description = 'Make HTTP requests'; category = ToolCategory.NETWORK; inputSchema = { type: 'object', properties: { url: { type: 'string' }, method: { type: 'string' }, headers: { type: 'object' }, body: { type: 'string' }, }, required: ['url'], }; outputSchema = { type: 'object', properties: { status: { type: 'number' }, data: { type: 'string' }, }, }; metadata: ToolMetadata = { version: '1.0.0', author: 'system', tags: ['network', 'http'], cost: 3, latency: 1000, reliability: 0.85, dependencies: [], conflictsWith: [], capabilities: [{ type: 'network', scope: 'external', permissions: ['http'] }], requirements: [{ type: 'environment', value: 'NETWORK_ACCESS' }], }; async execute(input: any, context: ToolContext): Promise<ToolResult> { return { toolId: this.id, success: true, output: { status: 200, data: 'response data' }, metadata: { executionTime: 800, memoryUsed: 2048, cost: 3, version: this.metadata.version, }, }; } } class CodeExecutionTool implements Tool { id = 'code_execution'; name = 'Code Executor'; description = 'Execute code in sandboxed environment'; category = ToolCategory.COMPUTATION; inputSchema = { type: 'object', properties: { code: { type: 'string' }, language: { type: 'string' }, }, required: ['code', 'language'], }; outputSchema = { type: 'object', properties: { result: { type: 'string' }, error: { type: 'string' }, }, }; metadata: ToolMetadata = { version: '1.0.0', author: 'system', tags: ['code', 'execution'], cost: 5, latency: 2000, reliability: 0.8, dependencies: [], conflictsWith: [], capabilities: [{ type: 'execute', scope: 'sandbox', permissions: ['code_execution'] }], requirements: [{ type: 'environment', value: 'SANDBOX' }], }; async execute(input: any, context: ToolContext): Promise<ToolResult> { return { toolId: this.id, success: true, output: { result: 'execution result' }, metadata: { executionTime: 1500, memoryUsed: 4096, cost: 5, version: this.metadata.version, }, }; } } class DataAnalysisTool implements Tool { id = 'data_analysis'; name = 'Data Analyzer'; description = 'Analyze and process data'; category = ToolCategory.DATA_PROCESSING; inputSchema = { type: 'object', properties: { data: { type: 'array' }, analysis_type: { type: 'string' }, }, required: ['data', 'analysis_type'], }; outputSchema = { type: 'object', properties: { results: { type: 'object' }, }, }; metadata: ToolMetadata = { version: '1.0.0', author: 'system', tags: ['data', 'analysis'], cost: 4, latency: 1500, reliability: 0.9, dependencies: [], conflictsWith: [], capabilities: [{ type: 'compute', scope: 'memory', permissions: ['data_processing'] }], requirements: [], }; async execute(input: any, context: ToolContext): Promise<ToolResult> { return { toolId: this.id, success: true, output: { results: { analysis: 'completed' } }, metadata: { executionTime: 1200, memoryUsed: 8192, cost: 4, version: this.metadata.version, }, }; } }