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.
This commit is contained in:
ARIA
2026-07-20 07:59:29 +00:00
parent 4710e4071b
commit 128c11b49d
+29 -3
View File
@@ -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 <tool_call>-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");