You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up of #644, observed on v0.1.97 which already includes the #646 fix. A new escape form: the model emits a typo'd render-tag echo — <acip tokens="36" type="text">m00473</acip> (acip, not acp). None of the tag-echo strip regexes match it, so the malformed fragment is passed through verbatim as the turn's entire text (43 chars), with stop_reason="end_turn" and zero tool_use, while the thinking block still contains a complete next-step plan. The agent records a degenerate turn as a normal completion and stalls mid-orchestration until a manual nudge.
No degenerate-turn detection — post-strip text empty or a pure echo fragment + end_turn + zero tool_use + non-empty thinking is treated as a normal completed turn by the model, bili, and the host. Nobody catches it.
Evidence chain (three-way closure, all UTC 2026-09-09)
1. Upstream raw SSE dump~/.local/share/billion-context/raw/1788980229387-0166b4ba-afc8-4d0b-92b0-a8f599f5bcbd-raw.sse (30,341 bytes / 226 events):
All text deltas concatenated = exactly the 43-char fragment <acip tokens="36" type="text">m00473</acip> — this is the turn's entire visible output.
message_delta carries genuine stop_reason="end_turn" with usage input=419, cache_read=115584, output=223 (ruling out the emitError fabrication path, which has an [acp-proxy: ...] text prefix and all-zero usage).
Zero tool_use content blocks.
The thinking block (386 chars) ends with a complete next-step plan — the model degenerated mid-orchestration (thinking–act disconnect), it did not deliberately finish.
2. bili.log: last acp-usage for the session at 18:57:13.762Z (input=116003 = 419+115584, closes with the dump), then zero session activity until 18:59:09Z when the user manually sends "continue" (processTurn: 267 msgs resumes normally). The string acip has 0 matches in the entire log — the strip never saw the fragment. The 6 [tag-echo] stripped lines in the surrounding window (18:55–18:58Z) are all exact-spelling <acp from other turns.
3. Host side (client log): the turn is recorded as a normal completion — responseLength=43, toolCallCount=0, finishReason="stop", followed by turn.completed, no error events.
The echoed ref m00473 is the message id the user later quoted when reporting the stall — confirming the stream belongs to the affected session.
All require the exact <acp opening; the string acip appears 0 times in the whole bundle. The typo'd tag is never matched, so #646's close-side bound handling never engages — the fragment rides through untouched.
The typo is chronic, not a one-off
Later dumps from the same day show the variant repeatedly, e.g. one turn mixing a correct <acp opening with a typo'd </acip closing (dump 1788980392406). Variant tolerance matters beyond a single fluke.
Impact
Mid-orchestration stall until a human nudge (~2 min here; the same family has caused multi-hour silent gaps).
The 43-char garbage fragment is shown to the user as the turn's report.
Suggestions
Echo detection should not depend on exact spelling — e.g. tolerate close variants of the tag name (<acp/<acip-ish shapes wrapping an acp-style tokens=/ref payload), scoped tightly so legit text is not eaten.
Degenerate-turn detection: after stripping, if the final text is empty or a pure echo fragment AND stop_reason=end_turn AND zero tool_use AND the thinking block is non-empty → emit a warning (or auto-retry the turn once). Currently all three layers treat it as a normal completion, which is what turns a model glitch into a silent stall.
Environment: bili v0.1.97 (includes #646, shipped in v0.1.96), GLM-5.3 upstream, dumps under ~/.local/share/billion-context/raw/.
Summary
Follow-up of #644, observed on v0.1.97 which already includes the #646 fix. A new escape form: the model emits a typo'd render-tag echo —
<acip tokens="36" type="text">m00473</acip>(acip, notacp). None of the tag-echo strip regexes match it, so the malformed fragment is passed through verbatim as the turn's entire text (43 chars), withstop_reason="end_turn"and zero tool_use, while the thinking block still contains a complete next-step plan. The agent records a degenerate turn as a normal completion and stalls mid-orchestration until a manual nudge.Two gaps:
<acpspelling — a one-letter typo structurally bypasses every defense added in fix: bound close-side tag-echo tail so a malformed </acp can't eat following content (#644) #646.end_turn+ zero tool_use + non-empty thinking is treated as a normal completed turn by the model, bili, and the host. Nobody catches it.Evidence chain (three-way closure, all UTC 2026-09-09)
1. Upstream raw SSE dump
~/.local/share/billion-context/raw/1788980229387-0166b4ba-afc8-4d0b-92b0-a8f599f5bcbd-raw.sse(30,341 bytes / 226 events):<acip tokens="36" type="text">m00473</acip>— this is the turn's entire visible output.message_deltacarries genuinestop_reason="end_turn"with usageinput=419, cache_read=115584, output=223(ruling out the emitError fabrication path, which has an[acp-proxy: ...]text prefix and all-zero usage).2. bili.log: last
acp-usagefor the session at18:57:13.762Z(input=116003= 419+115584, closes with the dump), then zero session activity until18:59:09Zwhen the user manually sends "continue" (processTurn: 267 msgsresumes normally). The stringaciphas 0 matches in the entire log — the strip never saw the fragment. The 6[tag-echo] strippedlines in the surrounding window (18:55–18:58Z) are all exact-spelling<acpfrom other turns.3. Host side (client log): the turn is recorded as a normal completion —
responseLength=43, toolCallCount=0, finishReason="stop", followed byturn.completed, no error events.The echoed ref
m00473is the message id the user later quoted when reporting the stall — confirming the stream belongs to the affected session.Why current defenses miss
Strip regexes in
dist/index.js(~offset 2223722):All require the exact
<acpopening; the stringacipappears 0 times in the whole bundle. The typo'd tag is never matched, so #646's close-side bound handling never engages — the fragment rides through untouched.The typo is chronic, not a one-off
Later dumps from the same day show the variant repeatedly, e.g. one turn mixing a correct
<acpopening with a typo'd</acipclosing (dump1788980392406). Variant tolerance matters beyond a single fluke.Impact
Suggestions
<acp/<acip-ish shapes wrapping an acp-styletokens=/ref payload), scoped tightly so legit text is not eaten.stop_reason=end_turnAND zero tool_use AND the thinking block is non-empty → emit a warning (or auto-retry the turn once). Currently all three layers treat it as a normal completion, which is what turns a model glitch into a silent stall.Environment: bili v0.1.97 (includes #646, shipped in v0.1.96), GLM-5.3 upstream, dumps under
~/.local/share/billion-context/raw/.