Skip to content

fix(ai): operations on blocks containing comments - #2953

Merged
nperez0111 merged 1 commit into
mainfrom
fix/ai-blocks-with-comments
Aug 10, 2026
Merged

fix(ai): operations on blocks containing comments#2953
nperez0111 merged 1 commit into
mainfrom
fix/ai-blocks-with-comments

Conversation

@nperez0111

@nperez0111 nperez0111 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #2947

Running the AI on a block that contains a comment fails with Error: html diff.

Rationale

Comment marks are tagged blocknoteIgnore (packages/core/src/comments/mark.ts), so they're deliberately excluded from the BlockNote document model. blocksToHTMLLossy therefore emits <p>Hello, world!</p> with no span.bn-thread-mark, and parsing that back gives a block without the mark.

createHTMLRebaseTool round-trips the target block through exactly that path and threw if the result differed from the document. For a block containing a comment it always differs, so the operation failed before the LLM's response could be applied. Blocks are only affected if they carry a comment themselves — editing a sibling block worked, which matches the video in the issue.

The rebase tool exists precisely to handle formats that can't express everything in the document: apply the operation to a "clean" projection, then rebase the result onto the real document through the invert map. createMDRebaseTool already does this for markdown; the HTML version asserted losslessness instead of building the projection.

Changes

  • createHTMLRebaseTool: apply the round-trip difference to the projection rather than throwing, matching createMDRebaseTool. The blocks.length !== 1 guard is unchanged, and an unmappable step still throws.
  • RESTYjsThreadStore.addThreadToDocument: use the ySync binding's type/mapping instead of the plugin state.

Impact

The second fix is a separate bug found while tracing the first, in the same area (comments + Yjs). addThreadToDocument passed the ySync plugin state where a binding was expected. The plugin state has a type but no mapping, so passing undefined as the mapping threw as soon as absolutePositionToRelativePosition reached a non-XmlText node:

TypeError: Cannot read properties of undefined (reading 'get')
  at absolutePositionToRelativePosition (y-prosemirror/src/lib.js:83)
  at RESTYjsThreadStore.addThreadToDocument (RESTYjsThreadStore.ts:65)

A BlockNote document starts with a blockGroup element, so this threw on every call — the Yjs positions were never actually sent. It can be dropped from this PR if you'd rather keep the two separate.

Testing

  • commentedContent.test.ts: building a rebase tool for a commented block, updating a commented block, and updating a sibling while another block has a comment. The first two fail on main with html diff. Asserts the comment stays anchored to "Hello" after "Hello, world!" is rewritten to "Hello, universe!", so the fix isn't just "stops throwing". Runs fully offline — tool calls are fed straight into StreamToolExecutor, no LLM.
  • RESTYjsThreadStore.test.ts: stubs fetch and asserts the emitted relative positions resolve back to the positions passed in, so a silently-wrong mapping fails it too.

packages/core 716 passed / 9 skipped, packages/xl-ai 204 passed / 260 skipped (skips are the API-key-gated model suites, unchanged).

Checklist

  • Code follows the project's coding standards.
  • Unit tests covering the new feature have been added.
  • All existing tests pass.
  • The documentation has been updated to reflect the new feature

Summary by CodeRabbit

  • Bug Fixes

    • Improved comment positioning when adding threads to collaborative documents.
    • Preserved comment anchors when updating HTML blocks or nearby sibling blocks.
    • Improved handling of document changes during HTML updates, with clearer errors when changes cannot be applied.
  • Tests

    • Added regression coverage for collaborative comment positions and HTML block updates.

@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
blocknote Ready Ready Preview Aug 10, 2026 10:01am
blocknote-website Ready Ready Preview Aug 10, 2026 10:01am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR fixes Yjs thread selection serialization by using the current binding. It also enables cumulative ProseMirror step mapping for HTML updates that affect commented blocks, with regression tests for comment-anchor preservation.

Changes

Yjs thread position resolution

Layer / File(s) Summary
Current binding resolution and regression coverage
packages/core/src/yjs/comments/RESTYjsThreadStore.ts, packages/core/src/yjs/comments/RESTYjsThreadStore.test.ts
addThreadToDocument resolves selections through the current Yjs binding. Tests verify that serialized relative positions resolve to the submitted selection.

Commented HTML block rebasing

