From ed3a8f64d85733f40c9e3c7589b9f2f9ddeb6b57 Mon Sep 17 00:00:00 2001 From: chengyongru <2755839590@qq.com> Date: Sun, 21 Jun 2026 00:26:09 +0800 Subject: [PATCH] fix: use deepseek for quick start onboarding Maintainer edit: restart the Quick Start default around a mainland-friendly provider instead of making OpenRouter the first-run dependency. Update wizard copy, default preset, focused tests, and beginner docs to use DeepSeek with the current deepseek-v4-flash model. --- README.md | 10 ++++---- docs/quick-start.md | 18 +++++++------- docs/start-without-technical-background.md | 28 +++++++++++----------- nanobot/cli/onboard.py | 10 ++++---- tests/agent/test_onboard_logic.py | 16 ++++++------- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 84498e04..bf03acfd 100644 --- a/README.md +++ b/README.md @@ -304,15 +304,15 @@ Skip this step if you already configured provider and model settings in the wiza `nanobot onboard --defaults` creates `~/.nanobot/config.json` and `~/.nanobot/workspace/`. Configure these **two parts** in the config file. Add or merge the following blocks into the existing file instead of replacing the whole file. -The example below uses [OpenRouter](https://openrouter.ai/keys) only so the JSON has concrete names. Provider examples are recipes, not rankings or endorsements. If you use another provider, replace the provider config key, API key, preset provider name, and model ID together. +The example below uses [DeepSeek](https://platform.deepseek.com/api_keys) only so the JSON has concrete names and the compact path does not depend on OpenRouter. Provider examples are recipes, not rankings or endorsements. If you use another provider, replace the provider config key, API key, preset provider name, and model ID together. *Set your API key*: ```json { "providers": { - "openrouter": { - "apiKey": "sk-or-v1-xxx" + "deepseek": { + "apiKey": "your-deepseek-api-key" } } } @@ -325,8 +325,8 @@ The example below uses [OpenRouter](https://openrouter.ai/keys) only so the JSON "modelPresets": { "primary": { "label": "Primary", - "provider": "openrouter", - "model": "anthropic/claude-opus-4.5", + "provider": "deepseek", + "model": "deepseek-v4-flash", "maxTokens": 8192, "contextWindowTokens": 65536, "temperature": 0.1 diff --git a/docs/quick-start.md b/docs/quick-start.md index 2c216c38..860a9969 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -9,7 +9,7 @@ If you have never used a terminal or edited a config file before, use [`start-wi You need: - Python 3.11 or newer. -- One LLM provider, company endpoint, subscription endpoint, or local model server you can call. The examples below use OpenRouter only so the snippets are concrete; any supported provider works when the key, provider name, and model ID match. +- One LLM provider, company endpoint, subscription endpoint, or local model server you can call. The examples below use DeepSeek only so the snippets are concrete and the compact path does not depend on OpenRouter; any supported provider works when the key, provider name, and model ID match. - Git only if you install from source. - Node.js or Bun only if you are developing the WebUI itself. @@ -128,8 +128,8 @@ Open `~/.nanobot/config.json`. Add or merge these blocks into the file created b ```json { "providers": { - "openrouter": { - "apiKey": "sk-or-v1-xxx" + "deepseek": { + "apiKey": "your-deepseek-api-key" } } } @@ -142,8 +142,8 @@ Open `~/.nanobot/config.json`. Add or merge these blocks into the file created b "modelPresets": { "primary": { "label": "Primary", - "provider": "openrouter", - "model": "anthropic/claude-opus-4.5", + "provider": "deepseek", + "model": "deepseek-v4-flash", "maxTokens": 8192, "contextWindowTokens": 65536, "temperature": 0.1 @@ -161,7 +161,7 @@ The provider and model inside a preset must match. The snippet above is only an | Replace | Where | |---|---| -| Provider config key, such as `openrouter` | `providers.` | +| Provider config key, such as `deepseek` | `providers.` | | API key or environment variable | `providers..apiKey` | | Preset provider name | `modelPresets.primary.provider` | | Model ID | `modelPresets.primary.model` | @@ -207,8 +207,8 @@ If you prefer not to store secrets in `config.json`, reference an environment va ```json { "providers": { - "openrouter": { - "apiKey": "${OPENROUTER_API_KEY}" + "deepseek": { + "apiKey": "${DEEPSEEK_API_KEY}" } } } @@ -260,7 +260,7 @@ Example prompt: ```text Read docs/quick-start.md, docs/providers.md, and docs/configuration.md in this checkout. -Then update ~/.nanobot/config.json to add an OpenRouter model preset named "primary". +Then update ~/.nanobot/config.json to add a DeepSeek model preset named "primary". Tell me exactly what changed and whether I need to run /restart. ``` diff --git a/docs/start-without-technical-background.md b/docs/start-without-technical-background.md index e98adf10..9b4e88ff 100644 --- a/docs/start-without-technical-background.md +++ b/docs/start-without-technical-background.md @@ -59,15 +59,15 @@ If `python3` works but `python` does not, replace `python` with `python3` in the ## 3. Get a Provider API Key -nanobot does not create AI accounts or API keys for you. Use an AI provider account, company endpoint, subscription endpoint, or local model server that you already control. The steps below use OpenRouter because it is the recommended beginner path in the wizard; it is not a ranking or endorsement. +nanobot does not create AI accounts or API keys for you. Use an AI provider account, company endpoint, subscription endpoint, or local model server that you already control. The steps below use DeepSeek because it is the recommended beginner path in the wizard and avoids making OpenRouter a first-run dependency; it is not a ranking or endorsement. For the example path: -1. Open [openrouter.ai/keys](https://openrouter.ai/keys). +1. Open [platform.deepseek.com/api_keys](https://platform.deepseek.com/api_keys). 2. Create or copy an API key. 3. Keep the key private. -An OpenRouter key usually starts with `sk-or-v1-`. Other providers use different key shapes. Keep the key nearby because the setup wizard will ask you to paste it. +Keep the key nearby because the setup wizard will ask you to paste it. ## 4. Install nanobot @@ -167,15 +167,15 @@ Move through the wizard like this: | When you see | Do this | |---|---| | A menu | Use the arrow keys to highlight an option, then press `Enter`. | -| The OpenRouter API key field | Paste the key, then press `Enter`. | +| The DeepSeek API key field | Paste the key, then press `Enter`. | | A back option in Advanced Settings | Choose it to return to the previous menu. | For the first setup, choose `[Q] Quick Start (API key only)`. It configures the recommended local browser UI and default AI settings for you. Use `Advanced Settings` later only if you need a different provider, chat app, or tool setup. -If you are following the OpenRouter example: +If you are following the DeepSeek example: 1. Choose `[Q] Quick Start (API key only)`. -2. Paste your OpenRouter API key. +2. Paste your DeepSeek API key. 3. Review the Quick Start summary. The wizard saves and exits when Quick Start finishes. The recommended path enables the local WebUI and default AI settings. You do not need to choose a model, endpoint, or chat channel for the first run. @@ -211,8 +211,8 @@ Merge them into one object: ```json { "providers": { - "openrouter": { - "apiKey": "sk-or-v1-your-key-here" + "deepseek": { + "apiKey": "your-deepseek-api-key" } }, "channels": { @@ -256,15 +256,15 @@ If this is a brand-new install and you have not configured anything else yet, re ```json { "providers": { - "openrouter": { - "apiKey": "sk-or-v1-your-key-here" + "deepseek": { + "apiKey": "your-deepseek-api-key" } }, "modelPresets": { "primary": { "label": "Primary", - "provider": "openrouter", - "model": "anthropic/claude-sonnet-4.5", + "provider": "deepseek", + "model": "deepseek-v4-flash", "maxTokens": 4096, "contextWindowTokens": 65536, "temperature": 0.1 @@ -283,9 +283,9 @@ If this is a brand-new install and you have not configured anything else yet, re } ``` -Replace `sk-or-v1-your-key-here` with your real OpenRouter key. +Replace `your-deepseek-api-key` with your real DeepSeek key. -If you use another provider, replace `openrouter`, `sk-or-v1-your-key-here`, and the `model` value with that provider's values. If the provider needs `apiBase`, add it under that provider's config block. +If you use another provider, replace `deepseek`, `your-deepseek-api-key`, and the `model` value with that provider's values. If the provider needs `apiBase`, add it under that provider's config block. Save the file. diff --git a/nanobot/cli/onboard.py b/nanobot/cli/onboard.py index afa75040..ad5bf9aa 100644 --- a/nanobot/cli/onboard.py +++ b/nanobot/cli/onboard.py @@ -54,8 +54,8 @@ _BACK_PRESSED = object() # Sentinel value for back navigation # offer existing presets as choices (e.g. AgentDefaults.model_preset). _MODEL_PRESET_CACHE: set[str] = set() -_QUICK_START_RECOMMENDED_PROVIDER = "openrouter" -_QUICK_START_RECOMMENDED_MODEL = "anthropic/claude-sonnet-4.5" +_QUICK_START_RECOMMENDED_PROVIDER = "deepseek" +_QUICK_START_RECOMMENDED_MODEL = "deepseek-v4-flash" _QUICK_START_STEPS = ("API key", "WebUI", "Review") @@ -388,7 +388,7 @@ def _show_main_menu_header() -> None: body = Table.grid(expand=True) body.add_column(ratio=1) body.add_row(f"{__logo__} [bold {_UI_TEXT}]nanobot[/] [{_UI_MUTED}]v{__version__}[/]") - body.add_row(f"[{_UI_ACCENT}]Quick Start only needs an OpenRouter API key.[/]") + body.add_row(f"[{_UI_ACCENT}]Quick Start only needs a DeepSeek API key.[/]") body.add_row( f"[{_UI_MUTED}]Use Advanced later for other providers or chat apps.[/]" ) @@ -1424,14 +1424,14 @@ def _configure_recommended_provider(config: Config) -> bool: ) api_key = _input_with_existing( - "OpenRouter API key (get one at https://openrouter.ai/keys)", + "DeepSeek API key (get one at https://platform.deepseek.com/api_keys)", provider_config.api_key, "str", ) if api_key is not None: provider_config.api_key = api_key.strip() or None if not provider_config.api_key: - console.print("[yellow]! OpenRouter API key is required for Quick Start[/yellow]") + console.print("[yellow]! DeepSeek API key is required for Quick Start[/yellow]") return False if default_api_base and not provider_config.api_base: provider_config.api_base = default_api_base diff --git a/tests/agent/test_onboard_logic.py b/tests/agent/test_onboard_logic.py index 473bc25d..b25bbc9d 100644 --- a/tests/agent/test_onboard_logic.py +++ b/tests/agent/test_onboard_logic.py @@ -920,7 +920,7 @@ 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_with_existing", lambda *a, **kw: "sk-or-test") + monkeypatch.setattr(onboard_wizard, "_input_with_existing", lambda *a, **kw: "sk-ds-test") 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) @@ -929,10 +929,10 @@ class TestMainMenuUpdate: assert onboard_wizard._configure_quick_start(config) is True assert pause_messages == ["Press Enter to save and exit..."] - assert config.providers.openrouter.api_key == "sk-or-test" - assert config.providers.openrouter.api_base == "https://openrouter.ai/api/v1" + assert config.providers.deepseek.api_key == "sk-ds-test" + assert config.providers.deepseek.api_base == "https://api.deepseek.com" assert config.agents.defaults.model_preset == "primary" - assert config.model_presets["primary"].provider == "openrouter" + assert config.model_presets["primary"].provider == "deepseek" assert config.model_presets["primary"].model == onboard_wizard._QUICK_START_RECOMMENDED_MODEL websocket = getattr(config.channels, "websocket") assert websocket["enabled"] is True @@ -947,8 +947,8 @@ class TestMainMenuUpdate: assert onboard_wizard._configure_recommended_provider(config) is False - assert config.providers.openrouter.api_key is None - assert config.providers.openrouter.api_base is None + assert config.providers.deepseek.api_key is None + assert config.providers.deepseek.api_base is None assert "primary" not in config.model_presets def test_quick_start_summary_calls_out_missing_api_key(self, monkeypatch): @@ -956,7 +956,7 @@ class TestMainMenuUpdate: config = Config() config.model_presets["primary"] = ModelPresetConfig( model=onboard_wizard._QUICK_START_RECOMMENDED_MODEL, - provider="openrouter", + provider="deepseek", ) captured: dict[str, list[tuple[str, str]]] = {} @@ -972,7 +972,7 @@ class TestMainMenuUpdate: labels = [label for label, _value in captured["rows"]] rows = dict(captured["rows"]) - assert rows["Status"] == "OpenRouter API key missing" + assert rows["Status"] == "DeepSeek API key missing" assert "API key" in rows["Next"] assert "nanobot gateway" in rows["Next"] assert labels.index("Next") < labels.index("Open")