Skip to content

fix(glm53): preserve content across reasoning and tool parsing - #433

Merged
choiceoh merged 3 commits into
mainfrom
codex/glm53-parser-content
Sep 6, 2026
Merged

choiceoh merged 3 commits into
mainfrom
codex/glm53-parser-content

Conversation

@choiceoh

@choiceoh choiceoh commented Sep 6, 2026

Copy link
Copy Markdown
Owner

GLM Chat Completions could delete literal tool-call XML with tool_choice="none", lose text after/between calls in non-streaming replies, and remove literal think tags or misalign token IDs inside tool arguments. Preserve that data in the GLM parser while keeping initial reasoning separation, typed arguments, tool IDs, and the requested tool-choice mode.

  • Add a GLM-only parser overlay pinned to the serving image's original SHA. Fix skipped tool recognition, content collection/whitespace handling, literal think tags after reasoning, and the first reasoning-to-content token boundary. Require the overlay in the launcher; test the candidate mount before deployment.
  • Exercise the real ParserManager glm45/glm47 dispatch, request adjustment/structural tags, and automatic history content-format detection. Retain direct-engine checks and add none/auto/required/named, repeated functions, literal tags, partial delimiters, reasoning visibility, and token/character chunk boundaries.
  • Add default-off glm53_required_first request ordering before template rendering. It preserves JSON Schema semantics and input objects; it does not downgrade forced calls. Pin the official HF template revision with differential text/media-placeholder/tool-history fixtures.
  • Add an explicitly invoked 16-request generation acceptance probe that checks schema/required fields, function names, termination, and SSE completion without executing tools.

Validation:

  • Exact glm53:v13-b12x-it image and local tokenizer, isolated CPU container with no GPU or network: 19 template/option/middleware tests + 5 acceptance-verdict tests + 26 parser scenarios / 3,765 streaming replays and a 3-request parser-reuse sequence passed. vLLM 0.1.dev20051+g487ecf187; parser SHA d339da08f143f8316f1cda96e0628c2e5438b9510039c2d262c37d058f8f401d.
  • Local GLM unittest discovery: 43 passed, 10 environment-dependent skips.
  • Repository checks: 6,612 checks, 30 megakernel regressions, and 20 fleet regressions passed; hardware-dependent local portions report skips.
  • ShellCheck error-level checks, shell syntax, launcher dry run, generated overlay parity, and diff whitespace checks passed.

Runtime limits: this PR does not deploy/restart production or establish NVFP4 generation-quality/forced-decoding convergence. The required-first option stays off pending a same-image/weights A/B. The new network acceptance probe is not invoked by the CPU release gate. HTTP/SSE finish reasons and partial arguments are not repaired or reclassified.

References: none content loss, required-first draft, forced generation report, official template update.


Note

Medium Risk
Changes sit on the hot path for GLM Chat Completions parsing and streaming deltas; mistakes could alter tool-call extraction, reasoning separation, or client-visible content, though scope is limited to the overlay and extensive CPU replay tests were added.

Overview
Adds a GLM-only glm47_moe parser overlay (pinned to the serving image base SHA) so Chat Completions no longer drops literal tool XML under tool_choice=none, loses text between/after tool calls in non-streaming replies, or strips/mis-handles think tags inside arguments. The overlay skips tool recognition instead of consuming-then-hiding, merges text with tool deltas, preserves whitespace, and tightens reasoning/token boundaries when thinking is off.

Chat middleware gains default-off glm53_required_first: before template render, tool parameter schemas are deep-copied and properties reordered so required fields appear first (nested/$defs included) without changing JSON Schema semantics or tool_choice.

Release gates now require the parser mount (start-glm53-nvfp4-tp4.sh), verify image parser SHA and mount the candidate in check-glm53-chat.sh, and expand CPU probes (glm53_chat_contract, test_glm53_tool_acceptance, pinned official HF template parity). An opt-in glm53_tool_choice_acceptance.py probe hits a live endpoint for generation A/B (not in the default CPU gate).

