diff --git a/app/models/dto.py b/app/models/dto.py index b170f37..e5cca55 100644 --- a/app/models/dto.py +++ b/app/models/dto.py @@ -11,6 +11,7 @@ from pydantic import BaseModel, Field from typing import List, Literal, Optional, Dict, Any import uuid +# WP-22: Erweiterte Kanten-Typen in EdgeKind EdgeKind = Literal["references", "references_at", "backlink", "next", "prev", "belongs_to", "depends_on", "related_to", "similar_to", "caused_by", "derived_from", "based_on", "solves", "blocks", "uses", "guides"] @@ -67,10 +68,7 @@ class FeedbackRequest(BaseModel): User-Feedback zu einem spezifischen Treffer oder der Gesamtantwort. """ query_id: str = Field(..., description="ID der ursprünglichen Suche") - # node_id ist optional: Wenn leer oder "generated_answer", gilt es für die Antwort. - # Wenn eine echte Chunk-ID, gilt es für die Quelle. node_id: str = Field(..., description="ID des bewerteten Treffers oder 'generated_answer'") - # Update: Range auf 1-5 erweitert für differenziertes Tuning score: int = Field(..., ge=1, le=5, description="1 (Irrelevant/Falsch) bis 5 (Perfekt)") comment: Optional[str] = None @@ -81,7 +79,6 @@ class ChatRequest(BaseModel): """ message: str = Field(..., description="Die Nachricht des Users") conversation_id: Optional[str] = Field(None, description="Optional: ID für Chat-Verlauf (noch nicht implementiert)") - # RAG Parameter (Override defaults) top_k: int = 5 explain: bool = False diff --git a/config/decision_engine.yaml b/config/decision_engine.yaml index d5ab878..3df4b89 100644 --- a/config/decision_engine.yaml +++ b/config/decision_engine.yaml @@ -1,5 +1,5 @@ # config/decision_engine.yaml -# Steuerung der Decision Engine (Intent Recognition) +# Steuerung der Decision Engine (Intent Recognition & Graph Routing) # Version: 2.5.0 (WP-22: Semantic Graph Routing) version: 2.5 diff --git a/tests/test_WP22_intelligence.py b/tests/test_WP22_intelligence.py index 52a29dd..cbf9ac6 100644 --- a/tests/test_WP22_intelligence.py +++ b/tests/test_WP22_intelligence.py @@ -9,11 +9,11 @@ import os import shutil import json import yaml +import asyncio # <--- FIX: Hier war der Fehler from unittest.mock import MagicMock, patch, AsyncMock from datetime import datetime # --- Imports der App-Module --- -# Wir gehen davon aus, dass wir im Root-Verzeichnis sind. from app.models.dto import ChatRequest, QueryRequest, QueryHit from app.services.edge_registry import EdgeRegistry from app.core.retriever import _compute_total_score, _get_status_multiplier @@ -161,10 +161,7 @@ class TestWP22Integration(unittest.TestCase): req = ChatRequest(message="Warum ist das passiert?", top_k=3) # EXECUTE Endpoint - # Wir müssen sicherstellen, dass _load_decision_config unsere Test-Config nutzt. - # Da wir os.environ gepatcht haben, sollte das klappen. - - # Wir müssen die Caches leeren, da Module-Level Variablen sonst alte Werte haben + # Cache Reset import app.routers.chat app.routers.chat._DECISION_CONFIG_CACHE = None @@ -173,7 +170,6 @@ class TestWP22Integration(unittest.TestCase): # ASSERTIONS # 1. Wurde der Retriever mit den Boosts aufgerufen? - # Wir inspecten das Argument 'boost_edges' im call_args des Retrievers called_query_req = mock_retriever.search.call_args[0][0] self.assertIsNotNone(called_query_req.boost_edges, "Retriever sollte boost_edges erhalten.") @@ -191,12 +187,8 @@ class TestWP22Integration(unittest.TestCase): async def test_regression_standard_query(self): print("\n🔵 TEST 5: Regression (Standard Query)") - # Request ohne Keyword -> Sollte FACT (Default) sein - # Oder LLM Fallback (hier gemockt) - mock_llm = AsyncMock() mock_llm.prompts = {} - # Simuliere LLM sagt nichts spezifisches -> Default FACT mock_llm.generate_raw_response.return_value = "Antwort." mock_retriever = AsyncMock() @@ -210,7 +202,6 @@ class TestWP22Integration(unittest.TestCase): response = await chat_endpoint(req, llm=mock_llm, retriever=mock_retriever) - # Prüfen ob System nicht crasht und vernünftige Defaults nutzt called_query_req = mock_retriever.search.call_args[0][0] # FACT strategy hat in unserem Test Setup 'part_of': 2.0 @@ -221,7 +212,6 @@ class TestWP22Integration(unittest.TestCase): print("✅ Regression Test bestanden (Standard-Flow intakt).") if __name__ == '__main__': - # Async Support für Unittest loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) unittest.main() \ No newline at end of file