agent: OpenHanako's own provider named as one of magpie's isn't magpie's, so Disconnect from magpie takes it off and the row says Not connected (Hu9956, #835) — OpenHanako spells every model provider/id, its own providers' as magpie's (magpie/<ref>), and a value of its own DeepSeek, deepseek/deepseek-v4-pro, read as magpie's deepseek/deepseek-v4-pro because magpie has a provider of that name. So the row stayed 已接入 on it: Disconnect put back the model the agent had before (its own deepseek/deepseek-v4-pro), took magpie's provider out, and the row still read as connected, on and on. An agent can now say what each of magpie's values in it starts with (Prefixed, magpie/ for OpenHanako); a value without it is the agent's own, never magpie's. TestHanakoOwnProviderNamedAsMagpies (own relay/glm-4.6 with magpie's relay: not wired, Connect, Disconnect puts it back and the row is off) fails on the old code. go vet, builds (darwin, GOOS=linux nogui, GOOS=windows) and go test -tags nogui -count=1 ./... under a temp HOME pass.

This commit is contained in:
yetone committed 2026-10-05 06:35:59 +08:00
1 parent c65ddd988d
commit 6fb05259d7
4 files changed
+48 -1

No files matched your search

+6
View File
@@ -176,6 +176,12 @@ type Agent struct {
// names, never taken for one of magpie's models nor moved by what
// matches the picker (RenameRefs moves the names in it).
SplitSuffix func(v string) (model, suffix string, one bool)
// Prefixed, when set, is what each of magpie's values in the agent's
// fields starts with ("magpie/", its provider there): a value without
// it is a model of one of the agent's own providers, never magpie's,
// even when magpie has a provider of the same name (OpenHanako's own
// deepseek/deepseek-v4-pro, #835).
Prefixed string
// detect, when set, says whether the agent is here in place of looking
// for its files and binary: a distro's, probed once.
detect func() bool
+1 -1
View File
@@ -207,7 +207,7 @@ func magpieValue(a *Agent, f Field, v string, vals map[string]string) bool {
return false
}
v, _, one := a.split(v)
if !one {
if !one || a.Prefixed != "" && !strings.HasPrefix(v, a.Prefixed) {
return false
}
if isMagpie(v) {
+3
View File
@@ -91,6 +91,9 @@ func hanako(home string) *Agent {
// what its provider client sends, though the key names it first
UA: []string{"hanaagent"},
Dir: dir, Path: path,
// its own providers' models are provider/id as magpie's are: one
// is magpie's only on magpie's provider
Prefixed: magpieID + "/",
Sync: func() error {
cur, ok := hanakoCurrent(dir)
if !ok || hanakoSame(cur, hanakoProvider()) {
+38
View File
@@ -461,3 +461,41 @@ func TestHanakoKey(t *testing.T) {
t.Fatal(k)
}
}
// One of OpenHanako's own providers named as one of magpie's (its own
// DeepSeek, and magpie's deepseek): its model isn't magpie's, so the row
// isn't connected on it, and Disconnect from magpie puts it back and is
// done, rather than leaving the row connected on the model it went back to
// (Hu9956, #835).
func TestHanakoOwnProviderNamedAsMagpies(t *testing.T) {
home, dir := hanakoTestHome(t)
catalogPath := filepath.Join(dir, "provider-catalog.json")
// the user's own relay provider, which magpie has one of too
hanakoWrite(t, catalogPath, `{"catalogVersion":2,"providers":{"relay":{"base_url":"https://x/v1","api":"openai-completions","api_key":"k","models":["glm-4.6"]}}}`, 0o600)
hanakoWrite(t, filepath.Join(dir, "user", "preferences.json"), `{"primaryAgent":"hana"}`, 0o644)
cfg := filepath.Join(dir, "agents", "hana", "config.yaml")
hanakoWrite(t, cfg, "models:\n chat:\n id: glm-4.6\n provider: relay\n", 0o644)
a := hanako(home)
if a.Wired() {
t.Fatal("its own relay/glm-4.6 reads as magpie's")
}
if err := a.Connect(); err != nil {
t.Fatal(err)
}
if !a.Wired() {
t.Fatalf("not wired after connect: %v", a.Values())
}
if err := a.Disconnect(); err != nil {
t.Fatal(err)
}
if chat, raw := hanakoChatOf(t, cfg); chat["id"] != "glm-4.6" || chat["provider"] != "relay" {
t.Fatalf("disconnected config:\n%s", raw)
}
if _, ok := hanakoCurrent(dir); ok {
t.Fatal("magpie's provider is still there")
}
if a.Wired() {
t.Fatalf("still connected after Disconnect: %v", a.Values())
}
}