|
import { useState, useEffect } from "react"; |
|
|
|
const BENCHMARK_STEPS = [ |
|
"configuration", |
|
"provider_check", |
|
"ingestion", |
|
"upload_ingest_to_hub", |
|
"summarization", |
|
"chunking", |
|
"single_shot_question_generation", |
|
]; |
|
|
|
export const useBenchmarkLogs = (sessionId, isDefault, onComplete) => { |
|
const [generationLogs, setGenerationLogs] = useState([]); |
|
const [error, setError] = useState(null); |
|
const [currentPhase, setCurrentPhase] = useState("initializing"); |
|
const [completedSteps, setCompletedSteps] = useState([]); |
|
const [activeStep, setActiveStep] = useState(1); |
|
const [generationComplete, setGenerationComplete] = useState(false); |
|
|
|
const checkForErrors = (logs) => { |
|
|
|
const hasInsufficientInfoError = logs.some((log) => |
|
log.includes( |
|
"Failed to generate benchmark: The document does not contain enough information" |
|
) |
|
); |
|
|
|
if (hasInsufficientInfoError) { |
|
return { |
|
hasError: true, |
|
error: |
|
"Your document doesn't contain enough information to generate a benchmark. Please try with a more comprehensive document that includes richer content.", |
|
}; |
|
} |
|
|
|
|
|
const hasRateLimitError = logs.some( |
|
(log) => |
|
log.includes("RATE_LIMIT_EXCEEDED") || |
|
log.includes("heavy load") || |
|
log.includes("rate limit") |
|
); |
|
|
|
if (hasRateLimitError) { |
|
return { |
|
hasError: true, |
|
error: |
|
"The demo is under heavy load at the moment. Please try again later.", |
|
}; |
|
} |
|
|
|
|
|
const hasModelError = logs.some( |
|
(log) => |
|
log.includes("Required models not available") || |
|
log.includes("Some required models are not available") |
|
); |
|
|
|
if (hasModelError) { |
|
return { |
|
hasError: true, |
|
error: |
|
"Some required models are not available at the moment. Please try again later.", |
|
}; |
|
} |
|
|
|
|
|
const hasConfigError = logs.some( |
|
(log) => |
|
log.includes("Error generating configuration") || |
|
log.includes("Configuration failed") |
|
); |
|
|
|
if (hasConfigError) { |
|
return { |
|
hasError: true, |
|
error: |
|
"Failed to generate benchmark configuration. Please try again later.", |
|
}; |
|
} |
|
|
|
|
|
const hasInsufficientContentError = logs.some( |
|
(log) => |
|
log.includes( |
|
"No valid questions produced in single_shot_question_generation" |
|
) || log.includes("No parseable JSON found") |
|
); |
|
|
|
if (hasInsufficientContentError) { |
|
return { |
|
hasError: true, |
|
error: |
|
"The document does not contain enough information to generate a meaningful benchmark. Please try with a more detailed document.", |
|
}; |
|
} |
|
|
|
return { hasError: false }; |
|
}; |
|
|
|
const updateSteps = (logs) => { |
|
const newCompletedSteps = []; |
|
|
|
logs.forEach((log) => { |
|
const match = log.match(/\[SUCCESS\] Stage completed: (\w+)/); |
|
if (match && match[1]) { |
|
const completedStep = match[1].trim(); |
|
if ( |
|
BENCHMARK_STEPS.includes(completedStep) && |
|
!newCompletedSteps.includes(completedStep) |
|
) { |
|
newCompletedSteps.push(completedStep); |
|
} |
|
} |
|
}); |
|
|
|
let newActiveStep = activeStep; |
|
|
|
if (newCompletedSteps.length > 0) { |
|
const maxCompletedStepIndex = Math.max( |
|
...newCompletedSteps.map((step) => BENCHMARK_STEPS.indexOf(step)) |
|
); |
|
const calculatedStep = maxCompletedStepIndex + 1; |
|
|
|
if (calculatedStep > activeStep) { |
|
newActiveStep = calculatedStep; |
|
} |
|
|
|
if (newActiveStep >= BENCHMARK_STEPS.length) { |
|
newActiveStep = BENCHMARK_STEPS.length; |
|
} |
|
} else if (activeStep === 0) { |
|
newActiveStep = 1; |
|
} |
|
|
|
return { newCompletedSteps, newActiveStep }; |
|
}; |
|
|
|
const updatePhase = (logs) => { |
|
const recentLogs = logs.slice(-10); |
|
|
|
const isComplete = recentLogs.some((log) => |
|
log.includes("[SUCCESS] Benchmark process completed successfully") |
|
); |
|
|
|
if (isComplete) { |
|
return "complete"; |
|
} else if ( |
|
recentLogs.some((log) => log.includes("Starting ingestion process")) |
|
) { |
|
return "benchmarking"; |
|
} else if ( |
|
recentLogs.some((log) => log.includes("Generating base configuration")) |
|
) { |
|
return "configuring"; |
|
} |
|
|
|
return currentPhase; |
|
}; |
|
|
|
useEffect(() => { |
|
if (generationLogs.length === 0) return; |
|
|
|
const errorCheck = checkForErrors(generationLogs); |
|
if (errorCheck.hasError) { |
|
setError(errorCheck.error); |
|
setGenerationComplete(true); |
|
if (onComplete) { |
|
onComplete({ |
|
success: false, |
|
error: errorCheck.error, |
|
sessionId, |
|
}); |
|
} |
|
return; |
|
} |
|
|
|
const { newCompletedSteps, newActiveStep } = updateSteps(generationLogs); |
|
const newPhase = updatePhase(generationLogs); |
|
|
|
if (JSON.stringify(newCompletedSteps) !== JSON.stringify(completedSteps)) { |
|
setCompletedSteps(newCompletedSteps); |
|
} |
|
|
|
if (newActiveStep !== activeStep) { |
|
setActiveStep(newActiveStep); |
|
} |
|
|
|
if (newPhase !== currentPhase) { |
|
setCurrentPhase(newPhase); |
|
} |
|
|
|
|
|
const recentLogs = generationLogs.slice(-10); |
|
const isComplete = recentLogs.some((log) => |
|
log.includes("[SUCCESS] Benchmark process completed successfully") |
|
); |
|
|
|
if (isComplete) { |
|
setGenerationComplete(true); |
|
if (onComplete) { |
|
onComplete({ |
|
success: true, |
|
sessionId, |
|
logs: generationLogs, |
|
}); |
|
} |
|
} |
|
}, [generationLogs, sessionId, onComplete]); |
|
|
|
return { |
|
generationLogs, |
|
setGenerationLogs, |
|
error, |
|
setError, |
|
currentPhase, |
|
completedSteps, |
|
activeStep, |
|
generationComplete, |
|
setGenerationComplete, |
|
}; |
|
}; |
|
|