This commit is contained in:
2026-08-07 17:05:03 +02:00
parent 246241fcda
commit f8bf8c944e
1172 changed files with 38091 additions and 924 deletions
+13 -17
View File
@@ -218,15 +218,9 @@ func TestSynthesisResearchesUnclearKnowledgeThenLearnsAndLinksArticle(t *testing
case 4:
content = `{"questions":[{"gap_id":"G-C-1","question":"Wie werden Gateway-Adresse und VPN-Verbindung laut Hersteller geprüft und validiert?","critical":true,"expect_actionable":true,"queries_de":["VPN Gateway Verbindung prüfen Hersteller Dokumentation"],"queries_en":[],"preferred_domains":[]}]}`
case 5:
content = `{"assessments":[{"index":1,"relevant":true,"relevance":0.94,"source_quality":"primary","source_quality_score":0.91,"actionable":true,"covered_gap_ids":["G-C-1"],"reason":"Direkte Herstelleranleitung mit Prüf- und Validierungsschritten."}]}`
case 6:
content = `{"assessments":[{"index":1,"relevant":true,"relevance":0.97,"source_quality":"primary","source_quality_score":0.94,"actionable":true,"covered_gap_ids":["G-C-1"],"reason":"Der Volltext enthält konkrete Diagnose-, Neustart- und Validierungsschritte."}]}`
case 7:
content = fmt.Sprintf(`{"topic":"VPN Gateway","purpose":"VPN-Fehler beheben","scope":[{"text":"Gilt für den dokumentierten VPN-Client.","source_refs":[%q]}],"facts":[{"text":"Gateway-Adresse und Netzwerkverbindung müssen geprüft werden.","source_refs":["R1"]}],"symptoms":[{"text":"Der VPN-Tunnel wird nicht aufgebaut.","source_refs":[%q]}],"prerequisites":[{"text":"Fehlermeldung und Zeitpunkt liegen vor.","source_refs":[%q]}],"solution_steps":[{"text":"Prüfen Sie die Internetverbindung.","source_refs":[%q,"R1"]},{"text":"Prüfen Sie die konfigurierte Gateway-Adresse und deren Erreichbarkeit.","source_refs":["R1"]},{"text":"Starten Sie den VPN-Client neu.","source_refs":[%q,"R1"]}],"validation_steps":[{"text":"Prüfen Sie, ob der VPN-Tunnel aufgebaut wird und eine interne Ressource erreichbar ist.","source_refs":["R1"]}],"troubleshooting":[{"text":"Bei anhaltendem Fehler mit Zeitstempel und Meldung eskalieren.","source_refs":[%q,"R1"]}],"contradictions":[],"critical_gaps":[],"optional_gaps":[{"id":"G-O-1","description":"Produktspezifische Screenshots fehlen.","reason":"Für die Ausführung nicht erforderlich.","research_queries":[]}],"resolved_gaps":[{"id":"G-C-1","description":"Gateway-Prüf- und Validierungsweg","source_refs":["R1"]}],"missing_information":["Produktspezifische Screenshots fehlen."],"research_queries":[],"ready_for_article":true}`, sourceA, sourceA, sourceC, sourceA, sourceB, sourceC)
case 8:
content = `{"title":"VPN-Gateway-Verbindung diagnostizieren","problem_description":"Der VPN-Client kann keine Verbindung zum konfigurierten Gateway aufbauen. Der Tunnel bleibt getrennt und der Remotezugriff ist nicht möglich.","scope":"Die Anleitung gilt für den dokumentierten VPN-Client und das konfigurierte zentrale Gateway.","symptoms":["Der VPN-Tunnel wird nicht aufgebaut.","Der Client meldet ein nicht erreichbares Gateway."],"key_points":[],"decision_criteria":[],"prerequisites":["Fehlermeldung und Zeitpunkt des Fehlers liegen vor."],"solution_steps":["Prüfen Sie die Internetverbindung des Rechners.","Kontrollieren Sie die konfigurierte Gateway-Adresse und testen Sie deren Erreichbarkeit.","Starten Sie den VPN-Client neu und wiederholen Sie den Verbindungsaufbau.","Eskalieren Sie einen anhaltenden Fehler mit Zeitstempel und Fehlermeldung."],"validation_steps":["Der VPN-Tunnel wird aufgebaut.","Eine interne Ressource ist erreichbar."],"troubleshooting":["Prüfen Sie bei erneutem Fehler die erfasste Meldung und den dokumentierten Eskalationsweg."],"categories":["Netzwerk","VPN"],"keywords":["VPN","Gateway"],"open_questions":[]}`
default:
content = `{"accepted":true,"confidence":0.93,"meta_content_detected":false,"unsupported_claims":[],"issues":[]}`
content = `{"accepted":true,"confidence":0.93,"meta_content_detected":false,"unsupported_claims":[],"issues":[],"claim_reviews":[{"claim":"Gateway-Adresse und Erreichbarkeit prüfen","verdict":"supported","source_refs":["R1"],"reason":"Im Volltext belegt."}],"missing_evidence_queries":[],"rewrite_instructions":[]}`
}
_ = json.NewEncoder(w).Encode(map[string]any{"message": map[string]any{"content": content}})
default:
@@ -332,10 +326,10 @@ func TestSynthesisResearchesUnclearKnowledgeThenLearnsAndLinksArticle(t *testing
if !linked {
t.Fatal("new article is not linked to its accepted full-text research evidence")
}
if chatCalls != 9 {
t.Fatalf("expected relation, plan, brief, research plan, two relevance gates, reconsolidation, article and quality calls, got %d", chatCalls)
if chatCalls != 6 {
t.Fatalf("expected relation, plan, brief, research plan, synthesis and claim review calls, got %d", chatCalls)
}
var resultEvent, candidateEvent, fetchEvent, acceptedEvent, ingestEvent, learnedEvent, roundEvent *model.Activity
var resultEvent, candidateEvent, fetchEvent, materialEvent, ingestEvent, learnedEvent, roundEvent, reviewEvent *model.Activity
for _, event := range broker.Recent() {
event := event
switch event.Type {
@@ -345,18 +339,20 @@ func TestSynthesisResearchesUnclearKnowledgeThenLearnsAndLinksArticle(t *testing
candidateEvent = &event
case "article.research.fetch.completed":
fetchEvent = &event
case "article.research.evidence.accepted":
acceptedEvent = &event
case "article.research.ingested":
case "article.research.material.collected":
materialEvent = &event
case "article.research.material.ingested":
ingestEvent = &event
case "article.research.learned":
learnedEvent = &event
case "article.research.round.completed":
case "article.research.collection.round.completed":
roundEvent = &event
case "article.review.completed":
reviewEvent = &event
}
}
if resultEvent == nil || candidateEvent == nil || fetchEvent == nil || acceptedEvent == nil || ingestEvent == nil || learnedEvent == nil || roundEvent == nil {
t.Fatalf("expected complete visible research pipeline, result=%v candidate=%v fetch=%v accepted=%v ingest=%v learned=%v round=%v", resultEvent != nil, candidateEvent != nil, fetchEvent != nil, acceptedEvent != nil, ingestEvent != nil, learnedEvent != nil, roundEvent != nil)
if resultEvent == nil || candidateEvent == nil || fetchEvent == nil || materialEvent == nil || ingestEvent == nil || learnedEvent == nil || roundEvent == nil || reviewEvent == nil {
t.Fatalf("expected research-generate-review pipeline, result=%v candidate=%v fetch=%v material=%v ingest=%v learned=%v round=%v review=%v", resultEvent != nil, candidateEvent != nil, fetchEvent != nil, materialEvent != nil, ingestEvent != nil, learnedEvent != nil, roundEvent != nil, reviewEvent != nil)
}
resultNodeIDs, _ := ingestEvent.Metadata["result_node_ids"].([]string)
if len(resultNodeIDs) != 1 || resultNodeIDs[0] != researchID {
@@ -450,7 +446,7 @@ func TestWriteKnowledgeArticleDraftPreservesUpdateTarget(t *testing.T) {
}
plan := model.ArticlePlanDecision{Action: "update", TargetArticleID: target.ID, Reason: "Der bestehende Artikel benötigt Diagnose und Validierung.", ExpectedValue: "Vollständiger Ablauf", ArticleType: "troubleshooting", SourceNodeIDs: nodeIDsFromArticleSources(sources)}
draft := model.KnowledgeArticleDraft{Title: "VPN-Artikel vollständig diagnostizieren", Text: strings.Repeat("Problem und Geltungsbereich. ", 5), Answer: strings.Repeat("1. Konkreten Prüfschritt ausführen. ", 8), Validation: []string{"VPN-Tunnel ist aktiv"}, Categories: []string{"VPN"}, Keywords: []string{"VPN"}, SourceNodeIDs: nodeIDsFromArticleSources(sources), Confidence: .9}
path, _, created, err := e.writeKnowledgeArticleDraft(sources, plan, model.KnowledgeBrief{Topic: "VPN", ReadyForArticle: true}, draft, nil, 3, 0, 1, 1)
path, _, created, err := e.writeKnowledgeArticleDraft(sources, plan, model.KnowledgeBrief{Topic: "VPN", ReadyForArticle: true}, draft, nil, nil, model.ArticleQualityDecision{Accepted: true, Confidence: .9}, 0, 3, 0, 1, 1)
if err != nil {
t.Fatal(err)
}