diff --git a/frontend/src/components/evaluation/FullTechniquesProgress.tsx b/frontend/src/components/evaluation/FullTechniquesProgress.tsx index bd6228e..e93ad6d 100644 --- a/frontend/src/components/evaluation/FullTechniquesProgress.tsx +++ b/frontend/src/components/evaluation/FullTechniquesProgress.tsx @@ -63,19 +63,22 @@ export const FullTechniquesProgress: React.FC = ({ etaSeconds={state.etaSeconds} totalTechniques={state.totalTechniques} completedTechniques={state.completedTechniques} + enrichmentMessage={state.enrichmentMessage} />

- {state.currentStage === 'deep_synthesis' ? 'Synthesizing Insights...' : + {state.currentStage === 'enrichment' ? 'Preparing Analysis...' : + state.currentStage === 'deep_synthesis' ? 'Synthesizing Insights...' : state.currentStage === 'quality_gate' ? 'Final Quality Gate...' : state.currentStage === 'complete' ? 'Evaluation Complete' : 'Tasting Flight in Progress'}

- {state.currentStage === 'deep_synthesis' ? 'Our Master Sommelier is blending the notes from all 75 techniques.' : + {state.currentStage === 'enrichment' ? 'Gathering context through code analysis, RAG, and web search.' : + state.currentStage === 'deep_synthesis' ? 'Our Master Sommelier is blending the notes from all 75 techniques.' : state.currentStage === 'quality_gate' ? 'Verifying final scores and generating the vintage report.' : state.currentStage === 'complete' ? 'Your vintage report is ready for review.' : 'Analyzing your codebase across 8 dimensions and 75 distinct techniques.'} diff --git a/frontend/src/components/evaluation/ProgressTopBar.tsx b/frontend/src/components/evaluation/ProgressTopBar.tsx index 7fc29ab..c766a1b 100644 --- a/frontend/src/components/evaluation/ProgressTopBar.tsx +++ b/frontend/src/components/evaluation/ProgressTopBar.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Wifi, WifiOff, Clock, GitBranch } from 'lucide-react'; +import { Wifi, WifiOff, Clock, GitBranch, Loader2 } from 'lucide-react'; interface ProgressTopBarProps { repoName: string; @@ -8,6 +8,7 @@ interface ProgressTopBarProps { etaSeconds?: number; totalTechniques: number; completedTechniques: number; + enrichmentMessage?: string | null; } export const ProgressTopBar: React.FC = ({ @@ -17,6 +18,7 @@ export const ProgressTopBar: React.FC = ({ etaSeconds, totalTechniques, completedTechniques, + enrichmentMessage, }) => { const formatTime = (seconds: number) => { const mins = Math.floor(seconds / 60); @@ -59,6 +61,12 @@ export const ProgressTopBar: React.FC = ({

+ {enrichmentMessage && ( +
+ + {enrichmentMessage} +
+ )}
{completedTechniques} / diff --git a/frontend/src/hooks/useFullTechniquesStream.ts b/frontend/src/hooks/useFullTechniquesStream.ts index 38bc354..8fe3e1e 100644 --- a/frontend/src/hooks/useFullTechniquesStream.ts +++ b/frontend/src/hooks/useFullTechniquesStream.ts @@ -22,6 +22,15 @@ interface CategoryStatus { status: 'pending' | 'running' | 'complete'; } +type EnrichmentPhase = 'idle' | 'code_analysis' | 'rag' | 'web_search' | 'complete'; +type EnrichmentStepStatus = 'pending' | 'running' | 'complete' | 'error'; + +interface EnrichmentStatus { + code_analysis: EnrichmentStepStatus; + rag: EnrichmentStepStatus; + web_search: EnrichmentStepStatus; +} + interface FullTechniquesStreamState { connectionStatus: 'connecting' | 'open' | 'retrying' | 'failed' | 'closed'; retryCount: number; @@ -31,7 +40,7 @@ interface FullTechniquesStreamState { failedTechniques: number; progressPercent: number; - currentStage: 'categories' | 'deep_synthesis' | 'quality_gate' | 'complete' | 'error'; + currentStage: 'enrichment' | 'categories' | 'deep_synthesis' | 'quality_gate' | 'complete' | 'error'; categories: Record; @@ -49,6 +58,10 @@ interface FullTechniquesStreamState { startedAt?: string; etaSeconds?: number; + + enrichmentPhase: EnrichmentPhase; + enrichmentMessage: string | null; + enrichmentStatus: EnrichmentStatus; } const CATEGORIES: Record = { @@ -83,13 +96,20 @@ const initialState: FullTechniquesStreamState = { completedTechniques: 0, failedTechniques: 0, progressPercent: 0, - currentStage: 'categories', + currentStage: 'enrichment', categories: INITIAL_CATEGORIES, techniques: {}, ledgerEvents: [], isComplete: false, tokensUsed: 0, costUsd: 0, + enrichmentPhase: 'idle', + enrichmentMessage: null, + enrichmentStatus: { + code_analysis: 'pending', + rag: 'pending', + web_search: 'pending', + }, }; type Action = @@ -139,6 +159,11 @@ function reducer(state: FullTechniquesStreamState, action: Action): FullTechniqu switch (event.event_type) { case 'technique_start': if (event.technique_id && event.technique_name && event.category_id) { + if (state.currentStage === 'enrichment') { + newState.currentStage = 'categories'; + newState.enrichmentPhase = 'complete'; + newState.enrichmentMessage = null; + } newState.techniques = { ...state.techniques, [event.technique_id]: { @@ -264,6 +289,46 @@ function reducer(state: FullTechniquesStreamState, action: Action): FullTechniqu newState.currentStage = 'error'; newState.error = event.error || event.message || 'Unknown error'; break; + + case 'enrichment_start': + if (event.sommelier) { + const phase = event.sommelier as EnrichmentPhase; + newState.enrichmentPhase = phase; + newState.enrichmentMessage = event.message || `${event.sommelier} starting...`; + newState.currentStage = 'enrichment'; + newState.enrichmentStatus = { + ...state.enrichmentStatus, + [event.sommelier]: 'running' as EnrichmentStepStatus, + }; + } + break; + + case 'enrichment_complete': + if (event.sommelier) { + newState.enrichmentStatus = { + ...state.enrichmentStatus, + [event.sommelier]: 'complete' as EnrichmentStepStatus, + }; + const allComplete = Object.values(newState.enrichmentStatus).every( + s => s === 'complete' + ); + if (allComplete) { + newState.enrichmentPhase = 'complete'; + newState.enrichmentMessage = null; + newState.currentStage = 'categories'; + } + } + break; + + case 'enrichment_error': + if (event.sommelier) { + newState.enrichmentStatus = { + ...state.enrichmentStatus, + [event.sommelier]: 'error' as EnrichmentStepStatus, + }; + newState.enrichmentMessage = event.message || `${event.sommelier} failed`; + } + break; } return newState; diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 1023753..d3cbab9 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -70,7 +70,10 @@ export type SSEEventType = | 'deep_synthesis_start' | 'deep_synthesis_complete' | 'quality_gate_complete' - | 'metrics_update'; + | 'metrics_update' + | 'enrichment_start' + | 'enrichment_complete' + | 'enrichment_error'; export interface SSEEvent { event_type: SSEEventType;