Add Calibrate AI Control UI and fleet LLM backend wiring.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Operators toggle Logic gates vs AI Control on Settings, refresh local Ollama models, and save ai_endpoint settings via Calibrate PUT; server scheduler and agent snapshot/command paths support stateless 60s fleet decisions.
This commit is contained in:
66
server/internal/ai/client_test.go
Normal file
66
server/internal/ai/client_test.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package ai
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListModelsOpenAI(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/v1/models" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"data": []map[string]string{{"id": "llama3.2"}, {"id": "mistral"}},
|
||||
})
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
models, err := ListModelsWithClient(context.Background(), srv.URL+"/v1", srv.Client())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(models) != 2 || models[0] != "llama3.2" {
|
||||
t.Fatalf("models: %v", models)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecideOpenAI(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/v1/chat/completions" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
var req map[string]interface{}
|
||||
_ = json.NewDecoder(r.Body).Decode(&req)
|
||||
msgs, _ := req["messages"].([]interface{})
|
||||
if len(msgs) != 2 {
|
||||
t.Fatalf("expected single-turn messages, got %d", len(msgs))
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"choices": []map[string]interface{}{
|
||||
{"message": map[string]string{"content": `{"commands":[{"type":"noop","args":{}}]}`}},
|
||||
},
|
||||
})
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
out, err := DecideWithClient(context.Background(), srv.URL+"/v1", "test-model", "sys", "user", srv.Client())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cmds := ParseCommands(out)
|
||||
if len(cmds) != 1 || cmds[0].Type != CmdNoop {
|
||||
t.Fatalf("parse: %+v", cmds)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeEndpoint(t *testing.T) {
|
||||
if got := normalizeEndpoint("http://127.0.0.1:11434"); got != "http://127.0.0.1:11434/v1" {
|
||||
t.Fatalf("got %q", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user