Commit graph

15 Commits

Autor SHA1 Nachricht Datum
Claude Code
88b18d0775 fix(researcher): Robusteres JSON-Parsing der Claude-Antworten
Behebt das Symptom, dass Recherche-Lagen wie staging Lage 6 "Friedrich Merz"
trotz erfolgreichem Refresh leer blieben. Claude lieferte nicht-leere Antworten
(1226-2125 Zeichen), die der bisherige Regex-Parser nicht extrahieren konnte —
die Recherche meldete "0 Artikel" und der Refresh wurde stumm als Erfolg
verbucht.

Aenderungen:
- _parse_response, select_relevant_feeds, extract_dynamic_keywords und
  select_relevant_telegram_channels nutzen jetzt json.JSONDecoder.raw_decode
  ueber Modul-Helper _extract_json_array/_extract_json_object. Damit werden
  auch JSON-Bloecke mit Vor-/Nachtext, Markdown-Fences oder verschachtelten
  Objekten zuverlaessig erkannt.
- Bei Parse-Fehlschlag wird jetzt ein gekuerztes Sample der Claude-Antwort
  geloggt, damit kuenftige Faelle direkt debuggbar sind.
- Neue ResearcherParseError-Exception unterscheidet "echt 0 Treffer" von
  "Antwort kaputt". search() gibt zusaetzlich ein parse_failed-Flag zurueck.
- Orchestrator-Multi-Pass: wenn alle 3 research-Durchlaeufe 0 neue Artikel
  ergeben UND mindestens einer am Parser scheiterte, wird der Refresh als
  Fehler markiert (statt als stiller Erfolg). Der WebSocket-refresh_error
  loest dann die sichtbare UI-Meldung aus.

Adhoc-Lagen sind unveraendert: dort fangen RSS und Telegram die kaputte
Claude-Antwort auf, dafuer ist nur die Diagnose im Log neu.
2026-04-30 20:45:41 +00:00
Claude Dev
a2aaa061d4 fix: Keine Gedankenstriche (mdash/endash) in LLM-generierten Inhalten
- Keine-Gedankenstriche-Regel in factchecker.py und researcher.py Prompts
- _sanitize_mdash() in claude_client.py als Sicherheitsnetz: ersetzt
  alle mdash/endash im Output durch Kommas
- analyzer.py hatte die Prompt-Regel bereits

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 22:37:01 +01:00
Claude Dev
474e2beca9 fix: URL-Verifizierung fuer WebSearch-Ergebnisse
- Prompt-Verbesserung: Claude muss exakte URLs aus WebSearch kopieren, keine konstruierten URLs
- Neue _verify_article_urls() Funktion im Orchestrator
- HEAD-Request auf jede WebSearch-URL, GET-Fallback bei 405
- Bei 404/unerreichbar: Ersetzung durch Google-Suchlink (site:domain headline)
- Nur WebSearch-URLs werden geprueft, RSS-URLs sind bereits verifiziert
2026-03-17 10:22:01 +01:00
Claude Dev
6a2bd9e9c9 feat: Adhoc-Recherche bekommt bestehende Artikel als Kontext
- RESEARCH_PROMPT_TEMPLATE: {existing_context} Platzhalter eingefügt
- search(): Baut bei Adhoc-Folge-Refreshes Kontextblock mit bis zu 30 bekannten Headlines auf
- orchestrator: Übergibt bestehende Artikel jetzt für ALLE Incident-Typen, nicht nur Research

