Skip to content

fix: match Muse Glimmer parsing to vLLM - #197

Merged
brendanhogan merged 3 commits into
mainfrom
fix/glimmer-vllm-parity
Oct 20, 2026
Merged

brendanhogan merged 3 commits into
mainfrom
fix/glimmer-vllm-parity

Conversation

@eligotts

@eligotts eligotts commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Muse Glimmer response parsing differs from stock vLLM for tool arguments, duplicated tool names, malformed invocations, and trailing answer newlines. For example, an ATEM value of 123 currently stays a string when the tool schema declares a string; vLLM decodes it to the integer 123.

Decode ATEM parameter values as JSON with a raw-text fallback, normalize duplicated registered bare tool names such as get_weather.get_weather, and preserve malformed tool markup as content without synthesizing dispatchable call names. Match vLLM's non-streaming handling of one final newline in an open answer while retaining newlines in closed answers and answers accompanying tool calls.

Add focused regression cases and update the shared argument tests to assert Glimmer's schema-independent decoding, retaining coverage for booleans, integers, null, arrays, and objects.

Validation:

  • uv run --frozen pytest tests/ -k 'muse or Muse' -q: 598 passed, 4 skipped.
  • uv run --frozen ruff check . and uv run --frozen ruff format --check .: passed.
  • uv run --frozen ty check renderers: exited successfully with 62 warning diagnostics.
  • git diff --check origin/main...HEAD: passed.

Note

Match Muse Glimmer response parsing to vLLM behavior

  • MuseGlimmerRenderer.parse_response in muse_glimmer.py now works from a set of registered tool names instead of a schema index, matching the vLLM reference parser
  • Parameter values are decoded with json.loads when possible and kept as text otherwise, without consulting tool schemas; scalar JSON values declared as strings are decoded
  • Removes one trailing newline from an unfinished plain answer, recovers malformed tool-channel markup as content (stripping reasoning sections), and normalizes doubled bare tool names like tool.tool
  • Risk: unclosed or malformed tool-channel entries no longer inherit the channel recipient as their call name — the call name is now None, and callers relying on that name will see the change

Macroscope summarized 49ada0e.


Note

Medium Risk
Parsing behavior changes for tool arguments, malformed tool channels, and trailing newlines; clients that assumed schema-preserved strings or recipient-filled error tool names may see different content and tool_calls.

Overview
Aligns Muse Glimmer parse_response with stock vLLM instead of schema-driven ATEM parsing.

Tool calls: Parameter bodies are decoded with json.loads when possible and left as text otherwise—no tool-schema coercion—so values like 123 or false become JSON scalars even when the schema says string. Invocation names are validated against registered tools, with normalization for doubled bare names (tool.tool → tool). Malformed or unclosed invocations no longer borrow the channel recipient as name (name is None); when nothing dispatchable parses, reasoning is stripped and leftover ATEM markup is kept in content.

Answers: Drops one trailing newline from an open to=user answer (no tools), while closed answers and post-tool answers keep their trailing newlines.

Tests add vLLM parity cases and teach the shared tool-arg suite that Glimmer expects schema-independent JSON decoding.

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

codex and others added 3 commits October 20, 2026 13:48
(cherry picked from commit d477c7c83abf11c4570366fae03ac8c8e21f1bf9)
(cherry picked from commit d6d6fa6853a84bfe3bfd44c4696089ae908748fc)
@eligotts
eligotts marked this pull request as ready for review October 20, 2026 20:56

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 49ada0e. Configure here.

Comment thread renderers/muse_glimmer.py
if "<atem:invoke" in remainder or "<atem:function_calls>" in remainder:
content = remainder
elif not content:
content = "" if "to=self<|message|>" in text else text

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reasoning hides malformed tool text

Medium Severity

When a tool channel cannot be dispatched and has no ATEM tags, parse_response sets content to an empty string if the completion also contains a reasoning span. That discards the reasoning-stripped leftover instead of keeping it, so the model’s tool-channel words vanish from the assistant message.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 49ada0e. Configure here.

@macroscopeapp

macroscopeapp Bot commented Oct 20, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This PR changes production Muse Glimmer parsing semantics for whitespace, tool names, argument decoding, and malformed tool output. An unresolved review finding identifies a case where malformed tool-channel text following reasoning may be discarded, requiring human review.

Notes:

  • Macroscope's correctness review did not run, so approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@brendanhogan brendanhogan self-assigned this Oct 20, 2026
@brendanhogan
brendanhogan merged commit 660de04 into main Oct 20, 2026
11 checks passed
@eligotts
eligotts deleted the fix/glimmer-vllm-parity branch October 20, 2026 21:26
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.

3 participants