fix: don't migrate Moonshot API keys to Z.ai (incompatible APIs)

Moonshot (Kimi) and Z.ai are separate services with incompatible API
keys. The previous migration blindly copied Moonshot config to Zai,
which would cause auth failures since a Moonshot key can't authenticate
against api.z.ai.

Changes:
- migrateProviders() now only migrates Zhipu→Zai (same company rebrand)
- Provider fallback for kimi/moonshot models tries Zai first, then
  falls back to legacy Moonshot config with api.moonshot.cn endpoint
- Explicit "moonshot"/"kimi" provider names also fallback correctly
- Update IDENTITY.md: Zhipu → Z.ai

https://claude.ai/code/session_01MYemTMPtHrcgidWs8UdjcG
This commit is contained in:
Claude 2026-02-18 18:57:37 +00:00
parent 09a03c4ed5
commit 47a626fb61
No known key found for this signature in database
3 changed files with 35 additions and 10 deletions

View file

@ -379,15 +379,13 @@ func LoadConfig(path string) (*Config, error) {
return cfg, nil
}
// migrateProviders merges deprecated Zhipu and Moonshot provider configs into Zai.
// If Zai is not configured, it falls back to Zhipu first, then Moonshot.
// migrateProviders merges deprecated Zhipu provider config into Zai.
// Zhipu AI rebranded to Z.ai in 2025 - same company, same API.
// Note: Moonshot (Kimi) is a separate service and is NOT migrated
// automatically, as Moonshot API keys are incompatible with Z.ai.
func (c *Config) migrateProviders() {
if c.Providers.Zai.APIKey == "" {
if c.Providers.Zhipu.APIKey != "" {
if c.Providers.Zai.APIKey == "" && c.Providers.Zhipu.APIKey != "" {
c.Providers.Zai = c.Providers.Zhipu
} else if c.Providers.Moonshot.APIKey != "" {
c.Providers.Zai = c.Providers.Moonshot
}
}
}

View file

@ -326,6 +326,8 @@ func CreateProvider(cfg *config.Config) (LLMProvider, error) {
}
}
case "moonshot", "kimi":
// Moonshot/Kimi is deprecated. Prefer using "zai" provider instead.
// Falls back to legacy Moonshot config for backward compat.
if cfg.Providers.Zai.APIKey != "" {
apiKey = cfg.Providers.Zai.APIKey
apiBase = cfg.Providers.Zai.APIBase
@ -333,6 +335,13 @@ func CreateProvider(cfg *config.Config) (LLMProvider, error) {
if apiBase == "" {
apiBase = "https://api.z.ai/api/paas/v4"
}
} else if cfg.Providers.Moonshot.APIKey != "" {
apiKey = cfg.Providers.Moonshot.APIKey
apiBase = cfg.Providers.Moonshot.APIBase
proxy = cfg.Providers.Moonshot.Proxy
if apiBase == "" {
apiBase = "https://api.moonshot.cn/v1"
}
}
case "github_copilot", "copilot":
if cfg.Providers.GitHubCopilot.APIBase != "" {
@ -349,7 +358,7 @@ func CreateProvider(cfg *config.Config) (LLMProvider, error) {
// Fallback: detect provider from model name
if apiKey == "" && apiBase == "" {
switch {
case (strings.Contains(lowerModel, "kimi") || strings.Contains(lowerModel, "moonshot") || strings.HasPrefix(model, "moonshot/") || strings.Contains(lowerModel, "zai") || strings.HasPrefix(model, "zai/")) && cfg.Providers.Zai.APIKey != "":
case (strings.Contains(lowerModel, "zai") || strings.HasPrefix(model, "zai/")) && cfg.Providers.Zai.APIKey != "":
apiKey = cfg.Providers.Zai.APIKey
apiBase = cfg.Providers.Zai.APIBase
proxy = cfg.Providers.Zai.Proxy
@ -357,6 +366,24 @@ func CreateProvider(cfg *config.Config) (LLMProvider, error) {
apiBase = "https://api.z.ai/api/paas/v4"
}
case (strings.Contains(lowerModel, "kimi") || strings.Contains(lowerModel, "moonshot") || strings.HasPrefix(model, "moonshot/")):
// Kimi/Moonshot models: prefer Zai, fallback to legacy Moonshot config
if cfg.Providers.Zai.APIKey != "" {
apiKey = cfg.Providers.Zai.APIKey
apiBase = cfg.Providers.Zai.APIBase
proxy = cfg.Providers.Zai.Proxy
if apiBase == "" {
apiBase = "https://api.z.ai/api/paas/v4"
}
} else if cfg.Providers.Moonshot.APIKey != "" {
apiKey = cfg.Providers.Moonshot.APIKey
apiBase = cfg.Providers.Moonshot.APIBase
proxy = cfg.Providers.Moonshot.Proxy
if apiBase == "" {
apiBase = "https://api.moonshot.cn/v1"
}
}
case strings.HasPrefix(model, "openrouter/") || strings.HasPrefix(model, "anthropic/") || strings.HasPrefix(model, "openai/") || strings.HasPrefix(model, "meta-llama/") || strings.HasPrefix(model, "deepseek/") || strings.HasPrefix(model, "google/"):
apiKey = cfg.Providers.OpenRouter.APIKey
proxy = cfg.Providers.OpenRouter.Proxy

View file

@ -11,7 +11,7 @@ Ultra-lightweight personal AI assistant written in Go, inspired by nanobot.
## Purpose
- Provide intelligent AI assistance with minimal resource usage
- Support multiple LLM providers (OpenAI, Anthropic, Zhipu, etc.)
- Support multiple LLM providers (OpenAI, Anthropic, Z.ai, etc.)
- Enable easy customization through skills system
- Run on minimal hardware ($10 boards, <10MB RAM)