feat: Beschreibung generieren Button im Neuer-Fall-Modal

KI-gestütztes Prompt Enhancement: Button generiert per Haiku aus dem
Titel eine strukturierte Beschreibung. Unterscheidet zwischen
Live-Monitoring (kompakte Vorfallsbeschreibung) und Recherche
(strukturiertes Briefing mit Schwerpunkten und Suchbegriffen).

- Neuer Endpoint POST /api/incidents/enhance-description
- Button erscheint für beide Lage-Typen, aktiv ab 3 Zeichen Titel
- Info-Hinweis wechselt je nach Typ mit Beispiel
- Spinner-Animation während der Generierung
Dieser Commit ist enthalten in:
Claude Dev
2026-03-27 23:31:05 +01:00
Ursprung 4f8400bfbd
Commit 6913c1e683
6 geänderte Dateien mit 142 neuen und 1 gelöschten Zeilen

Datei anzeigen

@@ -1,7 +1,7 @@
"""Incidents-Router: Lagen verwalten (Multi-Tenant)."""
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, Query, status
from fastapi.responses import StreamingResponse
from models import IncidentCreate, IncidentUpdate, IncidentResponse, SubscriptionUpdate, SubscriptionResponse
from models import IncidentCreate, IncidentUpdate, IncidentResponse, SubscriptionUpdate, SubscriptionResponse, DescriptionEnhanceRequest
from auth import get_current_user
from middleware.license_check import require_writable_license
from database import db_dependency, get_db
@@ -155,6 +155,65 @@ async def get_refreshing_incidents(
}
# --- Beschreibung generieren (Prompt Enhancement) ---
ENHANCE_PROMPT_RESEARCH = """Du generierst ein strukturiertes Recherche-Briefing fuer ein OSINT-Lagemonitoring-System.
WICHTIG: Verwende IMMER echte UTF-8-Umlaute (ae, oe, ue, ss) und KEINE Umschreibungen.
Titel: {title}
Vorhandener Kontext: {context}
Typ: Hintergrundrecherche
Erstelle ein praezises Recherche-Briefing mit:
1. Vollstaendiger Name/Bezeichnung des Themas (inkl. Rechtsform bei Unternehmen, voller Name bei Personen)
2. Recherche-Schwerpunkte (5-8 thematische Punkte, z.B. Geschichte, Finanzen, Fuehrung, Kontroversen, Innovation)
3. Relevante Suchbegriffe (deutsch + englisch, inkl. Abkuerzungen und alternative Schreibweisen)
Schreibe NUR das Briefing als Fliesstext mit Aufzaehlungen. Keine Erklaerungen davor oder danach."""
ENHANCE_PROMPT_ADHOC = """Du generierst eine praezise Vorfallsbeschreibung fuer ein OSINT-Lagemonitoring-System.
WICHTIG: Verwende IMMER echte UTF-8-Umlaute (ae, oe, ue, ss) und KEINE Umschreibungen.
Titel: {title}
Vorhandener Kontext: {context}
Typ: Live-Monitoring (aktuelle Ereignisse)
Erstelle eine knappe, informative Beschreibung mit:
1. Was ist passiert / worum geht es
2. Wo (geographischer Kontext)
3. Wer ist beteiligt (Akteure, Organisationen, Laender)
4. Wonach soll gesucht werden (aktuelle Entwicklungen, Reaktionen, Hintergruende)
Schreibe NUR die Beschreibung als Fliesstext (3-5 Zeilen). Keine Erklaerungen davor oder danach."""
_enhance_logger = logging.getLogger("osint.enhance")
@router.post("/enhance-description")
async def enhance_description(
data: DescriptionEnhanceRequest,
current_user: dict = Depends(get_current_user),
):
"""Generiert eine strukturierte Beschreibung per KI aus dem Titel."""
from agents.claude_client import call_claude
from config import CLAUDE_MODEL_FAST
template = ENHANCE_PROMPT_RESEARCH if data.type == "research" else ENHANCE_PROMPT_ADHOC
context = data.description.strip() if data.description and data.description.strip() else "Kein Kontext angegeben"
prompt = template.format(title=data.title.strip(), context=context)
try:
result, usage = await call_claude(prompt, tools=None, model=CLAUDE_MODEL_FAST)
_enhance_logger.info(
f"Beschreibung generiert fuer \"{data.title[:50]}\": "
f"{usage.input_tokens}in/{usage.output_tokens}out"
)
return {"description": result.strip()}
except Exception as e:
_enhance_logger.error(f"Beschreibung generieren fehlgeschlagen: {e}")
raise HTTPException(status_code=500, detail="Beschreibung konnte nicht generiert werden")
@router.get("/{incident_id}", response_model=IncidentResponse)
async def get_incident(
incident_id: int,