mindnet/app/routers/ingest.py

130 lines
4.1 KiB
Python
Raw Normal View History

2025-12-10 22:05:35 +01:00
"""
2025-12-11 11:35:27 +01:00
app/routers/ingest.py - DEBUG VERSION
2025-12-10 22:05:35 +01:00
"""
import os
import time
2025-12-11 08:18:41 +01:00
import logging
2025-12-10 22:05:35 +01:00
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
2025-12-11 11:35:27 +01:00
from typing import Optional, List, Dict, Any
2025-12-10 22:05:35 +01:00
from app.core.ingestion import IngestionService
2025-12-11 11:35:27 +01:00
from app.core.retriever import Retriever
from app.models.dto import QueryRequest
2025-12-10 22:05:35 +01:00
2025-12-11 10:46:37 +01:00
logger = logging.getLogger(__name__)
2025-12-10 22:05:35 +01:00
router = APIRouter()
2025-12-11 10:46:37 +01:00
# --- DTOs ---
2025-12-10 22:05:35 +01:00
class AnalyzeRequest(BaseModel):
text: str
type: str = "concept"
class SaveRequest(BaseModel):
markdown_content: str
2025-12-11 08:18:41 +01:00
filename: Optional[str] = None
2025-12-11 10:46:37 +01:00
folder: str = "00_Inbox"
2025-12-10 22:05:35 +01:00
class SaveResponse(BaseModel):
status: str
file_path: str
note_id: str
stats: Dict[str, Any]
2025-12-11 10:46:37 +01:00
# --- Endpoints ---
2025-12-10 22:05:35 +01:00
@router.post("/analyze")
async def analyze_draft(req: AnalyzeRequest):
"""
2025-12-11 11:35:27 +01:00
WP-11 Intelligence: Liefert Link-Vorschläge.
DEBUG MODE: Threshold gesenkt, Logging erhöht.
2025-12-10 22:05:35 +01:00
"""
try:
2025-12-11 11:35:27 +01:00
retriever = Retriever()
suggestions = []
query_text = req.text[:400]
logger.info(f"ANALYZING TEXT: '{query_text}' (Type: {req.type})")
if not query_text.strip():
return {"suggestions": []}
# Wir suchen
hits_result = await retriever.search(QueryRequest(query=query_text, top_k=5, mode="hybrid"))
logger.info(f"RETRIEVER FOUND: {len(hits_result.results)} raw hits")
seen_titles = set()
for hit in hits_result.results:
# Titel holen
title = hit.payload.get("title") or hit.payload.get("note_id") or hit.node_id
# Logging für jeden Treffer
logger.info(f" -> CHECK HIT: {title} | Score: {hit.total_score:.4f}")
if not title or title in seen_titles:
continue
seen_titles.add(title)
# Edge Logic
edge_kind = "related_to"
if req.type == "project": edge_kind = "depends_on"
if req.type == "decision": edge_kind = "references"
# --- ÄNDERUNG: THRESHOLD GESENKT ---
# War vorher 0.65. Jetzt 0.3 für Tests.
if hit.total_score > 0.3:
suggestions.append({
"target_title": title,
"target_id": hit.node_id,
"suggested_markdown": f"[[rel:{edge_kind} {title}]]",
"reason": f"Semantisch ähnlich ({hit.total_score:.2f})",
"type": "semantic"
})
else:
logger.info(f" -> SKIPPED (Score too low)")
logger.info(f"RETURNING {len(suggestions)} SUGGESTIONS")
return {"suggestions": suggestions}
2025-12-11 10:46:37 +01:00
2025-12-10 22:05:35 +01:00
except Exception as e:
2025-12-11 08:18:41 +01:00
logger.error(f"Analyze failed: {e}", exc_info=True)
2025-12-10 22:05:35 +01:00
raise HTTPException(status_code=500, detail=f"Analysis failed: {str(e)}")
@router.post("/save", response_model=SaveResponse)
async def save_note(req: SaveRequest):
2025-12-11 11:35:27 +01:00
"""WP-11 Persistence"""
2025-12-11 08:18:41 +01:00
try:
vault_root = os.getenv("MINDNET_VAULT_ROOT", "./vault")
abs_vault_root = os.path.abspath(vault_root)
if not os.path.exists(abs_vault_root):
2025-12-11 11:35:27 +01:00
os.makedirs(abs_vault_root, exist_ok=True)
2025-12-10 22:05:35 +01:00
2025-12-11 08:18:41 +01:00
final_filename = req.filename
if not final_filename:
final_filename = f"draft_{int(time.time())}.md"
2025-12-10 22:05:35 +01:00
2025-12-11 08:18:41 +01:00
ingest_service = IngestionService()
2025-12-11 11:35:27 +01:00
logger.info(f"Saving {final_filename}")
2025-12-11 08:18:41 +01:00
2025-12-11 11:35:27 +01:00
result = await ingest_service.save_and_index(
2025-12-11 08:18:41 +01:00
markdown_content=req.markdown_content,
2025-12-11 11:35:27 +01:00
filename=final_filename
2025-12-11 08:18:41 +01:00
)
if result.get("status") == "error":
raise HTTPException(status_code=500, detail=result.get("error"))
return SaveResponse(
status="success",
2025-12-11 11:35:27 +01:00
file_path=result.get("file_path", "unknown"),
2025-12-11 08:18:41 +01:00
note_id=result.get("note_id", "unknown"),
2025-12-11 11:35:27 +01:00
stats=result.get("stats", {})
2025-12-11 08:18:41 +01:00
)
except HTTPException as he:
raise he
except Exception as e:
logger.error(f"Save failed: {e}", exc_info=True)
raise HTTPException(status_code=500, detail=f"Save failed: {str(e)}")