Skip to content

Commit a94bae9

Browse files
Merge pull request #109 from 73ai/glm-integration
Add Z.AI (Zhipu AI) GLM provider
2 parents b656cf2 + 7b12a57 commit a94bae9

File tree

11 files changed

+844
-1
lines changed

11 files changed

+844
-1
lines changed

config/profiles.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,19 @@ var Profiles = map[string]ModelProfile{
7777
},
7878
Providers: []string{"openrouter"},
7979
},
80+
"zai": {
81+
Name: "zai",
82+
Label: "Z.AI (single provider)",
83+
Description: "GLM models from Z.AI. Free tier available.",
84+
Category: "single",
85+
Tiers: ProfileTiers{
86+
Default: "zai/glm-4.5-flash",
87+
Complex: "zai/glm-4.7",
88+
Fast: "zai/glm-4.5-flash",
89+
Nano: "zai/glm-4.5-flash",
90+
},
91+
Providers: []string{"zai"},
92+
},
8093
"openai": {
8194
Name: "openai",
8295
Label: "OpenAI (single provider)",
@@ -134,7 +147,7 @@ var Profiles = map[string]ModelProfile{
134147
// ProfileNames returns profile names in display order.
135148
var ProfileNames = []string{
136149
"starter", "standard", "premium",
137-
"gemini", "anthropic", "openai", "groq", "openrouter",
150+
"gemini", "anthropic", "openai", "groq", "openrouter", "zai",
138151
}
139152

140153
var profileNameRe = regexp.MustCompile(`^[a-z][a-z0-9-]{1,29}$`)

internal/cli/chat.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
_ "github.com/73ai/openbotkit/provider/groq"
2626
_ "github.com/73ai/openbotkit/provider/openai"
2727
_ "github.com/73ai/openbotkit/provider/openrouter"
28+
_ "github.com/73ai/openbotkit/provider/zai"
2829
"github.com/spf13/cobra"
2930
)
3031

internal/cli/settings_cmd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
_ "github.com/73ai/openbotkit/provider/groq"
1414
_ "github.com/73ai/openbotkit/provider/openai"
1515
_ "github.com/73ai/openbotkit/provider/openrouter"
16+
_ "github.com/73ai/openbotkit/provider/zai"
1617
"github.com/73ai/openbotkit/settings"
1718
"github.com/spf13/cobra"
1819
)

internal/cli/setup_models.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
_ "github.com/73ai/openbotkit/provider/groq"
1616
_ "github.com/73ai/openbotkit/provider/openai"
1717
_ "github.com/73ai/openbotkit/provider/openrouter"
18+
_ "github.com/73ai/openbotkit/provider/zai"
1819
"github.com/spf13/cobra"
1920
)
2021

provider/context_window.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ var contextWindows = map[string]int{
1616
"llama-3.3-70b-versatile": 131072,
1717
"llama-4-scout-17b-16e": 131072,
1818
"llama-4-maverick-17b-128e": 131072,
19+
"glm-4.5-flash": 128000,
20+
"glm-4.5-air": 128000,
21+
"glm-4.5": 128000,
22+
"glm-4.6": 128000,
23+
"glm-4.7": 200000,
24+
"glm-4.7-flash": 200000,
25+
"glm-4.7-flashx": 200000,
26+
"glm-5": 200000,
27+
"glm-5-turbo": 200000,
1928
}
2029

2130
// DefaultContextWindow returns the context window size for a model.

provider/context_window_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,25 @@ func TestDefaultContextWindow_NestedModelID(t *testing.T) {
5151
}
5252
}
5353

54+
func TestDefaultContextWindow_GLMModels(t *testing.T) {
55+
models := map[string]int{
56+
"glm-4.5-flash": 128000,
57+
"glm-4.5-air": 128000,
58+
"glm-4.5": 128000,
59+
"glm-4.6": 128000,
60+
"glm-4.7": 200000,
61+
"glm-4.7-flash": 200000,
62+
"glm-4.7-flashx": 200000,
63+
"glm-5": 200000,
64+
"glm-5-turbo": 200000,
65+
}
66+
for model, want := range models {
67+
if got := DefaultContextWindow(model); got != want {
68+
t.Errorf("%s = %d, want %d", model, got, want)
69+
}
70+
}
71+
}
72+
5473
func TestDefaultContextWindow_GroqModels(t *testing.T) {
5574
models := map[string]int{
5675
"llama-3.1-8b-instant": 131072,

provider/models.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ func ListModels(ctx context.Context, providerName, apiKey string, cfg config.Mod
3131
return listModelsGroq(ctx, apiKey, cfg)
3232
case "openrouter":
3333
return listModelsOpenRouter(ctx, apiKey, cfg)
34+
case "zai":
35+
return listModelsZAI(ctx, apiKey, cfg)
3436
default:
3537
return nil, fmt.Errorf("unknown provider %q", providerName)
3638
}
@@ -209,6 +211,43 @@ func listModelsOpenRouter(ctx context.Context, apiKey string, cfg config.ModelPr
209211
return listModelsOpenAICompat(ctx, apiKey, cfg, "https://openrouter.ai/api", "openrouter")
210212
}
211213

214+
// --- Z.AI ---
215+
216+
func listModelsZAI(ctx context.Context, apiKey string, cfg config.ModelProviderConfig) ([]AvailableModel, error) {
217+
url := baseURL(cfg, "https://api.z.ai/api/paas/v4") + "/models"
218+
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
219+
if err != nil {
220+
return nil, err
221+
}
222+
req.Header.Set("Authorization", "Bearer "+apiKey)
223+
224+
resp, err := http.DefaultClient.Do(req)
225+
if err != nil {
226+
return nil, err
227+
}
228+
defer resp.Body.Close()
229+
if resp.StatusCode != http.StatusOK {
230+
return nil, fmt.Errorf("zai list models: HTTP %d", resp.StatusCode)
231+
}
232+
233+
var body struct {
234+
Data []struct {
235+
ID string `json:"id"`
236+
} `json:"data"`
237+
}
238+
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
239+
return nil, err
240+
}
241+
242+
var models []AvailableModel
243+
for _, m := range body.Data {
244+
if strings.Contains(m.ID, "glm") {
245+
models = append(models, AvailableModel{ID: m.ID, DisplayName: m.ID, Provider: "zai"})
246+
}
247+
}
248+
return models, nil
249+
}
250+
212251
func listModelsOpenAICompat(ctx context.Context, apiKey string, cfg config.ModelProviderConfig, defaultBase, providerName string) ([]AvailableModel, error) {
213252
url := baseURL(cfg, defaultBase) + "/v1/models"
214253
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)

provider/registry.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var ProviderEnvVars = map[string]string{
1414
"gemini": "GEMINI_API_KEY",
1515
"groq": "GROQ_API_KEY",
1616
"openrouter": "OPENROUTER_API_KEY",
17+
"zai": "ZAI_API_KEY",
1718
}
1819

1920
// Factory creates a Provider from a model provider config and resolved API key.

0 commit comments

Comments
 (0)