diff --git a/app/(main)/evaluations/page.tsx b/app/(main)/evaluations/page.tsx index 28d4c74..67ce459 100644 --- a/app/(main)/evaluations/page.tsx +++ b/app/(main)/evaluations/page.tsx @@ -63,6 +63,7 @@ function SimplifiedEvalContent() { ); const [isEvaluating, setIsEvaluating] = useState(false); const [runMode, setRunMode] = useState("batch"); + const [runDuplicationFactor, setRunDuplicationFactor] = useState(""); const [nameError, setNameError] = useState(""); const [submitError, setSubmitError] = useState(""); @@ -91,6 +92,15 @@ function SimplifiedEvalContent() { else setIsDatasetsLoading(false); }, [isAuthenticated, loadStoredDatasets]); + useEffect(() => { + const dataset = storedDatasets.find( + (d) => d.dataset_id.toString() === selectedDatasetId, + ); + if (dataset) { + setRunDuplicationFactor(String(dataset.duplication_factor)); + } + }, [selectedDatasetId, storedDatasets]); + const handleFileSelect = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (!file) return; @@ -221,10 +231,32 @@ function SimplifiedEvalContent() { return; } + const selectedRunDataset = storedDatasets.find( + (d) => d.dataset_id.toString() === selectedDatasetId, + ); + + const trimmedDuplicationFactor = runDuplicationFactor.trim(); + let duplicationFactorOverride: number | undefined; + if (trimmedDuplicationFactor) { + if (!/^[1-9]\d*$/.test(trimmedDuplicationFactor)) { + toast.error("Duplication factor must be a whole number of 1 or more"); + return; + } + const parsedDuplicationFactor = parseInt(trimmedDuplicationFactor, 10); + if ( + !selectedRunDataset || + parsedDuplicationFactor !== selectedRunDataset.duplication_factor + ) { + duplicationFactorOverride = parsedDuplicationFactor; + } + } + setIsEvaluating(true); try { // `run_mode` is only sent when "fast" — omitting it means the backend // defaults to batch, which is the safe behaviour for older clients too. + // Likewise, `duplication_factor` is only sent when the user overrides + // the dataset's stored value. const payload: Record = { dataset_id: parseInt(selectedDatasetId), experiment_name: experimentName.trim(), @@ -232,6 +264,9 @@ function SimplifiedEvalContent() { config_version: selectedConfigVersion, run_mode: runMode === "fast" ? "fast" : "batch", }; + if (duplicationFactorOverride !== undefined) { + payload.duplication_factor = duplicationFactorOverride; + } await apiFetch("/api/evaluations", apiKey, { method: "POST", @@ -244,6 +279,7 @@ function SimplifiedEvalContent() { setSelectedConfigId(""); setSelectedConfigVersion(0); setRunMode("batch"); + setRunDuplicationFactor(""); toast.success(`Evaluation created!`); return true; } catch (error: unknown) { @@ -351,6 +387,8 @@ function SimplifiedEvalContent() { setActiveTab={setActiveTab} runMode={runMode} setRunMode={setRunMode} + duplicationFactor={runDuplicationFactor} + setDuplicationFactor={setRunDuplicationFactor} nameError={nameError} submitError={submitError} /> diff --git a/app/components/evaluations/EvaluationsTab.tsx b/app/components/evaluations/EvaluationsTab.tsx index 418277c..4a3f2d1 100644 --- a/app/components/evaluations/EvaluationsTab.tsx +++ b/app/components/evaluations/EvaluationsTab.tsx @@ -30,6 +30,8 @@ export interface EvaluationsTabProps { setActiveTab: (tab: Tab) => void; runMode: RunMode; setRunMode: (mode: RunMode) => void; + duplicationFactor: string; + setDuplicationFactor: (value: string) => void; nameError?: string; submitError?: string; } @@ -50,6 +52,8 @@ export default function EvaluationsTab({ setActiveTab, runMode, setRunMode, + duplicationFactor, + setDuplicationFactor, nameError, submitError, }: EvaluationsTabProps) { @@ -160,6 +164,8 @@ export default function EvaluationsTab({ setActiveTab, runMode, setRunMode, + duplicationFactor, + setDuplicationFactor, nameError, submitError, }; diff --git a/app/components/evaluations/RunEvaluationForm.tsx b/app/components/evaluations/RunEvaluationForm.tsx index 2236378..0e2c2aa 100644 --- a/app/components/evaluations/RunEvaluationForm.tsx +++ b/app/components/evaluations/RunEvaluationForm.tsx @@ -30,6 +30,8 @@ interface RunEvaluationFormProps { setActiveTab: (tab: Tab) => void; runMode: RunMode; setRunMode: (mode: RunMode) => void; + duplicationFactor: string; + setDuplicationFactor: (value: string) => void; nameError?: string; submitError?: string; } @@ -50,6 +52,8 @@ export default function RunEvaluationForm({ setActiveTab, runMode, setRunMode, + duplicationFactor, + setDuplicationFactor, nameError, submitError, }: RunEvaluationFormProps) { @@ -140,6 +144,22 @@ export default function RunEvaluationForm({ )} + {selectedDataset && ( +
+ +

+ Overrides the dataset's stored duplication factor for this run + only. Defaults to {selectedDataset.duplication_factor}. +

+
+ )} +