Skip to content
Closed
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
3 changes: 2 additions & 1 deletion agent/model_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def _resolve_requests_verify() -> bool | str:
_PROVIDER_PREFIXES: frozenset[str] = frozenset({
"openrouter", "nous", "openai-codex", "copilot", "copilot-acp",
"gemini", "ollama-cloud", "zai", "kimi-coding", "kimi-coding-cn", "stepfun", "minimax", "minimax-oauth", "minimax-cn", "anthropic", "deepseek",
"opencode-zen", "opencode-go", "kilocode", "alibaba", "novita",
"opencode-zen", "opencode-go", "kilocode", "alibaba", "alibaba-token-plan", "novita",
"qwen-oauth",
"xiaomi",
"arcee",
Expand Down Expand Up @@ -354,6 +354,7 @@ def _is_custom_endpoint(base_url: str) -> bool:
"api.minimax": "minimax",
"dashscope.aliyuncs.com": "alibaba",
"dashscope-intl.aliyuncs.com": "alibaba",
"token-plan.cn-beijing.maas.aliyuncs.com": "alibaba-token-plan",
"portal.qwen.ai": "qwen-oauth",
"openrouter.ai": "openrouter",
"generativelanguage.googleapis.com": "gemini",
Expand Down
9 changes: 5 additions & 4 deletions agent/system_prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,13 @@ def build_system_prompt_parts(agent: Any, system_message: Optional[str] = None)
if skills_prompt:
stable_parts.append(skills_prompt)

# Alibaba Coding Plan API always returns "glm-4.7" as model name regardless
# of the requested model. Inject explicit model identity into the system prompt
# so the agent can correctly report which model it is (workaround for API bug).
# Alibaba DashScope / Token Plan APIs may return a different model name than
# requested (e.g. returning "glm-4.7" regardless of the actual model).
# Inject explicit model identity into the system prompt so the agent can
# correctly report which model it is (workaround for API bug).
# Stable for the lifetime of an agent instance — model and provider are fixed
# at construction time.
if agent.provider == "alibaba":
if agent.provider in ("alibaba", "alibaba-coding-plan", "alibaba-token-plan"):
_model_short = agent.model.split("/")[-1] if "/" in agent.model else agent.model
stable_parts.append(
f"You are powered by the model named {_model_short}. "
Expand Down
10 changes: 10 additions & 0 deletions hermes_cli/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,14 @@ class ProviderConfig:
api_key_env_vars=("ALIBABA_CODING_PLAN_API_KEY", "DASHSCOPE_API_KEY"),
base_url_env_var="ALIBABA_CODING_PLAN_BASE_URL",
),
"alibaba-token-plan": ProviderConfig(
id="alibaba-token-plan",
name="Alibaba Cloud (Token Plan)",
auth_type="api_key",
inference_base_url="https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
api_key_env_vars=("ALIBABA_TOKEN_PLAN_API_KEY", "DASHSCOPE_API_KEY"),
base_url_env_var="ALIBABA_TOKEN_PLAN_BASE_URL",
),
"minimax-cn": ProviderConfig(
id="minimax-cn",
name="MiniMax (China)",
Expand Down Expand Up @@ -1495,6 +1503,8 @@ def resolve_provider(
"minimax-portal": "minimax-oauth", "minimax-global": "minimax-oauth", "minimax_oauth": "minimax-oauth",
"alibaba_coding": "alibaba-coding-plan", "alibaba-coding": "alibaba-coding-plan",
"alibaba_coding_plan": "alibaba-coding-plan",
"alibaba_token_plan": "alibaba-token-plan", "alibaba-token": "alibaba-token-plan",
"aliyun-token-plan": "alibaba-token-plan", "token-plan": "alibaba-token-plan",
"claude": "anthropic", "claude-code": "anthropic",
"github": "copilot", "github-copilot": "copilot",
"github-models": "copilot", "github-model": "copilot",
Expand Down
4 changes: 3 additions & 1 deletion hermes_cli/doctor.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ def _build_apikey_providers_list() -> list:
("Hugging Face", ("HF_TOKEN",), "https://router.huggingface.co/v1/models", "HF_BASE_URL", True),
("NVIDIA NIM", ("NVIDIA_API_KEY",), "https://integrate.api.nvidia.com/v1/models", "NVIDIA_BASE_URL", True),
("Alibaba/DashScope", ("DASHSCOPE_API_KEY",), "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/models", "DASHSCOPE_BASE_URL", True),
("Alibaba Token Plan", ("ALIBABA_TOKEN_PLAN_API_KEY", "DASHSCOPE_API_KEY"), "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1/models", "ALIBABA_TOKEN_PLAN_BASE_URL", True),
# MiniMax global: /v1 endpoint supports /models.
("MiniMax", ("MINIMAX_API_KEY",), "https://api.minimax.io/v1/models", "MINIMAX_BASE_URL", True),
# MiniMax CN: /v1 endpoint does NOT support /models (returns 404).
Expand All @@ -389,7 +390,8 @@ def _build_apikey_providers_list() -> list:
"StepFun Step Plan": "stepfun", "Kimi / Moonshot (China)": "kimi-coding-cn",
"Arcee AI": "arcee", "GMI Cloud": "gmi", "DeepSeek": "deepseek",
"Hugging Face": "huggingface", "NVIDIA NIM": "nvidia",
"Alibaba/DashScope": "alibaba", "MiniMax": "minimax",
"Alibaba/DashScope": "alibaba", "Alibaba Token Plan": "alibaba-token-plan",
"MiniMax": "minimax",
"MiniMax (China)": "minimax-cn",
"Kilo Code": "kilocode", "OpenCode Zen": "opencode-zen",
"OpenCode Go": "opencode-go",
Expand Down
16 changes: 16 additions & 0 deletions hermes_cli/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,22 @@ def _xai_curated_models() -> list[str]:
"glm-4.7",
"MiniMax-M2.5",
],
# Alibaba Token Plan (Team Edition) — subscription-based Credits billing,
# endpoint: token-plan.cn-beijing.maas.aliyuncs.com.
# Docs: https://help.aliyun.com/zh/model-studio/token-plan-overview
"alibaba-token-plan": [
"qwen3.7-max",
"qwen3.6-plus",
"qwen3.6-flash",
"deepseek-v4-pro",
"deepseek-v4-flash",
"deepseek-v3.2",
"kimi-k2.6",
"kimi-k2.5",
"glm-5.1",
"glm-5",
"MiniMax-M2.5",
],
# Curated HF model list — only agentic models that map to OpenRouter defaults.
"huggingface": [
"moonshotai/Kimi-K2.5",
Expand Down
10 changes: 10 additions & 0 deletions hermes_cli/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ class HermesOverlay:
transport="openai_chat",
base_url_env_var="ALIBABA_CODING_PLAN_BASE_URL",
),
"alibaba-token-plan": HermesOverlay(
transport="openai_chat",
base_url_env_var="ALIBABA_TOKEN_PLAN_BASE_URL",
),
"opencode": HermesOverlay(
transport="openai_chat",
is_aggregator=True,
Expand Down Expand Up @@ -311,6 +315,12 @@ class ProviderDef:
"alibaba-coding": "alibaba-coding-plan",
"alibaba_coding_plan": "alibaba-coding-plan",

# alibaba-token-plan
"alibaba_token_plan": "alibaba-token-plan",
"alibaba-token": "alibaba-token-plan",
"aliyun-token-plan": "alibaba-token-plan",
"token-plan": "alibaba-token-plan",

# google-gemini-cli (OAuth + Code Assist)
"gemini-cli": "google-gemini-cli",
"gemini-oauth": "google-gemini-cli",
Expand Down
24 changes: 24 additions & 0 deletions plugins/model-providers/alibaba-token-plan/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Alibaba Cloud Token Plan (Team Edition) provider profile.

Separate from the standard `alibaba` and `alibaba-coding-plan` profiles because
it hits a different endpoint (token-plan.cn-beijing.maas.aliyuncs.com) with
its own subscription-based billing (Credits).

Docs: https://help.aliyun.com/zh/model-studio/token-plan-overview
"""

from providers import register_provider
from providers.base import ProviderProfile

alibaba_token_plan = ProviderProfile(
name="alibaba-token-plan",
aliases=("alibaba_token_plan", "aliyun-token-plan", "token-plan"),
display_name="Alibaba Cloud (Token Plan)",
description="Alibaba Cloud Token Plan — team subscription (Credits)",
signup_url="https://www.aliyun.com/benefit/scene/tokenplan",
env_vars=("ALIBABA_TOKEN_PLAN_API_KEY", "DASHSCOPE_API_KEY", "ALIBABA_TOKEN_PLAN_BASE_URL"),
base_url="https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
auth_type="api_key",
)

register_provider(alibaba_token_plan)
5 changes: 5 additions & 0 deletions plugins/model-providers/alibaba-token-plan/plugin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: alibaba-token-plan-provider
kind: model-provider
version: 1.0.0
description: Alibaba Cloud Token Plan (Team Edition)
author: Nous Research
2 changes: 1 addition & 1 deletion tests/providers/test_plugin_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def test_all_profiles_register():
# Spot-check representative providers from different categories
for required in (
"openrouter", "anthropic", "custom", "bedrock", "openai-codex",
"minimax-oauth", "gmi", "xiaomi", "alibaba-coding-plan",
"minimax-oauth", "gmi", "xiaomi", "alibaba-coding-plan", "alibaba-token-plan",
):
assert required in names, f"Missing profile: {required}"

Expand Down