fix: deep_research Tool — Logging + allow_clarification=False

- Ausfuehrliches Logging fuer Debugging
- allow_clarification deaktiviert (verhindert Rueckfrage-Deadlock)
- Ergebnis-Schwelle auf 100 Zeichen gesenkt
This commit is contained in:
Homelab Cursor 2026-03-20 21:47:33 +01:00
parent 15ba1e5d3c
commit 7a3327eb90

View file

@ -1,12 +1,10 @@
"""Deep Research Tool — Open Deep Research (CT 121) via LangGraph API. """Deep Research Tool — Open Deep Research (CT 121) via LangGraph API."""
Ermoeglicht dem Hausmeister-Bot tiefe Web-Recherchen zu starten.
Ergebnisse kommen als ausfuehrlicher Report zurueck.
"""
import requests import requests
import time import time
import json import logging
log = logging.getLogger("deep_research")
DEEP_RESEARCH_URL = "http://10.10.10.121:2024" DEEP_RESEARCH_URL = "http://10.10.10.121:2024"
ASSISTANT_ID = "e9a5370f-7a53-55a8-ada8-6ab9ef15bb5b" ASSISTANT_ID = "e9a5370f-7a53-55a8-ada8-6ab9ef15bb5b"
@ -16,18 +14,17 @@ MAX_WAIT = 600
SYSTEM_PROMPT_EXTRA = """DEEP RESEARCH: SYSTEM_PROMPT_EXTRA = """DEEP RESEARCH:
Du hast Zugriff auf deep_research eine KI-gestuetzte Tiefenrecherche die 20-30 Quellen durchsucht. Du hast Zugriff auf deep_research eine KI-gestuetzte Tiefenrecherche die 20-30 Quellen durchsucht.
Nutze es wenn der User eine komplexe Frage stellt die gruendliche Recherche erfordert. Nutze es wenn der User explizit "recherchiere", "finde heraus", "vergleiche" sagt oder eine komplexe Frage hat.
Beispiele: "Recherchiere X", "Finde heraus...", "Vergleiche A und B", "Was gibt es Neues zu...". NICHT fuer einfache Fakten oder Homelab-Fragen.
NICHT fuer einfache Fakten oder Homelab-Fragen dafuer reichen die anderen Tools. WICHTIG: deep_research dauert 2-5 Minuten. Das ist normal. Warte auf das Ergebnis.
Das Ergebnis ist ein ausfuehrlicher Report. Fasse ihn fuer Telegram zusammen (max ~3000 Zeichen). Das Ergebnis ist ein ausfuehrlicher Report. Fasse ihn fuer Telegram zusammen (max ~3000 Zeichen)."""
deep_research dauert 2-10 Minuten. Sage dem User dass es laeuft."""
TOOLS = [ TOOLS = [
{ {
"type": "function", "type": "function",
"function": { "function": {
"name": "deep_research", "name": "deep_research",
"description": "Startet eine tiefe Web-Recherche zu einem Thema. Durchsucht 20-30 Quellen und erstellt einen ausfuehrlichen Report. Dauert 2-10 Minuten.", "description": "Startet eine tiefe Web-Recherche zu einem Thema. Durchsucht 20-30 Quellen und erstellt einen ausfuehrlichen Report. Dauert 2-5 Minuten — das ist normal, warte auf das Ergebnis.",
"parameters": { "parameters": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -62,6 +59,7 @@ def _start_run(thread_id, query):
"research_model": f"openai:{RESEARCH_MODEL}", "research_model": f"openai:{RESEARCH_MODEL}",
"compression_model": f"openai:{RESEARCH_MODEL}", "compression_model": f"openai:{RESEARCH_MODEL}",
"final_report_model": f"openai:{RESEARCH_MODEL}", "final_report_model": f"openai:{RESEARCH_MODEL}",
"allow_clarification": False,
} }
} }
} }
@ -76,18 +74,24 @@ def _poll_run(thread_id, run_id):
while elapsed < MAX_WAIT: while elapsed < MAX_WAIT:
time.sleep(POLL_INTERVAL) time.sleep(POLL_INTERVAL)
elapsed += POLL_INTERVAL elapsed += POLL_INTERVAL
try:
r = requests.get( r = requests.get(
f"{DEEP_RESEARCH_URL}/threads/{thread_id}/runs/{run_id}", f"{DEEP_RESEARCH_URL}/threads/{thread_id}/runs/{run_id}",
timeout=10) timeout=10)
r.raise_for_status() r.raise_for_status()
data = r.json() data = r.json()
status = data.get("status", "unknown") status = data.get("status", "unknown")
log.info("Poll %ds: status=%s", elapsed, status)
if status == "success": if status == "success":
return True, None return True, None
if status in ("error", "failed"): if status in ("error", "failed"):
return False, data.get("error", "Unbekannter Fehler") err = data.get("error", "Unbekannter Fehler")
log.error("Run failed: %s", err)
return False, err
if status == "interrupted": if status == "interrupted":
return False, "Research wurde unterbrochen" return False, "Research wurde unterbrochen"
except Exception as e:
log.warning("Poll error at %ds: %s", elapsed, e)
return False, f"Timeout nach {MAX_WAIT}s" return False, f"Timeout nach {MAX_WAIT}s"
@ -100,33 +104,47 @@ def _get_result(thread_id):
values = state.get("values", {}) values = state.get("values", {})
messages = values.get("messages", []) messages = values.get("messages", [])
log.info("Messages in result: %d", len(messages))
for i, msg in enumerate(messages):
content = msg.get("content", "")
clen = len(content) if isinstance(content, str) else 0
log.info(" msg[%d] type=%s len=%d", i, msg.get("type", "?"), clen)
for msg in reversed(messages): for msg in reversed(messages):
content = msg.get("content", "") content = msg.get("content", "")
if isinstance(content, str) and len(content) > 200: if isinstance(content, str) and len(content) > 100:
return content return content
return "Kein Report generiert." return "Kein Report generiert."
def handle_deep_research(query: str, **kw): def handle_deep_research(query: str, **kw):
log.info("deep_research gestartet: %s", query[:100])
try: try:
thread_id = _create_thread() thread_id = _create_thread()
log.info("Thread erstellt: %s", thread_id)
run_id = _start_run(thread_id, query) run_id = _start_run(thread_id, query)
log.info("Run gestartet: %s", run_id)
ok, error = _poll_run(thread_id, run_id) ok, error = _poll_run(thread_id, run_id)
if not ok: if not ok:
log.error("Research fehlgeschlagen: %s", error)
return f"Deep Research fehlgeschlagen: {error}" return f"Deep Research fehlgeschlagen: {error}"
report = _get_result(thread_id) report = _get_result(thread_id)
log.info("Report erhalten: %d Zeichen", len(report))
if len(report) > 6000: if len(report) > 6000:
report = report[:6000] + "\n\n[... Report gekuerzt, Original war laenger]" report = report[:6000] + "\n\n[... Report gekuerzt]"
return report return report
except requests.ConnectionError: except requests.ConnectionError:
log.error("CT 121 nicht erreichbar")
return "Deep Research (CT 121) nicht erreichbar. Service laeuft moeglicherweise nicht." return "Deep Research (CT 121) nicht erreichbar. Service laeuft moeglicherweise nicht."
except Exception as e: except Exception as e:
log.exception("Deep Research Fehler")
return f"Deep Research Fehler: {e}" return f"Deep Research Fehler: {e}"