|
4 | 4 | * Handles AI-powered issue enrichment with fix suggestions AND severity classification. |
5 | 5 | * Extracted from v9-grouped-report-formatter.ts for better modularity. |
6 | 6 | * |
7 | | - * Strategy: 1 AI call per group (cost-optimized) |
8 | | - * Cost: ~600 tokens per group = $0.0003 per group |
9 | | - * |
10 | | - * SESSION 13 FIX #2 (PROPER): Integrated AI Severity Classifier |
11 | | - * - Severity classification happens PER GROUP (not per issue) |
12 | | - * - Uses cheap models for classification (~150 tokens per group) |
13 | | - * - Total cost: ~29 groups × 150 tokens = ~4,350 tokens = ~$0.002 |
| 7 | + * OPTIMIZATION: Severity classification integrated into specialized agents |
| 8 | + * - Each agent classifies severity AS PART of generating fix suggestions |
| 9 | + * - 1 AI call per group (was 2 before: classify + enrich) |
| 10 | + * - Cost: ~600 tokens per group = $0.0003 per group = ~$0.009 per PR |
| 11 | + * - Savings: ~150 tokens per group (was ~$0.011, now ~$0.009) |
14 | 12 | */ |
15 | 13 |
|
16 | 14 | import { EnrichedIssue } from './types'; |
17 | 15 | import { IssueGroup } from '../utils/issue-grouping'; |
18 | | -import { |
19 | | - classifyIssueSeverity, |
20 | | - type Severity, |
21 | | - type SeverityClassificationInput |
22 | | -} from '../services/ai-severity-classifier'; |
23 | 16 |
|
24 | 17 | /** |
25 | 18 | * Get curated educational resources for specific rules |
@@ -54,108 +47,6 @@ export function getCuratedResourcesForRule(ruleId: string): Array<{ title: strin |
54 | 47 | return map[normalized] || []; |
55 | 48 | } |
56 | 49 |
|
57 | | -/** |
58 | | - * SESSION 13 FIX #2 (PROPER): AI-powered severity classification |
59 | | - * |
60 | | - * Re-classifies issue severity intelligently using AI, per group. |
61 | | - * This replaces the hardcoded severity mapping approach. |
62 | | - * |
63 | | - * Strategy: |
64 | | - * - Classify ONE representative issue per group |
65 | | - * - Apply the classified severity to ALL issues in that group |
66 | | - * - Cost-optimized: ~150 tokens per group = ~$0.0001 per group |
67 | | - * |
68 | | - * @param issues - All issues to re-classify |
69 | | - * @param groups - Issue groups for efficient processing |
70 | | - * @param modelConfigResolver - Model configuration resolver (from Supabase) |
71 | | - * @returns Issues with AI-classified severity |
72 | | - */ |
73 | | -export async function enrichIssuesWithSeverityClassification( |
74 | | - issues: EnrichedIssue[], |
75 | | - groups: IssueGroup[], |
76 | | - modelConfigResolver: any | null |
77 | | -): Promise<EnrichedIssue[]> { |
78 | | - // SESSION 13 FIX #2 (MANDATORY): AI severity classification is now always enabled |
79 | | - // This is a core feature that provides intelligent severity analysis |
80 | | - // If AI fails, we gracefully fall back to original severity (handled in catch blocks) |
81 | | - |
82 | | - console.log(`[AI Severity] Starting severity classification for ${groups.length} groups...`); |
83 | | - const startTime = Date.now(); |
84 | | - |
85 | | - try { |
86 | | - // Process groups in parallel (29 groups × ~150 tokens = ~4,350 tokens = ~$0.002) |
87 | | - const classificationPromises = groups.map(async (group) => { |
88 | | - const groupIssues = issues.filter(i => |
89 | | - i.rule === group.rule && i.tool === group.tool && i.severity === group.severity |
90 | | - ); |
91 | | - |
92 | | - if (groupIssues.length === 0) return; |
93 | | - |
94 | | - // Pick representative issue (first with code snippet) |
95 | | - const representative = groupIssues.find(i => i.snippet) || groupIssues[0]; |
96 | | - |
97 | | - // Save original severity for comparison |
98 | | - const originalSeverity = representative.severity as Severity; |
99 | | - |
100 | | - try { |
101 | | - const classificationInput: SeverityClassificationInput = { |
102 | | - tool: representative.tool, |
103 | | - rule: representative.rule, |
104 | | - originalSeverity, |
105 | | - title: representative.message || representative.rule, |
106 | | - description: representative.message || '', |
107 | | - codeSnippet: representative.snippet |
108 | | - }; |
109 | | - |
110 | | - // Get model from config resolver (uses Qwen via OpenRouter) |
111 | | - // SESSION 13 FIX #3 (CONFIG-BASED): Use config resolver to get model configuration |
112 | | - // Severity classification doesn't need a specific role, use code_quality as default |
113 | | - let model: string | undefined; |
114 | | - if (modelConfigResolver) { |
115 | | - const modelConfig = await modelConfigResolver.getModelConfiguration( |
116 | | - 'code_quality', // Severity classification uses code quality role |
117 | | - 'java', // Default to java (works for all languages) |
118 | | - 'medium' // Default to medium repo size |
119 | | - ); |
120 | | - model = modelConfig.primary_model; |
121 | | - } |
122 | | - |
123 | | - // Call AI Severity Classifier with config-based model |
124 | | - const classification = await classifyIssueSeverity(classificationInput, model); |
125 | | - |
126 | | - // Apply classified severity to ALL issues in this group |
127 | | - for (const issue of groupIssues) { |
128 | | - issue.severity = classification.severity; |
129 | | - issue.severityReasoning = classification.reasoning; |
130 | | - issue.severityConfidence = classification.confidence; |
131 | | - } |
132 | | - |
133 | | - // Log severity changes |
134 | | - if (classification.severity !== originalSeverity) { |
135 | | - console.log(`[AI Severity] ✅ ${group.rule}: ${originalSeverity} → ${classification.severity} (${classification.confidence} confidence)`); |
136 | | - } |
137 | | - |
138 | | - } catch (error: any) { |
139 | | - console.warn(`[AI Severity] ⚠️ Failed for ${group.rule}:`, error.message); |
140 | | - // Keep original severity on error |
141 | | - } |
142 | | - }); |
143 | | - |
144 | | - await Promise.all(classificationPromises); |
145 | | - |
146 | | - const duration = Date.now() - startTime; |
147 | | - const reclassifiedCount = issues.filter(i => i.severityReasoning).length; |
148 | | - console.log(`[AI Severity] Completed: ${reclassifiedCount}/${issues.length} issues re-classified in ${duration}ms`); |
149 | | - |
150 | | - return issues; |
151 | | - |
152 | | - } catch (error: any) { |
153 | | - console.error('[AI Severity] Fatal error:', error.message); |
154 | | - // Return issues with original severity |
155 | | - return issues; |
156 | | - } |
157 | | -} |
158 | | - |
159 | 50 | /** |
160 | 51 | * Enrich issues with AI-generated fix suggestions |
161 | 52 | * |
|
0 commit comments