From 128c11b49d6dd0dd4f89341def04dab1e4db305e Mon Sep 17 00:00:00 2001 From: ARIA Date: Mon, 20 Jul 2026 07:59:29 +0000 Subject: [PATCH] debug(proxy): Streaming-close/result-Events sichtbar loggen statt still leer zu bleiben Root Cause fuer 'Empty response (no content or reasoning)'-Retries im hermes-agent-Log noch nicht zweifelsfrei geklaert -- der bisherige Code konnte einen Subprocess-Abschluss ohne 'result'-Event (code===0, kein Fehler-Chunk) still mit nur [DONE] beenden, was beim Client exakt wie eine leere Antwort aussieht. Jetzt: immer ein sichtbarer Fehler-Chunk + Log-Zeile bei fehlendem result-Event, und ein Debug-Log bei jedem result-Event mit subtype/is_error/Textlaenge. Naechster Repro-Versuch mit docker logs hermes-proxy zeigt damit die echte Ursache. --- proxy-patches/routes.js | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/proxy-patches/routes.js b/proxy-patches/routes.js index 852e3df..db72ad8 100644 --- a/proxy-patches/routes.js +++ b/proxy-patches/routes.js @@ -116,6 +116,19 @@ async function handleStreamingResponse(req, res, subprocess, cliInput, requestId }); subprocess.on("result", (result) => { isComplete = true; + // ARIA-Patch (20.07.2026): Diagnose-Log fuer "Empty response"-Retries. + // Zeigt ob die "result"-Message ueberhaupt Text enthielt (result.result), + // welcher subtype/is_error sie hatte, und wieviele Zeichen am Ende als + // Content beim Client ankommen -- damit sich naechstes Mal in EINEM + // "docker logs hermes-proxy" sehen laesst ob (a) Claude wirklich leer + // geantwortet hat, (b) ein Fehler-Subtype ohne result-Feld vorlag, oder + // (c) der Text da ist aber beim Parsen/Weiterreichen verloren geht. + console.error( + "[Streaming][DEBUG] result-event: subtype=" + result?.subtype + + " is_error=" + result?.is_error + + " resultTextLen=" + (typeof result?.result === "string" ? result.result.length : "n/a (" + typeof result?.result + ")") + + " resultPreview=" + JSON.stringify((typeof result?.result === "string" ? result.result : "").slice(0, 200)) + ); if (!res.writableEnded) { // Volle Antwort ist da -- durch denselben Tool-Call-Parser wie im // Non-Streaming-Pfad jagen, damit -Bloecke als echtes @@ -166,10 +179,23 @@ async function handleStreamingResponse(req, res, subprocess, cliInput, requestId subprocess.on("close", (code) => { // Subprocess exited - ensure response is closed if (!res.writableEnded) { - if (code !== 0 && !isComplete) { - // Abnormal exit without result - send error + if (!isComplete) { + // ARIA-Patch (20.07.2026): vorher wurde hier NUR bei code!==0 ein + // Fehler gemeldet. Faelle in denen der Subprocess mit code===0 + // schliesst OHNE je ein "result"-Event gefeuert zu haben (z.B. + // Claude CLI liefert eine "result"-Message ohne "result"-Textfeld, + // oder ein "error_max_turns"/aehnlicher Abschluss-Subtype, oder das + // letzte JSON-Fragment im Buffer war unvollstaendig/unparsbar) + // wurden bisher STILL mit nur "[DONE]" beendet -- Hermes bekam einen + // Stream OHNE jeden content/tool_calls-Chunk und wertete das als + // "Empty response (no content or reasoning)" -> eigener Retry-Loop + // im hermes-agent-Container (agent.conversation_loop, retry 1/3..3/3). + // Jetzt: IMMER einen sichtbaren Fehler-Chunk schreiben, egal welcher + // Exit-Code -- macht die Ursache in "docker logs hermes-proxy" + // sichtbar statt lautlos leer zu bleiben. + console.error(`[Streaming] Subprocess closed (code=${code}) without ever emitting a "result" event -- no content/tool_calls was sent to the client.`); res.write(`data: ${JSON.stringify({ - error: { message: `Process exited with code ${code}`, type: "server_error", code: null }, + error: { message: `Claude CLI process closed (code ${code}) without producing a result`, type: "server_error", code: null }, })}\n\n`); } res.write("data: [DONE]\n\n");