mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(kimi): reconcile sk-kimi- routing with Anthropic SDK URL semantics
Follow-ups after salvaging xiaoqiang243's kimi-for-coding patches: - KIMI_CODE_BASE_URL: drop trailing /v1 (was /coding/v1). The /coding endpoint speaks Anthropic Messages, and the Anthropic SDK appends /v1/messages internally. /coding/v1 + SDK suffix produced /coding/v1/v1/messages (a 404). /coding + SDK suffix now yields /coding/v1/messages correctly. - kimi-coding ProviderConfig: keep legacy default api.moonshot.ai/v1 so non-sk-kimi- moonshot keys still authenticate. sk-kimi- keys are already redirected to api.kimi.com/coding via _resolve_kimi_base_url. - doctor.py: update Kimi UA to claude-code/0.1.0 (was KimiCLI/1.30.0) and rewrite /coding base URLs to /coding/v1 for the /models health check (Anthropic surface has no /models). - test_kimi_env_vars: accept KIMI_CODING_API_KEY as a secondary env var. E2E verified: sk-kimi-<key> → https://api.kimi.com/coding/v1/messages (Anthropic) sk-<legacy> → https://api.moonshot.ai/v1/chat/completions (OpenAI) UA: claude-code/0.1.0, x-api-key: <sk-kimi-*>
This commit is contained in:
parent
6caf8bd994
commit
b2ba351380
3 changed files with 26 additions and 9 deletions
|
|
@ -168,7 +168,10 @@ PROVIDER_REGISTRY: Dict[str, ProviderConfig] = {
|
|||
id="kimi-coding",
|
||||
name="Kimi / Moonshot",
|
||||
auth_type="api_key",
|
||||
inference_base_url="https://api.kimi.com/coding",
|
||||
# Legacy platform.moonshot.ai keys use this endpoint (OpenAI-compat).
|
||||
# sk-kimi- (Kimi Code) keys are auto-redirected to api.kimi.com/coding
|
||||
# by _resolve_kimi_base_url() below.
|
||||
inference_base_url="https://api.moonshot.ai/v1",
|
||||
api_key_env_vars=("KIMI_API_KEY", "KIMI_CODING_API_KEY"),
|
||||
base_url_env_var="KIMI_BASE_URL",
|
||||
),
|
||||
|
|
@ -340,10 +343,16 @@ def get_anthropic_key() -> str:
|
|||
# =============================================================================
|
||||
|
||||
# Kimi Code (kimi.com/code) issues keys prefixed "sk-kimi-" that only work
|
||||
# on api.kimi.com/coding/v1. Legacy keys from platform.moonshot.ai work on
|
||||
# api.moonshot.ai/v1 (the default). Auto-detect when user hasn't set
|
||||
# on api.kimi.com/coding. Legacy keys from platform.moonshot.ai work on
|
||||
# api.moonshot.ai/v1 (the old default). Auto-detect when user hasn't set
|
||||
# KIMI_BASE_URL explicitly.
|
||||
KIMI_CODE_BASE_URL = "https://api.kimi.com/coding/v1"
|
||||
#
|
||||
# Note: the base URL intentionally has NO /v1 suffix. The /coding endpoint
|
||||
# speaks the Anthropic Messages protocol, and the anthropic SDK appends
|
||||
# "/v1/messages" internally — so "/coding" + SDK suffix → "/coding/v1/messages"
|
||||
# (the correct target). Using "/coding/v1" here would produce
|
||||
# "/coding/v1/v1/messages" (a 404).
|
||||
KIMI_CODE_BASE_URL = "https://api.kimi.com/coding"
|
||||
|
||||
|
||||
def _resolve_kimi_base_url(api_key: str, default_url: str, env_override: str) -> str:
|
||||
|
|
|
|||
|
|
@ -943,18 +943,22 @@ def run_doctor(args):
|
|||
try:
|
||||
import httpx
|
||||
_base = os.getenv(_base_env, "") if _base_env else ""
|
||||
# Auto-detect Kimi Code keys (sk-kimi-) → api.kimi.com
|
||||
# Auto-detect Kimi Code keys (sk-kimi-) → api.kimi.com/coding/v1
|
||||
# (OpenAI-compat surface, which exposes /models for health check).
|
||||
if not _base and _key.startswith("sk-kimi-"):
|
||||
_base = "https://api.kimi.com/coding/v1"
|
||||
# Anthropic-compat endpoints (/anthropic) don't support /models.
|
||||
# Rewrite to the OpenAI-compat /v1 surface for health checks.
|
||||
# Anthropic-compat endpoints (/anthropic, api.kimi.com/coding
|
||||
# with no /v1) don't support /models. Rewrite to the OpenAI-compat
|
||||
# /v1 surface for health checks.
|
||||
if _base and _base.rstrip("/").endswith("/anthropic"):
|
||||
from agent.auxiliary_client import _to_openai_base_url
|
||||
_base = _to_openai_base_url(_base)
|
||||
if base_url_host_matches(_base, "api.kimi.com") and _base.rstrip("/").endswith("/coding"):
|
||||
_base = _base.rstrip("/") + "/v1"
|
||||
_url = (_base.rstrip("/") + "/models") if _base else _default_url
|
||||
_headers = {"Authorization": f"Bearer {_key}"}
|
||||
if base_url_host_matches(_base, "api.kimi.com"):
|
||||
_headers["User-Agent"] = "KimiCLI/1.30.0"
|
||||
_headers["User-Agent"] = "claude-code/0.1.0"
|
||||
_resp = httpx.get(
|
||||
_url,
|
||||
headers=_headers,
|
||||
|
|
|
|||
|
|
@ -71,7 +71,11 @@ class TestProviderRegistry:
|
|||
|
||||
def test_kimi_env_vars(self):
|
||||
pconfig = PROVIDER_REGISTRY["kimi-coding"]
|
||||
assert pconfig.api_key_env_vars == ("KIMI_API_KEY",)
|
||||
# KIMI_API_KEY is the primary env var; KIMI_CODING_API_KEY is a
|
||||
# secondary fallback for Kimi Code sk-kimi- keys so users don't
|
||||
# have to overload the same variable.
|
||||
assert "KIMI_API_KEY" in pconfig.api_key_env_vars
|
||||
assert "KIMI_CODING_API_KEY" in pconfig.api_key_env_vars
|
||||
assert pconfig.base_url_env_var == "KIMI_BASE_URL"
|
||||
|
||||
def test_minimax_env_vars(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue