fix: stripMarkers was suppressing all content inside fences

The inFence state machine was dropping all lines between fence
delimiters, not just the delimiters themselves. Tool output, assistant
code blocks — everything inside fences was being eaten.

Fix: remove only [[[...]]] marker lines and bare fence delimiter lines
(``` / ```lang). Preserve all content between them.
This commit is contained in:
Ollie Agent 2026-08-09 11:50:52 +02:00
parent d861e41d31
commit decd4eb6a0
1 changed files with 10 additions and 23 deletions

View File

@ -139,12 +139,12 @@ func streamAgentChatText(ctx HandlerCtx, cctx context.Context, base string) ([]b
}
}
// stripMarkers removes [[[...]]] marker lines and source fence lines from raw
// chat data. Partial lines (no trailing \n) are always passed through — they
// are streaming content, never markers.
// stripMarkers removes [[[...]]] marker lines and source fence delimiter lines
// from raw chat data. Content inside fences is preserved — only the ``` lines
// themselves are stripped. Partial lines (no trailing \n) are always passed
// through — they are streaming content, never markers.
func stripMarkers(data []byte) []byte {
var out []byte
inFence := false
for len(data) > 0 {
// Find next newline
nl := bytes.IndexByte(data, '\n')
@ -162,28 +162,15 @@ func stripMarkers(data []byte) []byte {
continue
}
// Drop fence open/close lines (``` with optional language suffix)
// Drop bare fence delimiter lines (``` or ```lang).
// These are the source fences wrapping tool output.
// Keep fences with 4+ backticks (````), those are user/assistant markdown.
stripped := bytes.TrimSpace(trimmed)
if bytes.HasPrefix(stripped, []byte("```")) {
if inFence {
inFence = false
continue
}
// Opening fence — only drop if it's a source fence (tool output),
// not markdown fences in assistant prose. Tool fences follow
// immediately after a marker line, so if we just dropped a marker
// and this is the next line, it's a source fence.
// Simplification: drop all bare ``` lines (no content on the line).
// Keep fences that are part of assistant markdown (they have text before/after).
if len(stripped) == 3 || (len(stripped) > 3 && stripped[3] != '`') {
inFence = true
continue
}
if bytes.HasPrefix(stripped, []byte("```")) && !bytes.HasPrefix(stripped, []byte("````")) {
continue
}
if !inFence {
out = append(out, line...)
}
out = append(out, line...)
}
return out
}