From 09796b183b50f03bd55da308ec7b677aff985abe Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Fri, 27 Mar 2026 22:10:10 -0700 Subject: [PATCH] fix: alibaba provider default endpoint and model list (#3484) - Change default inference_base_url from dashscope-intl Anthropic-compat endpoint to coding-intl OpenAI-compat /v1 endpoint. The old Anthropic endpoint 404'd when used with the OpenAI SDK (which appends /chat/completions to a /apps/anthropic base URL). - Update curated model list: remove models unavailable on coding-intl (qwen3-max, qwen-plus-latest, qwen3.5-flash, qwen-vl-max), add third-party models available on the platform (glm-5, glm-4.7, kimi-k2.5, MiniMax-M2.5). - URL-based api_mode auto-detection still works: overriding DASHSCOPE_BASE_URL to an /apps/anthropic endpoint automatically switches to anthropic_messages mode. - Update provider description and env var descriptions to reflect the coding-intl multi-provider platform. - Update tests to match new default URL and test the anthropic override path instead. --- hermes_cli/auth.py | 2 +- hermes_cli/config.py | 4 ++-- hermes_cli/main.py | 2 +- hermes_cli/models.py | 14 ++++++++++---- tests/test_runtime_provider_resolution.py | 18 +++++++++--------- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/hermes_cli/auth.py b/hermes_cli/auth.py index f83a29ddf..149cbcafb 100644 --- a/hermes_cli/auth.py +++ b/hermes_cli/auth.py @@ -160,7 +160,7 @@ PROVIDER_REGISTRY: Dict[str, ProviderConfig] = { id="alibaba", name="Alibaba Cloud (DashScope)", auth_type="api_key", - inference_base_url="https://dashscope-intl.aliyuncs.com/apps/anthropic", + inference_base_url="https://coding-intl.dashscope.aliyuncs.com/v1", api_key_env_vars=("DASHSCOPE_API_KEY",), base_url_env_var="DASHSCOPE_BASE_URL", ), diff --git a/hermes_cli/config.py b/hermes_cli/config.py index 6ad19a6f6..b955a5399 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -547,14 +547,14 @@ OPTIONAL_ENV_VARS = { "category": "provider", }, "DASHSCOPE_API_KEY": { - "description": "Alibaba Cloud DashScope API key for Qwen models", + "description": "Alibaba Cloud DashScope API key (Qwen + multi-provider models)", "prompt": "DashScope API Key", "url": "https://modelstudio.console.alibabacloud.com/", "password": True, "category": "provider", }, "DASHSCOPE_BASE_URL": { - "description": "Custom DashScope base URL (default: international endpoint)", + "description": "Custom DashScope base URL (default: coding-intl OpenAI-compat endpoint)", "prompt": "DashScope Base URL", "url": "", "password": False, diff --git a/hermes_cli/main.py b/hermes_cli/main.py index bc7cf9e9c..a50f33273 100644 --- a/hermes_cli/main.py +++ b/hermes_cli/main.py @@ -821,7 +821,7 @@ def cmd_model(args): ("opencode-zen", "OpenCode Zen (35+ curated models, pay-as-you-go)"), ("opencode-go", "OpenCode Go (open models, $10/month subscription)"), ("ai-gateway", "AI Gateway (Vercel — 200+ models, pay-per-use)"), - ("alibaba", "Alibaba Cloud / DashScope (Qwen models, Anthropic-compatible)"), + ("alibaba", "Alibaba Cloud / DashScope Coding (Qwen + multi-provider)"), ("huggingface", "Hugging Face Inference Providers (20+ open models)"), ] diff --git a/hermes_cli/models.py b/hermes_cli/models.py index 085d3ffb4..ff86443bd 100644 --- a/hermes_cli/models.py +++ b/hermes_cli/models.py @@ -208,14 +208,20 @@ _PROVIDER_MODELS: dict[str, list[str]] = { "google/gemini-3-pro-preview", "google/gemini-3-flash-preview", ], + # Alibaba DashScope Coding platform (coding-intl) — default endpoint. + # Supports Qwen models + third-party providers (GLM, Kimi, MiniMax). + # Users with classic DashScope keys should override DASHSCOPE_BASE_URL + # to https://dashscope-intl.aliyuncs.com/compatible-mode/v1 (OpenAI-compat) + # or https://dashscope-intl.aliyuncs.com/apps/anthropic (Anthropic-compat). "alibaba": [ "qwen3.5-plus", - "qwen3-max", "qwen3-coder-plus", "qwen3-coder-next", - "qwen-plus-latest", - "qwen3.5-flash", - "qwen-vl-max", + # Third-party models available on coding-intl + "glm-5", + "glm-4.7", + "kimi-k2.5", + "MiniMax-M2.5", ], # Curated HF model list — only agentic models that map to OpenRouter defaults. "huggingface": [ diff --git a/tests/test_runtime_provider_resolution.py b/tests/test_runtime_provider_resolution.py index 3597986bf..b63e87dac 100644 --- a/tests/test_runtime_provider_resolution.py +++ b/tests/test_runtime_provider_resolution.py @@ -534,8 +534,8 @@ def test_minimax_explicit_api_mode_respected(monkeypatch): assert resolved["api_mode"] == "chat_completions" -def test_alibaba_default_anthropic_endpoint_uses_anthropic_messages(monkeypatch): - """Alibaba with default /apps/anthropic URL should use anthropic_messages mode.""" +def test_alibaba_default_coding_intl_endpoint_uses_chat_completions(monkeypatch): + """Alibaba default coding-intl /v1 URL should use chat_completions mode.""" monkeypatch.setattr(rp, "resolve_provider", lambda *a, **k: "alibaba") monkeypatch.setattr(rp, "_get_model_config", lambda: {}) monkeypatch.setenv("DASHSCOPE_API_KEY", "test-dashscope-key") @@ -544,22 +544,22 @@ def test_alibaba_default_anthropic_endpoint_uses_anthropic_messages(monkeypatch) resolved = rp.resolve_runtime_provider(requested="alibaba") assert resolved["provider"] == "alibaba" - assert resolved["api_mode"] == "anthropic_messages" - assert resolved["base_url"] == "https://dashscope-intl.aliyuncs.com/apps/anthropic" + assert resolved["api_mode"] == "chat_completions" + assert resolved["base_url"] == "https://coding-intl.dashscope.aliyuncs.com/v1" -def test_alibaba_openai_compatible_v1_endpoint_stays_chat_completions(monkeypatch): - """Alibaba with /v1 coding endpoint should use chat_completions mode.""" +def test_alibaba_anthropic_endpoint_override_uses_anthropic_messages(monkeypatch): + """Alibaba with /apps/anthropic URL override should auto-detect anthropic_messages mode.""" monkeypatch.setattr(rp, "resolve_provider", lambda *a, **k: "alibaba") monkeypatch.setattr(rp, "_get_model_config", lambda: {}) monkeypatch.setenv("DASHSCOPE_API_KEY", "test-dashscope-key") - monkeypatch.setenv("DASHSCOPE_BASE_URL", "https://coding-intl.dashscope.aliyuncs.com/v1") + monkeypatch.setenv("DASHSCOPE_BASE_URL", "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic") resolved = rp.resolve_runtime_provider(requested="alibaba") assert resolved["provider"] == "alibaba" - assert resolved["api_mode"] == "chat_completions" - assert resolved["base_url"] == "https://coding-intl.dashscope.aliyuncs.com/v1" + assert resolved["api_mode"] == "anthropic_messages" + assert resolved["base_url"] == "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic" def test_named_custom_provider_anthropic_api_mode(monkeypatch):