Files
hermes-agent/plugins/model-providers/alibaba-coding-plan/__init__.py
Teknium 336b11584c fix: replay prior reasoning to every chat-completions route that can read it
Every model reasons and intends that reasoning to be replayed, but the
chat-completions wire echoed reasoning_content only to DeepSeek/Kimi/MiMo/
Ollama (plus a hardcoded Portal stealth model) and reasoning_details only to
OpenRouter; turn_context popped `reasoning` everywhere, so Ollama's /v1
(reads only `reasoning`) never saw any.

- message_sanitization owns one route->carrier table
  (_REASONING_CARRIER_ROUTES): strict schemas (Mistral, Groq, Cerebras,
  SambaNova) get nothing, Fireworks reasoning_content only, OpenRouter-format
  gateways (OpenRouter, Kilo, Vercel AI Gateway, Nous Portal) all three,
  Novita/MiniMax /v1/TokenHub + reasoning_details, local/Ollama/Upstage +
  reasoning, everyone else reasoning_content.
- The " " pad stays limited to the must-echo tier (DeepSeek, Kimi, MiMo);
  Ollama leaves it (no echo requirement) and the stealth hardcode is gone.
- Reactive recovery: a 4xx unknown-field rejection that NAMES a reasoning
  key this request carried is recorded per (provider, host, model) and the
  retry re-shapes api_messages without it. Generic upstream errors never
  count; a recorded key falls through, so no loop. History is untouched.
- Nous Portal reads reasoning_details again: the #118182 "replay budget"
  does not exist in the Portal and does not reproduce live.
- Gemini thought_signature survives on Gemini hosts/providers even when the
  model id is an alias.
- Vendor keep-reasoning flags (docs-only): GLM thinking.clear_thinking=false,
  DashScope preserve_thinking / clear_thinking, Kimi K2.x thinking.keep=all.
- stale_thinking_reaches_wire follows the same table, so compaction trigger
  and tail walks agree with what is sent.
2026-10-10 19:22:07 -07:00

42 lines
1.9 KiB
Python

"""Alibaba Cloud Coding Plan provider profiles (intl + CN): a dedicated endpoint
and key tier separate from ``alibaba``. Names match models.dev catalog keys.
The CN profile checks its own key first and keeps the shared vars as ordered
fallbacks so existing CN users configured with the shared key keep working.
"""
from typing import Any
from agent.reasoning_effort import dashscope_preserve_thinking_extras
from providers import register_provider
from providers.base import ProviderProfile
class DashScopeProfile(ProviderProfile):
"""DashScope compatible-mode: ask the server to keep replayed prior-turn reasoning."""
def build_api_kwargs_extras(self, *, model: str | None = None, **context: Any) -> tuple[dict[str, Any], dict[str, Any]]:
return dashscope_preserve_thinking_extras(model), {}
alibaba_coding_plan = DashScopeProfile(
name="alibaba-coding-plan", aliases=("alibaba_coding", "alibaba-coding", "dashscope-coding"),
display_name="Alibaba Cloud (Coding Plan)",
description="Alibaba Cloud Coding Plan (Dedicated coding tier)",
signup_url="https://help.aliyun.com/zh/model-studio/",
env_vars=("ALIBABA_CODING_PLAN_API_KEY", "DASHSCOPE_API_KEY", "ALIBABA_CODING_PLAN_BASE_URL"),
base_url="https://coding-intl.dashscope.aliyuncs.com/v1", auth_type="api_key",
)
alibaba_coding_plan_cn = DashScopeProfile(
name="alibaba-coding-plan-cn", aliases=("alibaba-coding-cn", "dashscope-coding-cn"),
display_name="Alibaba Cloud (Coding Plan, China)",
description="Alibaba Cloud Coding Plan, mainland-China endpoint",
signup_url="https://help.aliyun.com/zh/model-studio/",
env_vars=("ALIBABA_CODING_PLAN_CN_API_KEY", "ALIBABA_CODING_PLAN_API_KEY", "DASHSCOPE_API_KEY", "ALIBABA_CODING_PLAN_CN_BASE_URL"),
base_url="https://coding.dashscope.aliyuncs.com/v1", auth_type="api_key",
)
register_provider(alibaba_coding_plan)
register_provider(alibaba_coding_plan_cn)