bug-fix.js
1 /** 2 * Bug Fix Workflow 3 * 4 * Automated workflow: Triage → Developer → QA → Security 5 * 6 * Usage: 7 * import { createBugFixWorkflow } from './workflows/bug-fix.js'; 8 * const workflowId = await createBugFixWorkflow(errorMessage, stackTrace); 9 */ 10 11 import { createAgentTask } from '../utils/task-manager.js'; 12 import Logger from '../../utils/logger.js'; 13 import { getAll } from '../../utils/db.js'; 14 15 const logger = new Logger('BugFixWorkflow'); 16 17 /** 18 * Create a bug fix workflow 19 * 20 * @param {string} errorMessage - Error message 21 * @param {string} [stackTrace=''] - Stack trace 22 * @param {string} [stage='unknown'] - Pipeline stage where error occurred 23 * @param {number} [frequency=1] - How many times the error has occurred 24 * @param {Object} [options] - Additional options 25 * @param {number} [options.priority] - Override calculated priority 26 * @param {string} [options.created_by='system'] - Who created the workflow 27 * @returns {Promise<number>} - Triage task ID (parent of the workflow) 28 */ 29 export async function createBugFixWorkflow( 30 errorMessage, 31 stackTrace = '', 32 stage = 'unknown', 33 frequency = 1, 34 options = {} 35 ) { 36 const { priority, created_by = 'system' } = options; 37 38 logger.info('Creating bug fix workflow', { 39 error: errorMessage.substring(0, 100), 40 stage, 41 frequency, 42 }); 43 44 // Step 1: Create Triage task (will route to Developer) 45 const triageTaskId = await createAgentTask({ 46 task_type: 'classify_error', 47 assigned_to: 'triage', 48 created_by, 49 priority: priority || 5, 50 context: { 51 error_message: errorMessage, 52 stack_trace: stackTrace, 53 stage, 54 frequency, 55 }, 56 }); 57 58 logger.info('Bug fix workflow created', { 59 workflow_id: triageTaskId, 60 stage, 61 }); 62 63 return triageTaskId; 64 } 65 66 /** 67 * Create multiple bug fix workflows from a list of errors 68 * 69 * @param {Array<Object>} errors - Array of error objects 70 * @param {string} errors[].message - Error message 71 * @param {string} [errors[].stack] - Stack trace 72 * @param {string} [errors[].stage] - Pipeline stage 73 * @param {number} [errors[].frequency] - Occurrence count 74 * @returns {Promise<Array<number>>} - Array of workflow IDs 75 */ 76 export async function createBulkBugFixWorkflows(errors) { 77 const workflowIds = []; 78 79 for (const error of errors) { 80 try { 81 const workflowId = await createBugFixWorkflow( 82 error.message, 83 error.stack || '', 84 error.stage || 'unknown', 85 error.frequency || 1, 86 { created_by: error.created_by || 'system' } 87 ); 88 workflowIds.push(workflowId); 89 } catch (err) { 90 logger.error('Failed to create bug fix workflow', { 91 error: error.message, 92 err: err.message, 93 }); 94 } 95 } 96 97 return workflowIds; 98 } 99 100 /** 101 * Get workflow status 102 * 103 * @param {number} workflowId - Triage task ID (parent) 104 * @returns {Promise<Object>} - Workflow status 105 */ 106 export async function getBugFixWorkflowStatus(workflowId) { 107 // Get all tasks in the workflow chain 108 const tasks = await getAll( 109 `WITH RECURSIVE workflow_chain AS ( 110 SELECT * FROM tel.agent_tasks WHERE id = $1 111 UNION ALL 112 SELECT t.* FROM tel.agent_tasks t 113 INNER JOIN workflow_chain wc ON t.parent_task_id = wc.id 114 ) 115 SELECT * FROM workflow_chain 116 ORDER BY id ASC`, 117 [workflowId] 118 ); 119 120 const status = { 121 workflow_id: workflowId, 122 created_at: tasks[0]?.created_at, 123 stages: tasks.map(t => ({ 124 agent: t.assigned_to, 125 task_type: t.task_type, 126 status: t.status, 127 started_at: t.started_at, 128 completed_at: t.completed_at, 129 error_message: t.error_message, 130 })), 131 current_stage: tasks.find(t => t.status === 'running' || t.status === 'pending'), 132 is_complete: tasks.every(t => t.status === 'completed'), 133 has_failures: tasks.some(t => t.status === 'failed'), 134 is_blocked: tasks.some(t => t.status === 'blocked'), 135 }; 136 137 return status; 138 }