gepa_recover_component
Restore or recover a specific GEPA component within the Prompt Auto-Optimizer MCP server using strategies like restart, rebuild, or reset to defaults.
Instructions
Recover a specific GEPA component
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| componentType | Yes | Type of component to recover | |
| strategy | No | Recovery strategy to use | restart |
Implementation Reference
- src/mcp/server.ts:327-346 (registration)Registration of the 'gepa_recover_component' tool in the MCP server, including schema definitionname: 'gepa_recover_component', description: 'Recover a specific GEPA component', inputSchema: { type: 'object', properties: { componentType: { type: 'string', enum: ['evolution_engine', 'pareto_frontier', 'llm_adapter', 'trajectory_store', 'memory_cache'], description: 'Type of component to recover' }, strategy: { type: 'string', enum: ['restart', 'restore_from_backup', 'rebuild', 'reset_to_defaults'], default: 'restart', description: 'Recovery strategy to use' } }, required: ['componentType'] } },
- src/mcp/server.ts:1662-1734 (handler)MCP server handler method for gepa_recover_component tool that maps parameters and calls DisasterRecoverySystem.recoverComponentprivate async recoverComponent(params: { componentType: string; strategy?: string; }): Promise<{ content: { type: string; text: string; }[] }> { const { componentType, strategy = 'restart' } = params; try { await this.disasterRecovery.initialize(); // Map component types to internal types const componentMap: Record<string, any> = { 'evolution_engine': 'evolution_engine', 'pareto_frontier': 'pareto_frontier', 'llm_adapter': 'llm_adapter', 'trajectory_store': 'trajectory_store', 'memory_cache': 'memory_cache' }; const mappedComponentType = componentMap[componentType]; if (!mappedComponentType) { throw new Error(`Unknown component type: ${componentType}`); } const strategyMap: Record<string, any> = { 'restart': 'restart', 'restore_from_backup': 'restore_from_backup', 'rebuild': 'rebuild', 'reset_to_defaults': 'reset_to_defaults' }; const mappedStrategy = strategyMap[strategy]; if (!mappedStrategy) { throw new Error(`Unknown recovery strategy: ${strategy}`); } const result = await this.disasterRecovery.recoverComponent(mappedComponentType, mappedStrategy); return { content: [ { type: 'text', text: `# Component Recovery ${result.success ? 'Completed' : 'Failed'} ## Recovery Details - **Component**: ${componentType} - **Strategy**: ${strategy} - **Success**: ${result.success ? 'Yes' : 'No'} - **Duration**: ${result.duration} ms - **Start Time**: ${result.startTime.toISOString()} - **End Time**: ${result.endTime?.toISOString() || 'In progress'} ## Recovery Logs ${result.logs.map(log => `[${log}]`).join('\n')} ${result.preRecoveryState ? `## Pre-Recovery State - Status: ${result.preRecoveryState.status} - Last Action: ${result.preRecoveryState.lastAction}` : ''} ${result.postRecoveryState ? `## Post-Recovery State - Status: ${result.postRecoveryState.status} - Last Action: ${result.postRecoveryState.lastAction}` : ''} ${result.error ? `## Error ${result.error.message}` : ''} ${result.success ? `Component ${componentType} has been successfully recovered using ${strategy} strategy.` : `Component recovery failed. Check the error details and logs above.`}`, }, ], }; } catch (error) { throw new Error(`Failed to recover component: ${error instanceof Error ? error.message : 'Unknown error'}`); } }
- DisasterRecoverySystem facade delegating to ComponentRecoveryManagerasync recoverComponent(componentType: ComponentType, strategy?: RecoveryStrategy): Promise<RecoveryAttempt> { return this.componentRecoveryManager.recoverComponent(componentType, strategy); }
- Core implementation of component recovery: orchestrates strategy execution, captures pre/post states, updates health, handles errors and emits eventsasync recoverComponent( componentType: ComponentType, strategy?: RecoveryStrategy ): Promise<RecoveryAttempt> { return this.resilience.executeWithFullProtection( async () => { // Check if component is already being recovered const activeRecovery = Array.from(this.activeRecoveries.values()) .find(r => r.componentType === componentType && !r.endTime); if (activeRecovery) { throw new Error(`Component ${componentType} is already being recovered`); } // Get component configuration const componentConfig = this.config.componentConfigs.get(componentType); if (!componentConfig) { throw new Error(`No configuration found for component: ${componentType}`); } // Determine recovery strategy const selectedStrategy = strategy || this.selectOptimalStrategy(componentType); // Create recovery attempt const attempt: RecoveryAttempt = { id: this.generateRecoveryId(), componentType, strategy: selectedStrategy, startTime: new Date(), success: false, logs: [], preRecoveryState: await this.captureComponentState(componentType) }; this.activeRecoveries.set(attempt.id, attempt); try { // Execute recovery strategy await this.executeRecoveryStrategy(attempt); attempt.success = true; attempt.endTime = new Date(); attempt.duration = attempt.endTime.getTime() - attempt.startTime.getTime(); attempt.postRecoveryState = await this.captureComponentState(componentType); // Update component health await this.updateComponentHealth(componentType); // Record recovery history this.recordRecoveryAttempt(attempt); this.emit('componentRecovered', attempt); } catch (error) { attempt.success = false; attempt.error = error as Error; attempt.endTime = new Date(); attempt.duration = attempt.endTime.getTime() - attempt.startTime.getTime(); attempt.logs.push(`Recovery failed: ${(error as Error).message}`); this.recordRecoveryAttempt(attempt); this.emit('componentRecoveryFailed', attempt); throw error; } finally { this.activeRecoveries.delete(attempt.id); } return attempt; }, { serviceName: 'component-recovery', context: { name: 'recover-component', priority: 'high' } } ); }
- Supporting methods for recovery strategies (restart, restore, rebuild, etc.) and component health monitoring in ComponentRecoveryManagerprivate async executeRecoveryStrategy(attempt: RecoveryAttempt): Promise<void> { attempt.logs.push(`Starting recovery with strategy: ${attempt.strategy}`); switch (attempt.strategy) { case RecoveryStrategy.RESTART: await this.executeRestartRecovery(attempt); break; case RecoveryStrategy.RESTORE_FROM_BACKUP: await this.executeRestoreRecovery(attempt); break; case RecoveryStrategy.REBUILD: await this.executeRebuildRecovery(attempt); break; case RecoveryStrategy.FAILOVER: await this.executeFailoverRecovery(attempt); break; case RecoveryStrategy.RESET_TO_DEFAULTS: await this.executeResetRecovery(attempt); break; default: throw new Error(`Unknown recovery strategy: ${attempt.strategy}`); } } private async executeRestartRecovery(attempt: RecoveryAttempt): Promise<void> { attempt.logs.push('Executing restart recovery'); // Implementation would restart the component await new Promise(resolve => setTimeout(resolve, 1000)); // Simulate restart attempt.logs.push('Component restarted successfully'); } private async executeRestoreRecovery(attempt: RecoveryAttempt): Promise<void> { attempt.logs.push('Executing restore from backup recovery'); // Implementation would restore component from backup await new Promise(resolve => setTimeout(resolve, 5000)); // Simulate restore attempt.logs.push('Component restored from backup'); } private async executeRebuildRecovery(attempt: RecoveryAttempt): Promise<void> { attempt.logs.push('Executing rebuild recovery'); // Implementation would rebuild component from scratch await new Promise(resolve => setTimeout(resolve, 10000)); // Simulate rebuild attempt.logs.push('Component rebuilt successfully'); } private async executeFailoverRecovery(attempt: RecoveryAttempt): Promise<void> { attempt.logs.push('Executing failover recovery'); // Implementation would failover to backup instance await new Promise(resolve => setTimeout(resolve, 3000)); // Simulate failover attempt.logs.push('Failover completed successfully'); } private async executeResetRecovery(attempt: RecoveryAttempt): Promise<void> { attempt.logs.push('Executing reset to defaults recovery'); // Implementation would reset component to default configuration await new Promise(resolve => setTimeout(resolve, 2000)); // Simulate reset attempt.logs.push('Component reset to defaults'); } private async captureComponentState(componentType: ComponentType): Promise<ComponentState> { const health = this.componentHealth.get(componentType); return { type: componentType, timestamp: new Date(), status: health?.status || ComponentStatus.UNKNOWN, configuration: {}, // Would capture actual configuration metrics: health?.metrics || {}, errorLog: health?.errors || [], lastAction: 'health_check', dependencies: this.config.componentConfigs.get(componentType)?.dependencies || [] }; } private async updateComponentHealth(componentType: ComponentType): Promise<void> { await this.checkComponentHealth(componentType); } private recordRecoveryAttempt(attempt: RecoveryAttempt): void { if (!this.recoveryHistory.has(attempt.componentType)) { this.recoveryHistory.set(attempt.componentType, []); } const history = this.recoveryHistory.get(attempt.componentType)!; history.push(attempt); // Keep only recent attempts (last 20) if (history.length > 20) { history.splice(0, history.length - 20); } } private getRecoveryCount(componentType: ComponentType): number { const history = this.recoveryHistory.get(componentType) || []; return history.filter(attempt => attempt.success).length; } private getTotalRecoveryCount(): number { let total = 0; for (const history of this.recoveryHistory.values()) { total += history.filter(attempt => attempt.success).length; } return total; } private getDependentComponents(rootComponent: ComponentType): ComponentType[] { const dependents: ComponentType[] = []; for (const [componentType, config] of this.config.componentConfigs) { if (config.dependencies.includes(rootComponent)) { dependents.push(componentType); } } return dependents; } private calculateRecoveryOrder(components: ComponentType[]): ComponentType[] { // Topological sort based on dependency graph const sorted: ComponentType[] = []; const visited = new Set<ComponentType>(); const visiting = new Set<ComponentType>(); const visit = (component: ComponentType): void => { if (visiting.has(component)) { // Circular dependency detected return; } if (visited.has(component)) { return; } visiting.add(component); const config = this.config.componentConfigs.get(component); if (config) { for (const dependency of config.dependencies) { if (components.includes(dependency)) { visit(dependency); } } } visiting.delete(component); visited.add(component); sorted.push(component); }; for (const component of components) { visit(component); } return sorted; } private validateComponentConfigs(): void { for (const [componentType, config] of this.config.componentConfigs) { if (!config.recoveryStrategies || config.recoveryStrategies.length === 0) { throw new Error(`No recovery strategies defined for component: ${componentType}`); } // Validate dependencies exist for (const dependency of config.dependencies) { if (!this.config.componentConfigs.has(dependency)) { throw new Error(`Unknown dependency ${dependency} for component ${componentType}`); } } } } private generateRecoveryId(): string { return `recovery_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } /** * Cleanup resources */ async cleanup(): Promise<void> { if (this.monitoringTimer) { clearInterval(this.monitoringTimer); this.monitoringTimer = undefined; } this.removeAllListeners(); } }