fix(proxy): ein Bericht mitten im Turn geht nicht mehr verloren

Claude Code liefert in result.result nur den LETZTEN Textblock eines Turns.
Am 28.10. hat ARIA in einem 2-Stunden-Turn ihren Bericht geschrieben, danach
noch auf Laeufe gewartet und mit einer kurzen Notiz geendet — beim Brain kam
nur die Notiz an ("…steht im Bericht oben"), der Bericht war weg.

- Nicht-Streaming: alle Textbloecke des Turns sammeln; laengere fruehere
  (>= 300 Zeichen, z.B. Berichte) kommen vor die letzte Antwort. Kurze
  Zwischensaetze bleiben weg, <voice> nur aus der letzten Antwort.
- Belegprotokoll speichert jetzt auch Texte (geschwaerzt, max. 20k je
  Block), damit so etwas wiederherstellbar ist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-29 06:36:41 +01:00
co-authored by Claude Opus 5.5
parent f8ad877881
commit 0f8debbf99
2 changed files with 31 additions and 5 deletions
+15 -2
View File
@@ -99,7 +99,20 @@ function _parseToolCalls(text) {
return { tool_calls: tcs, rest: restParts.join("").trim() };
}
export function cliResultToOpenai(result, requestId) {
// Laengere Texte, die Claude im Turn VOR der letzten Antwort geschrieben hat
// (z.B. ein Bericht, danach noch Warten/Werkzeuge, dann eine kurze
// Schlussnotiz). result.result enthaelt nur den LETZTEN Textblock — der
// Bericht ging so verloren (28.10., 2-Stunden-Turn). Kurze Zwischensaetze
// ("Ich schaue nach …") bleiben weg, Sprachausgabe nur aus der letzten Antwort.
const EARLIER_TEXT_MIN = 300;
function _mergeEarlier(finalText, earlier) {
const keep = (earlier || [])
.map(t => String(t || "").replace(/<voice>[\s\S]*?<\/voice>/g, "").replace(/\[\[[A-Z_]+\]\]/g, "").trim())
.filter(t => t.length >= EARLIER_TEXT_MIN && !finalText.includes(t));
return keep.length ? keep.join("\n\n") + "\n\n" + finalText : finalText;
}
export function cliResultToOpenai(result, requestId, earlierTexts = []) {
// modelUsage ist die Wahrheit: die CLI tragt dort den Namen ein, unter dem
// der Request wirklich lief — bei einem Alias also die aufgeloeste Version
// ("opus" -> "claude-opus-5-5"). Leer bleibt es, wenn gar kein Call
@@ -121,7 +134,7 @@ export function cliResultToOpenai(result, requestId) {
message.content = rest || null;
finishReason = "tool_calls";
} else {
message.content = rawText;
message.content = _mergeEarlier(rawText, earlierTexts);
}
return {