agentic-qe
Version:
Agentic Quality Engineering Fleet System - AI-driven quality management platform
222 lines • 8.65 kB
JavaScript
;
/**
* 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