feat(eu-umbau): staan-Recherche-Schleife und Doppelspur (Phase 2)

Im EU-Modus laeuft die Recherche jetzt europaeisch: agents/eu_researcher.py
steuert eine Schleife aus Bedrock-Planung (Opus, EU-Profile) und staan-Suchen
(services/staan_client.py, Suche + Volltexte via full_content=markdown,
Pflicht-Domain-Ausschlussliste je Anfrage). Bildet die 4-Phasen-Tiefenrecherche
nach und liefert exakt das JSON der bisherigen CLI-WebSearch, Parsing und
Filter in researcher.search bleiben unveraendert. Anti-Halluzination: nur URLs
aus echten staan-Treffern werden akzeptiert; published_at nur wenn aus Inhalt
oder URL ableitbar (staan liefert keine Daten).

Doppelspur im Orchestrator: Lane-Schluessel ist jetzt (Organisation, Backend),
Aufloesung zentral in _resolve_ai_backend (Lage > Org-Setting > ENV). CLI- und
EU-Lauf derselben Organisation laufen gleichzeitig, gleiche Backends seriell.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
claude-dev
2026-07-30 20:12:31 +00:00
Ursprung e0edac2a18
Commit a7f1aa29ab
6 geänderte Dateien mit 589 neuen und 20 gelöschten Zeilen

Datei anzeigen

@@ -804,7 +804,28 @@ class ResearcherAgent:
)
try:
result, usage = await call_claude(prompt)
# EU-Modellweg (Phase 2). Läuft der Refresh über das Bedrock-Backend,
# übernimmt die gesteuerte staan-Schleife die komplette Recherche und
# liefert denselben JSON-Array-Text wie die CLI-WebSearch. Parsing,
# Quellenfilter und Sprachfilter darunter bleiben unverändert.
from agents.claude_client import _ai_backend_var
from config import AI_BACKEND
_backend = _ai_backend_var.get(None) or AI_BACKEND
if _backend == "bedrock":
from agents.eu_researcher import run_eu_research
result, usage = await run_eu_research(
title=title,
description=description,
incident_type=incident_type,
lang_instruction=lang_instruction,
existing_context=existing_context,
preferred_sources_block=preferred_sources_block,
output_language=output_language,
excluded_sources=await self._get_excluded_sources(user_id=user_id),
research_language_iso=research_language_iso or output_language_iso,
)
else:
result, usage = await call_claude(prompt)
try:
articles = self._parse_response(result)
except ResearcherParseError as parse_err: