Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hermes_cli/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class 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",
),
Expand Down
4 changes: 2 additions & 2 deletions hermes_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,14 +547,14 @@ def ensure_hermes_home():
"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,
Expand Down
2 changes: 1 addition & 1 deletion hermes_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)"),
]

Expand Down
14 changes: 10 additions & 4 deletions hermes_cli/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,20 @@
"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": [
Expand Down
18 changes: 9 additions & 9 deletions tests/test_runtime_provider_resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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):
Expand Down
Loading