* perf(update): reuse missing plugin payload id set
* perf(update): reuse missing plugin payload id set
---------
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(markdown): a fenced-code line with trailing text is content, not a closing fence
scanFenceSpans accepted any line starting with >=3 matching fence markers as a
closing fence, ignoring trailing text after the marker. Per CommonMark a closing
fence may be followed only by whitespace, so a code-content line such as
"``` not a close" was wrongly treated as a close: the block ended early, the
following lines were reported as outside any fence, and the trailing marker line
became a new unclosed opener.
That made isSafeFenceBreak() return true for offsets inside the real code block
and findFenceSpanAt() return undefined, so chunkers (chunkMarkdownText, the
embedded-agent block chunker) could split inside a fenced code block — the exact
thing this module exists to prevent.
Require the closing fence's trailing text to be whitespace-only. Opening info
strings, bare closes, and longer same-marker closes are unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(markdown): honor fence suffix whitespace rules
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
---------
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
chunkByNewline length-splits a single over-long line that has no usable break
point. The first head cut used a raw UTF-16 slice (lineValue.slice(0,
firstLimit)), so when firstLimit landed inside a surrogate pair it emitted a
chunk ending in a lone high surrogate and a next chunk starting with a lone low
surrogate, which render as U+FFFD on delivery. The recursive chunkText that
handles the remainder is already surrogate-safe; only this first cut was raw.
Route the head cut through avoidTrailingHighSurrogateBreak (the same helper
chunkText and chunkMarkdownText already use) so the cut backs off to a
code-point boundary. ASCII and non-surrogate cuts are unaffected. Reproduces at
the production-default 4096 limit for emoji-dense lines; chunkByNewline is the
published plugin-SDK channel.text helper, reachable with arbitrary outbound text.
Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary:
- The PR updates `ui/src/styles/chat/layout.css` so the WebChat composer model selector can size to long model/thinking labels and also changes the base inline-select menu width rule.
- PR surface: Source +1. Total +1 across 1 file.
- Reproducibility: yes. from source inspection: current main and `v2026.6.10` combine model and thinking text ... ro in this read-only review, but the PR's inspected before screenshot demonstrates the reported truncation.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 0cf1a65852.
- Required merge gates passed before the squash merge.
Prepared head SHA: 0cf1a65852
Review: https://github.com/openclaw/openclaw/pull/96990#issuecomment-4807967550
Co-authored-by: 0668000787 <ma.weibin@xydigit.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Approved-by: takhoffman