Files
selfheal-lab-apps/ai/internal/jev/client_test.go
T
seon 91cdd9ada5 feat(ai): add Jev shadow gates (triage before, review after the LLM diagnosis)
TypeSafe System One(Jev)への最小クライアントと、診断ループに並走する
shadow ゲート 2 つを追加した。triage はアラートと事前取得サンプルからラベル・
回復中か・層を判定し、review は診断の根拠・ランブック・target を検証して
best_action を選ぶ。JEV_MODE=shadow のときだけ動き、答えは ai.jev_shadow と
診断結果の jev フィールドに記録するだけで、処理の分岐は一切変えない。
2026-10-08 15:10:07 +09:00

44 lines
1.7 KiB
Go

package jev
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
)
func TestAskRoundTrip(t *testing.T) {
var got map[string]any
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/v1/systemone" || r.Header.Get("Authorization") != "Bearer k1" {
t.Errorf("bad request: %s %s", r.URL.Path, r.Header.Get("Authorization"))
}
_ = json.NewDecoder(r.Body).Decode(&got)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"model":"jev-1.13.0","answers":{"recovering":{"type":"noul","noul":0.91},"label":{"type":"choice","choice":"db_primary_down","probabilities":{"db_primary_down":0.8,"unknown":0.2},"confidence":0.6}},"usage":{"input_tokens":120,"output_tokens":4}}`))
}))
defer srv.Close()
c := New(srv.URL, "", func() (string, error) { return "k1", nil })
resp, err := c.Ask(context.Background(), map[string]any{"a": 1}, map[string]Question{
"recovering": {Type: "noul", Instructions: "q1"},
"label": {Type: "choice", Instructions: "q2", Criteria: map[string]string{"db_primary_down": "x", "unknown": "y"}},
})
if err != nil {
t.Fatal(err)
}
if got["model"] != "jev-1.13.0" || got["questions"].(map[string]any)["label"].(map[string]any)["type"] != "choice" {
t.Errorf("request body: %v", got)
}
if *resp.Answers["recovering"].Noul != 0.91 || resp.Answers["label"].Choice != "db_primary_down" || resp.Usage.InputTokens != 120 {
t.Errorf("response: %+v", resp)
}
}
func TestAskNoKey(t *testing.T) {
c := New("http://127.0.0.1:1", "", func() (string, error) { return "", nil })
if _, err := c.Ask(context.Background(), "s", nil); err != ErrNoKey {
t.Errorf("want ErrNoKey, got %v", err)
}
}