Skip to content

Commit cb9774b

Browse files
committed
feat(#268): display enrichment progress in full_techniques mode
- Add enrichment SSE event types to SSEEventType union - Add enrichment state tracking (phase, message, status per step) - Handle enrichment_start/complete/error events in reducer - Add 'enrichment' stage to currentStage - Add enrichment status indicator to ProgressTopBar - Update FullTechniquesProgress to show enrichment stage messaging Closes #268
1 parent a51a3c5 commit cb9774b

4 files changed

Lines changed: 85 additions & 6 deletions

File tree

frontend/src/components/evaluation/FullTechniquesProgress.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,22 @@ export const FullTechniquesProgress: React.FC<FullTechniquesProgressProps> = ({
6363
etaSeconds={state.etaSeconds}
6464
totalTechniques={state.totalTechniques}
6565
completedTechniques={state.completedTechniques}
66+
enrichmentMessage={state.enrichmentMessage}
6667
/>
6768

6869
<main className="flex-1 max-w-7xl w-full mx-auto p-4 md:p-6 space-y-8">
6970

7071
<div className="text-center space-y-2 py-4">
7172
<h1 className="text-3xl md:text-4xl font-serif font-bold text-[#722F37] animate-fade-in">
72-
{state.currentStage === 'deep_synthesis' ? 'Synthesizing Insights...' :
73+
{state.currentStage === 'enrichment' ? 'Preparing Analysis...' :
74+
state.currentStage === 'deep_synthesis' ? 'Synthesizing Insights...' :
7375
state.currentStage === 'quality_gate' ? 'Final Quality Gate...' :
7476
state.currentStage === 'complete' ? 'Evaluation Complete' :
7577
'Tasting Flight in Progress'}
7678
</h1>
7779
<p className="text-gray-600 max-w-2xl mx-auto">
78-
{state.currentStage === 'deep_synthesis' ? 'Our Master Sommelier is blending the notes from all 75 techniques.' :
80+
{state.currentStage === 'enrichment' ? 'Gathering context through code analysis, RAG, and web search.' :
81+
state.currentStage === 'deep_synthesis' ? 'Our Master Sommelier is blending the notes from all 75 techniques.' :
7982
state.currentStage === 'quality_gate' ? 'Verifying final scores and generating the vintage report.' :
8083
state.currentStage === 'complete' ? 'Your vintage report is ready for review.' :
8184
'Analyzing your codebase across 8 dimensions and 75 distinct techniques.'}

frontend/src/components/evaluation/ProgressTopBar.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { Wifi, WifiOff, Clock, GitBranch } from 'lucide-react';
2+
import { Wifi, WifiOff, Clock, GitBranch, Loader2 } from 'lucide-react';
33

44
interface ProgressTopBarProps {
55
repoName: string;
@@ -8,6 +8,7 @@ interface ProgressTopBarProps {
88
etaSeconds?: number;
99
totalTechniques: number;
1010
completedTechniques: number;
11+
enrichmentMessage?: string | null;
1112
}
1213

1314
export const ProgressTopBar: React.FC<ProgressTopBarProps> = ({
@@ -17,6 +18,7 @@ export const ProgressTopBar: React.FC<ProgressTopBarProps> = ({
1718
etaSeconds,
1819
totalTechniques,
1920
completedTechniques,
21+
enrichmentMessage,
2022
}) => {
2123
const formatTime = (seconds: number) => {
2224
const mins = Math.floor(seconds / 60);
@@ -59,6 +61,12 @@ export const ProgressTopBar: React.FC<ProgressTopBarProps> = ({
5961
</div>
6062

6163
<div className="flex items-center gap-4 text-sm">
64+
{enrichmentMessage && (
65+
<div className="flex items-center gap-1.5 px-3 py-1 rounded-full bg-amber-500/10 border border-amber-500/20 text-amber-700 text-xs font-medium">
66+
<Loader2 size={12} className="animate-spin" />
67+
<span className="truncate max-w-[150px]">{enrichmentMessage}</span>
68+
</div>
69+
)}
6270
<div className="hidden md:block text-gray-600 font-medium">
6371
<span className="text-[#722F37] font-bold">{completedTechniques}</span>
6472
<span className="text-gray-400 mx-1">/</span>

frontend/src/hooks/useFullTechniquesStream.ts

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ interface CategoryStatus {
2222
status: 'pending' | 'running' | 'complete';
2323
}
2424

25+
type EnrichmentPhase = 'idle' | 'code_analysis' | 'rag' | 'web_search' | 'complete';
26+
type EnrichmentStepStatus = 'pending' | 'running' | 'complete' | 'error';
27+
28+
interface EnrichmentStatus {
29+
code_analysis: EnrichmentStepStatus;
30+
rag: EnrichmentStepStatus;
31+
web_search: EnrichmentStepStatus;
32+
}
33+
2534
interface FullTechniquesStreamState {
2635
connectionStatus: 'connecting' | 'open' | 'retrying' | 'failed' | 'closed';
2736
retryCount: number;
@@ -31,7 +40,7 @@ interface FullTechniquesStreamState {
3140
failedTechniques: number;
3241
progressPercent: number;
3342

34-
currentStage: 'categories' | 'deep_synthesis' | 'quality_gate' | 'complete' | 'error';
43+
currentStage: 'enrichment' | 'categories' | 'deep_synthesis' | 'quality_gate' | 'complete' | 'error';
3544

3645
categories: Record<string, CategoryStatus>;
3746

@@ -49,6 +58,10 @@ interface FullTechniquesStreamState {
4958

5059
startedAt?: string;
5160
etaSeconds?: number;
61+
62+
enrichmentPhase: EnrichmentPhase;
63+
enrichmentMessage: string | null;
64+
enrichmentStatus: EnrichmentStatus;
5265
}
5366

5467
const CATEGORIES: Record<string, { name: string; total: number }> = {
@@ -83,13 +96,20 @@ const initialState: FullTechniquesStreamState = {
8396
completedTechniques: 0,
8497
failedTechniques: 0,
8598
progressPercent: 0,
86-
currentStage: 'categories',
99+
currentStage: 'enrichment',
87100
categories: INITIAL_CATEGORIES,
88101
techniques: {},
89102
ledgerEvents: [],
90103
isComplete: false,
91104
tokensUsed: 0,
92105
costUsd: 0,
106+
enrichmentPhase: 'idle',
107+
enrichmentMessage: null,
108+
enrichmentStatus: {
109+
code_analysis: 'pending',
110+
rag: 'pending',
111+
web_search: 'pending',
112+
},
93113
};
94114

95115
type Action =
@@ -139,6 +159,11 @@ function reducer(state: FullTechniquesStreamState, action: Action): FullTechniqu
139159
switch (event.event_type) {
140160
case 'technique_start':
141161
if (event.technique_id && event.technique_name && event.category_id) {
162+
if (state.currentStage === 'enrichment') {
163+
newState.currentStage = 'categories';
164+
newState.enrichmentPhase = 'complete';
165+
newState.enrichmentMessage = null;
166+
}
142167
newState.techniques = {
143168
...state.techniques,
144169
[event.technique_id]: {
@@ -264,6 +289,46 @@ function reducer(state: FullTechniquesStreamState, action: Action): FullTechniqu
264289
newState.currentStage = 'error';
265290
newState.error = event.error || event.message || 'Unknown error';
266291
break;
292+
293+
case 'enrichment_start':
294+
if (event.sommelier) {
295+
const phase = event.sommelier as EnrichmentPhase;
296+
newState.enrichmentPhase = phase;
297+
newState.enrichmentMessage = event.message || `${event.sommelier} starting...`;
298+
newState.currentStage = 'enrichment';
299+
newState.enrichmentStatus = {
300+
...state.enrichmentStatus,
301+
[event.sommelier]: 'running' as EnrichmentStepStatus,
302+
};
303+
}
304+
break;
305+
306+
case 'enrichment_complete':
307+
if (event.sommelier) {
308+
newState.enrichmentStatus = {
309+
...state.enrichmentStatus,
310+
[event.sommelier]: 'complete' as EnrichmentStepStatus,
311+
};
312+
const allComplete = Object.values(newState.enrichmentStatus).every(
313+
s => s === 'complete'
314+
);
315+
if (allComplete) {
316+
newState.enrichmentPhase = 'complete';
317+
newState.enrichmentMessage = null;
318+
newState.currentStage = 'categories';
319+
}
320+
}
321+
break;
322+
323+
case 'enrichment_error':
324+
if (event.sommelier) {
325+
newState.enrichmentStatus = {
326+
...state.enrichmentStatus,
327+
[event.sommelier]: 'error' as EnrichmentStepStatus,
328+
};
329+
newState.enrichmentMessage = event.message || `${event.sommelier} failed`;
330+
}
331+
break;
267332
}
268333

269334
return newState;

frontend/src/types/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ export type SSEEventType =
7070
| 'deep_synthesis_start'
7171
| 'deep_synthesis_complete'
7272
| 'quality_gate_complete'
73-
| 'metrics_update';
73+
| 'metrics_update'
74+
| 'enrichment_start'
75+
| 'enrichment_complete'
76+
| 'enrichment_error';
7477

7578
export interface SSEEvent {
7679
event_type: SSEEventType;

0 commit comments

Comments
 (0)