Unify onboarding provider selection

Replace the separate Cloud/Local illustrated path screen with a single provider step that switches between Cloud, Account, and Local choices.

Route the first-send gate account choice through onboarding, remove the old Cloud/Local card assets, and keep model setup in the existing onboarding flow.

Update static onboarding and welcome composer regressions for the merged provider step.
This commit is contained in:
Alessandro 2026-07-02 15:23:32 +02:00
parent b75b0f2c5c
commit 8d887e6f6d
8 changed files with 208 additions and 333 deletions

View file

@ -5,25 +5,56 @@ import yaml
PROJECT_ROOT = Path(__file__).resolve().parents[1]
def test_onboarding_contains_guided_cloud_local_flow():
def test_onboarding_contains_unified_provider_step():
html = (PROJECT_ROOT / "plugins/_onboarding/webui/onboarding.html").read_text(encoding="utf-8")
store = (PROJECT_ROOT / "plugins/_onboarding/webui/onboarding-store.js").read_text(encoding="utf-8")
gate_store = (PROJECT_ROOT / "webui/components/chat/model-gate-store.js").read_text(encoding="utf-8")
assert "Cloud" in html
assert "Local" in html
assert "Welcome to Agent Zero" in html
assert "Choose how to use AI models in Agent Zero" in html + store
assert "Choose your cloud AI provider" in html + store
assert "Choose your local LLM provider" in html + store
assert "cloud-card.webp" in html
assert "local-card.webp" in html
assert "Choose your AI provider" in store
# The illustrated Cloud/Local path screen is gone: one merged provider step.
assert "Choose how to use AI models in Agent Zero" not in html + store
assert "path-card" not in html
assert "cloud-card.webp" not in html
assert "local-card.webp" not in html
assert not (PROJECT_ROOT / "plugins/_onboarding/webui/assets/cloud-card.webp").exists()
assert not (PROJECT_ROOT / "plugins/_onboarding/webui/assets/local-card.webp").exists()
assert "choosePath" not in html + store + gate_store
assert "isStep('connect')" in html
assert "isStep('path')" not in html
assert "isStep('cloud')" not in html
assert "isStep('local')" not in html
# Cloud/Account/Local segmented switch on the merged step.
assert "mode-switch" in html
assert "setProviderMode('cloud')" in html
assert "setProviderMode('account')" in html
assert "setProviderMode('local')" in html
assert "providerMode === 'cloud'" in html
assert "providerMode === 'account'" in html
assert "providerMode === 'local'" in html
assert html.index("setProviderMode('cloud')") < html.index("setProviderMode('account')") < html.index("setProviderMode('local')")
assert '{ step: "connect", label: "Choose provider" }' in store
# Cloud pane lists every provider directly and only mentions API keys;
# accounts live in their own pane.
assert "Connect with an API key" in html
assert "cloudProviders()" in html
assert "Click here if you don't see your provider" not in html
assert "moreCloudOpen" not in html + store
assert "API key or account connection" not in html
# The chat model gate presets the mode before the modal opens (no flash).
assert "presetMode" in store
assert "onboardingStore.presetMode = this.choice;" in gate_store
assert "applyOnboardingChoice" not in gate_store
assert "oauthProviderCards()" in html + store
assert "selectOAuthProvider(provider.provider_id)" in html
assert "path-oauth-account-section" in html
assert "or connect your AI account" in html
assert "Connect one or more account-backed providers." not in html
assert ".path-oauth-account-section .oauth-account-section-head" in html
assert "font-weight: 760;" in html
assert "Connect ChatGPT/Codex Account" not in html
assert "Main model" in html
assert "Refresh model list" in html
@ -37,10 +68,7 @@ def test_onboarding_contains_guided_cloud_local_flow():
assert "submitOAuthManualCallback" in html + store
assert 'const OAUTH_START_API = "/plugins/_oauth/start_login";' in store
assert "/plugins/_oauth/start_device_login" not in store
assert "Click here if you don't see your provider" in html
assert "provider-description" not in html
assert "!$store.onboarding.isStep('cloud')" in html
assert "!$store.onboarding.isStep('local')" in html
assert "main-model-field" in html
assert "wide-inline-field" in html
assert "utility-panel" in html

View file

@ -123,13 +123,16 @@ def test_welcome_composer_can_create_a_chat_before_sending() -> None:
assert "const currentContext = globalThis.getContext?.();" in gate_store
assert "bypassModelGate: true" in gate_store
assert 'openPluginConfig("_model_config", "Advanced model configuration")' in gate_store
assert 'openPluginConfig("_oauth", "OAuth Connections")' in gate_store
assert 'openPluginConfig("_oauth"' not in gate_store
assert "Your message sends automatically once a model is connected." in gate_component
assert "openOnboarding('cloud')" in gate_component
assert "openOnboarding('account')" in gate_component
assert "openOnboarding('local')" in gate_component
assert "openOauthConfiguration()" in gate_component
assert gate_component.index("openOnboarding('cloud')") < gate_component.index("openOnboarding('account')") < gate_component.index("openOnboarding('local')")
assert "openOauthConfiguration" not in gate_component
assert "Show accounts" not in gate_component
assert "model-gate-accounts" not in gate_component
assert "Choose models" in gate_component
assert "Connected account:" in gate_component
assert "Advanced model configuration" in gate_component
assert "Advanced settings" not in gate_component
assert "model-gate-fields" not in gate_component