From 8499dbf132338c0979421b1cac62a34fad015073 Mon Sep 17 00:00:00 2001 From: ZJUCQR <310857001@qq.com> Date: Tue, 3 Feb 2026 16:27:15 +0800 Subject: [PATCH 1/2] add dashscope support --- nanobot/config/schema.py | 4 +++- nanobot/providers/litellm_provider.py | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/nanobot/config/schema.py b/nanobot/config/schema.py index 71e3361..695d769 100644 --- a/nanobot/config/schema.py +++ b/nanobot/config/schema.py @@ -52,6 +52,7 @@ class ProvidersConfig(BaseModel): openrouter: ProviderConfig = Field(default_factory=ProviderConfig) groq: ProviderConfig = Field(default_factory=ProviderConfig) zhipu: ProviderConfig = Field(default_factory=ProviderConfig) + dashscope: ProviderConfig = Field(default_factory=ProviderConfig) # 阿里云通义千问 vllm: ProviderConfig = Field(default_factory=ProviderConfig) gemini: ProviderConfig = Field(default_factory=ProviderConfig) @@ -92,13 +93,14 @@ class Config(BaseSettings): return Path(self.agents.defaults.workspace).expanduser() def get_api_key(self) -> str | None: - """Get API key in priority order: OpenRouter > Anthropic > OpenAI > Gemini > Zhipu > Groq > vLLM.""" + """Get API key in priority order: OpenRouter > Anthropic > OpenAI > Gemini > Zhipu > DashScope > Groq > vLLM.""" return ( self.providers.openrouter.api_key or self.providers.anthropic.api_key or self.providers.openai.api_key or self.providers.gemini.api_key or self.providers.zhipu.api_key or + self.providers.dashscope.api_key or self.providers.groq.api_key or self.providers.vllm.api_key or None diff --git a/nanobot/providers/litellm_provider.py b/nanobot/providers/litellm_provider.py index 547626d..18e19ff 100644 --- a/nanobot/providers/litellm_provider.py +++ b/nanobot/providers/litellm_provider.py @@ -51,6 +51,8 @@ class LiteLLMProvider(LLMProvider): os.environ.setdefault("GEMINI_API_KEY", api_key) elif "zhipu" in default_model or "glm" in default_model or "zai" in default_model: os.environ.setdefault("ZHIPUAI_API_KEY", api_key) + elif "dashscope" in default_model or "qwen" in default_model.lower(): + os.environ.setdefault("DASHSCOPE_API_KEY", api_key) elif "groq" in default_model: os.environ.setdefault("GROQ_API_KEY", api_key) @@ -95,6 +97,13 @@ class LiteLLMProvider(LLMProvider): model.startswith("openrouter/") ): model = f"zhipu/{model}" + + # For DashScope/Qwen, ensure prefix is present + if ("qwen" in model.lower() or "dashscope" in model.lower()) and not ( + model.startswith("dashscope/") or + model.startswith("openrouter/") + ): + model = f"dashscope/{model}" # For vLLM, use hosted_vllm/ prefix per LiteLLM docs # Convert openai/ prefix to hosted_vllm/ if user specified it From 520923eb76182f3e6a90b96458edccb42ff1a9c3 Mon Sep 17 00:00:00 2001 From: ZJUCQR <310857001@qq.com> Date: Tue, 3 Feb 2026 16:28:21 +0800 Subject: [PATCH 2/2] update readme --- README.md | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 55c6091..b62aab3 100644 --- a/README.md +++ b/README.md @@ -92,8 +92,7 @@ uv pip install nanobot-ai > [!TIP] > Set your API key in `~/.nanobot/config.json`. -> Get API keys: [OpenRouter](https://openrouter.ai/keys) (LLM) · [Brave Search](https://brave.com/search/api/) (optional, for web search) -> You can also change the model to `minimax/minimax-m2` for lower cost. +> Get API keys: [DashScope](https://dashscope.console.aliyun.com) (China) · [OpenRouter](https://openrouter.ai/keys) (Global) · [Brave Search](https://brave.com/search/api/) (optional, for web search) **1. Initialize** @@ -103,6 +102,7 @@ nanobot onboard **2. Configure** (`~/.nanobot/config.json`) +For OpenRouter - recommended for global users: ```json { "providers": { @@ -114,9 +114,22 @@ nanobot onboard "defaults": { "model": "anthropic/claude-opus-4-5" } + } +} +``` + +For DashScope - recommended for China users: +```json +{ + "providers": { + "dashscope": { + "apiKey": "sk-xxx" + } }, - "webSearch": { - "apiKey": "BSA-xxx" + "agents": { + "defaults": { + "model": "qwen-plus" + } } } ``` @@ -251,13 +264,15 @@ Config file: `~/.nanobot/config.json` ### Providers -| Provider | Purpose | Get API Key | -|----------|---------|-------------| -| `openrouter` | LLM (recommended, access to all models) | [openrouter.ai](https://openrouter.ai) | -| `anthropic` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) | -| `openai` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) | -| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) | -| `gemini` | LLM (Gemini direct) | [aistudio.google.com](https://aistudio.google.com) | +| Provider | Purpose | Models | Get API Key | +|----------|---------|--------|-------------| +| `dashscope` | LLM (China recommended) | `qwen-turbo`, `qwen-plus`, `qwen-max` | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) | +| `openrouter` | LLM (access to all models) | All major models | [openrouter.ai](https://openrouter.ai) | +| `anthropic` | LLM (Claude direct) | `claude-opus-4-5`, `claude-sonnet-4-5` | [console.anthropic.com](https://console.anthropic.com) | +| `openai` | LLM (GPT direct) | `gpt-4o`, `gpt-4-turbo` | [platform.openai.com](https://platform.openai.com) | +| `zhipu` | LLM (China) | `glm-4`, `glm-4-flash` | [open.bigmodel.cn](https://open.bigmodel.cn) | +| `groq` | LLM + **Voice transcription** | Llama, Whisper | [console.groq.com](https://console.groq.com) | +| `gemini` | LLM (Gemini direct) | `gemini-pro`, `gemini-ultra` | [aistudio.google.com](https://aistudio.google.com) | > **Note**: Groq provides free voice transcription via Whisper. If configured, Telegram voice messages will be automatically transcribed.