feat(agent-ui): first-run onboarding wizard — hardware pre-flight, in-app model download, connect-on-install#2204
Conversation
… in-app model download, and connect-on-install First-run users had no guided path: models and connectors could only be set up from the CLI, and a failed hardware match or download surfaced late (or was swallowed). This adds an in-app wizard that scans hardware, downloads the recommended model with visible progress and retry, and offers to connect an app before first run. Backend: - Feed detected NPU / GPU VRAM into hub.compatibility.check_compatibility so a no-NPU machine gets a real warning instead of a blanket "cannot verify" (#1727); values default to None to preserve the conservative fallback. - New onboarding router: GET /api/onboarding/preflight (hardware scan + tier + recommended model, running the shared compatibility checker so blockers match the hub install path), plus /status and /complete over the existing ~/.gaia/chat/initialized marker the CLI and agent-loop already read. Frontend: - New components/onboarding/ wizard: welcome -> pre-flight -> model download -> optional connector -> done, driven by a pure, unit-tested state machine (useOnboarding). Model download reuses POST /api/system/download-model and its status-fed progress; the connector step reuses the existing authorize flow (no grant logic rebuilt). Every failure surfaces a loud, actionable state with retry -- no silent skip that leaves a half-set-up app. Tests: Vitest for the state machine + wizard flow; pytest for the pre-flight route and the detected-NPU/GPU compatibility wiring.
|
Verdict: Approve with suggestions — safe to merge after a look at the one maintainability point below. This adds a first-run onboarding wizard to the Agent UI: a hardware pre-flight that gates on real capability (RAM/disk/NPU/GPU), an in-app model download with progress + retry, and an optional connect-an-app step, all backed by three new The one thing worth a second look: the backend's Lemonade device probe (NPU/GPU/VRAM parsing) is a near-copy of logic that already lives in the system-status router. It's not a bug, but the two copies have already drifted slightly in how they treat a missing NPU, so they'll keep drifting unless one calls the other. Nothing here blocks merge. No security concerns. No breaking changes — the init marker stays compatible with the existing 🔍 Technical details🟡 Important (non-blocking)Duplicated Lemonade device probe — drift risk ( 🟢 Minor / nitsFirst download poll is delayed ~2s ( New user-facing feature likely wants a doc line — the wizard and the Strengths
|
|
The first-run golden path can dead-end frozen: Fix: start the interval from the mount effect whenever the initial poll reports an active download (and clear it on unmount, as |
… freeze mid-download Starting the multi-GB model download and then remounting the onboarding wizard — a page refresh (the wizard re-shows until the init marker is written) or Back/return navigation — left the progress bar frozen: the mount effect polled exactly once, saw an in-flight download, rendered the bar, and never polled again. Continue never enabled and the first-run golden path dead-ended. The mount effect now resumes the same polling loop when the initial status reports an active download (downloading/starting). Both entry points share a guarded beginPolling() helper so a remount can't stack two intervals, and the loop still stops on unmount and on terminal states.
kovtcharov
left a comment
There was a problem hiding this comment.
The frozen-download flaw is fixed: polling is now extracted into beginPolling(), and the mount effect restarts it whenever the initial status reports an active download (downloading/starting) — so a remount mid-download resumes instead of freezing. Backed by a new 127-line ModelDownloadStep.test.tsx covering the remount-resume path. Verified on the PR branch.
Why this matters
Before: a first-time user had no guided path — models and connectors could only be set up from the terminal (
gaia init), a machine that couldn't meet an agent's requirements only found out at runtime, and a failed model download was swallowed silently. After: opening the Agent UI on a fresh machine launches an in-app wizard that scans the hardware and gates on real capability (RAM/disk/NPU/GPU), downloads the recommended model with visible progress and retry, and offers to connect an app (e.g. Google for Email triage) before first run. A non-technical user reaches a working chat without touching a terminal.Bundles the two first-run issues since they share one flow: #1726 (onboarding wizard + in-app model download) and #1727 (hardware pre-flight gating + connector-on-install).
Every failure state is loud and actionable — a hardware blocker disables Continue and names the shortfall, a failed download shows the backend's message with a Retry, and a missing OAuth credential shows exactly which env vars to set. Nothing silently skips to leave a half-set-up app.
What's in it
hub.compatibility.check_compatibility, so a no-NPU machine gets a real warning instead of a blanket "cannot verify" (values default toNoneto preserve the conservative fallback). NewGET /api/onboarding/preflightruns the same shared checker the hub install path uses, so blockers match./api/onboarding/status+/completeover the existing~/.gaia/chat/initializedmarker the CLI and agent-loop already read — UI and CLI stay in lock-step, and completing once suppresses the wizard for good.POST /api/system/download-modeland its status-fed SSE progress — no new download backend. Visible progress bar + Retry on failure.authorize/getConnectorinterface.components/onboarding/(welcome → pre-flight → download → optional connector → done), driven by a pure, unit-testeduseOnboardingstate machine. Isolated to new files; App.tsx edits are minimal (mount + first-run check).Test plan
python -m pytest tests/unit/test_onboarding_router.py tests/unit/test_hub_compatibility.py(36 passed): pre-flight tiers/blockers/warnings, NPU present/absent/unknown, GPU VRAM below/meets requirement, status/complete marker round-trip.npm run testinsrc/gaia/apps/webui(195 passed, incl. 13 new):useOnboardingstate machine (advance/back/guard/skip/goTo) + wizard flow (welcome skip, scan, blocker gating, advance).npm run build(tsc + vite) clean.~/.gaia): welcome → hardware check (Tier: Full, RAM/disk/NPU all green, Continue enabled) → model download (Continue correctly gated until the model is ready; explicit "Set up later" escape) → Google connector (optional; loud "OAuth credentials not configured" with the exact env vars) → "You're all set". Screenshots captured for each step.To verify locally:
Part of #2014
Closes #1726
Closes #1727