fix ci
This commit is contained in:
parent
80e0ff8393
commit
da7b5d499c
4 changed files with 66 additions and 134 deletions
|
|
@ -99,6 +99,7 @@ func createCodexAuthProvider() (LLMProvider, error) {
|
|||
// - Model "openai/gpt-4o" -> ("openai", "gpt-4o")
|
||||
// - Model "nvidia/z-ai/glm-5.1" -> ("nvidia", "z-ai/glm-5.1")
|
||||
// - Provider "nvidia", Model "z-ai/glm-5.1" -> ("nvidia", "z-ai/glm-5.1")
|
||||
// - Provider "openai", Model "openai/gpt-4o" -> ("openai", "openai/gpt-4o")
|
||||
// - Model "gpt-4o" -> ("openai", "gpt-4o")
|
||||
func ExtractProtocol(cfg *config.ModelConfig) (protocol, modelID string) {
|
||||
if cfg == nil {
|
||||
|
|
@ -107,13 +108,7 @@ func ExtractProtocol(cfg *config.ModelConfig) (protocol, modelID string) {
|
|||
|
||||
model := strings.TrimSpace(cfg.Model)
|
||||
if provider := strings.TrimSpace(cfg.Provider); provider != "" {
|
||||
normalized := NormalizeProvider(provider)
|
||||
if prefix, rest, found := strings.Cut(model, "/"); found {
|
||||
if NormalizeProvider(prefix) == normalized && strings.TrimSpace(rest) != "" {
|
||||
return normalized, strings.TrimSpace(rest)
|
||||
}
|
||||
}
|
||||
return normalized, model
|
||||
return NormalizeProvider(provider), model
|
||||
}
|
||||
if model == "" {
|
||||
return "", ""
|
||||
|
|
|
|||
|
|
@ -84,16 +84,16 @@ func TestExtractProtocol(t *testing.T) {
|
|||
wantModelID: "z-ai/glm-5.1",
|
||||
},
|
||||
{
|
||||
name: "explicit provider strips redundant matching prefix",
|
||||
name: "explicit provider preserves matching prefix",
|
||||
config: &config.ModelConfig{Provider: "openai", Model: "openai/gpt-4o"},
|
||||
wantProtocol: "openai",
|
||||
wantModelID: "gpt-4o",
|
||||
wantModelID: "openai/gpt-4o",
|
||||
},
|
||||
{
|
||||
name: "explicit provider strips redundant aliased prefix",
|
||||
name: "explicit provider preserves aliased prefix",
|
||||
config: &config.ModelConfig{Provider: "qwen", Model: "qwen/qwen-plus"},
|
||||
wantProtocol: "qwen-portal",
|
||||
wantModelID: "qwen-plus",
|
||||
wantModelID: "qwen/qwen-plus",
|
||||
},
|
||||
{
|
||||
name: "empty provider segment",
|
||||
|
|
@ -164,7 +164,7 @@ func TestCreateProviderFromConfig_UsesExplicitProvider(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCreateProviderFromConfig_StripsRedundantExplicitProviderPrefix(t *testing.T) {
|
||||
func TestCreateProviderFromConfig_PreservesExplicitProviderPrefixedModel(t *testing.T) {
|
||||
cfg := &config.ModelConfig{
|
||||
ModelName: "test-openai",
|
||||
Provider: "openai",
|
||||
|
|
@ -180,8 +180,8 @@ func TestCreateProviderFromConfig_StripsRedundantExplicitProviderPrefix(t *testi
|
|||
if provider == nil {
|
||||
t.Fatal("CreateProviderFromConfig() returned nil provider")
|
||||
}
|
||||
if modelID != "gpt-4o" {
|
||||
t.Fatalf("modelID = %q, want %q", modelID, "gpt-4o")
|
||||
if modelID != "openai/gpt-4o" {
|
||||
t.Fatalf("modelID = %q, want %q", modelID, "openai/gpt-4o")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,27 +51,6 @@ type modelResponse struct {
|
|||
IsVirtual bool `json:"is_virtual"`
|
||||
}
|
||||
|
||||
func normalizeExplicitProviderModel(mc *config.ModelConfig) {
|
||||
if mc == nil {
|
||||
return
|
||||
}
|
||||
|
||||
provider := strings.TrimSpace(mc.Provider)
|
||||
model := strings.TrimSpace(mc.Model)
|
||||
if provider == "" || model == "" {
|
||||
return
|
||||
}
|
||||
|
||||
prefix, rest, found := strings.Cut(model, "/")
|
||||
if !found || strings.TrimSpace(rest) == "" {
|
||||
return
|
||||
}
|
||||
|
||||
if providers.NormalizeProvider(prefix) == providers.NormalizeProvider(provider) {
|
||||
mc.Model = strings.TrimSpace(rest)
|
||||
}
|
||||
}
|
||||
|
||||
// handleListModels returns all model_list entries with masked API keys.
|
||||
//
|
||||
// GET /api/models
|
||||
|
|
@ -161,7 +140,6 @@ func (h *Handler) handleAddModel(w http.ResponseWriter, r *http.Request) {
|
|||
if mc.APIKey != "" {
|
||||
mc.ModelConfig.SetAPIKey(mc.APIKey)
|
||||
}
|
||||
normalizeExplicitProviderModel(&mc.ModelConfig)
|
||||
|
||||
cfg, err := config.LoadConfig(h.configPath)
|
||||
if err != nil {
|
||||
|
|
@ -288,7 +266,6 @@ func (h *Handler) handleUpdateModel(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
}
|
||||
normalizeExplicitProviderModel(&mc.ModelConfig)
|
||||
|
||||
cfg.ModelList[idx] = &mc.ModelConfig
|
||||
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@ func TestHandleAddModel_PersistsProvider(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestHandleAddModel_NormalizesRedundantExplicitProviderPrefix(t *testing.T) {
|
||||
func TestHandleAddModel_PreservesExplicitProviderPrefixedModel(t *testing.T) {
|
||||
configPath, cleanup := setupOAuthTestEnv(t)
|
||||
defer cleanup()
|
||||
|
||||
|
|
@ -538,8 +538,8 @@ func TestHandleAddModel_NormalizesRedundantExplicitProviderPrefix(t *testing.T)
|
|||
if got := added.Provider; got != "openai" {
|
||||
t.Fatalf("provider = %q, want %q", got, "openai")
|
||||
}
|
||||
if got := added.Model; got != "gpt-4o-mini" {
|
||||
t.Fatalf("model = %q, want %q", got, "gpt-4o-mini")
|
||||
if got := added.Model; got != "openai/gpt-4o-mini" {
|
||||
t.Fatalf("model = %q, want %q", got, "openai/gpt-4o-mini")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -662,7 +662,7 @@ func TestHandleUpdateModel_PersistsProvider(t *testing.T) {
|
|||
Model: "gpt-4o",
|
||||
Provider: "openai",
|
||||
}}
|
||||
if err := config.SaveConfig(configPath, cfg); err != nil {
|
||||
if err = config.SaveConfig(configPath, cfg); err != nil {
|
||||
t.Fatalf("SaveConfig() error = %v", err)
|
||||
}
|
||||
|
||||
|
|
@ -692,49 +692,7 @@ func TestHandleUpdateModel_PersistsProvider(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestHandleUpdateModel_PreservesProviderWhenOmitted(t *testing.T) {
|
||||
configPath, cleanup := setupOAuthTestEnv(t)
|
||||
defer cleanup()
|
||||
|
||||
cfg, err := config.LoadConfig(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadConfig() error = %v", err)
|
||||
}
|
||||
cfg.ModelList = []*config.ModelConfig{{
|
||||
ModelName: "editable",
|
||||
Model: "z-ai/glm-5.1",
|
||||
Provider: "nvidia",
|
||||
}}
|
||||
if err := config.SaveConfig(configPath, cfg); err != nil {
|
||||
t.Fatalf("SaveConfig() error = %v", err)
|
||||
}
|
||||
|
||||
h := NewHandler(configPath)
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodPut, "/api/models/0", bytes.NewBufferString(`{
|
||||
"model_name":"editable",
|
||||
"model":"z-ai/glm-5.1"
|
||||
}`))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want %d, body=%s", rec.Code, http.StatusOK, rec.Body.String())
|
||||
}
|
||||
|
||||
updated, err := config.LoadConfig(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadConfig() error = %v", err)
|
||||
}
|
||||
if got := updated.ModelList[0].Provider; got != "nvidia" {
|
||||
t.Fatalf("provider = %q, want %q", got, "nvidia")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleUpdateModel_NormalizesRedundantExplicitProviderPrefix(t *testing.T) {
|
||||
func TestHandleUpdateModel_PreservesExplicitProviderPrefixedModel(t *testing.T) {
|
||||
configPath, cleanup := setupOAuthTestEnv(t)
|
||||
defer cleanup()
|
||||
|
||||
|
|
@ -747,7 +705,7 @@ func TestHandleUpdateModel_NormalizesRedundantExplicitProviderPrefix(t *testing.
|
|||
Model: "gpt-4o",
|
||||
Provider: "openai",
|
||||
}}
|
||||
if err := config.SaveConfig(configPath, cfg); err != nil {
|
||||
if err = config.SaveConfig(configPath, cfg); err != nil {
|
||||
t.Fatalf("SaveConfig() error = %v", err)
|
||||
}
|
||||
|
||||
|
|
@ -775,8 +733,54 @@ func TestHandleUpdateModel_NormalizesRedundantExplicitProviderPrefix(t *testing.
|
|||
if got := updated.ModelList[0].Provider; got != "openai" {
|
||||
t.Fatalf("provider = %q, want %q", got, "openai")
|
||||
}
|
||||
if got := updated.ModelList[0].Model; got != "gpt-5.4" {
|
||||
t.Fatalf("model = %q, want %q", got, "gpt-5.4")
|
||||
if got := updated.ModelList[0].Model; got != "openai/gpt-5.4" {
|
||||
t.Fatalf("model = %q, want %q", got, "openai/gpt-5.4")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleListModels_PreservesExplicitProviderPrefixedModel(t *testing.T) {
|
||||
configPath, cleanup := setupOAuthTestEnv(t)
|
||||
defer cleanup()
|
||||
|
||||
cfg, err := config.LoadConfig(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadConfig() error = %v", err)
|
||||
}
|
||||
cfg.ModelList = []*config.ModelConfig{{
|
||||
ModelName: "openrouter-auto-explicit",
|
||||
Provider: "openrouter",
|
||||
Model: "openrouter/auto",
|
||||
}}
|
||||
if err := config.SaveConfig(configPath, cfg); err != nil {
|
||||
t.Fatalf("SaveConfig() error = %v", err)
|
||||
}
|
||||
|
||||
h := NewHandler(configPath)
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/models", nil)
|
||||
mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want %d, body=%s", rec.Code, http.StatusOK, rec.Body.String())
|
||||
}
|
||||
|
||||
var resp struct {
|
||||
Models []modelResponse `json:"models"`
|
||||
}
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("Unmarshal() error = %v", err)
|
||||
}
|
||||
if len(resp.Models) != 1 {
|
||||
t.Fatalf("len(models) = %d, want 1", len(resp.Models))
|
||||
}
|
||||
if got := resp.Models[0].Provider; got != "openrouter" {
|
||||
t.Fatalf("provider = %q, want %q", got, "openrouter")
|
||||
}
|
||||
if got := resp.Models[0].Model; got != "openrouter/auto" {
|
||||
t.Fatalf("model = %q, want %q", got, "openrouter/auto")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -792,7 +796,7 @@ func TestHandleUpdateModel_PreservesLegacyModelPrefixWhenProviderOmitted(t *test
|
|||
ModelName: "legacy-openrouter",
|
||||
Model: "openrouter/openai/gpt-5.4",
|
||||
}}
|
||||
if err := config.SaveConfig(configPath, cfg); err != nil {
|
||||
if err = config.SaveConfig(configPath, cfg); err != nil {
|
||||
t.Fatalf("SaveConfig() error = %v", err)
|
||||
}
|
||||
|
||||
|
|
@ -813,7 +817,7 @@ func TestHandleUpdateModel_PreservesLegacyModelPrefixWhenProviderOmitted(t *test
|
|||
var listResp struct {
|
||||
Models []modelResponse `json:"models"`
|
||||
}
|
||||
if err := json.Unmarshal(recList.Body.Bytes(), &listResp); err != nil {
|
||||
if err = json.Unmarshal(recList.Body.Bytes(), &listResp); err != nil {
|
||||
t.Fatalf("Unmarshal() error = %v", err)
|
||||
}
|
||||
if len(listResp.Models) != 1 {
|
||||
|
|
@ -862,7 +866,7 @@ func TestHandleUpdateModel_PreservesLegacyModelPrefixWhenProviderOmittedAndModel
|
|||
ModelName: "legacy-openrouter",
|
||||
Model: "openrouter/openai/gpt-5.4",
|
||||
}}
|
||||
if err := config.SaveConfig(configPath, cfg); err != nil {
|
||||
if err = config.SaveConfig(configPath, cfg); err != nil {
|
||||
t.Fatalf("SaveConfig() error = %v", err)
|
||||
}
|
||||
|
||||
|
|
@ -894,50 +898,6 @@ func TestHandleUpdateModel_PreservesLegacyModelPrefixWhenProviderOmittedAndModel
|
|||
}
|
||||
}
|
||||
|
||||
func TestHandleUpdateModel_OmittedProviderAllowsLegacyProviderChangeForSimpleVisibleModel(t *testing.T) {
|
||||
configPath, cleanup := setupOAuthTestEnv(t)
|
||||
defer cleanup()
|
||||
|
||||
cfg, err := config.LoadConfig(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadConfig() error = %v", err)
|
||||
}
|
||||
cfg.ModelList = []*config.ModelConfig{{
|
||||
ModelName: "legacy-openai",
|
||||
Model: "openai/gpt-5.4",
|
||||
}}
|
||||
if err := config.SaveConfig(configPath, cfg); err != nil {
|
||||
t.Fatalf("SaveConfig() error = %v", err)
|
||||
}
|
||||
|
||||
h := NewHandler(configPath)
|
||||
mux := http.NewServeMux()
|
||||
h.RegisterRoutes(mux)
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodPut, "/api/models/0", bytes.NewBufferString(`{
|
||||
"model_name":"legacy-openai",
|
||||
"model":"anthropic/claude-sonnet-4.6"
|
||||
}`))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
mux.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want %d, body=%s", rec.Code, http.StatusOK, rec.Body.String())
|
||||
}
|
||||
|
||||
updated, err := config.LoadConfig(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadConfig() error = %v", err)
|
||||
}
|
||||
if got := updated.ModelList[0].Provider; got != "" {
|
||||
t.Fatalf("provider = %q, want empty", got)
|
||||
}
|
||||
if got := updated.ModelList[0].Model; got != "anthropic/claude-sonnet-4.6" {
|
||||
t.Fatalf("model = %q, want %q", got, "anthropic/claude-sonnet-4.6")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleListModels_ReturnsProviderField(t *testing.T) {
|
||||
configPath, cleanup := setupOAuthTestEnv(t)
|
||||
defer cleanup()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue