Skip to content

fix: primeFold retries with demoted inline-think mirror (issue #64) - #124

Merged
ranxianglei merged 2 commits into
masterfrom
2026-08-22_demoted-inline-restart
Aug 22, 2026
Merged

fix: primeFold retries with demoted inline-think mirror (issue #64)#124
ranxianglei merged 2 commits into
masterfrom
2026-08-22_demoted-inline-restart

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

Problem

Follow-up to #122 (issue #64, responses variant). Verified on a real glm-5.3 session: restart still showed Blocks: none until the first provider request.

Root cause (this variant): on glm/deepseek/qwen-style openai-completions profiles the host demotes unsigned thinking to text (transform-messagesrenderDemotedThinking) and serializes it INLINE as a <think>…</think> tag inside the content string — there is no reasoning_content field. The primeFold mirror (viewToCoreStream) emitted reasoning pieces instead, splitting each thinking turn into reasoning+text while the live wire carried one text piece. The span fingerprints landed in different spaces, every in-stream compress replay was rejected (fold-replay-stale reason=fp), and the blocks only re-materialized at the first provider request.

Reconstruction rule verified byte-exact against a real wire dump (94/94 assistant messages match, dump req_7080.json, 208 msgs):

content = blocks in content order:
  thinking -> "<think>\n" + thinking + "\n</think>"  (+ "\n" if another block follows)
  text     -> stripRefTag(text)  (leading whitespace preserved; empty -> dropped)
no separator between blocks; no reasoning_content field

Fix

  • viewToCoreStream: new opts.demoteThinking variant that rebuilds assistant content byte-exactly per the rule above (no reasoning_content); default path unchanged.
  • runtime.ts primeFold: when the openai mirror yields zero blocks but the view contains compress calls, refold once with the demoted variant (preview makes the retry a fresh-slot full refold).

Tests

  • wire-transform.test.ts: byte-exact unit test for the demoted serialization (multi-block glue, text-only, whitespace-only-drop, default variant unchanged).
  • prime-provider-restart.test.ts: provider-mode restart regression with a glm-style wire (inline think tags, no reasoning_content) — block must be rebuilt before the first provider request. Verified the test guards the fix: disabling the retry fails exactly this test.

Full suite: 260 pass / 0 fail; tsc --noEmit clean.

On glm/deepseek/qwen-style openai-completions profiles the host demotes
unsigned thinking to text and serializes it INLINE as <think>...</think>
inside the content string (no reasoning_content field). The primeFold
mirror emitted reasoning pieces instead, landing the span fingerprints
in a different space: every in-stream compress replay was rejected
after restart and /acp showed 'Blocks: none' until the first provider
request refolded.

- viewToCoreStream: new opts.demoteThinking variant rebuilding the
  assistant content byte-exactly (tag + \n glue + text, ref tags
  stripped), no reasoning_content field
- runtime primeFold: when the openai mirror yields zero blocks but the
  view contains compress calls, refold once with the demoted variant
- tests: byte-exact unit test + provider-mode restart regression
  (verified: disabling the retry fails the new test)
@ranxianglei
ranxianglei merged commit c455dbd into master Aug 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant