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
This commit is contained in:
2026-08-29 01:07:47 -05:00
parent 2901bb8cae
commit 8614827d44
5 changed files with 242 additions and 13 deletions
+11
View File
@@ -66,3 +66,14 @@ func (r *Router) Tiers() []string {
sort.Strings(out)
return out
}
// Classes returns the sorted task classes known to the router (the
// `harness serve` model catalog is derived from it: one model per class).
func (r *Router) Classes() []string {
out := make([]string, 0, len(r.classes))
for k := range r.classes {
out = append(out, k)
}
sort.Strings(out)
return out
}
+10
View File
@@ -76,3 +76,13 @@ func TestNewRouterValidation(t *testing.T) {
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)
}
}