Skip to content

fix(edit): preserve unrelated lines during fuzzy text matching + NFKC fast-path fix#79

Merged
Muhammad Rizwan Shakeel Anwer (rizwan-saddal) merged 146 commits into
mainfrom
fix/edit-fuzzy-v2
Jun 27, 2026
Merged

fix(edit): preserve unrelated lines during fuzzy text matching + NFKC fast-path fix#79
Muhammad Rizwan Shakeel Anwer (rizwan-saddal) merged 146 commits into
mainfrom
fix/edit-fuzzy-v2

Conversation

@rizwan-saddal

Copy link
Copy Markdown
Collaborator

Fixes openclaw#89994. Upstream PR: openclaw#90060

Adopted from Sebastien Tardif (@SebTardif)'s PR openclaw#90060 with ClawSweeper P1 blocker fixed:

  • NFKC fast-path bug: Changed nfkcLine.length === origLine.length to nfkcLine === origLine. The length check was incorrect — NFKC can preserve total code-unit length while shifting internal positions (e.g. fi X éfi X é, both 6 code units, but X shifts from cp 2 to 3).
  • Added regression test for the exact length-neutral mixed expansion/composition case.
  • Includes all 5 original PR commits (offset mapper, Unicode safety, NFKC handling).

Impact on our runtime: We edit files with Arabic/Unicode content daily. Without this fix, any fuzzy edit on a file with smart quotes, em dashes, or NFKC characters silently rewrites unrelated lines. With it, only the matched region is touched.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

reviewed

Vincent Koc (vincentkoc) and others added 3 commits June 25, 2026 06:51
Adopted from PR openclaw#90060 (by @SebTardif) with ClawSweeper P1 fix:

The original PR's NFKC fast-path checked length equality (nfkcLine.length ===
origLine.length) to skip offset mapping. This is incorrect — NFKC can preserve
total code-unit length while shifting internal positions. For example,
"fi X é" (U+FB01 + X + e+combining-acute) normalizes to "fi X é" — both are
6 code units, but X shifts from codepoint 2 to 3.

Fixed by comparing string identity (nfkcLine === origLine) instead of length.
Added regression test for this exact length-neutral mixed case.

Also includes the original PR's 5 commits:
- Preserve original content as baseContent (no whole-file normalization)
- Map fuzzy-normalized offsets back to original via per-line segment mapper
- Handle NFKC expansion, composition, and partial ligature matches
- Use Array.from instead of spread for Unicode surrogate-pair safety

Fixes openclaw#89994. Upstream PR: openclaw#90060
lin-hongkuan and others added 20 commits June 25, 2026 14:36
…ing in a role word (openclaw#96392)

ROLE_TURN_MARKER_RE anchored only the end of the line (\b...:\s*$), so any
outbound line that merely ended with 'user:'/'system:'/'assistant:' was
truncated — e.g. 'Please send this reply to the user:' lost its last word.
Anchor the marker to the whole line so only a standalone leaked turn marker
(its own line) is stripped; standalone-marker behavior is unchanged.

Co-authored-by: ly-wang19 <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
* fix(discord): keep audio voice replies threaded

* chore: retrigger CI after base recovery
…ge scans don't starve later pages (openclaw#96390)

* fix(document-extract): render PDF image fallback per page so multi-page scans don't starve later pages

clawpdf's mode:"images" extract applies a single maxPixels budget across
every page, so the first page consumes it and later pages collapse to ~1x1
PNGs that vision OCR models reject. Render each selected page in its own
extract() call so the pixel budget resets per page and every page yields a
usable image.

* fix(document-extract): preserve aggregate PDF render budget

---------

Co-authored-by: Vincent Koc <[email protected]>
* fix(git-hooks): skip sequencer pre-commit formatting

* chore: rerun CI

* fix(git-hooks): skip revert sequencer formatting

---------

Co-authored-by: Vincent Koc <[email protected]>
ly-wang19 and others added 28 commits June 27, 2026 05:32
…a closing fence (openclaw#96745)

* 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) <[email protected]>

* fix(markdown): honor fence suffix whitespace rules

Co-authored-by: ly-wang19 <[email protected]>

---------

Co-authored-by: ly-wang19 <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
* perf(update): reuse missing plugin payload id set

* perf(update): reuse missing plugin payload id set

---------

Co-authored-by: ly-wang19 <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
…ackets (openclaw#96476)

Merged via squash.

Prepared head SHA: 2d69ed2
Co-authored-by: ly-wang19 <[email protected]>
Co-authored-by: vincentkoc <[email protected]>
Reviewed-by: @vincentkoc
* perf(memory): copy only requested embedding dimensions

* perf(memory): copy only requested embedding dimensions

---------

Co-authored-by: ly-wang19 <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
…es (fixes openclaw#96983) (openclaw#97044)

* fix(tools): treat no-op writes and edits as terminal tool-loop failures

Fixes openclaw#96983

* fix(tools): treat no-op writes and edits as terminal tool-loop failures

Fixes openclaw#96983

* fix(tools): preserve valid sibling edits in mixed no-op batches

Fixes openclaw#96983

* fix(tools): terminate apply_patch no-ops safely

* fix(tools): validate no-op edits independently

* fix(tools): preserve no-op edit overlap checks

* fix(tools): preserve no-op patch file formatting

* fix(tools): preserve move no-op formatting

* fix(tools): narrow same-path move no-op typing

* fix(tools): distinguish edit no-op errors

* fix(tools): keep edit previews aligned with execution

* fix(tools): align no-op validation and formatting

* fix(tools): preserve empty patch and preview no-ops

* fix(tools): preview fuzzy edit no-ops cleanly

* fix(tools): isolate fuzzy-equivalent edit no-ops

---------

Co-authored-by: Vincent Koc <[email protected]>
@rizwan-saddal
Muhammad Rizwan Shakeel Anwer (rizwan-saddal) merged commit 9f37626 into main Jun 27, 2026
2 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.

Bug: a fuzzy edit silently normalizes and rewrites unrelated lines across the whole file