feat: add Moonshot provider support
- Add moonshot to ProvidersConfig schema - Add MOONSHOT_API_BASE environment variable for custom endpoint - Handle kimi-k2.5 model temperature restriction (must be 1.0) - Fix is_vllm detection to exclude moonshot provider Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
be0cbb7bdd
commit
e680b734b1
@ -77,6 +77,7 @@ class ProvidersConfig(BaseModel):
|
||||
zhipu: ProviderConfig = Field(default_factory=ProviderConfig)
|
||||
vllm: ProviderConfig = Field(default_factory=ProviderConfig)
|
||||
gemini: ProviderConfig = Field(default_factory=ProviderConfig)
|
||||
moonshot: ProviderConfig = Field(default_factory=ProviderConfig)
|
||||
|
||||
|
||||
class GatewayConfig(BaseModel):
|
||||
@ -122,7 +123,7 @@ class Config(BaseSettings):
|
||||
return Path(self.agents.defaults.workspace).expanduser()
|
||||
|
||||
def get_api_key(self) -> str | None:
|
||||
"""Get API key in priority order: OpenRouter > DeepSeek > Anthropic > OpenAI > Gemini > Zhipu > Groq > vLLM."""
|
||||
"""Get API key in priority order: OpenRouter > DeepSeek > Anthropic > OpenAI > Gemini > Zhipu > Groq > Moonshot > vLLM."""
|
||||
return (
|
||||
self.providers.openrouter.api_key or
|
||||
self.providers.deepseek.api_key or
|
||||
@ -131,16 +132,19 @@ class Config(BaseSettings):
|
||||
self.providers.gemini.api_key or
|
||||
self.providers.zhipu.api_key or
|
||||
self.providers.groq.api_key or
|
||||
self.providers.moonshot.api_key or
|
||||
self.providers.vllm.api_key or
|
||||
None
|
||||
)
|
||||
|
||||
def get_api_base(self) -> str | None:
|
||||
"""Get API base URL if using OpenRouter, Zhipu or vLLM."""
|
||||
"""Get API base URL if using OpenRouter, Zhipu, Moonshot or vLLM."""
|
||||
if self.providers.openrouter.api_key:
|
||||
return self.providers.openrouter.api_base or "https://openrouter.ai/api/v1"
|
||||
if self.providers.zhipu.api_key:
|
||||
return self.providers.zhipu.api_base
|
||||
if self.providers.moonshot.api_key:
|
||||
return self.providers.moonshot.api_base
|
||||
if self.providers.vllm.api_base:
|
||||
return self.providers.vllm.api_base
|
||||
return None
|
||||
|
||||
@ -31,9 +31,15 @@ class LiteLLMProvider(LLMProvider):
|
||||
(api_key and api_key.startswith("sk-or-")) or
|
||||
(api_base and "openrouter" in api_base)
|
||||
)
|
||||
|
||||
|
||||
# Detect Moonshot by api_base or model name
|
||||
self.is_moonshot = (
|
||||
(api_base and "moonshot" in api_base) or
|
||||
("moonshot" in default_model or "kimi" in default_model)
|
||||
)
|
||||
|
||||
# Track if using custom endpoint (vLLM, etc.)
|
||||
self.is_vllm = bool(api_base) and not self.is_openrouter
|
||||
self.is_vllm = bool(api_base) and not self.is_openrouter and not self.is_moonshot
|
||||
|
||||
# Configure LiteLLM based on provider
|
||||
if api_key:
|
||||
@ -55,8 +61,12 @@ class LiteLLMProvider(LLMProvider):
|
||||
os.environ.setdefault("ZHIPUAI_API_KEY", api_key)
|
||||
elif "groq" in default_model:
|
||||
os.environ.setdefault("GROQ_API_KEY", api_key)
|
||||
|
||||
if api_base:
|
||||
elif "moonshot" in default_model or "kimi" in default_model:
|
||||
os.environ.setdefault("MOONSHOT_API_KEY", api_key)
|
||||
if api_base:
|
||||
os.environ["MOONSHOT_API_BASE"] = api_base
|
||||
|
||||
if api_base and not self.is_moonshot:
|
||||
litellm.api_base = api_base
|
||||
|
||||
# Disable LiteLLM logging noise
|
||||
@ -97,23 +107,33 @@ class LiteLLMProvider(LLMProvider):
|
||||
model.startswith("openrouter/")
|
||||
):
|
||||
model = f"zai/{model}"
|
||||
|
||||
|
||||
# For Moonshot/Kimi, ensure moonshot/ prefix (before vLLM check)
|
||||
if ("moonshot" in model.lower() or "kimi" in model.lower()) and not (
|
||||
model.startswith("moonshot/") or model.startswith("openrouter/")
|
||||
):
|
||||
model = f"moonshot/{model}"
|
||||
|
||||
# For Gemini, ensure gemini/ prefix if not already present
|
||||
if "gemini" in model.lower() and not model.startswith("gemini/"):
|
||||
model = f"gemini/{model}"
|
||||
|
||||
# For vLLM, use hosted_vllm/ prefix per LiteLLM docs
|
||||
# Convert openai/ prefix to hosted_vllm/ if user specified it
|
||||
if self.is_vllm:
|
||||
model = f"hosted_vllm/{model}"
|
||||
|
||||
# For Gemini, ensure gemini/ prefix if not already present
|
||||
if "gemini" in model.lower() and not model.startswith("gemini/"):
|
||||
model = f"gemini/{model}"
|
||||
|
||||
kwargs: dict[str, Any] = {
|
||||
"model": model,
|
||||
"messages": messages,
|
||||
"max_tokens": max_tokens,
|
||||
"temperature": temperature,
|
||||
}
|
||||
|
||||
|
||||
# kimi-k2.5 only supports temperature=1.0
|
||||
if "kimi-k2.5" in model.lower():
|
||||
kwargs["temperature"] = 1.0
|
||||
|
||||
# Pass api_base directly for custom endpoints (vLLM, etc.)
|
||||
if self.api_base:
|
||||
kwargs["api_base"] = self.api_base
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user