Effekt: Bei Adhoc-Auto-Refreshes findet Claude WebSearch gezielt neue Quellen statt immer dieselben Mainstream-Treffer

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 20:07:13 +01:00
Claude Dev
e0f8124e10 feat: Mehrstufige Deep-Research-Pipeline mit Quellenkontext
- DEEP_RESEARCH_PROMPT: 4-Phasen-Strategie (Breite Erfassung → Lückenanalyse → Gezielte Tiefenrecherche → Verifikation)
- Ziel 15-25 Quellen aus 5+ Quellentypen statt 8-15 aus Mainstream
- researcher.search(): Neuer Parameter existing_articles — bereits bekannte Quellen werden als Kontext übergeben, damit Claude gezielt neue Perspektiven findet
- orchestrator: DB-Abfrage vor Pipeline verschoben, bestehende Artikel als Kontext an Researcher übergeben (nur Research-Typ)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 18:33:56 +01:00
Claude Dev
0019d74aea feat: Intelligente Telegram-Kanal-Selektion und verbesserte Quellenzuordnung
- Researcher: Claude-basierte Vorauswahl relevanter Telegram-Kanäle per Haiku
- FactChecker: Verbesserte Quellen-Zuordnung mit Relevanz-Scoring (Top 5)
- FactChecker: URLs werden nicht mehr doppelt zugeordnet, sources_count wird aktualisiert
- TelegramParser: Kanal-Filterung per channel_ids statt categories
- TelegramParser: Lockereres Keyword-Matching (1 Match reicht, da vorselektiert)
- Models: telegram_categories Feld entfernt (durch KI-Selektion ersetzt)
- Main: Chat-Router eingebunden unter /api/chat

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 18:01:32 +01:00
claude-dev
5e19736a25 Per-User Domain-Ausschlüsse + Grundquellen-Schutz
- Neue Tabelle user_excluded_domains für benutzerspezifische Ausschlüsse
- Domain-Ausschlüsse wirken nur für den jeweiligen User, nicht org-weit
- user_id wird durch die gesamte Pipeline geschleust (Orchestrator → Researcher → RSS-Parser)
- Grundquellen (is_global) können nicht mehr bearbeitet/gelöscht werden im Frontend
- Grundquelle-Badge bei globalen Quellen statt Edit/Delete-Buttons
- Filter Von mir ausgeschlossen im Quellen-Modal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:30:21 +01:00
claude-dev
7734eefd35 Dynamische Keyword-Extraktion fuer RSS-Filterung + min_matches-Fix
- researcher.py: Neuer dedizierter Haiku-Call extract_dynamic_keywords()
  analysiert die letzten 30 Headlines und generiert 5 DE+EN Begriffspaare
- orchestrator.py: Dynamische Keywords vor Feed-Selektion aus DB-Headlines
- rss_parser.py: min_matches auf max 2 gedeckelt (vorher n/2, bei 10 Keywords = 5)
- analyzer.py: Fettdruck-Anweisungen entfernt

Vorher: 0 RSS-Treffer (min_matches=5 unerreichbar)
Nachher: 22 RSS-Treffer (Tagesschau 11, Al Jazeera 5, BBC 4, NYT 2)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:12:17 +01:00
claude-dev
f7809ccc77 Fix: TimeoutError wird nicht mehr verschluckt - Retry greift jetzt
- researcher.py/factchecker.py: TimeoutError wird nach oben durchgereicht
  statt vom breiten except Exception geschluckt zu werden
- orchestrator.py: Built-in TimeoutError zu TRANSIENT_ERRORS hinzugefuegt
  (war nur asyncio.TimeoutError, aber claude_client wirft TimeoutError)
- config.py: CLAUDE_TIMEOUT von 300s auf 420s erhoeht

Vorher: Timeout fuehrte zu "0 Artikel" ohne Retry (8 Timeouts seit 28.02.)
Nachher: Timeout loest bis zu 3 Retries aus (sofort, +2min, +5min)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:48:48 +01:00
claude-dev
d274a9c9b6 Fix: Echte UTF-8-Umlaute in KI-generierten Inhalten erzwingen
- Claude CLI Umgebung: LANG=C.UTF-8, LC_ALL=C.UTF-8 setzen
- Alle 10 Agent-Prompts: Explizite Anweisung für echte Umlaute (ä,ö,ü,ß)
  statt Umschreibungen (ae,oe,ue,ss)
- Betrifft: Researcher, Analyzer, Factchecker (jeweils initial + inkrementell)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 17:28:36 +01:00
claude-dev
ff4c54d9a8 Quellenvielfalt sicherstellen: Domain-Cap + Balance + Discovery-Verbesserungen
- config.py: MAX_FEEDS_PER_DOMAIN=3, MAX_ARTICLES_PER_DOMAIN_RSS=10
- rss_parser.py: _apply_domain_cap() begrenzt Artikel pro Domain nach RSS-Fetch
- orchestrator.py: Domain-Balance vor Feed-Selektion (max 3 Feeds/Domain),
  Domain-Cap in Background-Discovery
