From 7777b77abd92c043eb53859e13248e2d72a272aa Mon Sep 17 00:00:00 2001 From: Claude Code Date: Tue, 26 May 2026 00:22:34 +0000 Subject: [PATCH] feat(pipeline): Translator als Pipeline-Step + Watchdog-Limits erhoehen Folgefix zu 952df87. Der Translator-Block laeuft post-summary bei jp_demo 40+ Min und war bisher fuer das Frontend unsichtbar und fuer den Watchdog ein blinder Fleck (kein Pipeline-Step-Eintrag). Aenderungen: - pipeline_tracker.py: neuer Step 'translate' zwischen 'summary' und 'qc' (DE+EN Label/Tooltip). Bewusst conditional sichtbar: erscheint nur, wenn fremdsprachige Artikel ohne DE-Uebersetzung vorliegen UND translator_enabled fuer die Org an ist. - orchestrator.py: Translator-Block umrandet mit _pipe_start('translate') und _pipe_done('translate', count_value=uebersetzt, count_secondary= pending). Translator-Fehler schliesst Step trotzdem sauber ab. Bedingung 'pending_translations and translator_enabled' ersetzt das alte 'pending_translations' - skipped den Block sauber wenn Org-Override deaktiviert (war vorher redundant in translate_articles selbst). - main.py: ORPHAN_IDLE_LIMIT 30->60 Min, ORPHAN_HARD_LIMIT 90->120 Min. Deckt jp_demo Translator-Phase (beobachtet bis 41 Min) mit Puffer ab, ohne echte Haenger durchzulassen. Resultierend: Frontend zeigt den Uebersetzungs-Schritt mit Fortschritt (uebersetzt/gesamt). Watchdog killt nicht mehr vorzeitig. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/agents/orchestrator.py | 9 ++++++++- src/main.py | 4 ++-- src/services/pipeline_tracker.py | 4 ++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/agents/orchestrator.py b/src/agents/orchestrator.py index 7a9760f..86bf7e8 100644 --- a/src/agents/orchestrator.py +++ b/src/agents/orchestrator.py @@ -1753,6 +1753,7 @@ class AgentOrchestrator: # Idempotent: nur Artikel ohne headline_de/content_de werden geholt. # Lauft nach der Analyse (Lagebild ist schon committed) und vor QC # (damit normalize_umlaut_articles auch die frischen DE-Texte fasst). + _translate_step_started = False try: tr_cursor = await db.execute( """SELECT id, headline, content_original, language @@ -1764,7 +1765,10 @@ class AgentOrchestrator: (incident_id,), ) pending_translations = [dict(r) for r in await tr_cursor.fetchall()] - if pending_translations: + if pending_translations and translator_enabled: + # Pipeline-Schritt 9: Artikel uebersetzen (nur sichtbar wenn was zu uebersetzen) + await _pipe_start("translate") + _translate_step_started = True logger.info( "Translator fuer Incident %d: %d Artikel ohne DE-Uebersetzung", incident_id, len(pending_translations), @@ -1795,8 +1799,11 @@ class AgentOrchestrator: "Translator fuer Incident %d: %d/%d Artikel uebersetzt", incident_id, len(translations), len(pending_translations), ) + await _pipe_done("translate", count_value=len(translations), count_secondary=len(pending_translations)) except Exception as e: logger.error("Translator-Fehler fuer Incident %d: %s", incident_id, e, exc_info=True) + if _translate_step_started: + await _pipe_done("translate", count_value=0, count_secondary=0) # Refresh trotz Translator-Fehler weiterlaufen lassen # --- Neueste Entwicklungen (nur Live-Monitoring / adhoc) --- diff --git a/src/main.py b/src/main.py index 3aaa28c..9bec45c 100644 --- a/src/main.py +++ b/src/main.py @@ -252,8 +252,8 @@ async def cleanup_expired(): # vorzeitig gekillt werden. Ein Refresh gilt als verwaist, wenn entweder # (a) seit ORPHAN_IDLE_LIMIT Min kein Pipeline-Step Fortschritt zeigte, # oder (b) das harte Limit ORPHAN_HARD_LIMIT Min ueberschritten wurde. - ORPHAN_IDLE_LIMIT = 30 - ORPHAN_HARD_LIMIT = 90 + ORPHAN_IDLE_LIMIT = 60 + ORPHAN_HARD_LIMIT = 120 cursor = await db.execute( "SELECT id, incident_id, started_at FROM refresh_log WHERE status = 'running'" ) diff --git a/src/services/pipeline_tracker.py b/src/services/pipeline_tracker.py index 86cc43a..da47ced 100644 --- a/src/services/pipeline_tracker.py +++ b/src/services/pipeline_tracker.py @@ -36,6 +36,8 @@ _PIPELINE_STEPS_DE = [ "tooltip": "Aus Foren-Quellen (z.B. 5ch, Hatena, Note) wird ein Stimmungsbild der öffentlichen Diskussion extrahiert. Keine Faktenlage, sondern dominante Themen und Bruchlinien."}, {"key": "summary", "label": "Lagebild verfassen", "icon": "file-text", "tooltip": "Aus allen geprüften Meldungen wird ein zusammenhängendes Lagebild geschrieben, mit Quellenangaben am Text."}, + {"key": "translate", "label": "Artikel uebersetzen", "icon": "languages", + "tooltip": "Fremdsprachige Meldungen (z.B. japanisch) werden ins Lagebild-Output uebersetzt. Laeuft nur fuer Quellen-Pools mit nicht-deutschen Sprachen und kann bei vielen neuen Artikeln einige Minuten dauern."}, {"key": "qc", "label": "Qualitätscheck", "icon": "check-circle", "tooltip": "Eine letzte Kontrollprüfung am Ergebnis: Doppelte Fakten zusammenführen, Karten-Verortung prüfen, bevor du benachrichtigt wirst."}, {"key": "notify", "label": "Benachrichtigen", "icon": "bell", @@ -59,6 +61,8 @@ _PIPELINE_STEPS_EN = [ "tooltip": "Forum sources (5ch, Hatena, Note, etc.) are summarised into a public-mood overview. Not factual, but dominant themes and fault lines."}, {"key": "summary", "label": "Writing the briefing", "icon": "file-text", "tooltip": "All verified articles are combined into a coherent briefing with inline citations."}, + {"key": "translate", "label": "Translating articles", "icon": "languages", + "tooltip": "Foreign-language articles (e.g. Japanese) are translated into the briefing output language. Runs only when the source pool contains non-target-language items and can take several minutes for large incoming batches."}, {"key": "qc", "label": "Quality check", "icon": "check-circle", "tooltip": "A final review: consolidate duplicate facts, verify map locations, before you get notified."}, {"key": "notify", "label": "Notifying", "icon": "bell",