init
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/local/glpi-neural-brain/internal/activity"
|
||||
"github.com/local/glpi-neural-brain/internal/config"
|
||||
"github.com/local/glpi-neural-brain/internal/graph"
|
||||
)
|
||||
|
||||
func TestEnrichWritesAIThinkOnlyAfterStructuredQwenDecision(t *testing.T) {
|
||||
mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
switch r.URL.Path {
|
||||
case "/api/tags":
|
||||
_, _ = w.Write([]byte(`{"models":[]}`))
|
||||
case "/api/embed":
|
||||
var req struct {
|
||||
Input []string `json:"input"`
|
||||
}
|
||||
_ = json.NewDecoder(r.Body).Decode(&req)
|
||||
vectors := make([][]float64, len(req.Input))
|
||||
for i := range vectors {
|
||||
vectors[i] = []float64{1, float64(i) * .05, 0}
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"embeddings": vectors})
|
||||
case "/api/chat":
|
||||
content := `{"related":true,"relation_type":"supports","confidence":0.91,"explanation":"Beide Einträge behandeln denselben VPN-Störungsablauf.","needs_research":false,"research_query":"","title":"VPN-Gateway und Remotezugriff","synthesis":"Der Gateway-Fehler ist ein konkreter Teilbereich des Remotezugriffs.","keywords":["VPN","Gateway"]}`
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"message": map[string]any{"content": content}})
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}))
|
||||
defer mock.Close()
|
||||
|
||||
root := t.TempDir()
|
||||
knowledge := filepath.Join(root, "knowledge")
|
||||
staging := filepath.Join(root, "staging")
|
||||
data := filepath.Join(root, "data")
|
||||
for _, d := range []string{knowledge, staging, data} {
|
||||
if err := os.MkdirAll(d, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
write := func(name, body string) {
|
||||
if err := os.WriteFile(filepath.Join(knowledge, name), []byte(body), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
write("vpn.json", `{"id":"KB-VPN","title":"VPN Gateway","text":"Gateway nicht erreichbar","categories":["Netzwerk"],"keywords":["VPN","Gateway"],"source":"internal-kb"}`)
|
||||
write("remote.json", `{"id":"KB-REMOTE","title":"Remotezugriff und VPN","text":"Remotezugriff über VPN und Gateway","categories":["Netzwerk"],"keywords":["VPN","Remotezugriff"],"source":"internal-kb"}`)
|
||||
|
||||
g, err := graph.Open(data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cfg := config.Config{DataDir: data, KnowledgeDirs: []string{knowledge}, StagingDirs: []string{staging}, OllamaURL: mock.URL, ChatModel: "qwen3:8b", EmbeddingModel: "embeddinggemma", ScanInterval: time.Minute, EnrichInterval: time.Minute, SimilarityThreshold: .5, RelationThreshold: .7, TopK: 5, MaxContextChars: 8000}
|
||||
e := New(cfg, g, activity.New(20))
|
||||
if err := e.Scan(context.Background()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !e.ollamaOK {
|
||||
t.Fatal("mock Ollama should be healthy")
|
||||
}
|
||||
if err := e.EnrichOne(context.Background()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
files, err := filepath.Glob(filepath.Join(staging, "*.json"))
|
||||
if err != nil || len(files) != 1 {
|
||||
t.Fatalf("expected one AI-THINK file, files=%v err=%v", files, err)
|
||||
}
|
||||
var doc map[string]any
|
||||
b, _ := os.ReadFile(files[0])
|
||||
if err := json.Unmarshal(b, &doc); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if doc["auto_reply"] != false {
|
||||
t.Fatalf("AI-THINK must be auto_reply=false: %#v", doc["auto_reply"])
|
||||
}
|
||||
cats, _ := doc["categories"].([]any)
|
||||
found := false
|
||||
for _, c := range cats {
|
||||
if c == "AI-THINK" {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("AI-THINK category missing: %#v", cats)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user