mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-18 08:14:39 +00:00
feat: update MiniMax and Z.AI provider defaults
Refresh MiniMax to MiniMax-M3, update Z.AI defaults to glm-5.2, and add focused provider catalog/runtime coverage.
This commit is contained in:
1 parent
2a66401a28
commit
b5d5fce6e4
10 files changed
+480
-38
No files matched your search
+27
-14
@@ -76,8 +76,11 @@ func registerProviders(registry *providers.Registry, cfg *config.Config, modelRe
|
||||
}
|
||||
|
||||
if cfg.Providers.MiniMax.APIKey != "" {
|
||||
registry.Register(providers.NewOpenAIProvider("minimax", cfg.Providers.MiniMax.APIKey, "https://api.minimax.io/v1", "MiniMax-M2.5").
|
||||
WithChatPath("/text/chatcompletion_v2"))
|
||||
base := cfg.Providers.MiniMax.APIBase
|
||||
if base == "" {
|
||||
base = store.MiniMaxDefaultAPIBase
|
||||
}
|
||||
registry.Register(providers.NewOpenAIProvider("minimax", cfg.Providers.MiniMax.APIKey, base, store.MiniMaxDefaultModel))
|
||||
slog.Info("registered provider", "name", "minimax")
|
||||
}
|
||||
|
||||
@@ -109,18 +112,18 @@ func registerProviders(registry *providers.Registry, cfg *config.Config, modelRe
|
||||
if cfg.Providers.Zai.APIKey != "" {
|
||||
base := cfg.Providers.Zai.APIBase
|
||||
if base == "" {
|
||||
base = "https://api.z.ai/api/paas/v4"
|
||||
base = store.ZaiDefaultAPIBase
|
||||
}
|
||||
registry.Register(providers.NewOpenAIProvider("zai", cfg.Providers.Zai.APIKey, base, "glm-5"))
|
||||
registry.Register(providers.NewOpenAIProvider("zai", cfg.Providers.Zai.APIKey, base, store.ZaiDefaultModel))
|
||||
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"
|
||||
base = store.ZaiCodingDefaultAPIBase
|
||||
}
|
||||
registry.Register(providers.NewOpenAIProvider("zai-coding", cfg.Providers.ZaiCoding.APIKey, base, "glm-5"))
|
||||
registry.Register(providers.NewOpenAIProvider("zai-coding", cfg.Providers.ZaiCoding.APIKey, base, store.ZaiDefaultModel))
|
||||
slog.Info("registered provider", "name", "zai-coding")
|
||||
}
|
||||
|
||||
@@ -362,15 +365,15 @@ func registerProvidersFromDB(registry *providers.Registry, provStore store.Provi
|
||||
case store.ProviderZai:
|
||||
base := p.APIBase
|
||||
if base == "" {
|
||||
base = "https://api.z.ai/api/paas/v4"
|
||||
base = store.ZaiDefaultAPIBase
|
||||
}
|
||||
registry.RegisterForTenant(p.TenantID, providers.NewOpenAIProvider(p.Name, p.APIKey, base, "glm-5"))
|
||||
registry.RegisterForTenant(p.TenantID, providers.NewOpenAIProvider(p.Name, p.APIKey, base, store.ZaiDefaultModel))
|
||||
case store.ProviderZaiCoding:
|
||||
base := p.APIBase
|
||||
if base == "" {
|
||||
base = "https://api.z.ai/api/coding/paas/v4"
|
||||
base = store.ZaiCodingDefaultAPIBase
|
||||
}
|
||||
registry.RegisterForTenant(p.TenantID, providers.NewOpenAIProvider(p.Name, p.APIKey, base, "glm-5"))
|
||||
registry.RegisterForTenant(p.TenantID, providers.NewOpenAIProvider(p.Name, p.APIKey, base, store.ZaiDefaultModel))
|
||||
case store.ProviderOllamaCloud:
|
||||
base := p.APIBase
|
||||
if base == "" {
|
||||
@@ -413,11 +416,9 @@ func registerProvidersFromDB(registry *providers.Registry, provStore store.Provi
|
||||
})
|
||||
registry.RegisterForTenant(p.TenantID, prov)
|
||||
default:
|
||||
prov := providers.NewOpenAIProvider(p.Name, p.APIKey, p.APIBase, "")
|
||||
base, model := openAIProviderDefaults(p.ProviderType, p.APIBase)
|
||||
prov := providers.NewOpenAIProvider(p.Name, p.APIKey, base, model)
|
||||
prov.WithProviderType(p.ProviderType)
|
||||
if p.ProviderType == store.ProviderMiniMax {
|
||||
prov.WithChatPath("/text/chatcompletion_v2")
|
||||
}
|
||||
if p.ProviderType == store.ProviderOpenRouter {
|
||||
prov.WithSiteInfo("https://goclaw.sh", "GoClaw")
|
||||
}
|
||||
@@ -427,6 +428,18 @@ func registerProvidersFromDB(registry *providers.Registry, provStore store.Provi
|
||||
}
|
||||
}
|
||||
|
||||
func openAIProviderDefaults(providerType, apiBase string) (string, string) {
|
||||
switch providerType {
|
||||
case store.ProviderMiniMax:
|
||||
if apiBase == "" {
|
||||
apiBase = store.MiniMaxDefaultAPIBase
|
||||
}
|
||||
return apiBase, store.MiniMaxDefaultModel
|
||||
default:
|
||||
return apiBase, ""
|
||||
}
|
||||
}
|
||||
|
||||
func registerClaudeCLIFromConfig(registry *providers.Registry, cfg *config.Config) {
|
||||
if cfg == nil || cfg.Providers.ClaudeCLI.CLIPath == "" {
|
||||
return
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/nextlevelbuilder/goclaw/internal/config"
|
||||
"github.com/nextlevelbuilder/goclaw/internal/providers"
|
||||
"github.com/nextlevelbuilder/goclaw/internal/store"
|
||||
)
|
||||
|
||||
func TestRegisterProvidersUsesCurrentMiniMaxAndZaiDefaults(t *testing.T) {
|
||||
cfg := &config.Config{}
|
||||
cfg.Providers.MiniMax.APIKey = "minimax-token"
|
||||
cfg.Providers.Zai.APIKey = "zai-token"
|
||||
cfg.Providers.ZaiCoding.APIKey = "zai-coding-token"
|
||||
|
||||
registry := providers.NewRegistry(nil)
|
||||
registerProviders(registry, cfg, providers.NewInMemoryRegistry())
|
||||
|
||||
assertProviderDefault(t, registry, providers.MasterTenantID, "minimax", "MiniMax-M3", "https://api.minimax.io/v1")
|
||||
assertProviderDefault(t, registry, providers.MasterTenantID, "zai", "glm-5.2", "https://api.z.ai/api/paas/v4")
|
||||
assertProviderDefault(t, registry, providers.MasterTenantID, "zai-coding", "glm-5.2", "https://api.z.ai/api/coding/paas/v4")
|
||||
}
|
||||
|
||||
func TestRegisterProvidersMiniMaxUsesOpenAIChatCompletionsPath(t *testing.T) {
|
||||
var capturedPath string
|
||||
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
capturedPath = r.URL.Path
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||
"choices": []map[string]any{
|
||||
{
|
||||
"message": map[string]string{"content": "ok"},
|
||||
"finish_reason": "stop",
|
||||
},
|
||||
},
|
||||
})
|
||||
}))
|
||||
t.Cleanup(upstream.Close)
|
||||
|
||||
cfg := &config.Config{}
|
||||
cfg.Providers.MiniMax.APIKey = "minimax-token"
|
||||
cfg.Providers.MiniMax.APIBase = upstream.URL
|
||||
|
||||
registry := providers.NewRegistry(nil)
|
||||
registerProviders(registry, cfg, providers.NewInMemoryRegistry())
|
||||
|
||||
runtimeProvider, err := registry.GetForTenant(providers.MasterTenantID, "minimax")
|
||||
if err != nil {
|
||||
t.Fatalf("GetForTenant() error = %v", err)
|
||||
}
|
||||
_, err = runtimeProvider.Chat(context.Background(), providers.ChatRequest{
|
||||
Messages: []providers.Message{{Role: "user", Content: "hi"}},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Chat() error = %v", err)
|
||||
}
|
||||
if capturedPath != "/chat/completions" {
|
||||
t.Fatalf("captured path = %q, want /chat/completions", capturedPath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterProvidersFromDBUsesCurrentMiniMaxAndZaiDefaults(t *testing.T) {
|
||||
tenantID := uuid.New()
|
||||
providerStore := gatewayProvidersStoreStub{
|
||||
providers: []store.LLMProviderData{
|
||||
{
|
||||
BaseModel: store.BaseModel{ID: uuid.New()},
|
||||
TenantID: tenantID,
|
||||
Name: "db-minimax",
|
||||
ProviderType: store.ProviderMiniMax,
|
||||
APIKey: "minimax-token",
|
||||
Enabled: true,
|
||||
},
|
||||
{
|
||||
BaseModel: store.BaseModel{ID: uuid.New()},
|
||||
TenantID: tenantID,
|
||||
Name: "db-zai",
|
||||
ProviderType: store.ProviderZai,
|
||||
APIKey: "zai-token",
|
||||
Enabled: true,
|
||||
},
|
||||
{
|
||||
BaseModel: store.BaseModel{ID: uuid.New()},
|
||||
TenantID: tenantID,
|
||||
Name: "db-zai-coding",
|
||||
ProviderType: store.ProviderZaiCoding,
|
||||
APIKey: "zai-coding-token",
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
registry := providers.NewRegistry(nil)
|
||||
registerProvidersFromDB(registry, providerStore, nil, "", "", nil, &config.Config{}, providers.NewInMemoryRegistry())
|
||||
|
||||
assertProviderDefault(t, registry, tenantID, "db-minimax", "MiniMax-M3", "https://api.minimax.io/v1")
|
||||
assertProviderDefault(t, registry, tenantID, "db-zai", "glm-5.2", "https://api.z.ai/api/paas/v4")
|
||||
assertProviderDefault(t, registry, tenantID, "db-zai-coding", "glm-5.2", "https://api.z.ai/api/coding/paas/v4")
|
||||
}
|
||||
|
||||
func assertProviderDefault(t *testing.T, registry *providers.Registry, tenantID uuid.UUID, name, wantModel, wantBase string) {
|
||||
t.Helper()
|
||||
runtimeProvider, err := registry.GetForTenant(tenantID, name)
|
||||
if err != nil {
|
||||
t.Fatalf("GetForTenant(%q) error = %v", name, err)
|
||||
}
|
||||
if got := runtimeProvider.DefaultModel(); got != wantModel {
|
||||
t.Fatalf("%s DefaultModel() = %q, want %q", name, got, wantModel)
|
||||
}
|
||||
openai, ok := runtimeProvider.(*providers.OpenAIProvider)
|
||||
if !ok {
|
||||
t.Fatalf("%s runtime provider = %T, want *providers.OpenAIProvider", name, runtimeProvider)
|
||||
}
|
||||
if got := openai.APIBase(); got != wantBase {
|
||||
t.Fatalf("%s APIBase() = %q, want %q", name, got, wantBase)
|
||||
}
|
||||
}
|
||||
|
||||
type gatewayProvidersStoreStub struct {
|
||||
providers []store.LLMProviderData
|
||||
}
|
||||
|
||||
func (s gatewayProvidersStoreStub) CreateProvider(context.Context, *store.LLMProviderData) error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (s gatewayProvidersStoreStub) GetProvider(context.Context, uuid.UUID) (*store.LLMProviderData, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (s gatewayProvidersStoreStub) GetProviderByName(context.Context, string) (*store.LLMProviderData, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (s gatewayProvidersStoreStub) ListProviders(context.Context) ([]store.LLMProviderData, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (s gatewayProvidersStoreStub) ListAllProviders(context.Context) ([]store.LLMProviderData, error) {
|
||||
return s.providers, nil
|
||||
}
|
||||
|
||||
func (s gatewayProvidersStoreStub) UpdateProvider(context.Context, uuid.UUID, map[string]any) error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (s gatewayProvidersStoreStub) DeleteProvider(context.Context, uuid.UUID) error {
|
||||
return errors.New("not implemented")
|
||||
}
|
||||
Reference in new issue
Block a user