cli: a model typed as another agent spells it is put the way this one does — magpie/copilot/gpt-6 for Codex, which names catalog models copilot/gpt-6, and copilot/gpt-6 for Pi, which names them magpie/copilot/gpt-6 — rather than written as it is, where Codex took it for one of OpenAI's own and asked OpenAI for it; a magpie/… model the catalog doesn't have is refused, and a model the agent's picker doesn't list is still taken as it is

This commit is contained in:
yetone committed 2026-09-25 05:34:44 +08:00
1 parent 01cee5a268
commit 6648a8a2ec
3 files changed
+70

No files matched your search

+29
View File
@@ -156,3 +156,32 @@ func ids(as []*Agent) []string {
sort.Strings(s)
return s
}
// Spell puts a value typed for field key the way this agent spells it: a
// catalog model is "copilot/gpt-6" in some agents and "magpie/copilot/gpt-6"
// in others, and either is taken in both. A value the picker offers as is
// stays, and so does one it doesn't know (a model the agent reaches on its
// own that isn't listed); a "magpie/…" value the catalog doesn't have is an
// error rather than a model the agent would ask its own vendor for.
func (a *Agent) Spell(key, v string) (string, error) {
f := a.Field(key)
if f == nil || f.Options == nil || v == "" {
return v, nil
}
opts := f.Options(a.Values())
for _, o := range opts {
if o.Value == v {
return v, nil
}
}
ref, prefixed := strings.CutPrefix(v, magpieID+"/")
for _, o := range opts {
if o.Ref != "" && o.Ref == ref {
return o.Value, nil
}
}
if prefixed {
return "", fmt.Errorf("%s isn't a model in magpie's catalog (magpie models lists them)", ref)
}
return v, nil
}
+37
View File
@@ -0,0 +1,37 @@
package agent
import "testing"
func TestSpell(t *testing.T) {
opts := func(prefix string) func(map[string]string) []Option {
return func(map[string]string) []Option {
return []Option{
{Value: "gpt-6"},
{Value: prefix + "copilot/gpt-6-sol", Ref: "copilot/gpt-6-sol"},
}
}
}
get := func() string { return "" }
bare := &Agent{Fields: []Field{{Key: "model", Get: get, Options: opts("")}}}
prefixed := &Agent{Fields: []Field{{Key: "model", Get: get, Options: opts("magpie/")}}}
for _, c := range []struct {
a *Agent
in, out string
err bool
}{
{bare, "copilot/gpt-6-sol", "copilot/gpt-6-sol", false},
{bare, "magpie/copilot/gpt-6-sol", "copilot/gpt-6-sol", false},
{prefixed, "copilot/gpt-6-sol", "magpie/copilot/gpt-6-sol", false},
{prefixed, "magpie/copilot/gpt-6-sol", "magpie/copilot/gpt-6-sol", false},
{bare, "gpt-6", "gpt-6", false},
{bare, "some-unlisted-model", "some-unlisted-model", false},
{bare, "", "", false},
{bare, "magpie/copilot/nope", "", true},
{prefixed, "magpie/copilot/nope", "", true},
} {
got, err := c.a.Spell("model", c.in)
if got != c.out || (err != nil) != c.err {
t.Errorf("%q: got %q, %v; want %q, err %v", c.in, got, err, c.out, c.err)
}
}
}
+4
View File
@@ -192,6 +192,10 @@ func set(a *agent.Agent, key, value string) error {
}
return fmt.Errorf("%s has no field %q (fields: %s)", a.Name, key, strings.Join(keys, ", "))
}
value, err := a.Spell(f.Key, value)
if err != nil {
return err
}
if err := f.Set(value); err != nil {
return err
}