feat(pipeline): output_language pro Org durch die Pipeline reichen
- OUTPUT_LANGUAGE Konstante aus config.py entfernt (jetzt pro Org in organization_settings). - Orchestrator laedt output_language einmal pro Refresh aus der Org-Sprache. - researcher.search(), analyzer.analyze/.analyze_incremental/.generate_latest_developments, factchecker.check/.check_incremental/.check_incremental_twophase bekommen output_language als Parameter (Default Deutsch). - LANG_INTERNATIONAL / LANG_GERMAN_ONLY (+ Deep-Varianten) sind Funktionen, die je nach output_language die Sprachanweisung erzeugen (Deutsch | English | Fallback). - Sprachfilter in researcher.search ist org-relativ: bei nicht-international werden Artikel mit Sprache != output_language_iso gefiltert. Phase 2 von 8 (eng_demo / Org-Sprache). Bestandsorgs unveraendert, weil Default-Setting weiterhin de (siehe Phase-1-Migration).
Dieser Commit ist enthalten in:
@@ -153,12 +153,37 @@ Jedes Element hat diese Felder:
|
||||
|
||||
Antworte NUR mit dem JSON-Array. Keine Einleitung, keine Erklärung."""
|
||||
|
||||
# Sprach-Anweisungen
|
||||
LANG_INTERNATIONAL = "- Suche in Deutsch UND Englisch für internationale Abdeckung"
|
||||
LANG_GERMAN_ONLY = "- Suche NUR auf Deutsch bei deutschsprachigen Quellen (Deutschland, Österreich, Schweiz)\n- KEINE englischsprachigen oder anderssprachigen Quellen"
|
||||
# Sprach-Anweisungen (org-sprach-relativ; primary_display = "Deutsch" | "English")
|
||||
def lang_international(primary_display: str) -> str:
|
||||
if primary_display == "Deutsch":
|
||||
return "- Suche in Deutsch UND Englisch für internationale Abdeckung"
|
||||
if primary_display == "English":
|
||||
return "- Search in English AND other relevant languages for international coverage"
|
||||
return f"- Suche in {primary_display} und weiteren relevanten Sprachen"
|
||||
|
||||
LANG_DEEP_INTERNATIONAL = "- Suche in Deutsch, Englisch und weiteren relevanten Sprachen"
|
||||
LANG_DEEP_GERMAN_ONLY = "- Suche NUR auf Deutsch bei deutschsprachigen Quellen (Deutschland, Österreich, Schweiz)\n- KEINE englischsprachigen oder anderssprachigen Quellen"
|
||||
|
||||
def lang_primary_only(primary_display: str) -> str:
|
||||
if primary_display == "Deutsch":
|
||||
return "- Suche NUR auf Deutsch bei deutschsprachigen Quellen (Deutschland, Österreich, Schweiz)\n- KEINE englischsprachigen oder anderssprachigen Quellen"
|
||||
if primary_display == "English":
|
||||
return "- Search ONLY in English-language sources\n- NO sources in other languages"
|
||||
return f"- Suche NUR auf {primary_display}\n- KEINE Quellen in anderen Sprachen"
|
||||
|
||||
|
||||
def lang_deep_international(primary_display: str) -> str:
|
||||
if primary_display == "Deutsch":
|
||||
return "- Suche in Deutsch, Englisch und weiteren relevanten Sprachen"
|
||||
if primary_display == "English":
|
||||
return "- Search in English and other relevant languages"
|
||||
return f"- Suche in {primary_display} und weiteren relevanten Sprachen"
|
||||
|
||||
|
||||
def lang_deep_primary_only(primary_display: str) -> str:
|
||||
if primary_display == "Deutsch":
|
||||
return "- Suche NUR auf Deutsch bei deutschsprachigen Quellen (Deutschland, Österreich, Schweiz)\n- KEINE englischsprachigen oder anderssprachigen Quellen"
|
||||
if primary_display == "English":
|
||||
return "- Search ONLY in English-language sources\n- NO sources in other languages"
|
||||
return f"- Suche NUR auf {primary_display}\n- KEINE Quellen in anderen Sprachen"
|
||||
|
||||
|
||||
FEED_SELECTION_PROMPT_TEMPLATE = """Du bist ein OSINT-Analyst. Wähle aus dieser Feed-Liste die Feeds aus, die für die Lage relevant sein könnten. Generiere außerdem optimierte Suchbegriffe für das RSS-Matching.
|
||||
@@ -392,7 +417,7 @@ class ResearcherAgent:
|
||||
logger.warning(f"Keyword-Extraktion fehlgeschlagen: {e}")
|
||||
return None, None
|
||||
|
||||
async def search(self, title: str, description: str = "", incident_type: str = "adhoc", international: bool = True, user_id: int = None, existing_articles: list[dict] = None, preferred_sources: list[dict] = None) -> tuple[list[dict], ClaudeUsage | None, bool]:
|
||||
async def search(self, title: str, description: str = "", incident_type: str = "adhoc", international: bool = True, user_id: int = None, existing_articles: list[dict] = None, preferred_sources: list[dict] = None, output_language: str = "Deutsch", output_language_iso: str = "de") -> tuple[list[dict], ClaudeUsage | None, bool]:
|
||||
"""Sucht nach Informationen zu einem Vorfall.
|
||||
|
||||
Returns:
|
||||
@@ -400,8 +425,6 @@ class ResearcherAgent:
|
||||
das JSON aber nicht extrahierbar war. So kann der Orchestrator zwischen
|
||||
"echt keine Treffer" und "kaputte Antwort" unterscheiden.
|
||||
"""
|
||||
from config import OUTPUT_LANGUAGE
|
||||
|
||||
# Bevorzugte Web-Quellen als Prompt-Block (optional)
|
||||
preferred_sources_block = ""
|
||||
if preferred_sources:
|
||||
@@ -422,7 +445,7 @@ class ResearcherAgent:
|
||||
)
|
||||
|
||||
if incident_type == "research":
|
||||
lang_instruction = LANG_DEEP_INTERNATIONAL if international else LANG_DEEP_GERMAN_ONLY
|
||||
lang_instruction = lang_deep_international(output_language) if international else lang_deep_primary_only(output_language)
|
||||
# Bestehende Artikel als Kontext für den Prompt aufbereiten
|
||||
existing_context = ""
|
||||
if existing_articles:
|
||||
@@ -439,11 +462,11 @@ class ResearcherAgent:
|
||||
)
|
||||
prompt = DEEP_RESEARCH_PROMPT_TEMPLATE.format(
|
||||
title=title, description=description, language_instruction=lang_instruction,
|
||||
output_language=OUTPUT_LANGUAGE, existing_context=existing_context,
|
||||
output_language=output_language, existing_context=existing_context,
|
||||
preferred_sources_block=preferred_sources_block,
|
||||
)
|
||||
else:
|
||||
lang_instruction = LANG_INTERNATIONAL if international else LANG_GERMAN_ONLY
|
||||
lang_instruction = lang_international(output_language) if international else lang_primary_only(output_language)
|
||||
# Bestehende Artikel als Kontext: bei Folge-Refreshes findet Claude andere Quellen
|
||||
existing_context = ""
|
||||
if existing_articles:
|
||||
@@ -458,7 +481,7 @@ class ResearcherAgent:
|
||||
)
|
||||
prompt = RESEARCH_PROMPT_TEMPLATE.format(
|
||||
title=title, description=description, language_instruction=lang_instruction,
|
||||
output_language=OUTPUT_LANGUAGE, existing_context=existing_context,
|
||||
output_language=output_language, existing_context=existing_context,
|
||||
preferred_sources_block=preferred_sources_block,
|
||||
)
|
||||
|
||||
@@ -486,8 +509,8 @@ class ResearcherAgent:
|
||||
excluded = True
|
||||
break
|
||||
if not excluded:
|
||||
# Bei nur-deutsch: nicht-deutsche Ergebnisse nachfiltern
|
||||
if not international and article.get("language", "de") != "de":
|
||||
# Bei nur-primary: andersprachige Ergebnisse nachfiltern
|
||||
if not international and article.get("language", output_language_iso) != output_language_iso:
|
||||
continue
|
||||
filtered.append(article)
|
||||
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren