diff --git a/bridge/aria_bridge.py b/bridge/aria_bridge.py index 31f78e3..153c82b 100644 --- a/bridge/aria_bridge.py +++ b/bridge/aria_bridge.py @@ -1963,10 +1963,13 @@ class ARIABridge: url, data=payload, method="POST", headers={"Content-Type": "application/json"}, ) - # 20 Min Timeout — lange Multi-Tool-Workflows (Karten, - # PDFs, viele curl-Calls) brauchen das. 5 Min waren chronisch - # zu knapp und haben ARIA mitten in der Arbeit gekappt. - with urllib.request.urlopen(req, timeout=1200) as resp: + # Timeout MUSS zum Proxy passen (der laesst ARIA bis 24h + # rechnen). 1200s (20 Min) war zu knapp: lange Software-Dev- + # Turns dauern laenger → die Bridge gab auf, die Antwort ging + # verloren (kein Bubble), der Kontext blieb auf 'running' + # haengen. Jetzt 24h (env BRAIN_CHAT_TIMEOUT_SEC). + _chat_timeout = float(os.environ.get("BRAIN_CHAT_TIMEOUT_SEC", "86400")) + with urllib.request.urlopen(req, timeout=_chat_timeout) as resp: return resp.status, resp.read().decode("utf-8", errors="ignore") except Exception as exc: return None, str(exc) diff --git a/diagnostic/index.html b/diagnostic/index.html index 2cc4aa3..feb983f 100644 --- a/diagnostic/index.html +++ b/diagnostic/index.html @@ -1588,9 +1588,34 @@ const d = await r.json(); diagQueueStatus = d?.contexts || {}; renderContextStrip(); + reconcileDiagStates(); } catch {} } + // Selbstheilung: haengt ein Kontext lokal auf 'running', obwohl der Brain + // ihn NICHT als busy meldet, ist der Turn (z.B. durch einen Bridge-Timeout) + // ohne Antwort-Bubble abgebrochen — der Automat blieb sonst ewig 'running' + // (Folge-Nachrichten wandern in die Queue, obwohl ARIA idle ist; frueher + // half nur Ctrl+R, was die Queue-Nachricht verlor). Nach 2 aufeinander- + // folgenden not-busy-Polls (~4s Karenz gegen das Sende-Fenster) schalten + // wir die Queue weiter: angestellte Nachricht geht automatisch raus, sonst + // idle. + const diagStuckCounts = {}; + function reconcileDiagStates() { + const ctxs = diagQueueStatus || {}; + for (const pid of Object.keys(diagCtxStates)) { + if (diagCtxStates[pid] !== 'running') { diagStuckCounts[pid] = 0; continue; } + const busy = !!(ctxs[pid || '__main__'] && ctxs[pid || '__main__'].busy); + if (busy) { diagStuckCounts[pid] = 0; continue; } + diagStuckCounts[pid] = (diagStuckCounts[pid] || 0) + 1; + if (diagStuckCounts[pid] >= 2) { + diagStuckCounts[pid] = 0; + console.warn('[diag] Kontext', pid || '(main)', 'haengt auf running, Brain idle → Queue weiterschalten'); + advanceDiagQueue(pid); + } + } + } + async function refreshDiagProjectsCache() { try { const r = await fetch('/api/brain/projects/list?include_archived=false');