fix(chat): Nachrichten brechen nicht mehr ab (Bridge-Timeout) + Diagnostic-Selbstheilung
Ursache: Bridge-/chat-Aufruf hatte 1200s (20min) Timeout, der Proxy aber
24h. Lange Software-Dev-Turns dauern >20min → Bridge gab auf ('/chat
fehlgeschlagen: timed out'), der Brain lieferte die Antwort Minuten spaeter
(nur im Log, keine Bubble), und der Diagnostic-Kontext blieb auf 'running'
haengen (Folgenachrichten in die Queue trotz idler ARIA; nur Ctrl+R half,
verlor aber die Queue-Nachricht).
- Bridge: /chat-Timeout 1200s → 24h (env BRAIN_CHAT_TIMEOUT_SEC), passend
zum Proxy.
- Diagnostic: reconcileDiagStates() gleicht lokalen 'running'-Zustand gegen
die Brain-queue-status ab (2 Polls Karenz). Haengt ein Kontext, obwohl der
Brain nicht busy ist → Queue weiterschalten: angestellte Nachricht geht
automatisch raus statt verloren.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1963,10 +1963,13 @@ class ARIABridge:
|
|||||||
url, data=payload, method="POST",
|
url, data=payload, method="POST",
|
||||||
headers={"Content-Type": "application/json"},
|
headers={"Content-Type": "application/json"},
|
||||||
)
|
)
|
||||||
# 20 Min Timeout — lange Multi-Tool-Workflows (Karten,
|
# Timeout MUSS zum Proxy passen (der laesst ARIA bis 24h
|
||||||
# PDFs, viele curl-Calls) brauchen das. 5 Min waren chronisch
|
# rechnen). 1200s (20 Min) war zu knapp: lange Software-Dev-
|
||||||
# zu knapp und haben ARIA mitten in der Arbeit gekappt.
|
# Turns dauern laenger → die Bridge gab auf, die Antwort ging
|
||||||
with urllib.request.urlopen(req, timeout=1200) as resp:
|
# 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")
|
return resp.status, resp.read().decode("utf-8", errors="ignore")
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
return None, str(exc)
|
return None, str(exc)
|
||||||
|
|||||||
@@ -1588,9 +1588,34 @@
|
|||||||
const d = await r.json();
|
const d = await r.json();
|
||||||
diagQueueStatus = d?.contexts || {};
|
diagQueueStatus = d?.contexts || {};
|
||||||
renderContextStrip();
|
renderContextStrip();
|
||||||
|
reconcileDiagStates();
|
||||||
} catch {}
|
} 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() {
|
async function refreshDiagProjectsCache() {
|
||||||
try {
|
try {
|
||||||
const r = await fetch('/api/brain/projects/list?include_archived=false');
|
const r = await fetch('/api/brain/projects/list?include_archived=false');
|
||||||
|
|||||||
Reference in New Issue
Block a user