/** * AI Classify Step — uses AI to classify ambiguous fields when robotic classification fails. * Config: { * template_purpose: 'ambiguous_classification', * skip_if_valid?: boolean // skip if validation passed * } * Condition: typically checks context.validation.is_valid === false */ import { registerWorkflowStepExecutor } from '../ticket-workflow-engine'; import { aiTriageService } from '../ai-triage-service'; import { TicketWorkflowStep, WorkflowStepContext, WorkflowStepResult } from '../../types/ticket-workflow'; async function executeAiClassify( step: TicketWorkflowStep, context: WorkflowStepContext, _executionId: number ): Promise { // Check if we should skip (validation passed) if (step.config.skip_if_valid && context.validation?.is_valid) { return { success: true, output: { skipped: true, reason: 'Validation passed, AI not needed' } }; } // Get failed fields from validation const validationFailedFields = context.validation?.errors?.map(e => e.field) || []; if (validationFailedFields.length === 0) { return { success: true, output: { skipped: true, reason: 'No failed fields to classify' } }; } // Build ticket with current classification context const ticket = { ...context.ticket, ...(context.field_changes || {}) }; // Call AI classification const aiResult = await aiTriageService.classifyAmbiguous( ticket, validationFailedFields, context._settings ); // Merge AI results into context if (aiResult.classification) { if (!context.field_changes) { context.field_changes = {}; } // Update field changes with AI results if (aiResult.classification.issue_type !== undefined) { context.field_changes['issue_type'] = { before: ticket.issue_type || null, after: aiResult.classification.issue_type }; } if (aiResult.classification.sub_issue_type !== undefined) { context.field_changes['sub_issue_type'] = { before: ticket.sub_issue_type || null, after: aiResult.classification.sub_issue_type }; } if (aiResult.classification.ticket_type !== undefined) { context.field_changes['ticket_type'] = { before: ticket.ticket_type || null, after: aiResult.classification.ticket_type }; } if (aiResult.classification.priority !== undefined) { context.field_changes['priority'] = { before: ticket.priority || null, after: aiResult.classification.priority }; } } return { success: true, output: { method: 'ai', classification: aiResult.classification, failed_fields_addressed: validationFailedFields } }; } registerWorkflowStepExecutor('ai_classify', executeAiClassify);