provider: a Codex warm-up asks the account's cheapest model (#604) — warmModel took a model with mini in its id or else the first listed, and a GPT-6 account lists no mini and starts with the flagship gpt-6.1-sol. warmPick takes the cheapest by list price (the model's own, else models.dev's openai price), and with no price known a mini, then a luna (GPT-6's cheap one), then the first. TestWarmPick.

This commit is contained in:
yetone committed 2026-10-03 02:53:20 +08:00
1 parent 5154df624f
commit 1e80a84fe3
2 files changed
+67 -5

No files matched your search

+30 -5
View File
@@ -350,7 +350,7 @@ func warmCodexLogin(ctx context.Context, user string) error {
}
// warmModel is the model a warm-up asks, and at what effort: the account's
// smallest (a mini) or else the first it lists, at low.
// cheapest (warmPick), at low.
func warmModel(user string) (model, effort string, err error) {
ms, _, ok := catalog.Live(accountModels("codex", user))
if !ok {
@@ -362,10 +362,7 @@ func warmModel(user string) (model, effort string, err error) {
if len(ms) == 0 {
return "", "", errors.New("no Codex model is known yet")
}
m := ms[0]
if i := slices.IndexFunc(ms, func(m catalog.Model) bool { return strings.Contains(m.ID, "mini") }); i >= 0 {
m = ms[i]
}
m := warmPick(ms, func(id string) (catalog.Price, bool) { return catalog.PricedBy([]string{"openai"}, id) })
switch {
case slices.Contains(m.Efforts, "low"):
effort = "low"
@@ -375,6 +372,34 @@ func warmModel(user string) (model, effort string, err error) {
return m.ID, effort, nil
}
// warmPick is the cheapest of an account's models, by its list price where
// models.dev has one (#604: GPT-6's cheap one is gpt-6-luna; the list
// has no mini and starts with the flagship gpt-6.1-sol); with no price
// known, a mini, else a luna, else the first it lists.
func warmPick(ms []catalog.Model, price func(id string) (catalog.Price, bool)) catalog.Model {
best, cost := -1, 0.0
for i, m := range ms {
p, ok := catalog.Price{}, false
if m.Price != nil {
p, ok = *m.Price, true
} else {
p, ok = price(m.ID)
}
if c := p.Input + p.Output; ok && c > 0 && (best < 0 || c < cost) {
best, cost = i, c
}
}
if best >= 0 {
return ms[best]
}
for _, word := range []string{"mini", "luna"} {
if i := slices.IndexFunc(ms, func(m catalog.Model) bool { return strings.Contains(m.ID, word) }); i >= 0 {
return ms[i]
}
}
return ms[0]
}
// warmCodex sends one "hi" to the ChatGPT backend as a Codex account's
// requests go (codexBody: Codex's instructions, not stored), and reads the
// reply to its end.
+37
View File
@@ -12,6 +12,8 @@ import (
"sync"
"testing"
"time"
"github.com/yetone/magpie/internal/catalog"
)
const (
@@ -280,3 +282,38 @@ func TestCodexWarmRequest(t *testing.T) {
t.Fatalf("not kept: %v", CodexWarmed())
}
}
// #604: the warm-up asks the cheapest model, by price where it is known,
// else a mini, else a luna, else the first listed.
func TestWarmPick(t *testing.T) {
ids := func(ids ...string) []catalog.Model {
ms := make([]catalog.Model, len(ids))
for i, id := range ids {
ms[i] = catalog.Model{ID: id}
}
return ms
}
prices := map[string]catalog.Price{
"gpt-6.1-sol": {Input: 2, Output: 10}, "gpt-6-astra": {Input: 10, Output: 50},
"gpt-6-luna": {Input: 0.1, Output: 0.5}, "gpt-5.6-luna": {Input: 0.2, Output: 1.2},
}
priced := func(id string) (catalog.Price, bool) { p, ok := prices[id]; return p, ok }
none := func(string) (catalog.Price, bool) { return catalog.Price{}, false }
gpt6 := ids("gpt-6.1-sol", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5")
for _, c := range []struct {
name string
ms []catalog.Model
price func(string) (catalog.Price, bool)
want string
}{
{"priced", gpt6, priced, "gpt-6-luna"},
{"no prices: a luna", gpt6, none, "gpt-6-luna"},
{"no prices: a mini first", ids("gpt-5-codex", "gpt-5-codex-mini", "gpt-6-luna"), none, "gpt-5-codex-mini"},
{"no prices, no cheap name", ids("gpt-6.1-sol", "gpt-6-sol"), none, "gpt-6.1-sol"},
{"the model's own price first", []catalog.Model{{ID: "gpt-6.1-sol"}, {ID: "x", Price: &catalog.Price{Input: 0.01, Output: 0.01}}}, priced, "x"},
} {
if got := warmPick(c.ms, c.price).ID; got != c.want {
t.Errorf("%s: %s, want %s", c.name, got, c.want)
}
}
}