// Decides whether the photo-first flow can promise AI analysis. // When it cannot, logging must still reach manual Bristol entry in one action. const MANUAL_LABEL = 'Continue without AI'; const DISABLED_LABEL = 'Log it manually'; export function visionReadiness(status) { if (!status) { return { phase: 'checking', ready: false, manualOnly: true, manualLabel: MANUAL_LABEL, message: 'Checking the vision worker. Manual logging is already available.', }; } if (status.enabled === false) { return { phase: 'disabled', ready: false, manualOnly: true, manualLabel: DISABLED_LABEL, message: 'AI photo analysis is off in this build. Manual logging is fully available.', }; } if (status.providerReady !== true) { return { phase: 'offline', ready: false, manualOnly: true, manualLabel: MANUAL_LABEL, message: 'Vision worker offline. Manual logging is still available.', }; } // A worker that answers /v1/models has not necessarily loaded the model yet (#15), so readiness // passes only once the pinned model is confirmed loaded. An unconfirmed model fails closed to the // manual path instead of offering an AI control that fails after the upload. if (status.modelSeen !== true) { return { phase: 'loading', ready: false, manualOnly: true, manualLabel: MANUAL_LABEL, message: 'The vision worker is up but the model is not loaded yet. Manual logging is available.', }; } return { phase: 'ready', ready: true, manualOnly: false, manualLabel: '', message: '' }; }