fix: ask provider in quick start

Maintainer edit: replace Quick Start key/base detection with an explicit provider-first flow. Users choose the provider that issued the API key, paste the key, and only custom OpenAI-compatible setups ask for a base URL.
This commit is contained in:
chengyongru
2026-06-22 13:04:05 +08:00
committed by Xubin Ren
parent 2319b660e6
commit 71631f9ab0
3 changed files with 89 additions and 80 deletions
+32 -19
View File
@@ -866,7 +866,7 @@ class TestMainMenuUpdate:
dirty_choices = _get_main_menu_choices(True)
assert clean_choices == [
"[Q] Quick Start (API key first)",
"[Q] Quick Start (provider + key)",
"[A] Advanced Settings",
"[X] Exit",
]
@@ -880,7 +880,7 @@ class TestMainMenuUpdate:
initial_config = Config()
responses = iter([
"[Q] Quick Start (API key first)",
"[Q] Quick Start (provider + key)",
])
class FakePrompt:
@@ -906,13 +906,12 @@ class TestMainMenuUpdate:
assert result.should_save is True
assert result.config.agents.defaults.bot_name == "quickbot"
def test_quick_start_base_url_fallback_skips_advanced_prompts(self, monkeypatch):
"""The beginner path should ask for a base URL only when the key is not recognized."""
def test_quick_start_provider_choice_skips_advanced_prompts(self, monkeypatch):
"""The beginner path should ask for provider and API key without advanced settings."""
config = Config()
text_answers = iter(["sk-ds-test", "https://api.deepseek.com"])
def fail_model_input(*_args, **_kwargs):
raise AssertionError("Quick Start should not ask for a model ID when defaults are known")
raise AssertionError("Quick Start should not ask for a model ID when /models works")
def fail_websocket_config(*_args, **_kwargs):
raise AssertionError("Quick Start should not open WebSocket settings")
@@ -921,7 +920,9 @@ class TestMainMenuUpdate:
monkeypatch.setattr(onboard_wizard.console, "clear", lambda: None)
monkeypatch.setattr(onboard_wizard, "_show_section_header", lambda *a, **kw: None)
monkeypatch.setattr(onboard_wizard, "_input_text", lambda *a, **kw: next(text_answers))
monkeypatch.setattr(onboard_wizard, "_select_with_back", lambda *a, **kw: "DeepSeek")
monkeypatch.setattr(onboard_wizard, "_input_text", lambda *a, **kw: "sk-ds-test")
monkeypatch.setattr(onboard_wizard, "_fetch_first_quick_start_model", lambda *a, **kw: "deepseek-v4-flash")
monkeypatch.setattr(onboard_wizard, "_input_model_with_autocomplete", fail_model_input)
monkeypatch.setattr(onboard_wizard, "_configure_pydantic_model", fail_websocket_config)
monkeypatch.setattr(onboard_wizard, "_print_summary_panel", lambda *a, **kw: None)
@@ -934,27 +935,33 @@ class TestMainMenuUpdate:
assert config.providers.deepseek.api_base == "https://api.deepseek.com"
assert config.agents.defaults.model_preset == "primary"
assert config.model_presets["primary"].provider == "deepseek"
assert config.model_presets["primary"].model == onboard_wizard._QUICK_START_DEFAULT_MODELS["deepseek"]
assert config.model_presets["primary"].model == "deepseek-v4-flash"
websocket = getattr(config.channels, "websocket")
assert websocket["enabled"] is True
assert websocket["websocketRequiresToken"] is True
def test_quick_start_detects_provider_from_key_prefix(self, monkeypatch):
"""Unique key prefixes should identify the provider without asking for base URL."""
def test_quick_start_provider_choice_fetches_models_from_selected_provider(self, monkeypatch):
"""Known providers should fetch models only from the selected provider base URL."""
config = Config()
prompts: list[str] = []
def fake_input_text(prompt, *_args, **_kwargs):
prompts.append(prompt)
return "sk-or-test"
calls: dict[str, str] = {}
monkeypatch.setattr(onboard_wizard, "_show_quick_start_progress", lambda *_args: None)
monkeypatch.setattr(onboard_wizard, "_input_text", fake_input_text)
monkeypatch.setattr(onboard_wizard, "_fetch_first_quick_start_model", lambda *a, **kw: "openai/gpt-4o-mini")
monkeypatch.setattr(onboard_wizard, "_select_with_back", lambda *a, **kw: "OpenRouter")
monkeypatch.setattr(onboard_wizard, "_input_text", lambda *a, **kw: "sk-or-test")
def fake_fetch(api_base, api_key):
calls["api_base"] = api_base
calls["api_key"] = api_key
return "openai/gpt-4o-mini"
monkeypatch.setattr(onboard_wizard, "_fetch_first_quick_start_model", fake_fetch)
assert onboard_wizard._configure_quick_start_provider(config) is True
assert prompts == ["API key"]
assert calls == {
"api_base": "https://openrouter.ai/api/v1",
"api_key": "sk-or-test",
}
assert config.providers.openrouter.api_key == "sk-or-test"
assert config.providers.openrouter.api_base == "https://openrouter.ai/api/v1"
assert config.model_presets["primary"].provider == "openrouter"
@@ -972,6 +979,11 @@ class TestMainMenuUpdate:
return "custom-model"
monkeypatch.setattr(onboard_wizard, "_show_quick_start_progress", lambda *_args: None)
monkeypatch.setattr(
onboard_wizard,
"_select_with_back",
lambda *a, **kw: onboard_wizard._QUICK_START_CUSTOM_PROVIDER_CHOICE,
)
monkeypatch.setattr(onboard_wizard, "_input_text", lambda *a, **kw: next(text_answers))
monkeypatch.setattr(onboard_wizard, "_fetch_first_quick_start_model", fake_fetch)
@@ -988,6 +1000,7 @@ class TestMainMenuUpdate:
config = Config()
monkeypatch.setattr(onboard_wizard, "_show_quick_start_progress", lambda *_args: None)
monkeypatch.setattr(onboard_wizard, "_select_with_back", lambda *a, **kw: "DeepSeek")
monkeypatch.setattr(onboard_wizard, "_input_text", lambda *a, **kw: "")
assert onboard_wizard._configure_quick_start_provider(config) is False
@@ -1002,7 +1015,7 @@ class TestMainMenuUpdate:
"""Quick Start summary should not tell users to run gateway before adding a key."""
config = Config()
config.model_presets["primary"] = ModelPresetConfig(
model=onboard_wizard._QUICK_START_DEFAULT_MODELS["deepseek"],
model="deepseek-v4-flash",
provider="deepseek",
)