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:
3 files changed
+70
No files matched your search
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user