|
import React, { useState, useEffect, useRef } from "react"; |
|
import { Box, Typography, CircularProgress, Alert, Paper } from "@mui/material"; |
|
import { useNavigate, useSearchParams } from "react-router-dom"; |
|
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline"; |
|
import { useTimer } from "./hooks/useTimer"; |
|
import { useEvaluation } from "./hooks/useEvaluation"; |
|
import ErrorDisplay from "../common/ErrorDisplay"; |
|
|
|
|
|
const SIMULATION_MESSAGES = [ |
|
{ |
|
message: "Initializing evaluation environment", |
|
step: 1, |
|
totalSteps: 5, |
|
timing: 0, |
|
}, |
|
{ |
|
message: "Finding available model providers", |
|
step: 2, |
|
totalSteps: 5, |
|
timing: 1500, |
|
}, |
|
{ |
|
message: "Starting evaluation process", |
|
step: 3, |
|
totalSteps: 5, |
|
timing: 3000, |
|
}, |
|
{ message: "Evaluating models", step: 4, totalSteps: 5, timing: 5000 }, |
|
{ |
|
message: "Storing evaluation results", |
|
step: 5, |
|
totalSteps: 5, |
|
timing: 7000, |
|
}, |
|
]; |
|
|
|
|
|
const TOTAL_SIMULATION_DURATION = 8000; |
|
|
|
const BenchmarkEvaluation = ({ sessionId, isDefaultDocument, onComplete }) => { |
|
const [searchParams] = useSearchParams(); |
|
const isDefault = |
|
isDefaultDocument || |
|
["the-bitter-lesson", "hurricane-faq", "pokemon-guide"].includes(sessionId); |
|
|
|
const navigate = useNavigate(); |
|
const simulationTimeoutsRef = useRef([]); |
|
|
|
|
|
const [simulationStep, setSimulationStep] = useState(0); |
|
const [simulationComplete, setSimulationComplete] = useState(false); |
|
|
|
|
|
const { formatElapsedTime, stopTimer } = useTimer(); |
|
const { |
|
error, |
|
evaluationComplete: realComplete, |
|
currentStep, |
|
evaluationStarted, |
|
startEvaluation, |
|
currentStepLabel, |
|
totalSteps, |
|
} = useEvaluation(sessionId, () => { |
|
if (onComplete) { |
|
onComplete(); |
|
} |
|
}); |
|
|
|
|
|
useEffect(() => { |
|
|
|
if (!isDefault || simulationTimeoutsRef.current.length > 0) return; |
|
|
|
console.log("Starting simulation for default document:", sessionId); |
|
|
|
|
|
for (let i = 1; i < SIMULATION_MESSAGES.length; i++) { |
|
const messageData = SIMULATION_MESSAGES[i]; |
|
const timeout = setTimeout(() => { |
|
console.log(`Simulation step ${i + 1}: ${messageData.message}`); |
|
setSimulationStep(i); |
|
}, messageData.timing); |
|
|
|
simulationTimeoutsRef.current.push(timeout); |
|
} |
|
|
|
|
|
const finalTimeout = setTimeout(() => { |
|
console.log("Simulation complete, redirecting"); |
|
setSimulationComplete(true); |
|
if (onComplete) { |
|
onComplete(); |
|
} |
|
}, TOTAL_SIMULATION_DURATION); |
|
|
|
simulationTimeoutsRef.current.push(finalTimeout); |
|
|
|
|
|
return () => { |
|
simulationTimeoutsRef.current.forEach(clearTimeout); |
|
}; |
|
}, [isDefault, sessionId, onComplete]); |
|
|
|
|
|
useEffect(() => { |
|
if (realComplete || simulationComplete) { |
|
navigate(`/evaluation-display?session=${sessionId}`); |
|
} |
|
}, [realComplete, simulationComplete, sessionId, navigate]); |
|
|
|
|
|
useEffect(() => { |
|
if (!isDefault && !evaluationStarted) { |
|
startEvaluation(); |
|
} |
|
}, [isDefault, evaluationStarted, startEvaluation]); |
|
|
|
|
|
useEffect(() => { |
|
if (realComplete || simulationComplete) { |
|
stopTimer(); |
|
} |
|
}, [realComplete, simulationComplete, stopTimer]); |
|
|
|
const isComplete = realComplete || simulationComplete; |
|
const currentStepInfo = isDefault |
|
? `${SIMULATION_MESSAGES[simulationStep].message} (${SIMULATION_MESSAGES[simulationStep].step}/${SIMULATION_MESSAGES[simulationStep].totalSteps})` |
|
: `${currentStepLabel} (${currentStep + 1}/${totalSteps})`; |
|
|
|
return ( |
|
<Paper |
|
elevation={3} |
|
sx={{ |
|
p: 8, |
|
display: "flex", |
|
flexDirection: "column", |
|
alignItems: "center", |
|
justifyContent: "center", |
|
minHeight: 200, |
|
position: "relative", |
|
}} |
|
> |
|
{/* Temps estimé */} |
|
<Box |
|
sx={{ |
|
position: "absolute", |
|
top: 12, |
|
right: 12, |
|
backgroundColor: "rgba(0, 0, 0, 0.04)", |
|
borderRadius: "4px", |
|
px: 1, |
|
py: 0.5, |
|
display: "inline-flex", |
|
alignItems: "center", |
|
}} |
|
> |
|
<Typography |
|
variant="caption" |
|
sx={{ |
|
fontSize: "0.675rem", |
|
color: "text.secondary", |
|
fontWeight: 500, |
|
}} |
|
> |
|
Estimated time ~ 1m30s |
|
</Typography> |
|
</Box> |
|
|
|
{error ? ( |
|
<ErrorDisplay error={error} /> |
|
) : ( |
|
<> |
|
{isComplete ? ( |
|
<Alert severity="success" sx={{ width: "100%", mb: 3 }}> |
|
Evaluation completed successfully! |
|
</Alert> |
|
) : ( |
|
<> |
|
<CircularProgress size={60} sx={{ mb: 2 }} /> |
|
<Typography variant="h6" component="div" gutterBottom> |
|
Benchmark evaluation... |
|
</Typography> |
|
|
|
{/* Step progress indicator */} |
|
<Typography variant="body1" color="text.secondary"> |
|
{currentStepInfo} |
|
</Typography> |
|
|
|
{/* Timer display */} |
|
<Box |
|
sx={{ |
|
display: "flex", |
|
alignItems: "center", |
|
mt: 1, |
|
color: "text.secondary", |
|
opacity: 0.5, |
|
}} |
|
> |
|
<Typography variant="body2">{formatElapsedTime()}</Typography> |
|
</Box> |
|
</> |
|
)} |
|
</> |
|
)} |
|
</Paper> |
|
); |
|
}; |
|
|
|
export default BenchmarkEvaluation; |
|
|