Files
magpie/internal/agent/modelprefs_test.go
T
yetone 559ce02147 models: a model's own name given by the user keeps its provider after it too (#203 uclort: 如果在供应商模型页自定义模型名称,在 Codex 中就不会显示供应商了) — Entry.Label() showed "name · provider" only for a model's own (vendor's or models.dev's) name; a name the user gave it (provider's model page → Names & levels) dropped the provider entirely, so a renamed model in Codex's picker (and Pi's, ZCode's, OMP's, magpie's own gateway list — everything magpieModels/Label feeds) could no longer be told apart by vendor at a glance. Label() now appends " · provider" (or "routing group") to a custom name too, the same as it does for the vendor's own, and only leaves it off when the name already contains the provider's (case-insensitively), so a name like "Sol on A" isn't doubled to "Sol on A · A". No settings toggle added: the fix makes the provider suffix unconditional (what the issue actually asked for), so a preference to hide/show it would only reintroduce the gap; there's also no existing "model list" preferences surface to hang it on cheaply — Names & levels only holds the name and reasoning-level pickers. Tested with TestModelName (internal/provider/modelprefs_test.go, sandbox HOME): a custom name now reads "My Sol · A" in Label() and in CodexListed(), and "Sol on A" (already containing the provider) is left alone; and TestModelNameAndLevelsReachAgentFiles (internal/agent/modelprefs_test.go, sandbox HOME) checks the generated Codex model_catalog_json and Pi models.json entries carry "GLM · Relay" for a custom name and don't double it to "GLM via Relay · Relay" when the name already says Relay. go build -tags nogui (and GOOS=linux, GOOS=windows), go test -tags nogui -count=1 ./... pass except TestUserPath and TestClaudeAccountNamedAsItsLogin, which are load-flaky (pass alone, unrelated to this change) same as the pre-existing rtk.go gofmt / TestConfiguredModelsAdvertiseImageInput flakiness
2026-09-29 18:56:32 +08:00

99 lines
3.6 KiB
Go

package agent
import (
"encoding/json"
"os"
"path/filepath"
"strings"
"testing"
"github.com/yetone/magpie/internal/catalog"
"github.com/yetone/magpie/internal/provider"
)
// A model the user names, or keeps some reasoning levels of, is named so
// and offered only those in the lists magpie wrote into the agents' files,
// rewritten as soon as it is changed; a reset gives the model's own back.
func TestModelNameAndLevelsReachAgentFiles(t *testing.T) {
home := syncHome(t)
os.WriteFile(catalog.CachePath(), []byte(`{"zai":{"models":{"glm-4.6":{"id":"glm-4.6","name":"GLM-4.6","limit":{"context":204800},
"reasoning_options":[{"type":"effort","values":["low","medium","high"]}]}}}}`), 0o644)
catalog.Reset()
if err := provider.Save(provider.Provider{ID: "relay", Name: "Relay", Catalog: "zai", Key: "k", Chat: "http://127.0.0.1:1/v1", Models: []string{"glm-4.6"}}); err != nil {
t.Fatal(err)
}
piModels := filepath.Join(home, ".pi", "agent", "models.json")
writeFile(t, piModels, `{"providers":{"magpie":{"name":"magpie","models":[]}}}`)
codexDir := filepath.Join(home, ".codex")
codexCat := filepath.Join(codexDir, "magpie-models.json")
writeFile(t, filepath.Join(codexDir, "config.toml"), "model = \"relay/glm-4.6\"\nmodel_provider = \"magpie\"\nmodel_catalog_json = \""+codexCat+"\"\n")
writeFile(t, codexCat, `{"models":[]}`)
catalog.Changed = SyncCatalog
t.Cleanup(func() { catalog.Changed = nil })
if err := provider.SetModelName("relay/glm-4.6", "GLM"); err != nil {
t.Fatal(err)
}
if err := provider.SetModelEfforts("relay/glm-4.6", []string{"low", "high"}); err != nil {
t.Fatal(err)
}
var pi struct {
Providers map[string]struct {
Models []map[string]any `json:"models"`
} `json:"providers"`
}
if err := json.Unmarshal([]byte(readFile(piModels)), &pi); err != nil {
t.Fatal(err)
}
ms := pi.Providers["magpie"].Models
// a custom name still carries its provider, the same as GLM-4.6's own
// name would, so a picker full of renamed models can still be told
// apart by vendor
if len(ms) != 1 || ms[0]["id"] != "relay/glm-4.6" || ms[0]["name"] != "GLM · Relay" {
t.Fatalf("pi models.json: %v", ms)
}
var cx struct {
Models []struct {
Slug string `json:"slug"`
Name string `json:"display_name"`
Efforts []struct {
Effort string `json:"effort"`
} `json:"supported_reasoning_levels"`
} `json:"models"`
}
if err := json.Unmarshal([]byte(readFile(codexCat)), &cx); err != nil {
t.Fatal(err)
}
if len(cx.Models) != 1 || cx.Models[0].Slug != "relay/glm-4.6" || cx.Models[0].Name != "GLM · Relay" {
t.Fatalf("codex catalog: %+v", cx.Models)
}
var levels []string
for _, e := range cx.Models[0].Efforts {
levels = append(levels, e.Effort)
}
if strings.Join(levels, ",") != "low,high" {
t.Fatalf("codex levels: %v", levels)
}
// unless the custom name already says the provider: it isn't repeated
if err := provider.SetModelName("relay/glm-4.6", "GLM via Relay"); err != nil {
t.Fatal(err)
}
if got := readFile(codexCat); !strings.Contains(got, `"GLM via Relay"`) || strings.Contains(got, `"GLM via Relay · Relay"`) {
t.Fatalf("codex catalog, provider repeated:\n%s", got)
}
if err := provider.SetModelName("relay/glm-4.6", ""); err != nil {
t.Fatal(err)
}
if err := provider.SetModelEfforts("relay/glm-4.6", nil); err != nil {
t.Fatal(err)
}
if got := readFile(codexCat); !strings.Contains(got, `"GLM-4.6 · Relay"`) || !strings.Contains(got, `"medium"`) {
t.Fatalf("codex catalog after reset:\n%s", got)
}
if got := readFile(piModels); !strings.Contains(got, `"GLM-4.6 · Relay"`) {
t.Fatalf("pi models.json after reset:\n%s", got)
}
}