Skip to content

fix(web): validate the onboarding runtime before Continue is pressed - #7440

Open
open-design-crew[bot] wants to merge 2 commits into
mainfrom
fix/onboarding-continue-runtime-validation
Open

fix(web): validate the onboarding runtime before Continue is pressed#7440
open-design-crew[bot] wants to merge 2 commits into
mainfrom
fix/onboarding-continue-runtime-validation

Conversation

@open-design-crew

@open-design-crew open-design-crew Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Why

A user reported that after picking a local agent in onboarding, pressing Continue takes a long time to reach the next screen — "it used to go through instantly." I picked the report up, reproduced it, and traced it to a regression window.

#7164 moved the runtime connectivity check into the Continue click handler (handlePrimaryAction). That check is not a lightweight probe — it spawns the agent CLI as a child process, sends a smoke prompt, and waits for a real model reply. Measured against a local daemon (/api/test/connection):

agent per check
Claude Code (--model haiku) 5.5–6.2 s
Claude Code (default model) 7.1 s
Codex CLI (default model) 12.1 s
DEFAULT_AGENT_TIMEOUT_MS budget 45 s

So every user on the local-agent path stares at a greyed-out button still labelled "Continue" for several seconds after clicking it, which reads as the click having done nothing. Before #7164 that click was instant, because the validation came from the separate Test button next to it — which is exactly the "used to go through instantly" the report describes.

#7164's intent is right: nobody should finish onboarding carrying a runtime that cannot actually run. This PR keeps that guarantee and only moves the check off the click's critical path.

What users will see

  • On the Local Agent setup step, the selected agent now starts validating on its own. The panel shows "Testing connection…" and then the verdict (e.g. "Claude Code replied in 7119 ms — 'ok'"). You no longer have to press Test first to find out whether an agent works.
  • Continue usually advances immediately, because the answer is already in hand.
  • If you do press Continue before the check has finished, the button turns into a spinner with "Testing connection…" instead of just greying out with no explanation.
  • BYOK benefits the same way: pressing Continue during its existing auto-validation is no longer silently dropped.
  • Switching agent or model cancels the check still running for the previous selection, and the daemon reaps the agent child along with the aborted request, so nothing piles up.

Surface area

  • UI — validation status and Continue busy state on the onboarding Local Agent / BYOK setup step
  • Keyboard shortcut
  • CLI / env var
  • API / contract
  • Extension point
  • i18n keys — no new keys; the busy label reuses the existing settings.testRunning
  • New top-level dependency
  • Default behavior change — opening the local-agent setup step now issues one connectivity check on its own; previously a check only fired on Test or Continue
  • None

Screenshots

The change is mostly about timing and button state, which a still frame does not capture well. Reproducible comparison:

  1. Start onboarding against a clean data directory and reach the Local Agent setup step.
  2. Before: the panel shows no validation state at all; press Continue → the button greys out, still reading "Continue" → 7–12 s pass before the next screen.
  3. After: about 0.5 s after the step opens the panel shows "Testing connection…", then the agent's success line; pressing Continue advances immediately.

The panel's visual archive is covered by visual-onboarding-local-agent-panel in e2e/ui/visual-entry.test.ts; this PR adds a wait there so the capture lands on the settled state instead of racing the transient "testing" copy.

Bug fix verification

  • Red spec path: apps/web/tests/components/EntryShell.onboarding.test.tsx
    • validates the selected Local Agent in the background so Continue does not wait on a spawn
    • lets Continue join the in-flight Local Agent validation instead of dropping the click
  • Against main (d88941ba0, which already includes the just-merged fix(web): allow signed-out Local CLI and BYOK onboarding #7381): red — both stop at expect(testCalls).toBe(1) receiving 0, i.e. nothing validates before the click. The other 43 cases in the same file stay green, so the failure is precise. On this branch all 45 pass.
  • Also measured before/after in a real browser (one-off local harness, not committed): with a 7 s stand-in for the agent spawn, click-to-onboarding-finished went from 9086 ms on main to 3083 ms on this branch. The 3083 ms floor is the harness's own navigation work and is identical in both runs, so roughly 6 s of dead wait is gone.

Validation

  • pnpm guard
  • pnpm typecheck (whole repo) ✅
  • pnpm --filter @open-design/web typecheck
  • apps/web onboarding unit tests: 45 passed ✅ (after confirming the two new cases go red on the main baseline)
  • apps/web component suite (tests/components, 387 files / 4166 tests) ✅ — run before rebasing onto fix(web): allow signed-out Local CLI and BYOK onboarding #7381
  • Playwright e2e/ui/amr-onboarding.test.ts: 33 passed ✅
  • Playwright e2e/ui/visual-entry.test.ts local-agent capture ✅
  • Separately confirmed on the daemon side that aborting an /api/test/connection request reaps the spawned agent child — startOrJoinInlineTest's cancellation path depends on it
  • Full web / daemon suites left to CI

Adjacent issue (fixed here because it is a direct consequence of this change)

BYOK had the identical dead-button window: Continue was held disabled while its auto-validation ran. Removing connectStepTestRunning from disabled would have turned that from "greyed out" into "click silently dropped", so both paths now share the same join-the-in-flight-validation logic.

Continue on the Local Agent step ran the runtime smoke test inside the click
handler, so every user paid a full agent spawn plus a real model round trip
between pressing it and reaching the next screen: 7.1s for Claude Code and
12.1s for Codex CLI measured against a local daemon, against a 45s budget.
The button was only greyed out through that wait and still read "Continue",
so it looked like the click had done nothing. Before #7164 the click itself
was instant, because the validation came from the separate Test button.

Start the validation as soon as the selection settles instead, the way BYOK
already validates a settled provider, so it overlaps with the time the user
spends reading the panel and picking a model. Continue then takes the
already-validated result with no round trip at all. #7164's guarantee is
unchanged: onboarding still cannot complete on an unproven runtime.

`startOrJoinInlineTest` keeps that to one round trip per selection. A click
landing mid-flight joins the pass already validating those inputs rather than
being swallowed or spawning the agent a second time, and an attempt whose
inputs the user has moved past is aborted — the daemon kills the agent child
along with the request. A background pass no longer disables Continue; only a
click that is itself waiting marks the button busy, with a spinner and
"Testing connection…" in place of the label.

Internal report: OPEND-2281.
@lefarcen
lefarcen requested a review from nettee August 26, 2026 09:59
@lefarcen lefarcen added size/L PR changes 300-700 lines risk/medium Medium risk: regular code changes type/bugfix Bug fix needs-validation Runtime change detected; needs human or /explore agent validation. labels Aug 26, 2026
@lefarcen

Copy link
Copy Markdown
Contributor

🧪 This PR has changes that need a manual QA pass before merge — please hold off self-merging for now; we'll loop QA in once it's merge-ready.

The surrounding sentences already carry the reason the validation has to be
under way before Continue is pressed, so the id added nothing a reader of
this tree could act on.
@github-actions

Copy link
Copy Markdown
Contributor

Visual regression review

Head: 652afec · Base: c7d0dcc

2 changed · 51 unchanged · 0 new without baseline · 0 failed

Changed cases

Case Main PR Diff
visual-onboarding-local-agent
7,862 px (0.61%)
main pr diff
visual-onboarding-local-agent-panel
45,291 px (17.67%)
main pr diff
Unchanged cases
Case Main PR Diff
visual-avatar-local-agent-list
0 px (0.00%)
main pr diff
visual-avatar-local-agent-list-panel
0 px (0.00%)
main pr diff
visual-avatar-menu
0 px (0.00%)
main pr diff
visual-avatar-menu-panel
0 px (0.00%)
main pr diff
visual-avatar-open-design-model-picker
0 px (0.00%)
main pr diff
visual-critical-settings
0 px (0.00%)
main pr diff
visual-critical-workspace
0 px (0.00%)
main pr diff
visual-critical-workspace-preview
0 px (0.00%)
main pr diff
visual-deepseek-unpaid-campaign-600
0 px (0.00%)
main pr diff
visual-deepseek-unpaid-campaign-short-height
0 px (0.00%)
main pr diff
visual-design-system-detail
0 px (0.00%)
main pr diff
visual-design-systems
0 px (0.00%)
main pr diff
visual-home
0 px (0.00%)
main pr diff
visual-home-catalog
0 px (0.00%)
main pr diff
visual-home-context-picker
0 px (0.00%)
main pr diff
visual-home-context-picker-popover
0 px (0.00%)
main pr diff
visual-home-plugin-filter
0 px (0.00%)
main pr diff
visual-home-plugin-use-staged
0 px (0.00%)
main pr diff
visual-home-plugin-use-with-query
0 px (0.00%)
main pr diff
visual-home-staged-attachment
0 px (0.00%)
main pr diff

Visual diff is advisory only and does not block merging.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found two non-blocking lifecycle issues in the new onboarding validation flow; both are detailed inline below. The background Local Agent validation and Continue join behavior are otherwise covered by the passing unit and Playwright checks.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

const providerModelsAutoFetchKeyRef = useRef<string | null>(null);
const providerAutoTestKeyRef = useRef<string | null>(null);
const agentAutoTestKeyRef = useRef<string | null>(null);
const agentTestRunRef = useRef<OnboardingInlineTestRun | null>(null);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These new run refs are only aborted when a different input starts another run. The existing unmount cleanup (the useEffect around lines 2331–2339) and handleBackWithTracking only clear reveal timers/state, so leaving this setup step—Back, switching Local to BYOK, navigating away, or closing onboarding—leaves the automatic /api/test/connection request alive. For a local agent this can keep a spawned CLI running until the daemon timeout, and repeated abandoned visits can consume model calls and processes. Please add a shared cleanup that aborts both refs when the component unmounts and when setup/runtime is left, then cover Back/unmount with a hung-request test.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

const model = config.model;
const apiVersion =
protocol === 'azure' ? config.apiVersion?.trim() || undefined : undefined;
return startOrJoinInlineTest(providerTestRunRef, inputKey, async (signal) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

startOrJoinInlineTest now accepts a signal, but BYOK's auto-validation effect still returns while providerTestState.status is running (the effect at lines 3443–3458). If the user edits the key, base URL, or model during an in-flight request, providerTestInputKey changes and the effect exits without scheduling the new input; no new test begins until the old request resolves or times out, unless the user clicks Test or Continue. That leaves the selected configuration unvalidated and defeats the intended cancellation path. Remove that running-state early return, or otherwise schedule through this helper, so the changed-input run aborts the old request and starts immediately; add a regression test for editing while auto-validation is held.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-validation Runtime change detected; needs human or /explore agent validation. risk/medium Medium risk: regular code changes size/L PR changes 300-700 lines type/bugfix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants