diff --git a/ui/src/api/hardware.ts b/ui/src/api/hardware.ts index 4b1fab09..9049b801 100644 --- a/ui/src/api/hardware.ts +++ b/ui/src/api/hardware.ts @@ -3,6 +3,12 @@ import { api } from "./client"; export type HardwareTier = "gpu" | "apple_silicon" | "cpu_only"; +export interface VoiceCapability { + whisperAvailable: boolean; + piperAvailable: boolean; + voiceTierSufficient: boolean; +} + export interface HardwareInfo { totalGb: number; freeGb: number; @@ -13,6 +19,7 @@ export interface HardwareInfo { unifiedMemory: boolean; hardwareTier: HardwareTier; cpuModel: string | null; + voiceCapability?: VoiceCapability; } export type NexusMode = "personal_ai" | "project_builder" | "both"; diff --git a/ui/src/components/NexusOnboardingWizard.tsx b/ui/src/components/NexusOnboardingWizard.tsx index 5e61199a..8738514f 100644 --- a/ui/src/components/NexusOnboardingWizard.tsx +++ b/ui/src/components/NexusOnboardingWizard.tsx @@ -430,6 +430,7 @@ export function OnboardingWizard() { setStep(5); }} onSkip={() => setStep(5)} + voiceCapability={hardwareInfo?.voiceCapability} /> + + + ); + } + + // Sufficient hardware or unknown — show full UI + const neitherBinaryFound = + voiceCapability && + !voiceCapability.whisperAvailable && + !voiceCapability.piperAvailable; + return (
+ {/* Install note when tier is sufficient but binaries are missing */} + {neitherBinaryFound && ( +
+ +

+ Install whisper-cpp and piper for local voice features. You can enable voice now and configure binaries later. +

+
+ )} +
-
+

Speech-to-Text (Whisper)

- {micAvailable === false - ? "No microphone detected — unavailable" - : micAvailable === true - ? "Microphone detected — speak to your assistant" - : "Checking microphone..."} + {whisperStatusLabel()}

+ {whisperStatusIcon()}
-
+

Text-to-Speech (Piper)

- Hear responses read aloud. Runs entirely on your device — no server needed. + {piperStatusLabel()}

+ {piperStatusIcon()}
-