Files
MOPAC/internal/models/models_test.go
T
mrcharles 8614827d44 loop: shared bounded-turn core accepts history + knobs (ServeTurn)
Turn machinery refactored so the upcoming serve front door reuses it
instead of copying it: the round loop is now runTurn over arbitrary
message history with an optional tool palette and forwarded max_tokens/
temperature. The serve path (ServeTurn) is stateless chat over client
history with tools hard-off: a tool call the model produces anyway is
refused as a tool result, never executed. Also exposes the model router
(so serve can build its catalog) and a sorted class list; llm requests
can now carry temperature.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
2026-08-29 01:07:47 -05:00

89 lines
2.4 KiB
Go

package models
import (
"strings"
"testing"
)
func testRouter(t *testing.T) *Router {
t.Helper()
tiers := map[string]string{
"mopac-study": "glm-4.7-flash",
"mopac-code": "glm-5.2",
"mopac-review": "glm-5-turbo",
"mopac-primary": "glm-5.3",
"mopac-vision": "glm-4.6v",
}
classes := map[string]string{
"study": "mopac-study",
"read": "mopac-study",
"code": "mopac-code",
"review": "mopac-review",
"primary": "mopac-primary",
}
r, err := NewRouter(tiers, classes, "mopac-primary")
if err != nil {
t.Fatalf("NewRouter: %v", err)
}
return r
}
func TestResolve(t *testing.T) {
cases := []struct {
class string
tier string
model string
}{
{"study", "mopac-study", "glm-4.7-flash"},
{"read", "mopac-study", "glm-4.7-flash"},
{"code", "mopac-code", "glm-5.2"},
{"review", "mopac-review", "glm-5-turbo"},
{"primary", "mopac-primary", "glm-5.3"},
{"", "mopac-primary", "glm-5.3"}, // no class -> default tier
}
r := testRouter(t)
for _, tc := range cases {
d, err := r.Resolve(tc.class)
if err != nil {
t.Fatalf("Resolve(%q): %v", tc.class, err)
}
if d.Tier != tc.tier || d.Model != tc.model {
t.Errorf("Resolve(%q) = %s/%s, want %s/%s", tc.class, d.Tier, d.Model, tc.tier, tc.model)
}
}
}
func TestResolveUnknownClassIsError(t *testing.T) {
r := testRouter(t)
_, err := r.Resolve("urgent")
if err == nil {
t.Fatal("unknown class must error (routing stays auditable)")
}
if !strings.Contains(err.Error(), `[models.classes]`) {
t.Errorf("error should point at the config section: %v", err)
}
}
func TestNewRouterValidation(t *testing.T) {
tiers := map[string]string{"mopac-primary": "glm-5.3"}
if _, err := NewRouter(tiers, nil, "mopac-missing"); err == nil || !strings.Contains(err.Error(), "default tier") {
t.Errorf("missing default tier: err=%v", err)
}
if _, err := NewRouter(tiers, map[string]string{"x": "mopac-nope"}, "mopac-primary"); err == nil || !strings.Contains(err.Error(), "unknown tier") {
t.Errorf("class to unknown tier: err=%v", err)
}
if _, err := NewRouter(nil, nil, "mopac-primary"); err == nil {
t.Errorf("empty tiers must error")
}
}
func TestClasses(t *testing.T) {
// The serve front door builds its catalog from the sorted class list;
// it must be complete and ordered for stable /v1/models output.
got := testRouter(t).Classes()
want := "code primary read review study"
if strings.Join(got, " ") != want {
t.Errorf("Classes() = %v, want %v", got, want)
}
}