UNPKG

agentic-qe

Version:

Agentic Quality Engineering Fleet System - AI-driven quality management platform

222 lines 8.65 kB
"use strict"; /** * Workflow Pause Command * * Pauses running workflows with graceful shutdown and state preservation * Integrates with workflow execution handlers and memory * * @version 1.0.0 */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.displayPauseResult = exports.pauseWorkflow = void 0; const chalk_1 = __importDefault(require("chalk")); const SwarmMemoryManager_js_1 = require("../../../core/memory/SwarmMemoryManager.js"); const Logger_js_1 = require("../../../utils/Logger.js"); const logger = Logger_js_1.Logger.getInstance(); /** * Pause a running workflow */ async function pauseWorkflow(options) { logger.info('Pausing workflow', { workflowId: options.workflowId }); try { // Validate workflow ID if (!options.workflowId || options.workflowId.trim() === '') { throw new Error('Workflow ID is required'); } // Initialize memory manager const memory = new SwarmMemoryManager_js_1.SwarmMemoryManager(); // Retrieve workflow execution const execution = await retrieveWorkflowExecution(memory, options.workflowId); // Validate workflow status validateWorkflowForPause(execution); // Determine pause mode const pauseMode = options.immediate ? 'immediate' : 'graceful'; // Save current workflow state const savedState = await saveWorkflowState(memory, execution); // Notify agents about pause const notifiedAgents = await notifyAgentsOfPause(memory, execution); // Update workflow status execution.status = 'paused'; execution.pausedAt = new Date().toISOString(); execution.pauseReason = options.reason; execution.pauseMode = pauseMode; // Store updated execution in memory await memory.store(`workflow:execution:${execution.executionId}`, execution, { partition: 'workflow_executions', ttl: 86400 // 24 hours }); // Store pause checkpoint await memory.store(`aqe/swarm/workflow-cli-commands/checkpoint-${execution.workflowId}`, { checkpointId: `pause-${Date.now()}`, workflowId: execution.workflowId, executionId: execution.executionId, timestamp: execution.pausedAt, state: savedState, reason: options.reason }, { partition: 'workflow_cli', ttl: 604800 // 7 days }); // Update workflow status in memory await memory.store(`aqe/swarm/workflow-cli-commands/workflow-${execution.workflowId}-status`, { status: 'paused', timestamp: execution.pausedAt }, { partition: 'workflow_cli', ttl: 3600 }); // Create audit log entry await memory.postHint({ key: `aqe/audit/workflow-pause/${execution.workflowId}`, value: { action: 'pause', workflowId: execution.workflowId, timestamp: execution.pausedAt, reason: options.reason, mode: pauseMode }, ttl: 86400 }); // Update progress in memory await memory.store('aqe/swarm/workflow-cli-commands/progress', { command: 'pause', status: 'completed', timestamp: new Date().toISOString(), workflowId: execution.workflowId }, { partition: 'workflow_cli', ttl: 3600 }); const result = { success: true, workflowId: execution.workflowId, status: 'paused', pauseMode, workflow: { id: execution.workflowId, name: execution.workflowName || execution.workflowId, status: 'paused', pausedAt: execution.pausedAt, pauseReason: options.reason, savedState }, notifiedAgents }; logger.info('Workflow paused successfully', { workflowId: options.workflowId }); return result; } catch (error) { logger.error('Failed to pause workflow', { error, workflowId: options.workflowId }); throw error; } } exports.pauseWorkflow = pauseWorkflow; /** * Retrieve workflow execution from memory */ async function retrieveWorkflowExecution(memory, workflowId) { // Try to find execution by workflow ID const pattern = 'workflow:execution:%'; const entries = await memory.query(pattern, { partition: 'workflow_executions' }); const execution = entries.find(entry => entry.value.workflowId === workflowId); if (!execution) { throw new Error(`Workflow not found: ${workflowId}`); } return execution.value; } /** * Validate workflow can be paused */ function validateWorkflowForPause(execution) { if (execution.status === 'paused') { throw new Error(`Workflow ${execution.workflowId} is already paused`); } if (execution.status === 'completed') { throw new Error(`Cannot pause completed workflow ${execution.workflowId}`); } if (execution.status === 'failed') { throw new Error(`Cannot pause failed workflow ${execution.workflowId}`); } if (execution.status === 'cancelled') { throw new Error(`Cannot pause cancelled workflow ${execution.workflowId}`); } if (execution.status !== 'running') { throw new Error(`Cannot pause workflow ${execution.workflowId} with status: ${execution.status}`); } } /** * Save workflow state for recovery */ async function saveWorkflowState(memory, execution) { const savedState = { completedSteps: execution.completedSteps || [], currentStep: execution.currentStep, failedSteps: execution.failedSteps || [], progress: calculateProgress(execution), context: execution.context || {}, variables: execution.context?.variables || {}, checkpoints: execution.checkpoints || [] }; // Store state snapshot await memory.store(`workflow:state:${execution.executionId}`, savedState, { partition: 'workflow_states', ttl: 604800 // 7 days }); return savedState; } /** * Calculate workflow progress */ function calculateProgress(execution) { const total = (execution.completedSteps?.length || 0) + (execution.failedSteps?.length || 0); const completed = execution.completedSteps?.length || 0; return total > 0 ? completed / total : 0; } /** * Notify agents about workflow pause */ async function notifyAgentsOfPause(memory, execution) { const notifiedAgents = []; // Post notification to blackboard await memory.postHint({ key: `aqe/notifications/workflow-pause/${execution.workflowId}`, value: { event: 'workflow_paused', workflowId: execution.workflowId, executionId: execution.executionId, timestamp: new Date().toISOString() }, ttl: 3600 }); // In a real implementation, this would notify actual agents // For now, we'll simulate notification const mockAgents = ['qe-test-executor', 'qe-coverage-analyzer', 'qe-quality-gate']; notifiedAgents.push(...mockAgents); return notifiedAgents; } /** * Display pause result in console */ function displayPauseResult(result) { console.log(chalk_1.default.green('\n✓ Workflow paused successfully\n')); console.log(chalk_1.default.cyan('Workflow ID:'), result.workflow.id); console.log(chalk_1.default.cyan('Status:'), chalk_1.default.yellow(result.workflow.status)); console.log(chalk_1.default.cyan('Pause Mode:'), result.pauseMode); console.log(chalk_1.default.cyan('Paused At:'), result.workflow.pausedAt); if (result.workflow.pauseReason) { console.log(chalk_1.default.cyan('Reason:'), result.workflow.pauseReason); } console.log(chalk_1.default.cyan('Progress:'), `${(result.workflow.savedState.progress * 100).toFixed(1)}%`); console.log(chalk_1.default.cyan('Completed Steps:'), result.workflow.savedState.completedSteps.length); if (result.notifiedAgents.length > 0) { console.log(chalk_1.default.cyan('Notified Agents:'), result.notifiedAgents.join(', ')); } console.log(chalk_1.default.gray('\nWorkflow state has been saved and can be resumed later.\n')); } exports.displayPauseResult = displayPauseResult; //# sourceMappingURL=pause.js.map