feat: add Z.ai provider support (general API + coding plan) (#102)

* feat: add Z.ai provider support (general API + coding plan)

Add Z.ai (GLM) as a new LLM provider with two variants:
- `zai`: general API (api.z.ai/api/paas/v4)
- `zai_coding`: coding plan (api.z.ai/api/coding/paas/v4)

Reuses OpenAIProvider — Z.ai API is OpenAI-compatible with Bearer
token auth, SSE streaming, and reasoning_content support.

Includes: store constants, config struct fields, env var loading
(GOCLAW_ZAI_API_KEY, GOCLAW_ZAI_CODING_API_KEY), secret masking,
config + DB registration, onboard wizard, and UI provider types.

Default model: glm-5

Closes #100

* docs: add Z.ai provider entries to providers documentation
This commit is contained in:
Duc Nguyen authored and GitHub committed 2026-03-09 22:28:18 +07:00
1 parent 344e2ac7d1
commit e63ff014cb
8 files changed
+52

No files matched your search

+30
View File
@@ -98,6 +98,24 @@ func registerProviders(registry *providers.Registry, cfg *config.Config) {
slog.Info("registered provider", "name", "bailian")
}
if cfg.Providers.Zai.APIKey != "" {
base := cfg.Providers.Zai.APIBase
if base == "" {
base = "https://api.z.ai/api/paas/v4"
}
registry.Register(providers.NewOpenAIProvider("zai", cfg.Providers.Zai.APIKey, base, "glm-5"))
slog.Info("registered provider", "name", "zai")
}
if cfg.Providers.ZaiCoding.APIKey != "" {
base := cfg.Providers.ZaiCoding.APIBase
if base == "" {
base = "https://api.z.ai/api/coding/paas/v4"
}
registry.Register(providers.NewOpenAIProvider("zai-coding", cfg.Providers.ZaiCoding.APIKey, base, "glm-5"))
slog.Info("registered provider", "name", "zai-coding")
}
// Claude CLI provider (subscription-based, no API key needed)
if cfg.Providers.ClaudeCLI.CLIPath != "" {
cliPath := cfg.Providers.ClaudeCLI.CLIPath
@@ -243,6 +261,18 @@ func registerProvidersFromDB(registry *providers.Registry, provStore store.Provi
base = "https://coding-intl.dashscope.aliyuncs.com/v1"
}
registry.Register(providers.NewOpenAIProvider(p.Name, p.APIKey, base, "qwen3.5-plus"))
case store.ProviderZai:
base := p.APIBase
if base == "" {
base = "https://api.z.ai/api/paas/v4"
}
registry.Register(providers.NewOpenAIProvider(p.Name, p.APIKey, base, "glm-5"))
case store.ProviderZaiCoding:
base := p.APIBase
if base == "" {
base = "https://api.z.ai/api/coding/paas/v4"
}
registry.Register(providers.NewOpenAIProvider(p.Name, p.APIKey, base, "glm-5"))
case store.ProviderSuno:
// Suno is a media-only provider (music gen). Register as OpenAI-compat
// so credentialProvider interface works for API key/base extraction.
+2
View File
@@ -31,6 +31,8 @@ var defaultPlaceholderProviders = []store.LLMProviderData{
{Name: "synthetic", DisplayName: "Synthetic", ProviderType: store.ProviderOpenAICompat, APIBase: "https://api.synthetic.new/openai/v1", Enabled: false},
{Name: "alicloud-api", DisplayName: "AliCloud API", ProviderType: store.ProviderDashScope, APIBase: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", Enabled: false},
{Name: "alicloud-sub", DisplayName: "AliCloud Sub", ProviderType: store.ProviderBailian, APIBase: "https://coding-intl.dashscope.aliyuncs.com/v1", Enabled: false},
{Name: "zai", DisplayName: "Z.ai API", ProviderType: store.ProviderZai, APIBase: "https://api.z.ai/api/paas/v4", Enabled: false},
{Name: "zai-coding", DisplayName: "Z.ai Coding Plan", ProviderType: store.ProviderZaiCoding, APIBase: "https://api.z.ai/api/coding/paas/v4", Enabled: false},
}
// seedOnboardPlaceholders opens a PG store and seeds disabled placeholder providers