- source_rules.py: article_count in get_feeds_with_metadata(), Content-Hash
  in _validate_feed() für Duplikat-Erkennung bei Discovery
- researcher.py: QUELLENVIELFALT-Regel im Haiku Feed-Selektions-Prompt
- DB: 52 WordPress-Redirect-Duplikate deaktiviert (netzpolitik.org, bashinho.de)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:25:04 +01:00
claude-dev
23ac6d6fd7 Fix: researcher.py korrupte Datei repariert (base64-Transfer) 2026-03-04 20:32:31 +01:00
claude-dev
3d9a827bc8 Inkrementelle Analyse + Token-Optimierung + Relevanz-Scoring
TOKEN-OPTIMIERUNG:
- Inkrementelle Analyse: Folge-Refreshes senden nur noch das bisherige
  Lagebild + neue Artikel an Claude (statt alle Artikel erneut).
  Spart ~60-70% Tokens bei Lagen mit vielen Artikeln.
- Inkrementeller Faktencheck: Bestehende Fakten als Zusammenfassung,
  nur neue Artikel werden vollstaendig geprueft.
- Modell-Steuerung: Feed-Selektion nutzt jetzt Haiku (CLAUDE_MODEL_FAST)
  statt Opus. Spart ~50-70% bei Feed-Auswahl.
- Set-basierte DB-Deduplizierung: Bestehende URLs/Headlines einmal
  in Sets geladen statt N*M einzelne DB-Queries pro Artikel.

INHALTLICHE VERBESSERUNGEN:
- Relevanz-Scoring: Artikel nach Keyword-Dichte (40%),
  Quellen-Reputation (30%), Inhaltstiefe (20%), RSS-Score (10%).
- Flexibles RSS-Matching: min. Haelfte der Keywords statt alle.
  RSS-Artikel bekommen einen relevance_score.
- Fuzzy Claim-Matching: SequenceMatcher (0.7) statt exakter
  String-Vergleich. Verhindert Duplikat-Akkumulation.
- Translation-Fix: Nur gueltige DB-IDs (isinstance int).
- Researcher: WebFetch fuer Top-Artikel, erweiterte Zusammenfassungen.

DATEIEN:
- config.py: CLAUDE_MODEL_FAST
- claude_client.py: model-Parameter
- researcher.py: Haiku Feed-Selektion, erweiterte Prompts
- analyzer.py: Inkrementelle Analyse + analyze_incremental()
- factchecker.py: Inkrementeller Check + Fuzzy-Matching
- orchestrator.py: Set-Dedup, Relevanz-Scoring, inkrementeller Flow
- rss_parser.py: Flexibles Keyword-Matching + relevance_score
2026-03-04 20:22:47 +01:00
claude-dev
71296edb97 Großes Cleanup: Bugs fixen, Features fertigstellen, toten Code entfernen
Bugs behoben:
- handleEdit() async keyword hinzugefügt (E-Mail-Checkboxen funktionieren jetzt)
- parseUTC() Funktion definiert (Fortschritts-Timer nutzt Server-Startzeit)
- Status cancelling wird im Frontend korrekt angezeigt

Features fertiggestellt:
- Sidebar: Lagen nach Typ getrennt (adhoc/research) mit Zählern
- Quellen-Bearbeiten: Edit-Button pro Quelle, Formular vorausfüllen
- Lizenz-Info: Org-Name und Lizenzstatus im Header angezeigt

Toter Code entfernt:
- 5 verwaiste Dateien gelöscht (alte rss_parser, style.css, components.js, layout.js, setup_users)
- 6 ungenutzte Pydantic Models entfernt
- Ungenutzte Funktionen/Imports in auth.py, routers, agents, config
- Tote API-Methoden, Legacy-UI-Methoden, verwaiste WS-Handler
- Abgeschlossene DB-Migrationen aufgeräumt

Sonstiges:
- requirements.txt: passlib[bcrypt] durch bcrypt ersetzt
- Umlaute korrigiert (index.html)
- CSS: incident-type-label → incident-type-badge, .login-success hinzugefügt
- Schließen statt Schliessen im Feedback-Modal
2026-03-04 18:45:38 +01:00
claude-dev
8312d24912 Initial commit: AegisSight-Monitor (OSINT-Monitoringsystem) 2026-03-04 17:53:18 +01:00