Layer / File(s) Summary
Cumulative diff mapping and comment preservation
packages/xl-ai/src/api/formats/html-blocks/tools/rebaseTool.ts, packages/xl-ai/src/api/formats/html-blocks/commentedContent.test.ts
The rebase tool maps and applies non-empty HTML diff steps. Tests cover commented-block updates and sibling-block updates while preserving comment anchors.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Editor
  participant RESTYjsThreadStore
  participant YjsBinding
  participant Fetch
  Editor->>RESTYjsThreadStore: addThreadToDocument(selection)
  RESTYjsThreadStore->>YjsBinding: resolve selection positions
  RESTYjsThreadStore->>Fetch: submit serialized relative positions
  Fetch-->>Editor: return thread request
Loading
sequenceDiagram
  participant HTMLUpdate
  participant RebaseTool
  participant Mapping
  participant Transaction
  HTMLUpdate->>RebaseTool: provide HTML diff steps
  RebaseTool->>Mapping: map steps cumulatively
  Mapping-->>RebaseTool: return mapped steps
  RebaseTool->>Transaction: apply mapped steps
  Transaction-->>HTMLUpdate: preserve comment anchors
Loading

Possibly related PRs

Poem

A rabbit hops through comments bright,
While Yjs keeps each mark in sight.
Mapped steps cross the editor’s page,
Anchors stay still through every change.
“Binky!” says the test suite, light.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The RESTYjsThreadStore fix addresses a separate Yjs positioning bug not required by linked issue #2947. Move the RESTYjsThreadStore change to a separate pull request or link an issue that requires the Yjs positioning fix.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The HTML rebase changes enable AI rewrites on commented blocks and preserve comment anchors, satisfying issue #2947.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly summarizes the primary change: fixing AI operations on blocks that contain comments.
Description check ✅ Passed The description covers the required summary, rationale, changes, impact, testing, and checklist, with documentation correctly marked as incomplete.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ai-blocks-with-comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nperez0111 nperez0111 changed the title fix: AI operations on blocks containing comments fix(ai): operations on blocks containing comments Aug 10, 2026
Comment marks are tagged `blocknoteIgnore`, so they're deliberately not
part of the BlockNote document model. `blocksToHTMLLossy` therefore
drops them, and parsing the HTML back produces a block without them.

`createHTMLRebaseTool` round-trips the target block through exactly that
path and threw `html diff` if the result differed from the document — so
every AI operation on a block containing a comment failed before the
LLM's response could be applied.

Apply the round-trip difference to the projection instead of throwing,
which is what the rebase tool's invert map is for, and what
`createMDRebaseTool` already does for markdown. Comment anchors outside
the rewritten range are preserved.

Also fix `RESTYjsThreadStore.addThreadToDocument`, which passed the
`ySync` plugin state where a binding was expected. The plugin state has
no `mapping`, so adding a thread threw `Cannot read properties of
undefined (reading 'get')` as soon as the position walk reached the
first non-text node — which, for a BlockNote document, is immediately.
@nperez0111
nperez0111 force-pushed the fix/ai-blocks-with-comments branch from 64f2a12 to 25b93b2 Compare August 10, 2026 09:59
@pkg-pr-new

pkg-pr-new Bot commented Aug 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

@blocknote/ariakit

npm i https://pkg.pr.new/@blocknote/ariakit@2953

@blocknote/code-block

npm i https://pkg.pr.new/@blocknote/code-block@2953

@blocknote/core

npm i https://pkg.pr.new/@blocknote/core@2953

@blocknote/mantine

npm i https://pkg.pr.new/@blocknote/mantine@2953

@blocknote/react

npm i https://pkg.pr.new/@blocknote/react@2953

@blocknote/server-util

npm i https://pkg.pr.new/@blocknote/server-util@2953

@blocknote/shadcn

npm i https://pkg.pr.new/@blocknote/shadcn@2953

@blocknote/xl-ai

npm i https://pkg.pr.new/@blocknote/xl-ai@2953

@blocknote/xl-docx-exporter

npm i https://pkg.pr.new/@blocknote/xl-docx-exporter@2953

@blocknote/xl-email-exporter

npm i https://pkg.pr.new/@blocknote/xl-email-exporter@2953

@blocknote/xl-multi-column

npm i https://pkg.pr.new/@blocknote/xl-multi-column@2953

@blocknote/xl-odt-exporter

npm i https://pkg.pr.new/@blocknote/xl-odt-exporter@2953

@blocknote/xl-pdf-exporter

npm i https://pkg.pr.new/@blocknote/xl-pdf-exporter@2953

commit: 25b93b2

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-08-10 10:27 UTC

@nperez0111
nperez0111 merged commit decb3d2 into main Aug 10, 2026
19 checks passed
@nperez0111
nperez0111 deleted the fix/ai-blocks-with-comments branch August 10, 2026 10:27
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.

AI not working when comment

1 participant