Skip to content

[Markdown Agent] Apply document edits deterministically - #2967

Merged
George Ng (GeorgeNgMsft) merged 2 commits into
georgengmsft-markdown-workspace-createfrom
georgengmsft-markdown-safe-updates
Sep 4, 2026
Merged

[Markdown Agent] Apply document edits deterministically#2967
George Ng (GeorgeNgMsft) merged 2 commits into
georgengmsft-markdown-workspace-createfrom
georgengmsft-markdown-safe-updates

Conversation

@GeorgeNgMsft

@GeorgeNgMsft George Ng (GeorgeNgMsft) commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

What changed

This PR adds the raw-Markdown edit engine that later persistence layers can call. It does not yet change where documents are saved or add browser synchronization.

Before

A model can return several edits whose character offsets were all calculated from the same original Markdown. The previous application path processed those edits sequentially against an already-mutated string, so an early edit could move the text targeted by every later edit.

For example, starting with ABCDE:

  1. insert X at offset 1
  2. delete original range [3, 5) (DE)

Applying those operations in request order produces AXBCDE, then deletes offsets [3, 5) from that changed string (CD), yielding the incorrect result AXBE.

The previous path could also reverse multiple inserts at one position, silently clamp invalid ranges, and apply intersecting edits whose meaning became ambiguous after the first mutation.

After

applyDocumentOperations treats the operations as one edit batch against one original Markdown snapshot:

  • validates every character offset against the original text
  • rejects intersecting operations before changing anything
  • applies non-overlapping edits from the highest offset to the lowest, so edits later in the document cannot shift locations still waiting to be changed
  • preserves request order for multiple inserts at the same position
  • converts structured content into Markdown for insert/replace operations
  • supports adding and removing strong, emphasis, inline-code, and link marks

For the example above, the delete at [3, 5) runs first and removes DE; the insert at 1 then produces the intended AXBC.

This follows the established simultaneous text-edit model used by language tooling. The LSP contract describes text edits against a document range, while Microsoft’s reference Node implementation sorts edits and applies them from the end toward the beginning, rejecting overlap:

Why this is a separate stack layer

The original replacement change combined edit semantics with file persistence, stale-write protection, and browser synchronization. Isolating the operation engine makes its coordinate contract and edge cases reviewable before later layers use it for durable updates.

Deferred upward: durable workspace persistence, revision and binding conflict checks, streaming exactly-once persistence, view-service state, browser synchronization/autosave, same-file editor rebinding, and loopback-only binding.

Validation

  • cached TypeScript 5.4.5 strict no-emit check passed for markdownOperationSchema.ts and documentOperations.ts
  • direct compiled smoke tests passed for base-relative edits, same-position inserts, overlap rejection, mark add/remove, balanced-parenthesis links, and mismatched-link preservation
  • cached Prettier 3.5.3 changed-file check passed
  • git diff --check passed

The normal package build/Jest suite and PR ratchets could not run because this worktree had no node_modules; the single time-boxed restore did not complete while reaching unavailable Azure feed artifacts. The commit hook was bypassed after the equivalent cached Prettier, type, and smoke checks above.

@GeorgeNgMsft
George Ng (GeorgeNgMsft) force-pushed the georgengmsft-markdown-safe-updates branch from c3b1974 to 2424a5c Compare September 3, 2026 22:41
@GeorgeNgMsft George Ng (GeorgeNgMsft) changed the title fix(markdown): apply document edits deterministically [Markdown Agent] Apply document edits deterministically Sep 4, 2026
@GeorgeNgMsft
George Ng (GeorgeNgMsft) marked this pull request as ready for review September 4, 2026 05:58
Comment thread ts/packages/agents/markdown/src/agent/documentOperations.ts
Comment thread ts/packages/agents/markdown/src/agent/documentOperations.ts
Comment thread ts/packages/agents/markdown/src/agent/documentOperations.ts Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: dd89289c-6602-452d-b8c5-9221494be8f7
@GeorgeNgMsft
George Ng (GeorgeNgMsft) force-pushed the georgengmsft-markdown-safe-updates branch from ef02d96 to 333ee62 Compare September 4, 2026 21:57
@GeorgeNgMsft
George Ng (GeorgeNgMsft) added this pull request to the merge queue Sep 4, 2026
Merged via the queue into main with commit 64464af Sep 4, 2026
25 of 44 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