Reviewed by Cursor Bugbot for commit 3ad2c65. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI lite review requested due to automatic review settings September 6, 2026 15:49
@cursor

cursor Bot commented Sep 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_388c0e4e-b0e7-42ae-a0f5-ccf2fa3f7b53)

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-06T16:02:37.705974Z 3ad2c65 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new GLM parser overlay can retain stale tool definitions across reused parser instances because it only updates _tools when request.tools is truthy, which can break correctness for tool-less/empty-tool requests.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR hardens GLM-5.3 Chat Completions parsing and request normalization to prevent loss of literal tool-call XML / post-tool text / literal think tags, while adding an opt-in “required-first” tool-schema ordering tweak and expanding CPU-only regression and acceptance-style checks.

Changes:

  • Add a pinned GLM-only glm47_moe.py parser overlay that preserves user content across reasoning/tool parsing and fixes non-streaming / chunk-boundary content collection issues.
  • Add default-off glm53_required_first option to reorder JSON Schema properties so required fields appear first (recursively) without changing schema semantics or request payload.
  • Expand CPU tests/contract probes and add an opt-in network acceptance probe + pinned official HF template fixture for parity checks.
File summaries
File Description
tests/test_glm53_tool_acceptance.py New CPU-only unit tests for acceptance probe stream assembly / verdict checks.
tests/test_glm53_chat.py Adds pinned official template parity test and glm53_required_first regression coverage.
tests/fixtures/glm53_official_chat_template.json Pins upstream HF template revision/URL/SHA metadata.
tests/fixtures/glm53_official_chat_template.jinja Adds pinned upstream HF chat template fixture for parity checks.
profiles/README.md Updates overlay-file/module counts and runtime description to include GLM body preservation.
probes/glm53_tool_choice_acceptance.py New opt-in live-endpoint acceptance probe (schema/tool/SSE finish checks; no tool execution).
probes/glm53_chat_contract.py Exercises real ParserManager dispatch and auto content-format detection in CPU replay.
overlay/modules/glm53_runtime/README.md Documents new parser overlay behavior + required-first option + acceptance probe usage.
overlay/modules/glm53_runtime/manifest.tsv Adds pinned glm47_moe.py overlay entry for the serving image base SHA.
overlay/modules/glm53_runtime/glm53_chat.py Implements glm53_required_first normalization and recursive schema reordering.
overlay/modules/glm53_runtime/glm47_moe.py New content-preserving GLM-4.7 parser overlay built on the declarative parser engine.
launchers/start-glm53-nvfp4-tp4.sh Requires the new parser overlay mount before non-dry-run startup.
launchers/check-glm53-chat.sh Gates the overlay against the image’s stock parser SHA; runs added CPU tests.
build/glm53/manifest.tsv Build manifest updated to include the pinned parser overlay entry.
build/glm53/glm53_chat.py Build output mirrors glm53_chat.py required-first changes.
build/glm53/glm47_moe.py Build output mirrors the new pinned parser overlay.
Review details
  • Files reviewed: 16/16 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread overlay/modules/glm53_runtime/glm47_moe.py Outdated
Comment thread launchers/check-glm53-chat.sh
Comment thread tests/test_glm53_tool_acceptance.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df7cf4c291

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread overlay/modules/glm53_runtime/glm53_chat.py Outdated
Comment thread probes/glm53_tool_choice_acceptance.py Outdated
Comment thread probes/glm53_tool_choice_acceptance.py
@cursor

cursor Bot commented Sep 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_83f3fbdb-f42c-47d8-bde3-b0af8f413643)

@cursor

cursor Bot commented Sep 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_8867a7b7-224d-4960-b2f6-cfef3410b6f5)

@choiceoh
choiceoh merged commit cea6938 into main Sep 6, 2026
3 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.

2 participants