wulf-pulse/lib/services/workflow-steps/ai-classify.ts

99 lines
2.8 KiB
TypeScript

/**
* 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<WorkflowStepResult> {
// 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);