diff --git a/apps/web/src/app/api/vision-training/config.ts b/apps/web/src/app/api/vision-training/config.ts index 76ea4003..9a0b6dca 100644 --- a/apps/web/src/app/api/vision-training/config.ts +++ b/apps/web/src/app/api/vision-training/config.ts @@ -117,14 +117,8 @@ async function createVenv(): Promise { console.log(`[vision-training] Creating venv with ${basePython}...`) try { - // Remove incomplete venv if it exists - if (fs.existsSync(VENV_DIR)) { - console.log('[vision-training] Removing incomplete venv...') - fs.rmSync(VENV_DIR, { recursive: true, force: true }) - } - - // Create venv - await execAsync(`"${basePython}" -m venv "${VENV_DIR}"`, { timeout: 60000 }) + // Create venv (--clear removes existing incomplete venv) + await execAsync(`"${basePython}" -m venv --clear "${VENV_DIR}"`, { timeout: 60000 }) // Upgrade pip await execAsync(`"${TRAINING_PYTHON}" -m pip install --upgrade pip`, { diff --git a/apps/web/src/app/vision-training/train/page.tsx b/apps/web/src/app/vision-training/train/page.tsx index 2326910a..7626cead 100644 --- a/apps/web/src/app/vision-training/train/page.tsx +++ b/apps/web/src/app/vision-training/train/page.tsx @@ -74,28 +74,32 @@ export default function TrainModelPage() { const eventSourceRef = useRef(null) const logsEndRef = useRef(null) + // Fetch hardware info (also used for retry) + const fetchHardware = useCallback(async () => { + setHardwareLoading(true) + setHardwareInfo(null) + try { + const response = await fetch('/api/vision-training/hardware') + const data = await response.json() + setHardwareInfo(data) + } catch { + setHardwareInfo({ + available: false, + device: 'unknown', + deviceName: 'Failed to detect', + deviceType: 'unknown', + details: {}, + error: 'Failed to fetch hardware info', + }) + } finally { + setHardwareLoading(false) + } + }, []) + // Fetch hardware info on mount useEffect(() => { - async function fetchHardware() { - try { - const response = await fetch('/api/vision-training/hardware') - const data = await response.json() - setHardwareInfo(data) - } catch { - setHardwareInfo({ - available: false, - device: 'unknown', - deviceName: 'Failed to detect', - deviceType: 'unknown', - details: {}, - error: 'Failed to fetch hardware info', - }) - } finally { - setHardwareLoading(false) - } - } fetchHardware() - }, []) + }, [fetchHardware]) // Auto-scroll logs useEffect(() => { @@ -507,13 +511,36 @@ export default function TrainModelPage() { {/* Error details */} {hardwareInfo?.error && ( -
- {hardwareInfo.error} +
+

+ {hardwareInfo.error} +

{hardwareInfo.hint && ( - +

Hint: {hardwareInfo.hint} - +

)} +
)} @@ -536,6 +563,7 @@ export default function TrainModelPage() { )}