From e3099f6111e4249a7f006d5c12a7f0b31ccdbded Mon Sep 17 00:00:00 2001 From: zbeyens Date: Thu, 26 Mar 2026 17:24:07 +0100 Subject: [PATCH 1/9] fix: ai streaming history + task PR flow --- ...6-03-26-issue-4900-ai-streaming-history.md | 42 +++++++ .../plans/2026-03-26-pr-and-comment-4900.md | 19 +++ .../2026-03-26-task-skill-auto-pr-sync.md | 19 +++ ...w-should-snapshot-before-unsaved-chunks.md | 115 ++++++++++++++++++ .claude/skills/task/task.mdc | 22 +++- .codex/skills/task/SKILL.md | 21 +++- apps/www/public/r/ai-docs.json | 2 +- apps/www/public/r/ai-kit.json | 2 +- .../ai-chat-streaming/streamHistory.slow.tsx | 92 ++++++++++++++ .../components/editor/plugins/ai-kit.tsx | 27 ++-- docs/(plugins)/(ai)/ai.cn.mdx | 54 +++++--- docs/(plugins)/(ai)/ai.mdx | 54 +++++--- .../ai/src/lib/transforms/aiStreamSnapshot.ts | 58 +++++++++ packages/ai/src/lib/transforms/index.ts | 1 + packages/ai/src/lib/transforms/undoAI.ts | 8 ++ .../react/ai-chat/transforms/acceptAIChat.ts | 45 ++++++- .../ai/src/react/ai-chat/utils/resetAIChat.ts | 3 + tmp-issue-4900-editor-ai.png | Bin 0 -> 138532 bytes 18 files changed, 513 insertions(+), 71 deletions(-) create mode 100644 .claude/docs/plans/2026-03-26-issue-4900-ai-streaming-history.md create mode 100644 .claude/docs/plans/2026-03-26-pr-and-comment-4900.md create mode 100644 .claude/docs/plans/2026-03-26-task-skill-auto-pr-sync.md create mode 100644 .claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-snapshot-before-unsaved-chunks.md create mode 100644 apps/www/src/__tests__/package-integration/ai-chat-streaming/streamHistory.slow.tsx create mode 100644 packages/ai/src/lib/transforms/aiStreamSnapshot.ts create mode 100644 tmp-issue-4900-editor-ai.png diff --git a/.claude/docs/plans/2026-03-26-issue-4900-ai-streaming-history.md b/.claude/docs/plans/2026-03-26-issue-4900-ai-streaming-history.md new file mode 100644 index 0000000000..3b72c8f9ee --- /dev/null +++ b/.claude/docs/plans/2026-03-26-issue-4900-ai-streaming-history.md @@ -0,0 +1,42 @@ +# Issue 4900: AI streaming history bloat + +## Source of truth + +- Source type: GitHub issue +- Source id: #4900 +- Title: Streaming with withAIBatch accumulates operations and may slow undo +- URL: https://github.com/udecode/plate/issues/4900 +- Task type: bug / performance + +## Expected outcome + +- Long AI streaming sessions should not build a giant undo batch that makes `tf.ai.undo()` or accept flows slower as chunk count grows. +- Keep current AI insert/chat behavior intact from a user point of view. + +## Constraints and repo rules + +- Non-trivial task: use repo-local planning file, not root planning files. +- Check institutional learnings before implementation. +- Use a sane test seam before the fix if possible. +- If `.ts` changes, verify with install -> build -> typecheck sequence for touched package(s), then `pnpm lint:fix`. + +## Findings + +- No relevant prior solution found in `.claude/docs/solutions/`. +- `withAIBatch` only merges batches and tags the last undo batch. It does not compact operations. +- Streaming insert mode is wrapped with `withAIBatch(..., { split: isFirst })` in the AI kit integration. +- `undoAI` currently relies on the last undo batch being tagged as AI and calls native `editor.undo()`. +- Accept/hide logic already distinguishes AI preview state from accepted content using AI marks and anchor cleanup. + +## Working hypothesis + +- The real bug is treating streamed preview updates as normal history. +- Better fix: keep preview streaming out of history, then finalize or discard preview explicitly. +- If preview is unsaved, accept likely needs to remove preview without saving, then insert the final accepted content as one normal batch. + +## Next steps + +1. Confirm accept/reject/reset paths needed for unsaved preview. +2. Add a failing test that proves streaming no longer bloats undo history. +3. Implement the smallest package-level fix. +4. Verify targeted tests, then package build -> typecheck -> lint. diff --git a/.claude/docs/plans/2026-03-26-pr-and-comment-4900.md b/.claude/docs/plans/2026-03-26-pr-and-comment-4900.md new file mode 100644 index 0000000000..c8ce3c690c --- /dev/null +++ b/.claude/docs/plans/2026-03-26-pr-and-comment-4900.md @@ -0,0 +1,19 @@ +# PR And Comment 4900 + +## Goal + +Open or update the PR for the current checkout, then update the existing GitHub issue comment for issue `#4900` with the PR URL. + +## Checklist + +- [in_progress] Load the PR workflow and record the task plan +- [pending] Run `check` +- [pending] Inspect branch and PR state +- [pending] Commit and push the full current checkout +- [pending] Open or update the PR +- [pending] Update the existing `#4900` issue comment with the PR link + +## Findings + +- Repo rules require `check` before any PR create or update. +- Repo rules also require using the entire current checkout as-is, including unrelated changes. diff --git a/.claude/docs/plans/2026-03-26-task-skill-auto-pr-sync.md b/.claude/docs/plans/2026-03-26-task-skill-auto-pr-sync.md new file mode 100644 index 0000000000..44d2ad2595 --- /dev/null +++ b/.claude/docs/plans/2026-03-26-task-skill-auto-pr-sync.md @@ -0,0 +1,19 @@ +# Task Skill Auto PR Sync + +## Goal + +Update the task skill so verified code-changing tracked work opens or updates the PR before any tracker comment, and any GitHub issue comment includes the PR URL. + +## Checklist + +- [completed] Read the current `task` skill source and adjacent skill/repo rules +- [completed] Update `.claude/skills/task/task.mdc` with PR-before-comment behavior +- [completed] Run the skill sync step +- [completed] Verify the generated task skill reflects the new rules + +## Findings + +- The current task skill explicitly says not to default to PR creation. +- The current GitHub sync-back section says not to mention PR mechanics in the issue comment. +- Repo rules already require `check` before PR creation, so the task skill should defer to that workflow instead of inventing a new one. +- `pnpm run prepare` runs `pnpm dlx skiller@latest apply`, which regenerated `.codex/skills/task/SKILL.md` with the new wording. diff --git a/.claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-snapshot-before-unsaved-chunks.md b/.claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-snapshot-before-unsaved-chunks.md new file mode 100644 index 0000000000..5cdea7651c --- /dev/null +++ b/.claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-snapshot-before-unsaved-chunks.md @@ -0,0 +1,115 @@ +--- +module: AI +date: 2026-03-26 +problem_type: performance_issue +component: assistant +symptoms: + - "Long insert-mode AI streams make `tf.ai.undo()` slower as chunk count grows" + - "Accepting streamed AI output also gets slower after long responses" + - "The last AI undo batch contains one history entry but still stores a large number of underlying operations" +root_cause: logic_error +resolution_type: code_fix +severity: high +tags: + - ai + - streaming + - undo + - history + - withAIBatch + - streamInsertChunk + - performance +--- + +# AI streaming preview should snapshot before unsaved chunks + +## Problem + +Insert-mode AI streaming was wrapping every `streamInsertChunk` call in `withAIBatch`. + +That looked reasonable because it kept the whole preview in one undo batch, but the batch still accumulated every streamed operation. Undo cost therefore scaled with chunk count instead of the final accepted content. + +## Symptoms + +- `tf.ai.undo()` became progressively slower after long streamed responses. +- Accepting insert-mode AI output also slowed down after long streams. +- History looked compact at a glance because there was only one undo batch, but that batch still held a large operations array. + +## What Didn't Work + +Reading `withAIBatch` in isolation was misleading. It only does two things: + +1. merge into the current history batch +2. tag the batch as AI-generated + +It does not compact prior operations. + +Chasing `streamInsertChunk` alone was also the wrong level. The real problem was not the transform logic itself. The problem was treating streamed preview updates as normal history writes. + +## Solution + +Capture the editor state once before insert-mode streaming starts, stream preview chunks with `withoutSaving`, and only write history when the user accepts the final result. + +The implementation had three parts: + +### 1. Capture a pre-stream snapshot + +```ts +captureAIStreamSnapshot(editor); + +editor.tf.withoutSaving(() => { + editor.tf.insertNodes({ + children: [{ text: '' }], + type: getPluginType(editor, KEYS.aiChat), + }); +}); +``` + +### 2. Keep streamed preview out of history + +```ts +editor.tf.withoutSaving(() => { + if (!getOption('streaming')) return; + + editor.tf.withScrolling(() => { + streamInsertChunk(editor, chunk, { + textProps: { + [getPluginType(editor, KEYS.ai)]: true, + }, + }); + }); +}); +``` + +### 3. Accept by restoring the snapshot, then committing the final value once + +```ts +if (!commitAIStreamValue(editor, getAcceptedInsertValue(editor))) { + withAIBatch(editor, () => { + tf.ai.removeMarks(); + editor.getTransforms(AIChatPlugin).aiChat.removeAnchor(); + }); +} +``` + +`tf.ai.undo()` also gained a snapshot restore fallback. If there is no AI-tagged history batch but AI preview content still exists, it restores the captured pre-stream state instead of trying to replay chunk history. + +## Why This Works + +Preview streaming and accepted editor history have different jobs: + +- preview streaming needs responsive incremental rendering +- accepted editor history needs one sane undo step + +Using one mechanism for both creates the slowdown. A merged history batch is still a transcript of every chunk. Restoring a snapshot avoids that transcript entirely. + +The accept path then turns the preview into one fresh history entry whose cost scales with the final document diff, not with how many network chunks arrived on the way there. + +## Prevention + +- Do not use `withAIBatch` for insert-mode preview streaming. Use it for saved AI edits, not for chunk-by-chunk preview rendering. +- If streamed content is disposable preview state, snapshot first and stream with `withoutSaving`. +- When accept should remain undoable, restore the snapshot and commit the final accepted value in one new batch. +- Test both sides of the flow: + - preview streaming should leave history empty before accept + - accept should create one compact undoable batch + - `tf.ai.undo()` should restore the original pre-stream value when preview is still present diff --git a/.claude/skills/task/task.mdc b/.claude/skills/task/task.mdc index e841226bae..9b2c702034 100644 --- a/.claude/skills/task/task.mdc +++ b/.claude/skills/task/task.mdc @@ -12,7 +12,9 @@ Handle $ARGUMENTS. Be thorough, not ceremonial. Start from the source of truth, - Prefer targeted tests and checks during iteration. - Keep the user updated at milestones. - Verify the actual result before claiming done. -- Do not default to research swarms, review swarms, browser proof, PR creation, or compounding. +- Do not default to research swarms, review swarms, or browser proof. +- For verified code-changing work, default to creating or updating the PR unless the user explicitly said not to. +- Do not default to compounding. ## Intake @@ -83,7 +85,8 @@ Apply this section only when the task source is a tracker item. - Use `gh` for fetch and sync-back. - If useful, rename the thread to ` `. - If the task is code-changing, prefer a branch name that includes the issue number. -- If the task reaches a meaningful outcome and came from the issue, post a concise issue comment unless blocked or the user said not to. +- If the task changed code and reached a verified meaningful outcome, create or update the PR before any issue comment unless blocked or the user said not to. +- If the task reaches a meaningful outcome and came from the issue, post a concise issue comment after the PR exists unless blocked or the user said not to. ### Linear @@ -94,7 +97,7 @@ Apply this section only when the task source is a tracker item. ### Tracked Task Non-Rules -- Do not require PR creation for every tracked task. +- Do not require PR creation for tracker tasks that did not change code, ended blocked, or were purely investigative. - Do not require browser screenshots for every tracked task. - Do not require tracker comments for investigations that ended blocked or inconclusive unless sync-back is useful. @@ -122,6 +125,9 @@ Apply this section only when the task source is a tracker item. - `agent-browser` or `test-browser` Use only when there is a real browser surface to verify. Require real browser proof only for browser or UI tasks. +- `git-commit-push-pr` + Use when verified work changed code and should ship as a PR. + Create or update the PR before any tracker comment. - `ce-compound` Use only after verified, non-trivial work that produced reusable knowledge. Never load it at the start. @@ -188,6 +194,7 @@ Keep verification mandatory but proportional. - Run browser verification only for browser or UI tasks. - Run broader repo-wide gates only when repo instructions require them or the change scope justifies them. - If the repo has a standard final gate, run it last. +- If verified work changed code, create or update the PR before tracker sync-back unless the user explicitly said not to. - If the task came from a tracked issue and the task reached a meaningful outcome, sync back unless the user said not to. - If UI changed, capture proof from the real browser surface. - Do not hardcode PR creation, screenshots, or tracker comments for every task. @@ -237,6 +244,7 @@ Apply this section only when the task came from a tracker item and reached a mea - Keep it focused on: - reproduced or baselined, when relevant - fixed or implemented + - PR: , when one exists - re-verified, with browser mention only when relevant - remaining caveat, if any - Do not mention: @@ -244,7 +252,9 @@ Apply this section only when the task came from a tracker item and reached a mea - tests, typecheck, or lint - screenshot paths - branch names - - PR mechanics + - commit, push, or staging mechanics +- Do not write the issue comment before the PR exists. +- If writing the comment after code-changing work, include the full PR URL. - Start only the first sentence with `Codex ...`. - Italicize each paragraph separately. @@ -253,6 +263,8 @@ Example: ```md _Codex implemented and verified this issue._ +_PR: https://github.com/owner/repo/pull/123._ + _Reproduced the bug, applied the fix, and re-verified the affected flow._ _Remaining caveat: none._ @@ -286,4 +298,4 @@ _Remaining caveat: none._ - Verification matched the change scope. - Final handoff matched the task type. - Testing or batch handoff reported the completed slice, verification, and remaining queue when relevant. -- Any tracker, browser, review, or compound follow-up was done only if actually relevant. \ No newline at end of file +- Any tracker, browser, review, or compound follow-up was done only if actually relevant. diff --git a/.codex/skills/task/SKILL.md b/.codex/skills/task/SKILL.md index 3759a803e7..70d06b9beb 100644 --- a/.codex/skills/task/SKILL.md +++ b/.codex/skills/task/SKILL.md @@ -19,7 +19,9 @@ Handle $ARGUMENTS. Be thorough, not ceremonial. Start from the source of truth, - Prefer targeted tests and checks during iteration. - Keep the user updated at milestones. - Verify the actual result before claiming done. -- Do not default to research swarms, review swarms, browser proof, PR creation, or compounding. +- Do not default to research swarms, review swarms, or browser proof. +- For verified code-changing work, default to creating or updating the PR unless the user explicitly said not to. +- Do not default to compounding. ## Intake @@ -90,7 +92,8 @@ Apply this section only when the task source is a tracker item. - Use `gh` for fetch and sync-back. - If useful, rename the thread to ` `. - If the task is code-changing, prefer a branch name that includes the issue number. -- If the task reaches a meaningful outcome and came from the issue, post a concise issue comment unless blocked or the user said not to. +- If the task changed code and reached a verified meaningful outcome, create or update the PR before any issue comment unless blocked or the user said not to. +- If the task reaches a meaningful outcome and came from the issue, post a concise issue comment after the PR exists unless blocked or the user said not to. ### Linear @@ -101,7 +104,7 @@ Apply this section only when the task source is a tracker item. ### Tracked Task Non-Rules -- Do not require PR creation for every tracked task. +- Do not require PR creation for tracker tasks that did not change code, ended blocked, or were purely investigative. - Do not require browser screenshots for every tracked task. - Do not require tracker comments for investigations that ended blocked or inconclusive unless sync-back is useful. @@ -129,6 +132,9 @@ Apply this section only when the task source is a tracker item. - `agent-browser` or `test-browser` Use only when there is a real browser surface to verify. Require real browser proof only for browser or UI tasks. +- `git-commit-push-pr` + Use when verified work changed code and should ship as a PR. + Create or update the PR before any tracker comment. - `ce-compound` Use only after verified, non-trivial work that produced reusable knowledge. Never load it at the start. @@ -195,6 +201,7 @@ Keep verification mandatory but proportional. - Run browser verification only for browser or UI tasks. - Run broader repo-wide gates only when repo instructions require them or the change scope justifies them. - If the repo has a standard final gate, run it last. +- If verified work changed code, create or update the PR before tracker sync-back unless the user explicitly said not to. - If the task came from a tracked issue and the task reached a meaningful outcome, sync back unless the user said not to. - If UI changed, capture proof from the real browser surface. - Do not hardcode PR creation, screenshots, or tracker comments for every task. @@ -244,6 +251,7 @@ Apply this section only when the task came from a tracker item and reached a mea - Keep it focused on: - reproduced or baselined, when relevant - fixed or implemented + - PR: , when one exists - re-verified, with browser mention only when relevant - remaining caveat, if any - Do not mention: @@ -251,7 +259,9 @@ Apply this section only when the task came from a tracker item and reached a mea - tests, typecheck, or lint - screenshot paths - branch names - - PR mechanics + - commit, push, or staging mechanics +- Do not write the issue comment before the PR exists. +- If writing the comment after code-changing work, include the full PR URL. - Start only the first sentence with `Codex ...`. - Italicize each paragraph separately. @@ -260,6 +270,8 @@ Example: ```md _Codex implemented and verified this issue._ +_PR: https://github.com/owner/repo/pull/123._ + _Reproduced the bug, applied the fix, and re-verified the affected flow._ _Remaining caveat: none._ @@ -294,3 +306,4 @@ _Remaining caveat: none._ - Final handoff matched the task type. - Testing or batch handoff reported the completed slice, verification, and remaining queue when relevant. - Any tracker, browser, review, or compound follow-up was done only if actually relevant. + diff --git a/apps/www/public/r/ai-docs.json b/apps/www/public/r/ai-docs.json index 2c654c5adf..9684ab68b3 100644 --- a/apps/www/public/r/ai-docs.json +++ b/apps/www/public/r/ai-docs.json @@ -7,7 +7,7 @@ "files": [ { "path": "../../docs/(plugins)/(ai)/ai.mdx", - "content": "---\ntitle: AI\ndescription: AI-powered writing assistance.\ndocs:\n - route: https://pro.platejs.org/docs/examples/ai\n title: Plus\n---\n\n\n\n\n\n## Features\n\n- **Context-aware command menu** that adapts to cursor, text selection, and block selection workflows.\n- **Streaming Markdown/MDX insertion** with table, column, and code block support powered by `streamInsertChunk`.\n- **Insert and chat review modes** with undo-safe batching via `withAIBatch` and `tf.ai.undo()`.\n- **Block selection aware transforms** to replace or append entire sections using `tf.aiChat.replaceSelection` and `tf.aiChat.insertBelow`.\n- **Direct integration with `@ai-sdk/react`** so `api.aiChat.submit` can stream responses from Vercel AI SDK helpers.\n- **Suggestion and comment utilities** that diff AI edits, accept/reject changes, and map AI feedback back to document ranges.\n\n\n\n## Kit Usage\n\n\n\n### Installation\n\nThe fastest way to add AI functionality is with the `AIKit`. It ships the configured `AIPlugin`, `AIChatPlugin`, Markdown streaming helpers, cursor overlay, and their [Plate UI](/docs/installation/plate-ui) components.\n\n\n\n- [`AIMenu`](/docs/components/ai-menu): Floating command surface for prompts, tool shortcuts, and chat review.\n- [`AILoadingBar`](/docs/components/ai-loading-bar): Displays streaming status at the editor container.\n- [`AIAnchorElement`](/docs/components/ai-anchor-element): Invisible anchor node used to position the floating menu during streaming.\n- [`AILeaf`](/docs/components/ai-leaf): Renders AI-marked text with subtle styling.\n\n### Add Kit\n\n```tsx\nimport { createPlateEditor } from 'platejs/react';\nimport { AIKit } from '@/components/editor/plugins/ai-kit';\n\nconst editor = createPlateEditor({\n plugins: [\n // ...otherPlugins,\n ...AIKit,\n ],\n});\n```\n\n### Add API Route\n\nExpose a streaming command endpoint that proxies your model provider:\n\n\n\n### Configure Environment\n\nSet your AI Gateway key locally (replace with your provider secret if you are not using a gateway):\n\n```bash title=\".env.local\"\nAI_GATEWAY_API_KEY=\"your-api-key\"\n```\n\n\n\n## Manual Usage\n\n\n\n### Installation\n\n```bash\nnpm install @platejs/ai @platejs/markdown @platejs/selection @ai-sdk/react ai\n```\n\n`@platejs/suggestion` is optional but required for diff-based edit suggestions.\n\n### Add Plugins\n\n```tsx\nimport { createPlateEditor } from 'platejs/react';\nimport { AIChatPlugin, AIPlugin } from '@platejs/ai/react';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { MarkdownPlugin } from '@platejs/markdown';\n\nexport const editor = createPlateEditor({\n plugins: [\n BlockSelectionPlugin,\n MarkdownPlugin,\n AIPlugin,\n AIChatPlugin, // extended in the next step\n ],\n});\n```\n\n- `BlockSelectionPlugin`: Enables multi-block selections that `AIChatPlugin` relies on for insert/replace transforms.\n- `MarkdownPlugin`: Provides Markdown serialization used by streaming utilities.\n- `AIPlugin`: Adds the AI mark and transforms for undoing AI batches.\n- `AIChatPlugin`: Supplies the AI combobox, API helpers, and transforms.\n\nUse `AIPlugin.withComponent` with your own element (or [`AILeaf`](/docs/components/ai-leaf)) to highlight AI-generated text.\n\n### Configure AIChatPlugin\n\nExtend `AIChatPlugin` to hook streaming and edits. The example mirrors the core logic from `AIKit` while keeping the UI headless.\n\n```tsx\nimport { AIChatPlugin, applyAISuggestions, streamInsertChunk, useChatChunk } from '@platejs/ai/react';\nimport { withAIBatch } from '@platejs/ai';\nimport { getPluginType, KEYS, PathApi } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nexport const aiChatPlugin = AIChatPlugin.extend({\n options: {\n chatOptions: {\n api: '/api/ai/command',\n body: {\n model: 'openai/gpt-4o-mini',\n },\n },\n trigger: ' ',\n triggerPreviousCharPattern: /^\\s?$/,\n },\n useHooks: ({ editor, getOption }) => {\n const mode = usePluginOption(AIChatPlugin, 'mode');\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n\n useChatChunk({\n onChunk: ({ chunk, isFirst, text }) => {\n if (mode === 'insert') {\n if (isFirst) {\n editor.setOption(AIChatPlugin, 'streaming', true);\n\n editor.tf.insertNodes(\n {\n children: [{ text: '' }],\n type: getPluginType(editor, KEYS.aiChat),\n },\n {\n at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),\n }\n );\n }\n\n if (!getOption('streaming')) return;\n\n withAIBatch(\n editor,\n () => {\n streamInsertChunk(editor, chunk, {\n textProps: {\n [getPluginType(editor, KEYS.ai)]: true,\n },\n });\n },\n { split: isFirst }\n );\n }\n\n if (toolName === 'edit' && mode === 'chat') {\n withAIBatch(\n editor,\n () => {\n applyAISuggestions(editor, text);\n },\n { split: isFirst }\n );\n }\n },\n onFinish: () => {\n editor.setOption(AIChatPlugin, 'streaming', false);\n editor.setOption(AIChatPlugin, '_blockChunks', '');\n editor.setOption(AIChatPlugin, '_blockPath', null);\n editor.setOption(AIChatPlugin, '_mdxName', null);\n },\n });\n },\n});\n```\n\n- `useChatChunk`: Watches `UseChatHelpers` status and yields incremental chunks.\n- `streamInsertChunk`: Streams Markdown/MDX into the document, reusing the existing block when possible.\n- `applyAISuggestions`: Converts responses into transient suggestion nodes when `toolName === 'edit'`.\n- `withAIBatch`: Marks history batches so `tf.ai.undo()` only reverts the last AI-generated change.\n\nProvide your own `render` components (toolbar button, floating menu, etc.) when you extend the plugin.\n\n### Build API Route\n\nHandle `api.aiChat.submit` requests on the server. Each request includes the chat `messages` from `@ai-sdk/react` and a `ctx` payload that contains the editor `children`, current `selection`, and last `toolName`.\n[Complete API example](https://github.com/udecode/plate-playground-template/blob/main/src/app/api/ai/command/route.ts)\n\n```ts title=\"app/api/ai/command/route.ts\"\nimport { createGateway } from '@ai-sdk/gateway';\nimport { convertToCoreMessages, streamText } from 'ai';\nimport { createSlateEditor } from 'platejs';\n\nimport { BaseEditorKit } from '@/registry/components/editor/editor-base-kit';\nimport { markdownJoinerTransform } from '@/registry/lib/markdown-joiner-transform';\n\nexport async function POST(req: Request) {\n const { apiKey, ctx, messages, model } = await req.json();\n\n const editor = createSlateEditor({\n plugins: BaseEditorKit,\n selection: ctx.selection,\n value: ctx.children,\n });\n\n const gateway = createGateway({\n apiKey: apiKey ?? process.env.AI_GATEWAY_API_KEY!,\n });\n\n const result = streamText({\n experimental_transform: markdownJoinerTransform(),\n messages: convertToCoreMessages(messages),\n model: gateway(model ?? 'openai/gpt-4o-mini'),\n system: ctx.toolName === 'edit' ? 'You are an editor that rewrites user text.' : undefined,\n });\n\n return result.toDataStreamResponse();\n}\n```\n\n- `ctx.children` and `ctx.selection` are rehydrated into a Slate editor so you can build rich prompts (see [Prompt Templates](#prompt-templates)).\n- Forward provider settings (model, apiKey, temperature, gateway flags, etc.) through `chatOptions.body`; everything you add is passed verbatim in the JSON payload and can be read before calling `createGateway`.\n- Always read secrets from the server. The client should only send opaque identifiers or short-lived tokens.\n- Return a streaming response so `useChat` and `useChatChunk` can process tokens incrementally.\n\n### Connect `useChat`\n\nBridge the editor and your model endpoint with `@ai-sdk/react`. Store helpers on the plugin so transforms can reload, stop, or show chat state.\n\n```tsx\nimport { useEffect } from 'react';\n\nimport { type UIMessage, DefaultChatTransport } from 'ai';\nimport { type UseChatHelpers, useChat } from '@ai-sdk/react';\nimport { AIChatPlugin } from '@platejs/ai/react';\nimport { useEditorPlugin } from 'platejs/react';\n\ntype ChatMessage = UIMessage<{}, { toolName: 'comment' | 'edit' | 'generate'; comment?: unknown }>;\n\nexport const useEditorAIChat = () => {\n const { editor, setOption } = useEditorPlugin(AIChatPlugin);\n\n const chat = useChat({\n id: 'editor',\n api: '/api/ai/command',\n transport: new DefaultChatTransport(),\n onData(data) {\n if (data.type === 'data-toolName') {\n editor.setOption(AIChatPlugin, 'toolName', data.data);\n }\n },\n });\n\n useEffect(() => {\n setOption('chat', chat as UseChatHelpers);\n }, [chat, setOption]);\n\n return chat;\n};\n```\n\nCombine the helper with `useEditorChat` to keep the floating menu anchored correctly:\n\n```tsx\nimport { useEditorChat } from '@platejs/ai/react';\n\nuseEditorChat({\n onOpenChange: (open) => {\n if (!open) chat.stop?.();\n },\n});\n```\n\nNow you can submit prompts programmatically:\n\n```tsx\nimport { AIChatPlugin } from '@platejs/ai/react';\n\neditor.getApi(AIChatPlugin).aiChat.submit('', {\n prompt: {\n default: 'Continue the document after {block}',\n selecting: 'Rewrite {selection} with a clearer tone',\n },\n toolName: 'generate',\n});\n```\n\n\n\n## Prompt Templates\n\n### Client Prompting\n\n- `api.aiChat.submit` accepts an `EditorPrompt`. Provide a string, an object with `default`/`selecting`/`blockSelecting`, or a function that receives `{ editor, isSelecting, isBlockSelecting }`. The helper `getEditorPrompt` in the client turns that value into the final string.\n- Combine it with `replacePlaceholders(editor, template, { prompt })` to expand `{editor}`, `{block}`, `{blockSelection}`, and `{prompt}` using Markdown generated by `@platejs/ai`.\n\n```tsx\nimport { replacePlaceholders } from '@platejs/ai';\n\neditor.getApi(AIChatPlugin).aiChat.submit('Improve tone', {\n prompt: ({ isSelecting }) =>\n isSelecting\n ? replacePlaceholders(editor, 'Rewrite {blockSelection} using a friendly tone.')\n : replacePlaceholders(editor, 'Continue {block} with two more sentences.'),\n toolName: 'generate',\n});\n```\n\n### Server Prompting\n\nThe demo backend in `apps/www/src/app/api/ai/command` reconstructs the editor from `ctx` and builds structured prompts:\n\n- `getChooseToolPrompt` decides whether the request is `generate`, `edit`, or `comment`.\n- `getGeneratePrompt`, `getEditPrompt`, and `getCommentPrompt` transform the current editor state into instructions tailored to each mode.\n- Utility helpers like `getMarkdown`, `getMarkdownWithSelection`, and `buildStructuredPrompt` (see `apps/www/src/app/api/ai/command/prompts.ts`) make it easy to embed block ids, selections, and MDX tags into the LLM request.\n\nAugment the payload you send from the client to fine-tune server prompts:\n\n```ts\neditor.setOption(aiChatPlugin, 'chatOptions', {\n api: '/api/ai/command',\n body: {\n model: 'openai/gpt-4o-mini',\n tone: 'playful',\n temperature: 0.4,\n },\n});\n```\n\nEverything under `chatOptions.body` arrives in the route handler, letting you swap providers, pass user-specific metadata, or branch into different prompt templates.\n\n## Keyboard Shortcuts\n\n\n Open the AI menu in an empty block (cursor mode)\n Show the AI menu (set via `shortcuts.show`)\n Hide the AI menu and stop streaming\n\n\n## Streaming\n\nThe streaming utilities keep complex layouts intact while responses arrive:\n\n- `streamInsertChunk(editor, chunk, options)` deserializes Markdown chunks, updates the current block in place, and appends new blocks as needed. Use `textProps`/`elementProps` to tag streamed nodes (e.g., mark AI text).\n- `streamDeserializeMd` and `streamDeserializeInlineMd` provide lower-level access if you need to control streaming for custom node types.\n- `streamSerializeMd` mirrors the editor state so you can detect drift between streamed content and the response buffer.\n\nReset the internal `_blockChunks`, `_blockPath`, and `_mdxName` options when streaming finishes to start the next response from a clean slate.\n\n## Streaming Example\n\n\n\n## Plate Plus\n\n\n\n## Hooks\n\n### `useAIChatEditor`\n\nRegisters an auxiliary editor for chat previews and deserializes Markdown with block-level memoization.\n\n\n\n Editor instance dedicated to the chat preview.\n Markdown content returned by the model.\n Pass `parser` to filter tokens before deserialization.\n\n\n\n```tsx\nimport { usePlateEditor } from 'platejs/react';\nimport { MarkdownPlugin } from '@platejs/markdown';\nimport { AIChatPlugin, useAIChatEditor } from '@platejs/ai/react';\n\nconst aiPreviewEditor = usePlateEditor({\n plugins: [MarkdownPlugin, AIChatPlugin],\n});\n\nuseAIChatEditor(aiPreviewEditor, responseMarkdown, {\n parser: { exclude: ['space'] },\n});\n```\n\n### `useEditorChat`\n\nConnects `UseChatHelpers` to editor state so the AI menu knows whether to anchor to cursor, selection, or block selection.\n\n\n\n void\" optional>Called when the menu opens on block selection.\n void\" optional>Called whenever the menu opens or closes.\n void\" optional>Called when the menu opens at the cursor.\n void\" optional>Called when the menu opens on a text selection.\n\n\n\n### `useChatChunk`\n\nStreams chat responses chunk-by-chunk and gives you full control over insertion.\n\n\n\n void\">Handle each streamed chunk.\n void\" optional>Called when streaming finishes.\n\n\n\n## Utilities\n\n### `withAIBatch`\n\nGroups editor operations into a single history batch and flags it as AI-generated so `tf.ai.undo()` removes it safely.\n\n\n\n Target editor.\n void\">Operations to run.\n Set `split: true` to start a new history batch.\n\n\n\n### `applyAISuggestions`\n\nDiffs AI output against stored `chatNodes` and writes transient suggestion nodes. Requires `@platejs/suggestion`.\n\n\n\n Editor to apply suggestions to.\n Markdown response from the model.\n\n\n\nComplementary helpers allow you to finalize or discard the diff:\n\n- `acceptAISuggestions(editor)`: Converts transient suggestion nodes into permanent suggestions.\n- `rejectAISuggestions(editor)`: Removes transient suggestion nodes and clears suggestion marks.\n\n### `aiCommentToRange`\n\nMaps streamed comment metadata back to document ranges so comments can be inserted automatically.\n\n\n\n Editor instance.\n Block id and text used to locate the range.\n\nRange matching the comment or `null` if it cannot be found.\n\n\n### `findTextRangeInBlock`\n\nFuzzy-search helper that uses LCS to find the closest match inside a block.\n\n\n\n Block node to search.\n Text snippet to locate.\n\nMatched range or `null`.\n\n\n### `getEditorPrompt`\n\nGenerates prompts that respect cursor, selection, or block selection states.\n\n\n\n Editor providing context.\n String, config, or function describing the prompt.\n\nContextualized prompt string.\n\n\n### `replacePlaceholders`\n\nReplaces placeholders like `{editor}`, `{blockSelection}`, and `{prompt}` with serialized Markdown.\n\n\n\n Editor providing content.\n Template text.\n Prompt value injected into `{prompt}`.\n\nTemplate with placeholders replaced by Markdown.\n\n\n## Plugins\n\n### `AIPlugin`\n\nAdds an `ai` mark to streamed text and exposes transforms to remove AI nodes or undo the last AI batch. Use `.withComponent` to render AI-marked text with a custom component.\n\n\n \n AI content is stored on text nodes.\n AI marks are regular text properties, not decorations.\n \n\n\n### `AIChatPlugin`\n\nMain plugin that powers the AI menu, chat state, and transforms.\n\n\n \n Character(s) that open the command menu. Defaults to `' '`.\n Pattern that must match the character before the trigger. Defaults to `/^\\s?$/`.\n boolean\" optional>Return `false` to cancel opening in specific contexts.\n Store helpers from `useChat` so API calls can access them.\n Snapshot of nodes used to diff edit suggestions (managed internally).\n Selection captured before submitting a prompt (managed internally).\n Controls whether responses stream directly into the document or open a review panel. Defaults to `'insert'`.\n Whether the AI menu is visible. Defaults to `false`.\n True while a response is streaming. Defaults to `false`.\n Active tool used to interpret the response.\n \n\n\n## API\n\n### `api.aiChat.submit(input, options?)`\n\nSubmits a prompt to your model provider. When `mode` is omitted it defaults to `'insert'` for a collapsed cursor and `'chat'` otherwise.\n\n\n\n Raw input from the user.\n Fine-tune submission behaviour.\n\n\n Override the response mode.\n Forwarded to `chat.sendMessage` (model, headers, etc.).\n String, config, or function processed by `getEditorPrompt`.\n Tags the submission so hooks can react differently.\n\n\n\n### `api.aiChat.reset(options?)`\n\nClears chat state, removes AI nodes, and optionally undoes the last AI batch.\n\n\n\n Pass `undo: false` to keep streamed content.\n\n\n\n### `api.aiChat.node(options?)`\n\nRetrieves the first AI node that matches the specified criteria.\n\n\n\n Set `anchor: true` to get the anchor node or `streaming: true` to retrieve the node currently being streamed into.\n\nMatching node entry, if found.\n\n\n### `api.aiChat.reload()`\n\nReplays the last prompt using the stored `UseChatHelpers`, restoring the original selection or block selection before resubmitting.\n\n### `api.aiChat.stop()`\n\nStops streaming and calls `chat.stop`.\n\n### `api.aiChat.show()`\n\nOpens the AI menu, clears previous chat messages, and resets tool state.\n\n### `api.aiChat.hide(options?)`\n\nCloses the AI menu, optionally undoing the last AI batch and refocusing the editor.\n\n\n\n Set `focus: false` to keep focus outside the editor or `undo: false` to preserve inserted content.\n\n\n\n## Transforms\n\n### `tf.aiChat.accept()`\n\nAccepts the latest response. In insert mode it removes AI marks and places the caret at the end of the streamed content. In chat mode it applies the pending suggestions.\n\n### `tf.aiChat.insertBelow(sourceEditor, options?)`\n\nInserts the chat preview (`sourceEditor`) below the current selection or block selection.\n\n\n\n Editor containing the generated content.\n Copy formatting from the source selection. Defaults to `'single'`.\n\n\n\n### `tf.aiChat.replaceSelection(sourceEditor, options?)`\n\nReplaces the current selection or block selection with the chat preview.\n\n\n\n Editor containing the generated content.\n Controls how much formatting from the original selection should be applied.\n\n\n\n### `tf.aiChat.removeAnchor(options?)`\n\nRemoves the temporary anchor node used to position the AI menu.\n\n\n\n Filters the nodes to remove.\n\n\n\n### `tf.ai.insertNodes(nodes, options?)`\n\nInserts nodes tagged with the AI mark at the current selection (or `options.target`).\n\n### `tf.ai.removeMarks(options?)`\n\nClears the AI mark from matching nodes.\n\n### `tf.ai.removeNodes(options?)`\n\nRemoves text nodes that are marked as AI-generated.\n\n### `tf.ai.undo()`\n\nUndoes the latest history entry if it was created by `withAIBatch` and contained AI content. Clears the paired redo entry to avoid re-applying AI output.\n\n## Customization\n\n### Adding Custom AI Commands\n\n\n\nExtend the `aiChatItems` map to add new commands. Each command receives `{ aiEditor, editor, input }` and can dispatch `api.aiChat.submit` with custom prompts or transforms.\n\n#### Simple Custom Command\n\n```tsx\nsummarizeInBullets: {\n icon: ,\n label: 'Summarize in bullets',\n value: 'summarizeInBullets',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit('', {\n prompt: 'Summarize the current selection using bullet points',\n toolName: 'generate',\n });\n },\n},\n```\n\n#### Command with Complex Logic\n\n```tsx\ngenerateTOC: {\n icon: ,\n label: 'Generate table of contents',\n value: 'generateTOC',\n onSelect: ({ editor }) => {\n const headings = editor.api.nodes({\n match: (n) => ['h1', 'h2', 'h3'].includes(n.type as string),\n });\n\n const prompt =\n headings.length === 0\n ? 'Create a realistic table of contents for this document'\n : 'Generate a table of contents that reflects the existing headings';\n\n void editor.getApi(AIChatPlugin).aiChat.submit('', {\n mode: 'insert',\n prompt,\n toolName: 'generate',\n });\n },\n},\n```\n\nThe menu automatically switches between command and suggestion states:\n\n- `cursorCommand`: Cursor is collapsed and no response yet.\n- `selectionCommand`: Text is selected and no response yet.\n- `cursorSuggestion` / `selectionSuggestion`: A response exists, so actions like Accept, Try Again, or Insert Below are shown.\n\nUse `toolName` (`'generate' | 'edit' | 'comment'`) to control how streaming hooks process the response. For example, `'edit'` enables diff-based suggestions, and `'comment'` allows you to convert streamed comments into discussion threads with `aiCommentToRange`.\n", + "content": "---\ntitle: AI\ndescription: AI-powered writing assistance.\ndocs:\n - route: https://pro.platejs.org/docs/examples/ai\n title: Plus\n---\n\n\n\n\n\n## Features\n\n- **Context-aware command menu** that adapts to cursor, text selection, and block selection workflows.\n- **Streaming Markdown/MDX insertion** with table, column, and code block support powered by `streamInsertChunk`.\n- **Insert and chat review modes** with snapshot-based insert previews plus undo-safe batching via `withAIBatch` and `tf.ai.undo()`.\n- **Block selection aware transforms** to replace or append entire sections using `tf.aiChat.replaceSelection` and `tf.aiChat.insertBelow`.\n- **Direct integration with `@ai-sdk/react`** so `api.aiChat.submit` can stream responses from Vercel AI SDK helpers.\n- **Suggestion and comment utilities** that diff AI edits, accept/reject changes, and map AI feedback back to document ranges.\n\n\n\n## Kit Usage\n\n\n\n### Installation\n\nThe fastest way to add AI functionality is with the `AIKit`. It ships the configured `AIPlugin`, `AIChatPlugin`, Markdown streaming helpers, cursor overlay, and their [Plate UI](/docs/installation/plate-ui) components.\n\n\n\n- [`AIMenu`](/docs/components/ai-menu): Floating command surface for prompts, tool shortcuts, and chat review.\n- [`AILoadingBar`](/docs/components/ai-loading-bar): Displays streaming status at the editor container.\n- [`AIAnchorElement`](/docs/components/ai-anchor-element): Invisible anchor node used to position the floating menu during streaming.\n- [`AILeaf`](/docs/components/ai-leaf): Renders AI-marked text with subtle styling.\n\n### Add Kit\n\n```tsx\nimport { createPlateEditor } from 'platejs/react';\nimport { AIKit } from '@/components/editor/plugins/ai-kit';\n\nconst editor = createPlateEditor({\n plugins: [\n // ...otherPlugins,\n ...AIKit,\n ],\n});\n```\n\n### Add API Route\n\nExpose a streaming command endpoint that proxies your model provider:\n\n\n\n### Configure Environment\n\nSet your AI Gateway key locally (replace with your provider secret if you are not using a gateway):\n\n```bash title=\".env.local\"\nAI_GATEWAY_API_KEY=\"your-api-key\"\n```\n\n\n\n## Manual Usage\n\n\n\n### Installation\n\n```bash\nnpm install @platejs/ai @platejs/markdown @platejs/selection @ai-sdk/react ai\n```\n\n`@platejs/suggestion` is optional but required for diff-based edit suggestions.\n\n### Add Plugins\n\n```tsx\nimport { createPlateEditor } from 'platejs/react';\nimport { AIChatPlugin, AIPlugin } from '@platejs/ai/react';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { MarkdownPlugin } from '@platejs/markdown';\n\nexport const editor = createPlateEditor({\n plugins: [\n BlockSelectionPlugin,\n MarkdownPlugin,\n AIPlugin,\n AIChatPlugin, // extended in the next step\n ],\n});\n```\n\n- `BlockSelectionPlugin`: Enables multi-block selections that `AIChatPlugin` relies on for insert/replace transforms.\n- `MarkdownPlugin`: Provides Markdown serialization used by streaming utilities.\n- `AIPlugin`: Adds the AI mark and transforms for undoing AI batches.\n- `AIChatPlugin`: Supplies the AI combobox, API helpers, and transforms.\n\nUse `AIPlugin.withComponent` with your own element (or [`AILeaf`](/docs/components/ai-leaf)) to highlight AI-generated text.\n\n### Configure AIChatPlugin\n\nExtend `AIChatPlugin` to hook streaming and edits. The example mirrors the core logic from `AIKit` while keeping the UI headless.\n\n```tsx\nimport { AIChatPlugin, applyAISuggestions, streamInsertChunk, useChatChunk } from '@platejs/ai/react';\nimport { captureAIStreamSnapshot, withAIBatch } from '@platejs/ai';\nimport { getPluginType, KEYS, PathApi } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nexport const aiChatPlugin = AIChatPlugin.extend({\n options: {\n chatOptions: {\n api: '/api/ai/command',\n body: {\n model: 'openai/gpt-4o-mini',\n },\n },\n trigger: ' ',\n triggerPreviousCharPattern: /^\\s?$/,\n },\n useHooks: ({ editor, getOption }) => {\n const mode = usePluginOption(AIChatPlugin, 'mode');\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n\n useChatChunk({\n onChunk: ({ chunk, isFirst, text }) => {\n if (mode === 'insert') {\n if (isFirst) {\n captureAIStreamSnapshot(editor);\n editor.setOption(AIChatPlugin, 'streaming', true);\n\n editor.tf.withoutSaving(() => {\n editor.tf.insertNodes(\n {\n children: [{ text: '' }],\n type: getPluginType(editor, KEYS.aiChat),\n },\n {\n at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),\n }\n );\n });\n }\n\n editor.tf.withoutSaving(() => {\n if (!getOption('streaming')) return;\n\n editor.tf.withScrolling(() => {\n streamInsertChunk(editor, chunk, {\n textProps: {\n [getPluginType(editor, KEYS.ai)]: true,\n },\n });\n });\n });\n }\n\n if (toolName === 'edit' && mode === 'chat') {\n withAIBatch(\n editor,\n () => {\n applyAISuggestions(editor, text);\n },\n { split: isFirst }\n );\n }\n },\n onFinish: () => {\n editor.setOption(AIChatPlugin, 'streaming', false);\n editor.setOption(AIChatPlugin, '_blockChunks', '');\n editor.setOption(AIChatPlugin, '_blockPath', null);\n editor.setOption(AIChatPlugin, '_mdxName', null);\n },\n });\n },\n});\n```\n\n- `useChatChunk`: Watches `UseChatHelpers` status and yields incremental chunks.\n- `captureAIStreamSnapshot`: Stores the pre-stream editor state so `tf.ai.undo()` can discard preview content without replaying every streamed chunk.\n- `streamInsertChunk`: Streams Markdown/MDX into the document, reusing the existing block when possible.\n- `applyAISuggestions`: Converts responses into transient suggestion nodes when `toolName === 'edit'`.\n- `withAIBatch`: Marks saved AI batches so suggestion review and accepted AI changes stay undo-safe.\n\nProvide your own `render` components (toolbar button, floating menu, etc.) when you extend the plugin.\n\n### Build API Route\n\nHandle `api.aiChat.submit` requests on the server. Each request includes the chat `messages` from `@ai-sdk/react` and a `ctx` payload that contains the editor `children`, current `selection`, and last `toolName`.\n[Complete API example](https://github.com/udecode/plate-playground-template/blob/main/src/app/api/ai/command/route.ts)\n\n```ts title=\"app/api/ai/command/route.ts\"\nimport { createGateway } from '@ai-sdk/gateway';\nimport { convertToCoreMessages, streamText } from 'ai';\nimport { createSlateEditor } from 'platejs';\n\nimport { BaseEditorKit } from '@/registry/components/editor/editor-base-kit';\nimport { markdownJoinerTransform } from '@/registry/lib/markdown-joiner-transform';\n\nexport async function POST(req: Request) {\n const { apiKey, ctx, messages, model } = await req.json();\n\n const editor = createSlateEditor({\n plugins: BaseEditorKit,\n selection: ctx.selection,\n value: ctx.children,\n });\n\n const gateway = createGateway({\n apiKey: apiKey ?? process.env.AI_GATEWAY_API_KEY!,\n });\n\n const result = streamText({\n experimental_transform: markdownJoinerTransform(),\n messages: convertToCoreMessages(messages),\n model: gateway(model ?? 'openai/gpt-4o-mini'),\n system: ctx.toolName === 'edit' ? 'You are an editor that rewrites user text.' : undefined,\n });\n\n return result.toDataStreamResponse();\n}\n```\n\n- `ctx.children` and `ctx.selection` are rehydrated into a Slate editor so you can build rich prompts (see [Prompt Templates](#prompt-templates)).\n- Forward provider settings (model, apiKey, temperature, gateway flags, etc.) through `chatOptions.body`; everything you add is passed verbatim in the JSON payload and can be read before calling `createGateway`.\n- Always read secrets from the server. The client should only send opaque identifiers or short-lived tokens.\n- Return a streaming response so `useChat` and `useChatChunk` can process tokens incrementally.\n\n### Connect `useChat`\n\nBridge the editor and your model endpoint with `@ai-sdk/react`. Store helpers on the plugin so transforms can reload, stop, or show chat state.\n\n```tsx\nimport { useEffect } from 'react';\n\nimport { type UIMessage, DefaultChatTransport } from 'ai';\nimport { type UseChatHelpers, useChat } from '@ai-sdk/react';\nimport { AIChatPlugin } from '@platejs/ai/react';\nimport { useEditorPlugin } from 'platejs/react';\n\ntype ChatMessage = UIMessage<{}, { toolName: 'comment' | 'edit' | 'generate'; comment?: unknown }>;\n\nexport const useEditorAIChat = () => {\n const { editor, setOption } = useEditorPlugin(AIChatPlugin);\n\n const chat = useChat({\n id: 'editor',\n api: '/api/ai/command',\n transport: new DefaultChatTransport(),\n onData(data) {\n if (data.type === 'data-toolName') {\n editor.setOption(AIChatPlugin, 'toolName', data.data);\n }\n },\n });\n\n useEffect(() => {\n setOption('chat', chat as UseChatHelpers);\n }, [chat, setOption]);\n\n return chat;\n};\n```\n\nCombine the helper with `useEditorChat` to keep the floating menu anchored correctly:\n\n```tsx\nimport { useEditorChat } from '@platejs/ai/react';\n\nuseEditorChat({\n onOpenChange: (open) => {\n if (!open) chat.stop?.();\n },\n});\n```\n\nNow you can submit prompts programmatically:\n\n```tsx\nimport { AIChatPlugin } from '@platejs/ai/react';\n\neditor.getApi(AIChatPlugin).aiChat.submit('', {\n prompt: {\n default: 'Continue the document after {block}',\n selecting: 'Rewrite {selection} with a clearer tone',\n },\n toolName: 'generate',\n});\n```\n\n\n\n## Prompt Templates\n\n### Client Prompting\n\n- `api.aiChat.submit` accepts an `EditorPrompt`. Provide a string, an object with `default`/`selecting`/`blockSelecting`, or a function that receives `{ editor, isSelecting, isBlockSelecting }`. The helper `getEditorPrompt` in the client turns that value into the final string.\n- Combine it with `replacePlaceholders(editor, template, { prompt })` to expand `{editor}`, `{block}`, `{blockSelection}`, and `{prompt}` using Markdown generated by `@platejs/ai`.\n\n```tsx\nimport { replacePlaceholders } from '@platejs/ai';\n\neditor.getApi(AIChatPlugin).aiChat.submit('Improve tone', {\n prompt: ({ isSelecting }) =>\n isSelecting\n ? replacePlaceholders(editor, 'Rewrite {blockSelection} using a friendly tone.')\n : replacePlaceholders(editor, 'Continue {block} with two more sentences.'),\n toolName: 'generate',\n});\n```\n\n### Server Prompting\n\nThe demo backend in `apps/www/src/app/api/ai/command` reconstructs the editor from `ctx` and builds structured prompts:\n\n- `getChooseToolPrompt` decides whether the request is `generate`, `edit`, or `comment`.\n- `getGeneratePrompt`, `getEditPrompt`, and `getCommentPrompt` transform the current editor state into instructions tailored to each mode.\n- Utility helpers like `getMarkdown`, `getMarkdownWithSelection`, and `buildStructuredPrompt` (see `apps/www/src/app/api/ai/command/prompts.ts`) make it easy to embed block ids, selections, and MDX tags into the LLM request.\n\nAugment the payload you send from the client to fine-tune server prompts:\n\n```ts\neditor.setOption(aiChatPlugin, 'chatOptions', {\n api: '/api/ai/command',\n body: {\n model: 'openai/gpt-4o-mini',\n tone: 'playful',\n temperature: 0.4,\n },\n});\n```\n\nEverything under `chatOptions.body` arrives in the route handler, letting you swap providers, pass user-specific metadata, or branch into different prompt templates.\n\n## Keyboard Shortcuts\n\n\n Open the AI menu in an empty block (cursor mode)\n Show the AI menu (set via `shortcuts.show`)\n Hide the AI menu and stop streaming\n\n\n## Streaming\n\nThe streaming utilities keep complex layouts intact while responses arrive:\n\n- `streamInsertChunk(editor, chunk, options)` deserializes Markdown chunks, updates the current block in place, and appends new blocks as needed. Use `textProps`/`elementProps` to tag streamed nodes (e.g., mark AI text).\n- `streamDeserializeMd` and `streamDeserializeInlineMd` provide lower-level access if you need to control streaming for custom node types.\n- `streamSerializeMd` mirrors the editor state so you can detect drift between streamed content and the response buffer.\n\nReset the internal `_blockChunks`, `_blockPath`, and `_mdxName` options when streaming finishes to start the next response from a clean slate.\n\n## Streaming Example\n\n\n\n## Plate Plus\n\n\n\n## Hooks\n\n### `useAIChatEditor`\n\nRegisters an auxiliary editor for chat previews and deserializes Markdown with block-level memoization.\n\n\n\n Editor instance dedicated to the chat preview.\n Markdown content returned by the model.\n Pass `parser` to filter tokens before deserialization.\n\n\n\n```tsx\nimport { usePlateEditor } from 'platejs/react';\nimport { MarkdownPlugin } from '@platejs/markdown';\nimport { AIChatPlugin, useAIChatEditor } from '@platejs/ai/react';\n\nconst aiPreviewEditor = usePlateEditor({\n plugins: [MarkdownPlugin, AIChatPlugin],\n});\n\nuseAIChatEditor(aiPreviewEditor, responseMarkdown, {\n parser: { exclude: ['space'] },\n});\n```\n\n### `useEditorChat`\n\nConnects `UseChatHelpers` to editor state so the AI menu knows whether to anchor to cursor, selection, or block selection.\n\n\n\n void\" optional>Called when the menu opens on block selection.\n void\" optional>Called whenever the menu opens or closes.\n void\" optional>Called when the menu opens at the cursor.\n void\" optional>Called when the menu opens on a text selection.\n\n\n\n### `useChatChunk`\n\nStreams chat responses chunk-by-chunk and gives you full control over insertion.\n\n\n\n void\">Handle each streamed chunk.\n void\" optional>Called when streaming finishes.\n\n\n\n## Utilities\n\n### `captureAIStreamSnapshot`\n\nCaptures the current editor state before insert-mode streaming so `tf.ai.undo()` can discard preview content without replaying every streamed chunk.\n\n\n\n Target editor.\n Custom snapshot to store instead of the current editor state.\n\nStored snapshot.\n\n\n### `withAIBatch`\n\nGroups editor operations into a single history batch and flags it as AI-generated so `tf.ai.undo()` removes it safely.\n\n\n\n Target editor.\n void\">Operations to run.\n Set `split: true` to start a new history batch.\n\n\n\n### `applyAISuggestions`\n\nDiffs AI output against stored `chatNodes` and writes transient suggestion nodes. Requires `@platejs/suggestion`.\n\n\n\n Editor to apply suggestions to.\n Markdown response from the model.\n\n\n\nComplementary helpers allow you to finalize or discard the diff:\n\n- `acceptAISuggestions(editor)`: Converts transient suggestion nodes into permanent suggestions.\n- `rejectAISuggestions(editor)`: Removes transient suggestion nodes and clears suggestion marks.\n\n### `aiCommentToRange`\n\nMaps streamed comment metadata back to document ranges so comments can be inserted automatically.\n\n\n\n Editor instance.\n Block id and text used to locate the range.\n\nRange matching the comment or `null` if it cannot be found.\n\n\n### `findTextRangeInBlock`\n\nFuzzy-search helper that uses LCS to find the closest match inside a block.\n\n\n\n Block node to search.\n Text snippet to locate.\n\nMatched range or `null`.\n\n\n### `getEditorPrompt`\n\nGenerates prompts that respect cursor, selection, or block selection states.\n\n\n\n Editor providing context.\n String, config, or function describing the prompt.\n\nContextualized prompt string.\n\n\n### `replacePlaceholders`\n\nReplaces placeholders like `{editor}`, `{blockSelection}`, and `{prompt}` with serialized Markdown.\n\n\n\n Editor providing content.\n Template text.\n Prompt value injected into `{prompt}`.\n\nTemplate with placeholders replaced by Markdown.\n\n\n## Plugins\n\n### `AIPlugin`\n\nAdds an `ai` mark to streamed text and exposes transforms to remove AI nodes or undo the last AI batch. Use `.withComponent` to render AI-marked text with a custom component.\n\n\n \n AI content is stored on text nodes.\n AI marks are regular text properties, not decorations.\n \n\n\n### `AIChatPlugin`\n\nMain plugin that powers the AI menu, chat state, and transforms.\n\n\n \n Character(s) that open the command menu. Defaults to `' '`.\n Pattern that must match the character before the trigger. Defaults to `/^\\s?$/`.\n boolean\" optional>Return `false` to cancel opening in specific contexts.\n Store helpers from `useChat` so API calls can access them.\n Snapshot of nodes used to diff edit suggestions (managed internally).\n Selection captured before submitting a prompt (managed internally).\n Controls whether responses stream directly into the document or open a review panel. Defaults to `'insert'`.\n Whether the AI menu is visible. Defaults to `false`.\n True while a response is streaming. Defaults to `false`.\n Active tool used to interpret the response.\n \n\n\n## API\n\n### `api.aiChat.submit(input, options?)`\n\nSubmits a prompt to your model provider. When `mode` is omitted it defaults to `'insert'` for a collapsed cursor and `'chat'` otherwise.\n\n\n\n Raw input from the user.\n Fine-tune submission behaviour.\n\n\n Override the response mode.\n Forwarded to `chat.sendMessage` (model, headers, etc.).\n String, config, or function processed by `getEditorPrompt`.\n Tags the submission so hooks can react differently.\n\n\n\n### `api.aiChat.reset(options?)`\n\nClears chat state, removes AI nodes, and optionally undoes the last AI batch.\n\n\n\n Pass `undo: false` to keep streamed content.\n\n\n\n### `api.aiChat.node(options?)`\n\nRetrieves the first AI node that matches the specified criteria.\n\n\n\n Set `anchor: true` to get the anchor node or `streaming: true` to retrieve the node currently being streamed into.\n\nMatching node entry, if found.\n\n\n### `api.aiChat.reload()`\n\nReplays the last prompt using the stored `UseChatHelpers`, restoring the original selection or block selection before resubmitting.\n\n### `api.aiChat.stop()`\n\nStops streaming and calls `chat.stop`.\n\n### `api.aiChat.show()`\n\nOpens the AI menu, clears previous chat messages, and resets tool state.\n\n### `api.aiChat.hide(options?)`\n\nCloses the AI menu, optionally undoing the last AI batch and refocusing the editor.\n\n\n\n Set `focus: false` to keep focus outside the editor or `undo: false` to preserve inserted content.\n\n\n\n## Transforms\n\n### `tf.aiChat.accept()`\n\nAccepts the latest response. In insert mode it removes AI marks and places the caret at the end of the streamed content. In chat mode it applies the pending suggestions.\n\n### `tf.aiChat.insertBelow(sourceEditor, options?)`\n\nInserts the chat preview (`sourceEditor`) below the current selection or block selection.\n\n\n\n Editor containing the generated content.\n Copy formatting from the source selection. Defaults to `'single'`.\n\n\n\n### `tf.aiChat.replaceSelection(sourceEditor, options?)`\n\nReplaces the current selection or block selection with the chat preview.\n\n\n\n Editor containing the generated content.\n Controls how much formatting from the original selection should be applied.\n\n\n\n### `tf.aiChat.removeAnchor(options?)`\n\nRemoves the temporary anchor node used to position the AI menu.\n\n\n\n Filters the nodes to remove.\n\n\n\n### `tf.ai.insertNodes(nodes, options?)`\n\nInserts nodes tagged with the AI mark at the current selection (or `options.target`).\n\n### `tf.ai.removeMarks(options?)`\n\nClears the AI mark from matching nodes.\n\n### `tf.ai.removeNodes(options?)`\n\nRemoves text nodes that are marked as AI-generated.\n\n### `tf.ai.undo()`\n\nUndoes the latest AI history entry when it was created by `withAIBatch`. When insert-mode preview streaming used `captureAIStreamSnapshot`, it restores that snapshot instead of replaying every streamed chunk. In both cases it avoids re-applying AI output from redo.\n\n## Customization\n\n### Adding Custom AI Commands\n\n\n\nExtend the `aiChatItems` map to add new commands. Each command receives `{ aiEditor, editor, input }` and can dispatch `api.aiChat.submit` with custom prompts or transforms.\n\n#### Simple Custom Command\n\n```tsx\nsummarizeInBullets: {\n icon: ,\n label: 'Summarize in bullets',\n value: 'summarizeInBullets',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit('', {\n prompt: 'Summarize the current selection using bullet points',\n toolName: 'generate',\n });\n },\n},\n```\n\n#### Command with Complex Logic\n\n```tsx\ngenerateTOC: {\n icon: ,\n label: 'Generate table of contents',\n value: 'generateTOC',\n onSelect: ({ editor }) => {\n const headings = editor.api.nodes({\n match: (n) => ['h1', 'h2', 'h3'].includes(n.type as string),\n });\n\n const prompt =\n headings.length === 0\n ? 'Create a realistic table of contents for this document'\n : 'Generate a table of contents that reflects the existing headings';\n\n void editor.getApi(AIChatPlugin).aiChat.submit('', {\n mode: 'insert',\n prompt,\n toolName: 'generate',\n });\n },\n},\n```\n\nThe menu automatically switches between command and suggestion states:\n\n- `cursorCommand`: Cursor is collapsed and no response yet.\n- `selectionCommand`: Text is selected and no response yet.\n- `cursorSuggestion` / `selectionSuggestion`: A response exists, so actions like Accept, Try Again, or Insert Below are shown.\n\nUse `toolName` (`'generate' | 'edit' | 'comment'`) to control how streaming hooks process the response. For example, `'edit'` enables diff-based suggestions, and `'comment'` allows you to convert streamed comments into discussion threads with `aiCommentToRange`.\n", "type": "registry:file", "target": "content/docs/plate/(plugins)/(ai)/ai.mdx" } diff --git a/apps/www/public/r/ai-kit.json b/apps/www/public/r/ai-kit.json index 09e2c45778..4c2d06832d 100644 --- a/apps/www/public/r/ai-kit.json +++ b/apps/www/public/r/ai-kit.json @@ -16,7 +16,7 @@ "files": [ { "path": "src/registry/components/editor/plugins/ai-kit.tsx", - "content": "'use client';\n\nimport { withAIBatch } from '@platejs/ai';\nimport {\n AIChatPlugin,\n AIPlugin,\n applyAISuggestions,\n streamInsertChunk,\n useChatChunk,\n} from '@platejs/ai/react';\nimport { getPluginType, KEYS, PathApi } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nimport { AILoadingBar, AIMenu } from '@/registry/ui/ai-menu';\nimport { AIAnchorElement, AILeaf } from '@/registry/ui/ai-node';\n\nimport { useChat } from '../use-chat';\nimport { CursorOverlayKit } from './cursor-overlay-kit';\nimport { MarkdownKit } from './markdown-kit';\n\nexport const aiChatPlugin = AIChatPlugin.extend({\n options: {\n chatOptions: {\n api: '/api/ai/command',\n body: {},\n },\n },\n render: {\n afterContainer: AILoadingBar,\n afterEditable: AIMenu,\n node: AIAnchorElement,\n },\n shortcuts: { show: { keys: 'mod+j' } },\n useHooks: ({ editor, getOption }) => {\n useChat();\n\n const mode = usePluginOption(AIChatPlugin, 'mode');\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n useChatChunk({\n onChunk: ({ chunk, isFirst, nodes, text: content }) => {\n if (isFirst && mode === 'insert') {\n editor.tf.withoutSaving(() => {\n editor.tf.insertNodes(\n {\n children: [{ text: '' }],\n type: getPluginType(editor, KEYS.aiChat),\n },\n {\n at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),\n }\n );\n });\n editor.setOption(AIChatPlugin, 'streaming', true);\n }\n\n if (mode === 'insert' && nodes.length > 0) {\n withAIBatch(\n editor,\n () => {\n if (!getOption('streaming')) return;\n editor.tf.withScrolling(() => {\n streamInsertChunk(editor, chunk, {\n textProps: {\n [getPluginType(editor, KEYS.ai)]: true,\n },\n });\n });\n },\n { split: isFirst }\n );\n }\n\n if (toolName === 'edit' && mode === 'chat') {\n withAIBatch(\n editor,\n () => {\n applyAISuggestions(editor, content);\n },\n {\n split: isFirst,\n }\n );\n }\n },\n onFinish: () => {\n editor.setOption(AIChatPlugin, 'streaming', false);\n editor.setOption(AIChatPlugin, '_blockChunks', '');\n editor.setOption(AIChatPlugin, '_blockPath', null);\n editor.setOption(AIChatPlugin, '_mdxName', null);\n },\n });\n },\n});\n\nexport const AIKit = [\n ...CursorOverlayKit,\n ...MarkdownKit,\n AIPlugin.withComponent(AILeaf),\n aiChatPlugin,\n];\n", + "content": "'use client';\n\nimport { captureAIStreamSnapshot, withAIBatch } from '@platejs/ai';\nimport {\n AIChatPlugin,\n AIPlugin,\n applyAISuggestions,\n streamInsertChunk,\n useChatChunk,\n} from '@platejs/ai/react';\nimport { getPluginType, KEYS, PathApi } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nimport { AILoadingBar, AIMenu } from '@/registry/ui/ai-menu';\nimport { AIAnchorElement, AILeaf } from '@/registry/ui/ai-node';\n\nimport { useChat } from '../use-chat';\nimport { CursorOverlayKit } from './cursor-overlay-kit';\nimport { MarkdownKit } from './markdown-kit';\n\nexport const aiChatPlugin = AIChatPlugin.extend({\n options: {\n chatOptions: {\n api: '/api/ai/command',\n body: {},\n },\n },\n render: {\n afterContainer: AILoadingBar,\n afterEditable: AIMenu,\n node: AIAnchorElement,\n },\n shortcuts: { show: { keys: 'mod+j' } },\n useHooks: ({ editor, getOption }) => {\n useChat();\n\n const mode = usePluginOption(AIChatPlugin, 'mode');\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n useChatChunk({\n onChunk: ({ chunk, isFirst, nodes, text: content }) => {\n if (isFirst && mode === 'insert') {\n captureAIStreamSnapshot(editor);\n\n editor.tf.withoutSaving(() => {\n editor.tf.insertNodes(\n {\n children: [{ text: '' }],\n type: getPluginType(editor, KEYS.aiChat),\n },\n {\n at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),\n }\n );\n });\n editor.setOption(AIChatPlugin, 'streaming', true);\n }\n\n if (mode === 'insert' && nodes.length > 0) {\n editor.tf.withoutSaving(() => {\n if (!getOption('streaming')) return;\n\n editor.tf.withScrolling(() => {\n streamInsertChunk(editor, chunk, {\n textProps: {\n [getPluginType(editor, KEYS.ai)]: true,\n },\n });\n });\n });\n }\n\n if (toolName === 'edit' && mode === 'chat') {\n withAIBatch(\n editor,\n () => {\n applyAISuggestions(editor, content);\n },\n {\n split: isFirst,\n }\n );\n }\n },\n onFinish: () => {\n editor.setOption(AIChatPlugin, 'streaming', false);\n editor.setOption(AIChatPlugin, '_blockChunks', '');\n editor.setOption(AIChatPlugin, '_blockPath', null);\n editor.setOption(AIChatPlugin, '_mdxName', null);\n },\n });\n },\n});\n\nexport const AIKit = [\n ...CursorOverlayKit,\n ...MarkdownKit,\n AIPlugin.withComponent(AILeaf),\n aiChatPlugin,\n];\n", "type": "registry:component" } ] diff --git a/apps/www/src/__tests__/package-integration/ai-chat-streaming/streamHistory.slow.tsx b/apps/www/src/__tests__/package-integration/ai-chat-streaming/streamHistory.slow.tsx new file mode 100644 index 0000000000..2d3d0f7827 --- /dev/null +++ b/apps/www/src/__tests__/package-integration/ai-chat-streaming/streamHistory.slow.tsx @@ -0,0 +1,92 @@ +import { ElementApi, KEYS, PathApi, getPluginType } from 'platejs'; + +import { AIPlugin } from '../../../../../../packages/ai/src/react/ai/AIPlugin'; +import { AIChatPlugin } from '../../../../../../packages/ai/src/react/ai-chat/AIChatPlugin'; +import { streamInsertChunk } from '../../../../../../packages/ai/src/react/ai-chat/streaming/streamInsertChunk'; +import { acceptAIChat } from '../../../../../../packages/ai/src/react/ai-chat/transforms/acceptAIChat'; +import { captureAIStreamSnapshot } from '../../../../../../packages/ai/src/lib/transforms/aiStreamSnapshot'; +import { createTestEditor } from './__tests__/createTestEditor'; + +const streamPreview = (chunks: string[]) => { + const { editor } = createTestEditor(); + const initialValue = JSON.parse(JSON.stringify(editor.children)); + + editor.setOption(AIChatPlugin, 'mode', 'insert'); + editor.setOption(AIChatPlugin, 'open', true); + + captureAIStreamSnapshot(editor); + + editor.tf.withoutSaving(() => { + editor.tf.insertNodes( + { + children: [{ text: '' }], + type: getPluginType(editor, KEYS.aiChat), + }, + { + at: PathApi.next(editor.selection!.focus.path.slice(0, 1)), + } + ); + }); + + editor.setOption(AIChatPlugin, 'streaming', true); + + for (const chunk of chunks) { + editor.tf.withoutSaving(() => { + streamInsertChunk(editor, chunk, { + textProps: { + [getPluginType(editor, KEYS.ai)]: true, + }, + }); + }); + } + + editor.setOption(AIChatPlugin, 'streaming', false); + editor.setOption(AIChatPlugin, '_blockChunks', ''); + editor.setOption(AIChatPlugin, '_blockPath', null); + editor.setOption(AIChatPlugin, '_mdxName', null); + + return { editor, initialValue }; +}; + +describe('ai chat streaming history', () => { + it('keeps insert-mode preview out of history and restores the snapshot on ai undo', () => { + const { editor, initialValue } = streamPreview(['hello', ' world']); + + expect(editor.history.undos).toHaveLength(0); + + editor.getTransforms(AIPlugin).ai.undo(); + + expect(editor.children).toEqual(initialValue); + expect(editor.history.undos).toHaveLength(0); + }); + + it('accepts streamed preview as a compact undoable batch', () => { + const chunks = Array.from({ length: 40 }, () => 'chunk '); + const { editor, initialValue } = streamPreview(chunks); + + acceptAIChat(editor); + + expect(editor.history.undos).toHaveLength(1); + expect(editor.history.undos[0].operations.length).toBeLessThan( + chunks.length + ); + expect( + editor.api.some({ + at: [], + match: (n: any) => + ElementApi.isElement(n) && + n.type === getPluginType(editor, KEYS.aiChat), + }) + ).toBe(false); + expect( + editor.api.some({ + at: [], + match: (n: any) => !!n[getPluginType(editor, KEYS.ai)], + }) + ).toBe(false); + + editor.undo(); + + expect(editor.children).toEqual(initialValue); + }); +}); diff --git a/apps/www/src/registry/components/editor/plugins/ai-kit.tsx b/apps/www/src/registry/components/editor/plugins/ai-kit.tsx index f859e04d15..fbd87f7363 100644 --- a/apps/www/src/registry/components/editor/plugins/ai-kit.tsx +++ b/apps/www/src/registry/components/editor/plugins/ai-kit.tsx @@ -1,6 +1,6 @@ 'use client'; -import { withAIBatch } from '@platejs/ai'; +import { captureAIStreamSnapshot, withAIBatch } from '@platejs/ai'; import { AIChatPlugin, AIPlugin, @@ -39,6 +39,8 @@ export const aiChatPlugin = AIChatPlugin.extend({ useChatChunk({ onChunk: ({ chunk, isFirst, nodes, text: content }) => { if (isFirst && mode === 'insert') { + captureAIStreamSnapshot(editor); + editor.tf.withoutSaving(() => { editor.tf.insertNodes( { @@ -54,20 +56,17 @@ export const aiChatPlugin = AIChatPlugin.extend({ } if (mode === 'insert' && nodes.length > 0) { - withAIBatch( - editor, - () => { - if (!getOption('streaming')) return; - editor.tf.withScrolling(() => { - streamInsertChunk(editor, chunk, { - textProps: { - [getPluginType(editor, KEYS.ai)]: true, - }, - }); + editor.tf.withoutSaving(() => { + if (!getOption('streaming')) return; + + editor.tf.withScrolling(() => { + streamInsertChunk(editor, chunk, { + textProps: { + [getPluginType(editor, KEYS.ai)]: true, + }, }); - }, - { split: isFirst } - ); + }); + }); } if (toolName === 'edit' && mode === 'chat') { diff --git a/docs/(plugins)/(ai)/ai.cn.mdx b/docs/(plugins)/(ai)/ai.cn.mdx index dd2ee7e667..e1eff54f09 100644 --- a/docs/(plugins)/(ai)/ai.cn.mdx +++ b/docs/(plugins)/(ai)/ai.cn.mdx @@ -14,7 +14,7 @@ docs: - **上下文感知命令菜单**,可适应光标、文本选择和块选择工作流。 - **流式 Markdown/MDX 插入**,支持表格、列和代码块,由 `streamInsertChunk` 驱动。 -- **插入和聊天审查模式**,通过 `withAIBatch` 和 `tf.ai.undo()` 实现撤销安全批处理。 +- **插入和聊天审查模式**,通过基于快照的插入预览以及 `withAIBatch` 和 `tf.ai.undo()` 实现撤销安全批处理。 - **块选择感知变换**,使用 `tf.aiChat.replaceSelection` 和 `tf.aiChat.insertBelow` 替换或追加整个部分。 - **与 `@ai-sdk/react` 直接集成**,使 `api.aiChat.submit` 可以从 Vercel AI SDK 助手流式传输响应。 - **建议和评论工具**,可对 AI 编辑进行差异比较、接受/拒绝更改,并将 AI 反馈映射回文档范围。 @@ -109,7 +109,7 @@ export const editor = createPlateEditor({ ```tsx import { AIChatPlugin, applyAISuggestions, streamInsertChunk, useChatChunk } from '@platejs/ai/react'; -import { withAIBatch } from '@platejs/ai'; +import { captureAIStreamSnapshot, withAIBatch } from '@platejs/ai'; import { getPluginType, KEYS, PathApi } from 'platejs'; import { usePluginOption } from 'platejs/react'; @@ -132,32 +132,33 @@ export const aiChatPlugin = AIChatPlugin.extend({ onChunk: ({ chunk, isFirst, text }) => { if (mode === 'insert') { if (isFirst) { + captureAIStreamSnapshot(editor); editor.setOption(AIChatPlugin, 'streaming', true); - editor.tf.insertNodes( - { - children: [{ text: '' }], - type: getPluginType(editor, KEYS.aiChat), - }, - { - at: PathApi.next(editor.selection!.focus.path.slice(0, 1)), - } - ); + editor.tf.withoutSaving(() => { + editor.tf.insertNodes( + { + children: [{ text: '' }], + type: getPluginType(editor, KEYS.aiChat), + }, + { + at: PathApi.next(editor.selection!.focus.path.slice(0, 1)), + } + ); + }); } - if (!getOption('streaming')) return; + editor.tf.withoutSaving(() => { + if (!getOption('streaming')) return; - withAIBatch( - editor, - () => { + editor.tf.withScrolling(() => { streamInsertChunk(editor, chunk, { textProps: { [getPluginType(editor, KEYS.ai)]: true, }, }); - }, - { split: isFirst } - ); + }); + }); } if (toolName === 'edit' && mode === 'chat') { @@ -182,9 +183,10 @@ export const aiChatPlugin = AIChatPlugin.extend({ ``` - `useChatChunk`:监视 `UseChatHelpers` 状态并生成增量块。 +- `captureAIStreamSnapshot`:保存流式开始前的编辑器状态,使 `tf.ai.undo()` 可以直接丢弃预览内容,而不必回放每个流式块。 - `streamInsertChunk`:将 Markdown/MDX 流式传输到文档中,尽可能重用现有块。 - `applyAISuggestions`:当 `toolName === 'edit'` 时,将响应转换为临时建议节点。 -- `withAIBatch`:标记历史批次,使 `tf.ai.undo()` 仅还原最后一次 AI 生成的更改。 +- `withAIBatch`:标记已保存的 AI 批次,使建议审查和已接受的 AI 更改保持可撤销。 扩展插件时,请提供您自己的 `render` 组件(工具栏按钮、浮动菜单等)。 @@ -416,6 +418,18 @@ useAIChatEditor(aiPreviewEditor, responseMarkdown, { ## 工具函数 +### `captureAIStreamSnapshot` + +在插入模式开始流式传输前捕获当前编辑器状态,使 `tf.ai.undo()` 可以直接丢弃预览内容,而不必回放每个流式块。 + + + + 目标编辑器。 + 可选,自定义要存储的快照,而不是当前编辑器状态。 + +已存储的快照。 + + ### `withAIBatch` 将编辑器操作分组到单个历史批次中,并将其标记为 AI 生成,以便 `tf.ai.undo()` 安全地移除它。 @@ -639,7 +653,7 @@ useAIChatEditor(aiPreviewEditor, responseMarkdown, { ### `tf.ai.undo()` -如果最新的历史条目是由 `withAIBatch` 创建的并包含 AI 内容,则撤销它。清除配对的重做条目以避免重新应用 AI 输出。 +如果最新的 AI 历史条目由 `withAIBatch` 创建,则撤销它。若插入模式预览流使用了 `captureAIStreamSnapshot`,则直接恢复该快照,而不是回放每个流式块。两种情况下都会避免通过重做重新应用 AI 输出。 ## 自定义 diff --git a/docs/(plugins)/(ai)/ai.mdx b/docs/(plugins)/(ai)/ai.mdx index c38856bb68..aa261d32b3 100644 --- a/docs/(plugins)/(ai)/ai.mdx +++ b/docs/(plugins)/(ai)/ai.mdx @@ -14,7 +14,7 @@ docs: - **Context-aware command menu** that adapts to cursor, text selection, and block selection workflows. - **Streaming Markdown/MDX insertion** with table, column, and code block support powered by `streamInsertChunk`. -- **Insert and chat review modes** with undo-safe batching via `withAIBatch` and `tf.ai.undo()`. +- **Insert and chat review modes** with snapshot-based insert previews plus undo-safe batching via `withAIBatch` and `tf.ai.undo()`. - **Block selection aware transforms** to replace or append entire sections using `tf.aiChat.replaceSelection` and `tf.aiChat.insertBelow`. - **Direct integration with `@ai-sdk/react`** so `api.aiChat.submit` can stream responses from Vercel AI SDK helpers. - **Suggestion and comment utilities** that diff AI edits, accept/reject changes, and map AI feedback back to document ranges. @@ -109,7 +109,7 @@ Extend `AIChatPlugin` to hook streaming and edits. The example mirrors the core ```tsx import { AIChatPlugin, applyAISuggestions, streamInsertChunk, useChatChunk } from '@platejs/ai/react'; -import { withAIBatch } from '@platejs/ai'; +import { captureAIStreamSnapshot, withAIBatch } from '@platejs/ai'; import { getPluginType, KEYS, PathApi } from 'platejs'; import { usePluginOption } from 'platejs/react'; @@ -132,32 +132,33 @@ export const aiChatPlugin = AIChatPlugin.extend({ onChunk: ({ chunk, isFirst, text }) => { if (mode === 'insert') { if (isFirst) { + captureAIStreamSnapshot(editor); editor.setOption(AIChatPlugin, 'streaming', true); - editor.tf.insertNodes( - { - children: [{ text: '' }], - type: getPluginType(editor, KEYS.aiChat), - }, - { - at: PathApi.next(editor.selection!.focus.path.slice(0, 1)), - } - ); + editor.tf.withoutSaving(() => { + editor.tf.insertNodes( + { + children: [{ text: '' }], + type: getPluginType(editor, KEYS.aiChat), + }, + { + at: PathApi.next(editor.selection!.focus.path.slice(0, 1)), + } + ); + }); } - if (!getOption('streaming')) return; + editor.tf.withoutSaving(() => { + if (!getOption('streaming')) return; - withAIBatch( - editor, - () => { + editor.tf.withScrolling(() => { streamInsertChunk(editor, chunk, { textProps: { [getPluginType(editor, KEYS.ai)]: true, }, }); - }, - { split: isFirst } - ); + }); + }); } if (toolName === 'edit' && mode === 'chat') { @@ -182,9 +183,10 @@ export const aiChatPlugin = AIChatPlugin.extend({ ``` - `useChatChunk`: Watches `UseChatHelpers` status and yields incremental chunks. +- `captureAIStreamSnapshot`: Stores the pre-stream editor state so `tf.ai.undo()` can discard preview content without replaying every streamed chunk. - `streamInsertChunk`: Streams Markdown/MDX into the document, reusing the existing block when possible. - `applyAISuggestions`: Converts responses into transient suggestion nodes when `toolName === 'edit'`. -- `withAIBatch`: Marks history batches so `tf.ai.undo()` only reverts the last AI-generated change. +- `withAIBatch`: Marks saved AI batches so suggestion review and accepted AI changes stay undo-safe. Provide your own `render` components (toolbar button, floating menu, etc.) when you extend the plugin. @@ -416,6 +418,18 @@ Streams chat responses chunk-by-chunk and gives you full control over insertion. ## Utilities +### `captureAIStreamSnapshot` + +Captures the current editor state before insert-mode streaming so `tf.ai.undo()` can discard preview content without replaying every streamed chunk. + + + + Target editor. + Custom snapshot to store instead of the current editor state. + +Stored snapshot. + + ### `withAIBatch` Groups editor operations into a single history batch and flags it as AI-generated so `tf.ai.undo()` removes it safely. @@ -639,7 +653,7 @@ Removes text nodes that are marked as AI-generated. ### `tf.ai.undo()` -Undoes the latest history entry if it was created by `withAIBatch` and contained AI content. Clears the paired redo entry to avoid re-applying AI output. +Undoes the latest AI history entry when it was created by `withAIBatch`. When insert-mode preview streaming used `captureAIStreamSnapshot`, it restores that snapshot instead of replaying every streamed chunk. In both cases it avoids re-applying AI output from redo. ## Customization diff --git a/packages/ai/src/lib/transforms/aiStreamSnapshot.ts b/packages/ai/src/lib/transforms/aiStreamSnapshot.ts new file mode 100644 index 0000000000..94dc2b4759 --- /dev/null +++ b/packages/ai/src/lib/transforms/aiStreamSnapshot.ts @@ -0,0 +1,58 @@ +import cloneDeep from 'lodash/cloneDeep.js'; +import type { SlateEditor, TRange, Value } from 'platejs'; + +type AIStreamSnapshot = { + children: Value; + selection: TRange | null; +}; + +const AI_STREAM_SNAPSHOT = new WeakMap(); + +export const captureAIStreamSnapshot = ( + editor: SlateEditor, + snapshot: AIStreamSnapshot = { + children: cloneDeep(editor.children), + selection: cloneDeep(editor.selection), + } +) => { + AI_STREAM_SNAPSHOT.set(editor, snapshot); + + return snapshot; +}; + +export const clearAIStreamSnapshot = (editor: SlateEditor) => { + AI_STREAM_SNAPSHOT.delete(editor); +}; + +export const getAIStreamSnapshot = (editor: SlateEditor) => + AI_STREAM_SNAPSHOT.get(editor); + +export const restoreAIStreamSnapshot = (editor: SlateEditor) => { + const snapshot = getAIStreamSnapshot(editor); + + if (!snapshot) return false; + + editor.tf.withoutSaving(() => { + editor.tf.setValue(cloneDeep(snapshot.children)); + + if (snapshot.selection) { + editor.tf.setSelection(cloneDeep(snapshot.selection)); + } else { + editor.tf.deselect(); + } + }); + + clearAIStreamSnapshot(editor); + + return true; +}; + +export const commitAIStreamValue = (editor: SlateEditor, value: Value) => { + if (!restoreAIStreamSnapshot(editor)) return false; + + editor.tf.withNewBatch(() => { + editor.tf.setValue(cloneDeep(value)); + }); + + return true; +}; diff --git a/packages/ai/src/lib/transforms/index.ts b/packages/ai/src/lib/transforms/index.ts index e8489a6ecb..4b09f16ffc 100644 --- a/packages/ai/src/lib/transforms/index.ts +++ b/packages/ai/src/lib/transforms/index.ts @@ -3,6 +3,7 @@ */ export * from './insertAINodes'; +export * from './aiStreamSnapshot'; export * from './removeAIMarks'; export * from './removeAINodes'; export * from './undoAI'; diff --git a/packages/ai/src/lib/transforms/undoAI.ts b/packages/ai/src/lib/transforms/undoAI.ts index c719def057..5ac825e2b3 100644 --- a/packages/ai/src/lib/transforms/undoAI.ts +++ b/packages/ai/src/lib/transforms/undoAI.ts @@ -2,6 +2,8 @@ import type { SlateEditor } from 'platejs'; import { getTransientSuggestionKey } from '@platejs/suggestion'; +import { restoreAIStreamSnapshot } from './aiStreamSnapshot'; + export const undoAI = (editor: SlateEditor) => { const hasAINodeOrAISuggestion = editor.api.some({ @@ -16,5 +18,11 @@ export const undoAI = (editor: SlateEditor) => { if ((editor.history.undos.at(-1) as any)?.ai && hasAINodeOrAISuggestion) { editor.undo(); editor.history.redos.pop(); + + return; + } + + if (hasAINodeOrAISuggestion) { + restoreAIStreamSnapshot(editor); } }; diff --git a/packages/ai/src/react/ai-chat/transforms/acceptAIChat.ts b/packages/ai/src/react/ai-chat/transforms/acceptAIChat.ts index 0a3929bc02..d08e78cd13 100644 --- a/packages/ai/src/react/ai-chat/transforms/acceptAIChat.ts +++ b/packages/ai/src/react/ai-chat/transforms/acceptAIChat.ts @@ -1,11 +1,42 @@ -import { KEYS } from 'platejs'; +import cloneDeep from 'lodash/cloneDeep.js'; +import { ElementApi, KEYS, TextApi, getPluginType } from 'platejs'; import { type PlateEditor, getEditorPlugin } from 'platejs/react'; -import { withAIBatch } from '../../../lib'; +import { commitAIStreamValue, withAIBatch } from '../../../lib'; import { AIPlugin } from '../../ai/AIPlugin'; import { type AIChatPluginConfig, AIChatPlugin } from '../AIChatPlugin'; import { acceptAISuggestions } from '../utils/acceptAISuggestions'; +const getAcceptedInsertValue = (editor: PlateEditor) => { + const aiChatType = getPluginType(editor, KEYS.aiChat); + const aiType = getPluginType(editor, KEYS.ai); + + const stripTracking = (node: any): any | null => { + if (ElementApi.isElement(node) && node.type === aiChatType) { + return null; + } + + if (TextApi.isText(node)) { + const { [aiType]: _ai, ...rest } = node; + + return rest; + } + + if (!node.children) return node; + + return { + ...node, + children: node.children + .map((child: any) => stripTracking(child)) + .filter(Boolean), + }; + }; + + return cloneDeep(editor.children) + .map((node) => stripTracking(node)) + .filter(Boolean); +}; + export const acceptAIChat = (editor: PlateEditor) => { const mode = editor.getOption(AIChatPlugin, 'mode'); @@ -15,10 +46,12 @@ export const acceptAIChat = (editor: PlateEditor) => { const lastAINodePath = api.aiChat.node({ at: [], reverse: true })![1]; - withAIBatch(editor, () => { - tf.ai.removeMarks(); - editor.getTransforms(AIChatPlugin).aiChat.removeAnchor(); - }); + if (!commitAIStreamValue(editor, getAcceptedInsertValue(editor))) { + withAIBatch(editor, () => { + tf.ai.removeMarks(); + editor.getTransforms(AIChatPlugin).aiChat.removeAnchor(); + }); + } api.aiChat.hide(); editor.tf.focus(); diff --git a/packages/ai/src/react/ai-chat/utils/resetAIChat.ts b/packages/ai/src/react/ai-chat/utils/resetAIChat.ts index d4184149cc..7ee7dac35b 100644 --- a/packages/ai/src/react/ai-chat/utils/resetAIChat.ts +++ b/packages/ai/src/react/ai-chat/utils/resetAIChat.ts @@ -1,6 +1,7 @@ import { KEYS } from 'platejs'; import { type PlateEditor, getEditorPlugin } from 'platejs/react'; +import { clearAIStreamSnapshot } from '../../../lib/transforms/aiStreamSnapshot'; import type { AIChatPluginConfig } from '../AIChatPlugin'; import { AIPlugin } from '../../ai/AIPlugin'; @@ -34,4 +35,6 @@ export const resetAIChat = ( if (undo) { editor.getTransforms(AIPlugin).ai.undo(); } + + clearAIStreamSnapshot(editor); }; diff --git a/tmp-issue-4900-editor-ai.png b/tmp-issue-4900-editor-ai.png new file mode 100644 index 0000000000000000000000000000000000000000..b5084557c1ae49e0e8615262641d1269050b2c63 GIT binary patch literal 138532 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%0D1Te@IAFH1n$L#x?pbN=c6EepKf$uu3eR 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 diff --git a/tmp-pr-4902-editor-ai.png b/tmp-pr-4902-editor-ai.png deleted file mode 100644 index 28bcf02630a1f1ce3d59b796e238520659916d5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138132 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 LXe+-~v Date: Thu, 26 Mar 2026 21:29:31 +0100 Subject: [PATCH 5/9] Localize AI preview rollback and stabilize chat spec mocks --- packages/ai/src/lib/transforms/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ai/src/lib/transforms/index.ts b/packages/ai/src/lib/transforms/index.ts index e8489a6ecb..7acb350c5c 100644 --- a/packages/ai/src/lib/transforms/index.ts +++ b/packages/ai/src/lib/transforms/index.ts @@ -2,6 +2,7 @@ * @file Automatically generated by barrelsby. */ +export * from './aiStreamSnapshot'; export * from './insertAINodes'; export * from './removeAIMarks'; export * from './removeAINodes'; From 1f8d303333b9b73887a853d28201e2f224b459e3 Mon Sep 17 00:00:00 2001 From: zbeyens Date: Thu, 26 Mar 2026 21:39:19 +0100 Subject: [PATCH 6/9] docs: sync ai preview api --- .changeset/ai-preview-history.md | 5 + .changeset/slate-redo-selection.md | 5 + apps/www/public/r/ai-docs.json | 2 +- apps/www/public/r/ai-kit.json | 2 +- .../public/r/components-changelog-docs.json | 2 +- docs/(plugins)/(ai)/ai.cn.mdx | 119 ++++++++++++------ docs/(plugins)/(ai)/ai.mdx | 119 ++++++++++++------ docs/components/changelog.mdx | 3 + 8 files changed, 184 insertions(+), 73 deletions(-) create mode 100644 .changeset/ai-preview-history.md create mode 100644 .changeset/slate-redo-selection.md diff --git a/.changeset/ai-preview-history.md b/.changeset/ai-preview-history.md new file mode 100644 index 0000000000..b2503d6bad --- /dev/null +++ b/.changeset/ai-preview-history.md @@ -0,0 +1,5 @@ +--- +"@platejs/ai": patch +--- + +Fix insert-mode AI preview history so streamed chunks stay out of undo history and selection survives accept, undo, and redo diff --git a/.changeset/slate-redo-selection.md b/.changeset/slate-redo-selection.md new file mode 100644 index 0000000000..c919d06613 --- /dev/null +++ b/.changeset/slate-redo-selection.md @@ -0,0 +1,5 @@ +--- +"@platejs/slate": patch +--- + +Fix redo to restore selection after undoing history batches that clear the active selection diff --git a/apps/www/public/r/ai-docs.json b/apps/www/public/r/ai-docs.json index 9684ab68b3..9102c0d912 100644 --- a/apps/www/public/r/ai-docs.json +++ b/apps/www/public/r/ai-docs.json @@ -7,7 +7,7 @@ "files": [ { "path": "../../docs/(plugins)/(ai)/ai.mdx", - "content": "---\ntitle: AI\ndescription: AI-powered writing assistance.\ndocs:\n - route: https://pro.platejs.org/docs/examples/ai\n title: Plus\n---\n\n\n\n\n\n## Features\n\n- **Context-aware command menu** that adapts to cursor, text selection, and block selection workflows.\n- **Streaming Markdown/MDX insertion** with table, column, and code block support powered by `streamInsertChunk`.\n- **Insert and chat review modes** with snapshot-based insert previews plus undo-safe batching via `withAIBatch` and `tf.ai.undo()`.\n- **Block selection aware transforms** to replace or append entire sections using `tf.aiChat.replaceSelection` and `tf.aiChat.insertBelow`.\n- **Direct integration with `@ai-sdk/react`** so `api.aiChat.submit` can stream responses from Vercel AI SDK helpers.\n- **Suggestion and comment utilities** that diff AI edits, accept/reject changes, and map AI feedback back to document ranges.\n\n\n\n## Kit Usage\n\n\n\n### Installation\n\nThe fastest way to add AI functionality is with the `AIKit`. It ships the configured `AIPlugin`, `AIChatPlugin`, Markdown streaming helpers, cursor overlay, and their [Plate UI](/docs/installation/plate-ui) components.\n\n\n\n- [`AIMenu`](/docs/components/ai-menu): Floating command surface for prompts, tool shortcuts, and chat review.\n- [`AILoadingBar`](/docs/components/ai-loading-bar): Displays streaming status at the editor container.\n- [`AIAnchorElement`](/docs/components/ai-anchor-element): Invisible anchor node used to position the floating menu during streaming.\n- [`AILeaf`](/docs/components/ai-leaf): Renders AI-marked text with subtle styling.\n\n### Add Kit\n\n```tsx\nimport { createPlateEditor } from 'platejs/react';\nimport { AIKit } from '@/components/editor/plugins/ai-kit';\n\nconst editor = createPlateEditor({\n plugins: [\n // ...otherPlugins,\n ...AIKit,\n ],\n});\n```\n\n### Add API Route\n\nExpose a streaming command endpoint that proxies your model provider:\n\n\n\n### Configure Environment\n\nSet your AI Gateway key locally (replace with your provider secret if you are not using a gateway):\n\n```bash title=\".env.local\"\nAI_GATEWAY_API_KEY=\"your-api-key\"\n```\n\n\n\n## Manual Usage\n\n\n\n### Installation\n\n```bash\nnpm install @platejs/ai @platejs/markdown @platejs/selection @ai-sdk/react ai\n```\n\n`@platejs/suggestion` is optional but required for diff-based edit suggestions.\n\n### Add Plugins\n\n```tsx\nimport { createPlateEditor } from 'platejs/react';\nimport { AIChatPlugin, AIPlugin } from '@platejs/ai/react';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { MarkdownPlugin } from '@platejs/markdown';\n\nexport const editor = createPlateEditor({\n plugins: [\n BlockSelectionPlugin,\n MarkdownPlugin,\n AIPlugin,\n AIChatPlugin, // extended in the next step\n ],\n});\n```\n\n- `BlockSelectionPlugin`: Enables multi-block selections that `AIChatPlugin` relies on for insert/replace transforms.\n- `MarkdownPlugin`: Provides Markdown serialization used by streaming utilities.\n- `AIPlugin`: Adds the AI mark and transforms for undoing AI batches.\n- `AIChatPlugin`: Supplies the AI combobox, API helpers, and transforms.\n\nUse `AIPlugin.withComponent` with your own element (or [`AILeaf`](/docs/components/ai-leaf)) to highlight AI-generated text.\n\n### Configure AIChatPlugin\n\nExtend `AIChatPlugin` to hook streaming and edits. The example mirrors the core logic from `AIKit` while keeping the UI headless.\n\n```tsx\nimport { AIChatPlugin, applyAISuggestions, streamInsertChunk, useChatChunk } from '@platejs/ai/react';\nimport { captureAIStreamSnapshot, withAIBatch } from '@platejs/ai';\nimport { getPluginType, KEYS, PathApi } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nexport const aiChatPlugin = AIChatPlugin.extend({\n options: {\n chatOptions: {\n api: '/api/ai/command',\n body: {\n model: 'openai/gpt-4o-mini',\n },\n },\n trigger: ' ',\n triggerPreviousCharPattern: /^\\s?$/,\n },\n useHooks: ({ editor, getOption }) => {\n const mode = usePluginOption(AIChatPlugin, 'mode');\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n\n useChatChunk({\n onChunk: ({ chunk, isFirst, text }) => {\n if (mode === 'insert') {\n if (isFirst) {\n captureAIStreamSnapshot(editor);\n editor.setOption(AIChatPlugin, 'streaming', true);\n\n editor.tf.withoutSaving(() => {\n editor.tf.insertNodes(\n {\n children: [{ text: '' }],\n type: getPluginType(editor, KEYS.aiChat),\n },\n {\n at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),\n }\n );\n });\n }\n\n editor.tf.withoutSaving(() => {\n if (!getOption('streaming')) return;\n\n editor.tf.withScrolling(() => {\n streamInsertChunk(editor, chunk, {\n textProps: {\n [getPluginType(editor, KEYS.ai)]: true,\n },\n });\n });\n });\n }\n\n if (toolName === 'edit' && mode === 'chat') {\n withAIBatch(\n editor,\n () => {\n applyAISuggestions(editor, text);\n },\n { split: isFirst }\n );\n }\n },\n onFinish: () => {\n editor.setOption(AIChatPlugin, 'streaming', false);\n editor.setOption(AIChatPlugin, '_blockChunks', '');\n editor.setOption(AIChatPlugin, '_blockPath', null);\n editor.setOption(AIChatPlugin, '_mdxName', null);\n },\n });\n },\n});\n```\n\n- `useChatChunk`: Watches `UseChatHelpers` status and yields incremental chunks.\n- `captureAIStreamSnapshot`: Stores the pre-stream editor state so `tf.ai.undo()` can discard preview content without replaying every streamed chunk.\n- `streamInsertChunk`: Streams Markdown/MDX into the document, reusing the existing block when possible.\n- `applyAISuggestions`: Converts responses into transient suggestion nodes when `toolName === 'edit'`.\n- `withAIBatch`: Marks saved AI batches so suggestion review and accepted AI changes stay undo-safe.\n\nProvide your own `render` components (toolbar button, floating menu, etc.) when you extend the plugin.\n\n### Build API Route\n\nHandle `api.aiChat.submit` requests on the server. Each request includes the chat `messages` from `@ai-sdk/react` and a `ctx` payload that contains the editor `children`, current `selection`, and last `toolName`.\n[Complete API example](https://github.com/udecode/plate-playground-template/blob/main/src/app/api/ai/command/route.ts)\n\n```ts title=\"app/api/ai/command/route.ts\"\nimport { createGateway } from '@ai-sdk/gateway';\nimport { convertToCoreMessages, streamText } from 'ai';\nimport { createSlateEditor } from 'platejs';\n\nimport { BaseEditorKit } from '@/registry/components/editor/editor-base-kit';\nimport { markdownJoinerTransform } from '@/registry/lib/markdown-joiner-transform';\n\nexport async function POST(req: Request) {\n const { apiKey, ctx, messages, model } = await req.json();\n\n const editor = createSlateEditor({\n plugins: BaseEditorKit,\n selection: ctx.selection,\n value: ctx.children,\n });\n\n const gateway = createGateway({\n apiKey: apiKey ?? process.env.AI_GATEWAY_API_KEY!,\n });\n\n const result = streamText({\n experimental_transform: markdownJoinerTransform(),\n messages: convertToCoreMessages(messages),\n model: gateway(model ?? 'openai/gpt-4o-mini'),\n system: ctx.toolName === 'edit' ? 'You are an editor that rewrites user text.' : undefined,\n });\n\n return result.toDataStreamResponse();\n}\n```\n\n- `ctx.children` and `ctx.selection` are rehydrated into a Slate editor so you can build rich prompts (see [Prompt Templates](#prompt-templates)).\n- Forward provider settings (model, apiKey, temperature, gateway flags, etc.) through `chatOptions.body`; everything you add is passed verbatim in the JSON payload and can be read before calling `createGateway`.\n- Always read secrets from the server. The client should only send opaque identifiers or short-lived tokens.\n- Return a streaming response so `useChat` and `useChatChunk` can process tokens incrementally.\n\n### Connect `useChat`\n\nBridge the editor and your model endpoint with `@ai-sdk/react`. Store helpers on the plugin so transforms can reload, stop, or show chat state.\n\n```tsx\nimport { useEffect } from 'react';\n\nimport { type UIMessage, DefaultChatTransport } from 'ai';\nimport { type UseChatHelpers, useChat } from '@ai-sdk/react';\nimport { AIChatPlugin } from '@platejs/ai/react';\nimport { useEditorPlugin } from 'platejs/react';\n\ntype ChatMessage = UIMessage<{}, { toolName: 'comment' | 'edit' | 'generate'; comment?: unknown }>;\n\nexport const useEditorAIChat = () => {\n const { editor, setOption } = useEditorPlugin(AIChatPlugin);\n\n const chat = useChat({\n id: 'editor',\n api: '/api/ai/command',\n transport: new DefaultChatTransport(),\n onData(data) {\n if (data.type === 'data-toolName') {\n editor.setOption(AIChatPlugin, 'toolName', data.data);\n }\n },\n });\n\n useEffect(() => {\n setOption('chat', chat as UseChatHelpers);\n }, [chat, setOption]);\n\n return chat;\n};\n```\n\nCombine the helper with `useEditorChat` to keep the floating menu anchored correctly:\n\n```tsx\nimport { useEditorChat } from '@platejs/ai/react';\n\nuseEditorChat({\n onOpenChange: (open) => {\n if (!open) chat.stop?.();\n },\n});\n```\n\nNow you can submit prompts programmatically:\n\n```tsx\nimport { AIChatPlugin } from '@platejs/ai/react';\n\neditor.getApi(AIChatPlugin).aiChat.submit('', {\n prompt: {\n default: 'Continue the document after {block}',\n selecting: 'Rewrite {selection} with a clearer tone',\n },\n toolName: 'generate',\n});\n```\n\n\n\n## Prompt Templates\n\n### Client Prompting\n\n- `api.aiChat.submit` accepts an `EditorPrompt`. Provide a string, an object with `default`/`selecting`/`blockSelecting`, or a function that receives `{ editor, isSelecting, isBlockSelecting }`. The helper `getEditorPrompt` in the client turns that value into the final string.\n- Combine it with `replacePlaceholders(editor, template, { prompt })` to expand `{editor}`, `{block}`, `{blockSelection}`, and `{prompt}` using Markdown generated by `@platejs/ai`.\n\n```tsx\nimport { replacePlaceholders } from '@platejs/ai';\n\neditor.getApi(AIChatPlugin).aiChat.submit('Improve tone', {\n prompt: ({ isSelecting }) =>\n isSelecting\n ? replacePlaceholders(editor, 'Rewrite {blockSelection} using a friendly tone.')\n : replacePlaceholders(editor, 'Continue {block} with two more sentences.'),\n toolName: 'generate',\n});\n```\n\n### Server Prompting\n\nThe demo backend in `apps/www/src/app/api/ai/command` reconstructs the editor from `ctx` and builds structured prompts:\n\n- `getChooseToolPrompt` decides whether the request is `generate`, `edit`, or `comment`.\n- `getGeneratePrompt`, `getEditPrompt`, and `getCommentPrompt` transform the current editor state into instructions tailored to each mode.\n- Utility helpers like `getMarkdown`, `getMarkdownWithSelection`, and `buildStructuredPrompt` (see `apps/www/src/app/api/ai/command/prompts.ts`) make it easy to embed block ids, selections, and MDX tags into the LLM request.\n\nAugment the payload you send from the client to fine-tune server prompts:\n\n```ts\neditor.setOption(aiChatPlugin, 'chatOptions', {\n api: '/api/ai/command',\n body: {\n model: 'openai/gpt-4o-mini',\n tone: 'playful',\n temperature: 0.4,\n },\n});\n```\n\nEverything under `chatOptions.body` arrives in the route handler, letting you swap providers, pass user-specific metadata, or branch into different prompt templates.\n\n## Keyboard Shortcuts\n\n\n Open the AI menu in an empty block (cursor mode)\n Show the AI menu (set via `shortcuts.show`)\n Hide the AI menu and stop streaming\n\n\n## Streaming\n\nThe streaming utilities keep complex layouts intact while responses arrive:\n\n- `streamInsertChunk(editor, chunk, options)` deserializes Markdown chunks, updates the current block in place, and appends new blocks as needed. Use `textProps`/`elementProps` to tag streamed nodes (e.g., mark AI text).\n- `streamDeserializeMd` and `streamDeserializeInlineMd` provide lower-level access if you need to control streaming for custom node types.\n- `streamSerializeMd` mirrors the editor state so you can detect drift between streamed content and the response buffer.\n\nReset the internal `_blockChunks`, `_blockPath`, and `_mdxName` options when streaming finishes to start the next response from a clean slate.\n\n## Streaming Example\n\n\n\n## Plate Plus\n\n\n\n## Hooks\n\n### `useAIChatEditor`\n\nRegisters an auxiliary editor for chat previews and deserializes Markdown with block-level memoization.\n\n\n\n Editor instance dedicated to the chat preview.\n Markdown content returned by the model.\n Pass `parser` to filter tokens before deserialization.\n\n\n\n```tsx\nimport { usePlateEditor } from 'platejs/react';\nimport { MarkdownPlugin } from '@platejs/markdown';\nimport { AIChatPlugin, useAIChatEditor } from '@platejs/ai/react';\n\nconst aiPreviewEditor = usePlateEditor({\n plugins: [MarkdownPlugin, AIChatPlugin],\n});\n\nuseAIChatEditor(aiPreviewEditor, responseMarkdown, {\n parser: { exclude: ['space'] },\n});\n```\n\n### `useEditorChat`\n\nConnects `UseChatHelpers` to editor state so the AI menu knows whether to anchor to cursor, selection, or block selection.\n\n\n\n void\" optional>Called when the menu opens on block selection.\n void\" optional>Called whenever the menu opens or closes.\n void\" optional>Called when the menu opens at the cursor.\n void\" optional>Called when the menu opens on a text selection.\n\n\n\n### `useChatChunk`\n\nStreams chat responses chunk-by-chunk and gives you full control over insertion.\n\n\n\n void\">Handle each streamed chunk.\n void\" optional>Called when streaming finishes.\n\n\n\n## Utilities\n\n### `captureAIStreamSnapshot`\n\nCaptures the current editor state before insert-mode streaming so `tf.ai.undo()` can discard preview content without replaying every streamed chunk.\n\n\n\n Target editor.\n Custom snapshot to store instead of the current editor state.\n\nStored snapshot.\n\n\n### `withAIBatch`\n\nGroups editor operations into a single history batch and flags it as AI-generated so `tf.ai.undo()` removes it safely.\n\n\n\n Target editor.\n void\">Operations to run.\n Set `split: true` to start a new history batch.\n\n\n\n### `applyAISuggestions`\n\nDiffs AI output against stored `chatNodes` and writes transient suggestion nodes. Requires `@platejs/suggestion`.\n\n\n\n Editor to apply suggestions to.\n Markdown response from the model.\n\n\n\nComplementary helpers allow you to finalize or discard the diff:\n\n- `acceptAISuggestions(editor)`: Converts transient suggestion nodes into permanent suggestions.\n- `rejectAISuggestions(editor)`: Removes transient suggestion nodes and clears suggestion marks.\n\n### `aiCommentToRange`\n\nMaps streamed comment metadata back to document ranges so comments can be inserted automatically.\n\n\n\n Editor instance.\n Block id and text used to locate the range.\n\nRange matching the comment or `null` if it cannot be found.\n\n\n### `findTextRangeInBlock`\n\nFuzzy-search helper that uses LCS to find the closest match inside a block.\n\n\n\n Block node to search.\n Text snippet to locate.\n\nMatched range or `null`.\n\n\n### `getEditorPrompt`\n\nGenerates prompts that respect cursor, selection, or block selection states.\n\n\n\n Editor providing context.\n String, config, or function describing the prompt.\n\nContextualized prompt string.\n\n\n### `replacePlaceholders`\n\nReplaces placeholders like `{editor}`, `{blockSelection}`, and `{prompt}` with serialized Markdown.\n\n\n\n Editor providing content.\n Template text.\n Prompt value injected into `{prompt}`.\n\nTemplate with placeholders replaced by Markdown.\n\n\n## Plugins\n\n### `AIPlugin`\n\nAdds an `ai` mark to streamed text and exposes transforms to remove AI nodes or undo the last AI batch. Use `.withComponent` to render AI-marked text with a custom component.\n\n\n \n AI content is stored on text nodes.\n AI marks are regular text properties, not decorations.\n \n\n\n### `AIChatPlugin`\n\nMain plugin that powers the AI menu, chat state, and transforms.\n\n\n \n Character(s) that open the command menu. Defaults to `' '`.\n Pattern that must match the character before the trigger. Defaults to `/^\\s?$/`.\n boolean\" optional>Return `false` to cancel opening in specific contexts.\n Store helpers from `useChat` so API calls can access them.\n Snapshot of nodes used to diff edit suggestions (managed internally).\n Selection captured before submitting a prompt (managed internally).\n Controls whether responses stream directly into the document or open a review panel. Defaults to `'insert'`.\n Whether the AI menu is visible. Defaults to `false`.\n True while a response is streaming. Defaults to `false`.\n Active tool used to interpret the response.\n \n\n\n## API\n\n### `api.aiChat.submit(input, options?)`\n\nSubmits a prompt to your model provider. When `mode` is omitted it defaults to `'insert'` for a collapsed cursor and `'chat'` otherwise.\n\n\n\n Raw input from the user.\n Fine-tune submission behaviour.\n\n\n Override the response mode.\n Forwarded to `chat.sendMessage` (model, headers, etc.).\n String, config, or function processed by `getEditorPrompt`.\n Tags the submission so hooks can react differently.\n\n\n\n### `api.aiChat.reset(options?)`\n\nClears chat state, removes AI nodes, and optionally undoes the last AI batch.\n\n\n\n Pass `undo: false` to keep streamed content.\n\n\n\n### `api.aiChat.node(options?)`\n\nRetrieves the first AI node that matches the specified criteria.\n\n\n\n Set `anchor: true` to get the anchor node or `streaming: true` to retrieve the node currently being streamed into.\n\nMatching node entry, if found.\n\n\n### `api.aiChat.reload()`\n\nReplays the last prompt using the stored `UseChatHelpers`, restoring the original selection or block selection before resubmitting.\n\n### `api.aiChat.stop()`\n\nStops streaming and calls `chat.stop`.\n\n### `api.aiChat.show()`\n\nOpens the AI menu, clears previous chat messages, and resets tool state.\n\n### `api.aiChat.hide(options?)`\n\nCloses the AI menu, optionally undoing the last AI batch and refocusing the editor.\n\n\n\n Set `focus: false` to keep focus outside the editor or `undo: false` to preserve inserted content.\n\n\n\n## Transforms\n\n### `tf.aiChat.accept()`\n\nAccepts the latest response. In insert mode it removes AI marks and places the caret at the end of the streamed content. In chat mode it applies the pending suggestions.\n\n### `tf.aiChat.insertBelow(sourceEditor, options?)`\n\nInserts the chat preview (`sourceEditor`) below the current selection or block selection.\n\n\n\n Editor containing the generated content.\n Copy formatting from the source selection. Defaults to `'single'`.\n\n\n\n### `tf.aiChat.replaceSelection(sourceEditor, options?)`\n\nReplaces the current selection or block selection with the chat preview.\n\n\n\n Editor containing the generated content.\n Controls how much formatting from the original selection should be applied.\n\n\n\n### `tf.aiChat.removeAnchor(options?)`\n\nRemoves the temporary anchor node used to position the AI menu.\n\n\n\n Filters the nodes to remove.\n\n\n\n### `tf.ai.insertNodes(nodes, options?)`\n\nInserts nodes tagged with the AI mark at the current selection (or `options.target`).\n\n### `tf.ai.removeMarks(options?)`\n\nClears the AI mark from matching nodes.\n\n### `tf.ai.removeNodes(options?)`\n\nRemoves text nodes that are marked as AI-generated.\n\n### `tf.ai.undo()`\n\nUndoes the latest AI history entry when it was created by `withAIBatch`. When insert-mode preview streaming used `captureAIStreamSnapshot`, it restores that snapshot instead of replaying every streamed chunk. In both cases it avoids re-applying AI output from redo.\n\n## Customization\n\n### Adding Custom AI Commands\n\n\n\nExtend the `aiChatItems` map to add new commands. Each command receives `{ aiEditor, editor, input }` and can dispatch `api.aiChat.submit` with custom prompts or transforms.\n\n#### Simple Custom Command\n\n```tsx\nsummarizeInBullets: {\n icon: ,\n label: 'Summarize in bullets',\n value: 'summarizeInBullets',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit('', {\n prompt: 'Summarize the current selection using bullet points',\n toolName: 'generate',\n });\n },\n},\n```\n\n#### Command with Complex Logic\n\n```tsx\ngenerateTOC: {\n icon: ,\n label: 'Generate table of contents',\n value: 'generateTOC',\n onSelect: ({ editor }) => {\n const headings = editor.api.nodes({\n match: (n) => ['h1', 'h2', 'h3'].includes(n.type as string),\n });\n\n const prompt =\n headings.length === 0\n ? 'Create a realistic table of contents for this document'\n : 'Generate a table of contents that reflects the existing headings';\n\n void editor.getApi(AIChatPlugin).aiChat.submit('', {\n mode: 'insert',\n prompt,\n toolName: 'generate',\n });\n },\n},\n```\n\nThe menu automatically switches between command and suggestion states:\n\n- `cursorCommand`: Cursor is collapsed and no response yet.\n- `selectionCommand`: Text is selected and no response yet.\n- `cursorSuggestion` / `selectionSuggestion`: A response exists, so actions like Accept, Try Again, or Insert Below are shown.\n\nUse `toolName` (`'generate' | 'edit' | 'comment'`) to control how streaming hooks process the response. For example, `'edit'` enables diff-based suggestions, and `'comment'` allows you to convert streamed comments into discussion threads with `aiCommentToRange`.\n", + "content": "---\ntitle: AI\ndescription: AI-powered writing assistance.\ndocs:\n - route: https://pro.platejs.org/docs/examples/ai\n title: Plus\n---\n\n\n\n\n\n## Features\n\n- **Context-aware command menu** that adapts to cursor, text selection, and block selection workflows.\n- **Streaming Markdown/MDX insertion** with table, column, and code block support powered by `streamInsertChunk`.\n- **Insert and chat review modes** with localized insert previews plus undo-safe batching via `withAIBatch` and `tf.ai.undo()`.\n- **Block selection aware transforms** to replace or append entire sections using `tf.aiChat.replaceSelection` and `tf.aiChat.insertBelow`.\n- **Direct integration with `@ai-sdk/react`** so `api.aiChat.submit` can stream responses from Vercel AI SDK helpers.\n- **Suggestion and comment utilities** that diff AI edits, accept/reject changes, and map AI feedback back to document ranges.\n\n\n\n## Kit Usage\n\n\n\n### Installation\n\nThe fastest way to add AI functionality is with the `AIKit`. It ships the configured `AIPlugin`, `AIChatPlugin`, Markdown streaming helpers, cursor overlay, and their [Plate UI](/docs/installation/plate-ui) components.\n\n\n\n- [`AIMenu`](/docs/components/ai-menu): Floating command surface for prompts, tool shortcuts, and chat review.\n- [`AILoadingBar`](/docs/components/ai-loading-bar): Displays streaming status at the editor container.\n- [`AIAnchorElement`](/docs/components/ai-anchor-element): Invisible anchor node used to position the floating menu during streaming.\n- [`AILeaf`](/docs/components/ai-leaf): Renders AI-marked text with subtle styling.\n\n### Add Kit\n\n```tsx\nimport { createPlateEditor } from 'platejs/react';\nimport { AIKit } from '@/components/editor/plugins/ai-kit';\n\nconst editor = createPlateEditor({\n plugins: [\n // ...otherPlugins,\n ...AIKit,\n ],\n});\n```\n\n### Add API Route\n\nExpose a streaming command endpoint that proxies your model provider:\n\n\n\n### Configure Environment\n\nSet your AI Gateway key locally (replace with your provider secret if you are not using a gateway):\n\n```bash title=\".env.local\"\nAI_GATEWAY_API_KEY=\"your-api-key\"\n```\n\n\n\n## Manual Usage\n\n\n\n### Installation\n\n```bash\nnpm install @platejs/ai @platejs/markdown @platejs/selection @ai-sdk/react ai\n```\n\n`@platejs/suggestion` is optional but required for diff-based edit suggestions.\n\n### Add Plugins\n\n```tsx\nimport { createPlateEditor } from 'platejs/react';\nimport { AIChatPlugin, AIPlugin } from '@platejs/ai/react';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { MarkdownPlugin } from '@platejs/markdown';\n\nexport const editor = createPlateEditor({\n plugins: [\n BlockSelectionPlugin,\n MarkdownPlugin,\n AIPlugin,\n AIChatPlugin, // extended in the next step\n ],\n});\n```\n\n- `BlockSelectionPlugin`: Enables multi-block selections that `AIChatPlugin` relies on for insert/replace transforms.\n- `MarkdownPlugin`: Provides Markdown serialization used by streaming utilities.\n- `AIPlugin`: Adds the AI mark and transforms for undoing AI batches.\n- `AIChatPlugin`: Supplies the AI combobox, API helpers, and transforms.\n\nUse `AIPlugin.withComponent` with your own element (or [`AILeaf`](/docs/components/ai-leaf)) to highlight AI-generated text.\n\n### Configure AIChatPlugin\n\nExtend `AIChatPlugin` to hook streaming and edits. The example mirrors the core logic from `AIKit` while keeping the UI headless.\n\n```tsx\nimport cloneDeep from 'lodash/cloneDeep';\nimport { BaseAIPlugin, withAIBatch } from '@platejs/ai';\nimport {\n AIChatPlugin,\n applyAISuggestions,\n getInsertPreviewStart,\n streamInsertChunk,\n useChatChunk,\n} from '@platejs/ai/react';\nimport { ElementApi, getPluginType, KEYS, PathApi } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nexport const aiChatPlugin = AIChatPlugin.extend({\n options: {\n chatOptions: {\n api: '/api/ai/command',\n body: {\n model: 'openai/gpt-4o-mini',\n },\n },\n trigger: ' ',\n triggerPreviousCharPattern: /^\\s?$/,\n },\n useHooks: ({ editor, getOption }) => {\n const mode = usePluginOption(AIChatPlugin, 'mode');\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n\n useChatChunk({\n onChunk: ({ chunk, isFirst, text }) => {\n if (isFirst && mode === 'insert') {\n const { startBlock, startInEmptyParagraph } =\n getInsertPreviewStart(editor);\n\n editor.getTransforms(BaseAIPlugin).ai.beginPreview({\n originalBlocks:\n startInEmptyParagraph &&\n startBlock &&\n ElementApi.isElement(startBlock)\n ? [cloneDeep(startBlock)]\n : [],\n });\n\n editor.setOption(AIChatPlugin, 'streaming', true);\n\n editor.tf.withoutSaving(() => {\n editor.tf.insertNodes(\n {\n children: [{ text: '' }],\n type: getPluginType(editor, KEYS.aiChat),\n },\n {\n at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),\n }\n );\n });\n }\n\n if (mode === 'insert') {\n editor.tf.withoutSaving(() => {\n if (!getOption('streaming')) return;\n\n editor.tf.withScrolling(() => {\n streamInsertChunk(editor, chunk, {\n textProps: {\n [getPluginType(editor, KEYS.ai)]: true,\n },\n });\n });\n });\n }\n\n if (toolName === 'edit' && mode === 'chat') {\n withAIBatch(\n editor,\n () => {\n applyAISuggestions(editor, text);\n },\n { split: isFirst }\n );\n }\n },\n onFinish: () => {\n editor.setOption(AIChatPlugin, 'streaming', false);\n editor.setOption(AIChatPlugin, '_blockChunks', '');\n editor.setOption(AIChatPlugin, '_blockPath', null);\n editor.setOption(AIChatPlugin, '_mdxName', null);\n },\n });\n },\n});\n```\n\n- `useChatChunk`: Watches `UseChatHelpers` status and yields incremental chunks.\n- `tf.ai.beginPreview`: Captures the rollback slice and selection for insert-mode preview before the first streamed chunk is written.\n- `streamInsertChunk`: Streams Markdown/MDX into the document, reusing the existing block when possible.\n- `applyAISuggestions`: Converts responses into transient suggestion nodes when `toolName === 'edit'`.\n- `withAIBatch`: Marks saved AI batches so suggestion review and accepted AI changes stay undo-safe.\n\nProvide your own `render` components (toolbar button, floating menu, etc.) when you extend the plugin.\n\n### Build API Route\n\nHandle `api.aiChat.submit` requests on the server. Each request includes the chat `messages` from `@ai-sdk/react` and a `ctx` payload that contains the editor `children`, current `selection`, and last `toolName`.\n[Complete API example](https://github.com/udecode/plate-playground-template/blob/main/src/app/api/ai/command/route.ts)\n\n```ts title=\"app/api/ai/command/route.ts\"\nimport { createGateway } from '@ai-sdk/gateway';\nimport { convertToCoreMessages, streamText } from 'ai';\nimport { createSlateEditor } from 'platejs';\n\nimport { BaseEditorKit } from '@/registry/components/editor/editor-base-kit';\nimport { markdownJoinerTransform } from '@/registry/lib/markdown-joiner-transform';\n\nexport async function POST(req: Request) {\n const { apiKey, ctx, messages, model } = await req.json();\n\n const editor = createSlateEditor({\n plugins: BaseEditorKit,\n selection: ctx.selection,\n value: ctx.children,\n });\n\n const gateway = createGateway({\n apiKey: apiKey ?? process.env.AI_GATEWAY_API_KEY!,\n });\n\n const result = streamText({\n experimental_transform: markdownJoinerTransform(),\n messages: convertToCoreMessages(messages),\n model: gateway(model ?? 'openai/gpt-4o-mini'),\n system: ctx.toolName === 'edit' ? 'You are an editor that rewrites user text.' : undefined,\n });\n\n return result.toDataStreamResponse();\n}\n```\n\n- `ctx.children` and `ctx.selection` are rehydrated into a Slate editor so you can build rich prompts (see [Prompt Templates](#prompt-templates)).\n- Forward provider settings (model, apiKey, temperature, gateway flags, etc.) through `chatOptions.body`; everything you add is passed verbatim in the JSON payload and can be read before calling `createGateway`.\n- Always read secrets from the server. The client should only send opaque identifiers or short-lived tokens.\n- Return a streaming response so `useChat` and `useChatChunk` can process tokens incrementally.\n\n### Connect `useChat`\n\nBridge the editor and your model endpoint with `@ai-sdk/react`. Store helpers on the plugin so transforms can reload, stop, or show chat state.\n\n```tsx\nimport { useEffect } from 'react';\n\nimport { type UIMessage, DefaultChatTransport } from 'ai';\nimport { type UseChatHelpers, useChat } from '@ai-sdk/react';\nimport { AIChatPlugin } from '@platejs/ai/react';\nimport { useEditorPlugin } from 'platejs/react';\n\ntype ChatMessage = UIMessage<{}, { toolName: 'comment' | 'edit' | 'generate'; comment?: unknown }>;\n\nexport const useEditorAIChat = () => {\n const { editor, setOption } = useEditorPlugin(AIChatPlugin);\n\n const chat = useChat({\n id: 'editor',\n api: '/api/ai/command',\n transport: new DefaultChatTransport(),\n onData(data) {\n if (data.type === 'data-toolName') {\n editor.setOption(AIChatPlugin, 'toolName', data.data);\n }\n },\n });\n\n useEffect(() => {\n setOption('chat', chat as UseChatHelpers);\n }, [chat, setOption]);\n\n return chat;\n};\n```\n\nCombine the helper with `useEditorChat` to keep the floating menu anchored correctly:\n\n```tsx\nimport { useEditorChat } from '@platejs/ai/react';\n\nuseEditorChat({\n onOpenChange: (open) => {\n if (!open) chat.stop?.();\n },\n});\n```\n\nNow you can submit prompts programmatically:\n\n```tsx\nimport { AIChatPlugin } from '@platejs/ai/react';\n\neditor.getApi(AIChatPlugin).aiChat.submit('', {\n prompt: {\n default: 'Continue the document after {block}',\n selecting: 'Rewrite {selection} with a clearer tone',\n },\n toolName: 'generate',\n});\n```\n\n\n\n## Prompt Templates\n\n### Client Prompting\n\n- `api.aiChat.submit` accepts an `EditorPrompt`. Provide a string, an object with `default`/`selecting`/`blockSelecting`, or a function that receives `{ editor, isSelecting, isBlockSelecting }`. The helper `getEditorPrompt` in the client turns that value into the final string.\n- Combine it with `replacePlaceholders(editor, template, { prompt })` to expand `{editor}`, `{block}`, `{blockSelection}`, and `{prompt}` using Markdown generated by `@platejs/ai`.\n\n```tsx\nimport { replacePlaceholders } from '@platejs/ai';\n\neditor.getApi(AIChatPlugin).aiChat.submit('Improve tone', {\n prompt: ({ isSelecting }) =>\n isSelecting\n ? replacePlaceholders(editor, 'Rewrite {blockSelection} using a friendly tone.')\n : replacePlaceholders(editor, 'Continue {block} with two more sentences.'),\n toolName: 'generate',\n});\n```\n\n### Server Prompting\n\nThe demo backend in `apps/www/src/app/api/ai/command` reconstructs the editor from `ctx` and builds structured prompts:\n\n- `getChooseToolPrompt` decides whether the request is `generate`, `edit`, or `comment`.\n- `getGeneratePrompt`, `getEditPrompt`, and `getCommentPrompt` transform the current editor state into instructions tailored to each mode.\n- Utility helpers like `getMarkdown`, `getMarkdownWithSelection`, and `buildStructuredPrompt` (see `apps/www/src/app/api/ai/command/prompts.ts`) make it easy to embed block ids, selections, and MDX tags into the LLM request.\n\nAugment the payload you send from the client to fine-tune server prompts:\n\n```ts\neditor.setOption(aiChatPlugin, 'chatOptions', {\n api: '/api/ai/command',\n body: {\n model: 'openai/gpt-4o-mini',\n tone: 'playful',\n temperature: 0.4,\n },\n});\n```\n\nEverything under `chatOptions.body` arrives in the route handler, letting you swap providers, pass user-specific metadata, or branch into different prompt templates.\n\n## Keyboard Shortcuts\n\n\n Open the AI menu in an empty block (cursor mode)\n Show the AI menu (set via `shortcuts.show`)\n Hide the AI menu and stop streaming\n\n\n## Streaming\n\nThe streaming utilities keep complex layouts intact while responses arrive:\n\n- `streamInsertChunk(editor, chunk, options)` deserializes Markdown chunks, updates the current block in place, and appends new blocks as needed. Use `textProps`/`elementProps` to tag streamed nodes (e.g., mark AI text).\n- `streamDeserializeMd` and `streamDeserializeInlineMd` provide lower-level access if you need to control streaming for custom node types.\n- `streamSerializeMd` mirrors the editor state so you can detect drift between streamed content and the response buffer.\n\nReset the internal `_blockChunks`, `_blockPath`, and `_mdxName` options when streaming finishes to start the next response from a clean slate.\n\n## Streaming Example\n\n\n\n## Plate Plus\n\n\n\n## Hooks\n\n### `useAIChatEditor`\n\nRegisters an auxiliary editor for chat previews and deserializes Markdown with block-level memoization.\n\n\n\n Editor instance dedicated to the chat preview.\n Markdown content returned by the model.\n Pass `parser` to filter tokens before deserialization.\n\n\n\n```tsx\nimport { usePlateEditor } from 'platejs/react';\nimport { MarkdownPlugin } from '@platejs/markdown';\nimport { AIChatPlugin, useAIChatEditor } from '@platejs/ai/react';\n\nconst aiPreviewEditor = usePlateEditor({\n plugins: [MarkdownPlugin, AIChatPlugin],\n});\n\nuseAIChatEditor(aiPreviewEditor, responseMarkdown, {\n parser: { exclude: ['space'] },\n});\n```\n\n### `useEditorChat`\n\nConnects `UseChatHelpers` to editor state so the AI menu knows whether to anchor to cursor, selection, or block selection.\n\n\n\n void\" optional>Called when the menu opens on block selection.\n void\" optional>Called whenever the menu opens or closes.\n void\" optional>Called when the menu opens at the cursor.\n void\" optional>Called when the menu opens on a text selection.\n\n\n\n### `useChatChunk`\n\nStreams chat responses chunk-by-chunk and gives you full control over insertion.\n\n\n\n void\">Handle each streamed chunk.\n void\" optional>Called when streaming finishes.\n\n\n\n## Utilities\n\n### `withAIBatch`\n\nGroups editor operations into a single history batch and flags it as AI-generated so `tf.ai.undo()` removes it safely.\n\n\n\n Target editor.\n void\">Operations to run.\n Set `split: true` to start a new history batch.\n\n\n\n### `applyAISuggestions`\n\nDiffs AI output against stored `chatNodes` and writes transient suggestion nodes. Requires `@platejs/suggestion`.\n\n\n\n Editor to apply suggestions to.\n Markdown response from the model.\n\n\n\nComplementary helpers allow you to finalize or discard the diff:\n\n- `acceptAISuggestions(editor)`: Converts transient suggestion nodes into permanent suggestions.\n- `rejectAISuggestions(editor)`: Removes transient suggestion nodes and clears suggestion marks.\n\n### `aiCommentToRange`\n\nMaps streamed comment metadata back to document ranges so comments can be inserted automatically.\n\n\n\n Editor instance.\n Block id and text used to locate the range.\n\nRange matching the comment or `null` if it cannot be found.\n\n\n### `findTextRangeInBlock`\n\nFuzzy-search helper that uses LCS to find the closest match inside a block.\n\n\n\n Block node to search.\n Text snippet to locate.\n\nMatched range or `null`.\n\n\n### `getEditorPrompt`\n\nGenerates prompts that respect cursor, selection, or block selection states.\n\n\n\n Editor providing context.\n String, config, or function describing the prompt.\n\nContextualized prompt string.\n\n\n### `replacePlaceholders`\n\nReplaces placeholders like `{editor}`, `{blockSelection}`, and `{prompt}` with serialized Markdown.\n\n\n\n Editor providing content.\n Template text.\n Prompt value injected into `{prompt}`.\n\nTemplate with placeholders replaced by Markdown.\n\n\n## Plugins\n\n### `AIPlugin`\n\nAdds an `ai` mark to streamed text and exposes transforms to remove AI nodes or undo the last AI batch. Use `.withComponent` to render AI-marked text with a custom component.\n\n\n \n AI content is stored on text nodes.\n AI marks are regular text properties, not decorations.\n \n\n\n### `AIChatPlugin`\n\nMain plugin that powers the AI menu, chat state, and transforms.\n\n\n \n Character(s) that open the command menu. Defaults to `' '`.\n Pattern that must match the character before the trigger. Defaults to `/^\\s?$/`.\n boolean\" optional>Return `false` to cancel opening in specific contexts.\n Store helpers from `useChat` so API calls can access them.\n Snapshot of nodes used to diff edit suggestions (managed internally).\n Selection captured before submitting a prompt (managed internally).\n Controls whether responses stream directly into the document or open a review panel. Defaults to `'insert'`.\n Whether the AI menu is visible. Defaults to `false`.\n True while a response is streaming. Defaults to `false`.\n Active tool used to interpret the response.\n \n\n\n## API\n\n### `api.aiChat.submit(input, options?)`\n\nSubmits a prompt to your model provider. When `mode` is omitted it defaults to `'insert'` for a collapsed cursor and `'chat'` otherwise.\n\n\n\n Raw input from the user.\n Fine-tune submission behaviour.\n\n\n Override the response mode.\n Forwarded to `chat.sendMessage` (model, headers, etc.).\n String, config, or function processed by `getEditorPrompt`.\n Tags the submission so hooks can react differently.\n\n\n\n### `api.aiChat.reset(options?)`\n\nClears chat state, removes AI nodes, and optionally undoes the last AI batch.\n\n\n\n Pass `undo: false` to keep streamed content.\n\n\n\n### `api.aiChat.node(options?)`\n\nRetrieves the first AI node that matches the specified criteria.\n\n\n\n Set `anchor: true` to get the anchor node or `streaming: true` to retrieve the node currently being streamed into.\n\nMatching node entry, if found.\n\n\n### `api.aiChat.reload()`\n\nReplays the last prompt using the stored `UseChatHelpers`, restoring the original selection or block selection before resubmitting.\n\n### `api.aiChat.stop()`\n\nStops streaming and calls `chat.stop`.\n\n### `api.aiChat.show()`\n\nOpens the AI menu, clears previous chat messages, and resets tool state.\n\n### `api.aiChat.hide(options?)`\n\nCloses the AI menu, optionally undoing the last AI batch and refocusing the editor.\n\n\n\n Set `focus: false` to keep focus outside the editor or `undo: false` to preserve inserted content.\n\n\n\n## Transforms\n\n### `tf.aiChat.accept()`\n\nAccepts the latest response. In insert mode it removes AI marks and places the caret at the end of the streamed content. In chat mode it applies the pending suggestions.\n\n### `tf.aiChat.insertBelow(sourceEditor, options?)`\n\nInserts the chat preview (`sourceEditor`) below the current selection or block selection.\n\n\n\n Editor containing the generated content.\n Copy formatting from the source selection. Defaults to `'single'`.\n\n\n\n### `tf.aiChat.replaceSelection(sourceEditor, options?)`\n\nReplaces the current selection or block selection with the chat preview.\n\n\n\n Editor containing the generated content.\n Controls how much formatting from the original selection should be applied.\n\n\n\n### `tf.aiChat.removeAnchor(options?)`\n\nRemoves the temporary anchor node used to position the AI menu.\n\n\n\n Filters the nodes to remove.\n\n\n\n### `tf.ai.insertNodes(nodes, options?)`\n\nInserts nodes tagged with the AI mark at the current selection (or `options.target`).\n\n### `tf.ai.removeMarks(options?)`\n\nClears the AI mark from matching nodes.\n\n### `tf.ai.removeNodes(options?)`\n\nRemoves text nodes that are marked as AI-generated.\n\n### `tf.ai.beginPreview(options?)`\n\nCaptures the rollback slice and selection for insert-mode AI preview. Call it once before writing the first unsaved preview chunk.\n\n\n\n Top-level blocks that the preview will overwrite. Use `[]` when preview inserts after existing content.\n\nReturns `true` when a new preview rollback point was stored, or `false` when preview state already exists.\n\n\n### `tf.ai.acceptPreview()`\n\nCommits the active preview as one fresh undoable batch, strips preview-only markers, and clears preview bookkeeping.\n\n\nReturns `true` when an active preview was committed.\n\n\n### `tf.ai.cancelPreview()`\n\nRestores the rollback point for the active preview and clears preview bookkeeping.\n\n\nReturns `true` when an active preview was restored.\n\n\n### `tf.ai.discardPreview()`\n\nClears preview bookkeeping without restoring content. Use it when the previewed content should stay in place.\n\n\nReturns `true` when active preview bookkeeping was cleared.\n\n\n### `tf.ai.hasPreview()`\n\nReports whether an insert-mode preview rollback point is currently active.\n\n\nReturns `true` when preview rollback state exists.\n\n\n### `tf.ai.undo()`\n\nUndoes the latest AI history entry when it was created by `withAIBatch`. If an insert-mode preview is active, it cancels that preview first instead of replaying every streamed chunk. In both cases it avoids re-applying AI output from redo.\n\n## Customization\n\n### Adding Custom AI Commands\n\n\n\nExtend the `aiChatItems` map to add new commands. Each command receives `{ aiEditor, editor, input }` and can dispatch `api.aiChat.submit` with custom prompts or transforms.\n\n#### Simple Custom Command\n\n```tsx\nsummarizeInBullets: {\n icon: ,\n label: 'Summarize in bullets',\n value: 'summarizeInBullets',\n onSelect: ({ editor }) => {\n void editor.getApi(AIChatPlugin).aiChat.submit('', {\n prompt: 'Summarize the current selection using bullet points',\n toolName: 'generate',\n });\n },\n},\n```\n\n#### Command with Complex Logic\n\n```tsx\ngenerateTOC: {\n icon: ,\n label: 'Generate table of contents',\n value: 'generateTOC',\n onSelect: ({ editor }) => {\n const headings = editor.api.nodes({\n match: (n) => ['h1', 'h2', 'h3'].includes(n.type as string),\n });\n\n const prompt =\n headings.length === 0\n ? 'Create a realistic table of contents for this document'\n : 'Generate a table of contents that reflects the existing headings';\n\n void editor.getApi(AIChatPlugin).aiChat.submit('', {\n mode: 'insert',\n prompt,\n toolName: 'generate',\n });\n },\n},\n```\n\nThe menu automatically switches between command and suggestion states:\n\n- `cursorCommand`: Cursor is collapsed and no response yet.\n- `selectionCommand`: Text is selected and no response yet.\n- `cursorSuggestion` / `selectionSuggestion`: A response exists, so actions like Accept, Try Again, or Insert Below are shown.\n\nUse `toolName` (`'generate' | 'edit' | 'comment'`) to control how streaming hooks process the response. For example, `'edit'` enables diff-based suggestions, and `'comment'` allows you to convert streamed comments into discussion threads with `aiCommentToRange`.\n", "type": "registry:file", "target": "content/docs/plate/(plugins)/(ai)/ai.mdx" } diff --git a/apps/www/public/r/ai-kit.json b/apps/www/public/r/ai-kit.json index f6901d0168..9a5b8894dc 100644 --- a/apps/www/public/r/ai-kit.json +++ b/apps/www/public/r/ai-kit.json @@ -16,7 +16,7 @@ "files": [ { "path": "src/registry/components/editor/plugins/ai-kit.tsx", - "content": "'use client';\n\nimport cloneDeep from 'lodash/cloneDeep.js';\nimport { BaseAIPlugin, withAIBatch } from '@platejs/ai';\nimport {\n AIChatPlugin,\n AIPlugin,\n applyAISuggestions,\n getInsertPreviewStart,\n streamInsertChunk,\n useChatChunk,\n} from '@platejs/ai/react';\nimport { getPluginType, KEYS, PathApi } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nimport { AILoadingBar, AIMenu } from '@/registry/ui/ai-menu';\nimport { AIAnchorElement, AILeaf } from '@/registry/ui/ai-node';\n\nimport { useChat } from '../use-chat';\nimport { CursorOverlayKit } from './cursor-overlay-kit';\nimport { MarkdownKit } from './markdown-kit';\n\nexport const aiChatPlugin = AIChatPlugin.extend({\n options: {\n chatOptions: {\n api: '/api/ai/command',\n body: {},\n },\n },\n render: {\n afterContainer: AILoadingBar,\n afterEditable: AIMenu,\n node: AIAnchorElement,\n },\n shortcuts: { show: { keys: 'mod+j' } },\n useHooks: ({ editor, getOption }) => {\n useChat();\n\n const mode = usePluginOption(AIChatPlugin, 'mode');\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n useChatChunk({\n onChunk: ({ chunk, isFirst, nodes, text: content }) => {\n if (isFirst && mode === 'insert') {\n const { startBlock, startInEmptyParagraph } =\n getInsertPreviewStart(editor);\n\n editor.getTransforms(BaseAIPlugin).ai.beginPreview({\n originalBlocks:\n startInEmptyParagraph && startBlock ? [cloneDeep(startBlock)] : [],\n });\n\n editor.tf.withoutSaving(() => {\n editor.tf.insertNodes(\n {\n children: [{ text: '' }],\n type: getPluginType(editor, KEYS.aiChat),\n },\n {\n at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),\n }\n );\n });\n editor.setOption(AIChatPlugin, 'streaming', true);\n }\n\n if (mode === 'insert' && nodes.length > 0) {\n editor.tf.withoutSaving(() => {\n if (!getOption('streaming')) return;\n\n editor.tf.withScrolling(() => {\n streamInsertChunk(editor, chunk, {\n textProps: {\n [getPluginType(editor, KEYS.ai)]: true,\n },\n });\n });\n });\n }\n\n if (toolName === 'edit' && mode === 'chat') {\n withAIBatch(\n editor,\n () => {\n applyAISuggestions(editor, content);\n },\n {\n split: isFirst,\n }\n );\n }\n },\n onFinish: () => {\n editor.setOption(AIChatPlugin, 'streaming', false);\n editor.setOption(AIChatPlugin, '_blockChunks', '');\n editor.setOption(AIChatPlugin, '_blockPath', null);\n editor.setOption(AIChatPlugin, '_mdxName', null);\n },\n });\n },\n});\n\nexport const AIKit = [\n ...CursorOverlayKit,\n ...MarkdownKit,\n AIPlugin.withComponent(AILeaf),\n aiChatPlugin,\n];\n", + "content": "'use client';\n\nimport cloneDeep from 'lodash/cloneDeep.js';\nimport { BaseAIPlugin, withAIBatch } from '@platejs/ai';\nimport {\n AIChatPlugin,\n AIPlugin,\n applyAISuggestions,\n getInsertPreviewStart,\n streamInsertChunk,\n useChatChunk,\n} from '@platejs/ai/react';\nimport { ElementApi, getPluginType, KEYS, PathApi } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nimport { AILoadingBar, AIMenu } from '@/registry/ui/ai-menu';\nimport { AIAnchorElement, AILeaf } from '@/registry/ui/ai-node';\n\nimport { useChat } from '../use-chat';\nimport { CursorOverlayKit } from './cursor-overlay-kit';\nimport { MarkdownKit } from './markdown-kit';\n\nexport const aiChatPlugin = AIChatPlugin.extend({\n options: {\n chatOptions: {\n api: '/api/ai/command',\n body: {},\n },\n },\n render: {\n afterContainer: AILoadingBar,\n afterEditable: AIMenu,\n node: AIAnchorElement,\n },\n shortcuts: { show: { keys: 'mod+j' } },\n useHooks: ({ editor, getOption }) => {\n useChat();\n\n const mode = usePluginOption(AIChatPlugin, 'mode');\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n useChatChunk({\n onChunk: ({ chunk, isFirst, nodes, text: content }) => {\n if (isFirst && mode === 'insert') {\n const { startBlock, startInEmptyParagraph } =\n getInsertPreviewStart(editor);\n\n editor.getTransforms(BaseAIPlugin).ai.beginPreview({\n originalBlocks:\n startInEmptyParagraph &&\n startBlock &&\n ElementApi.isElement(startBlock)\n ? [cloneDeep(startBlock)]\n : [],\n });\n\n editor.tf.withoutSaving(() => {\n editor.tf.insertNodes(\n {\n children: [{ text: '' }],\n type: getPluginType(editor, KEYS.aiChat),\n },\n {\n at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),\n }\n );\n });\n editor.setOption(AIChatPlugin, 'streaming', true);\n }\n\n if (mode === 'insert' && nodes.length > 0) {\n editor.tf.withoutSaving(() => {\n if (!getOption('streaming')) return;\n\n editor.tf.withScrolling(() => {\n streamInsertChunk(editor, chunk, {\n textProps: {\n [getPluginType(editor, KEYS.ai)]: true,\n },\n });\n });\n });\n }\n\n if (toolName === 'edit' && mode === 'chat') {\n withAIBatch(\n editor,\n () => {\n applyAISuggestions(editor, content);\n },\n {\n split: isFirst,\n }\n );\n }\n },\n onFinish: () => {\n editor.setOption(AIChatPlugin, 'streaming', false);\n editor.setOption(AIChatPlugin, '_blockChunks', '');\n editor.setOption(AIChatPlugin, '_blockPath', null);\n editor.setOption(AIChatPlugin, '_mdxName', null);\n },\n });\n },\n});\n\nexport const AIKit = [\n ...CursorOverlayKit,\n ...MarkdownKit,\n AIPlugin.withComponent(AILeaf),\n aiChatPlugin,\n];\n", "type": "registry:component" } ] diff --git a/apps/www/public/r/components-changelog-docs.json b/apps/www/public/r/components-changelog-docs.json index 1d81262ad0..1737e05ebb 100644 --- a/apps/www/public/r/components-changelog-docs.json +++ b/apps/www/public/r/components-changelog-docs.json @@ -7,7 +7,7 @@ "files": [ { "path": "../../docs/components/changelog.mdx", - "content": "---\ntitle: Changelog\ndescription: Latest component updates and announcements.\ntoc: true\n---\n\nSince Plate UI is not a component library, a changelog is maintained here.\n\nUse the [CLI](https://platejs.org/docs/components/cli) to install the latest version of the components.\n\n## March 2026 #29\n\n### March 11 #29.1\n- `table-node`: Improved large-table editing performance by applying column widths at the table level, row heights at the row level, and keeping editable resize handles aligned with the table control column.\n\n## January 2026 #28\n\n### January 20 #28.3\n- **AIChat**: Fixed assistant input width not expanding when panel is expanded\n\n### January 19 #28.2\n- **`inline-combobox`**: Added keyboard navigation cycling at list boundaries\n - ArrowUp at first item cycles to last item\n - ArrowDown at last item cycles to first item\n - Prevents null activeId using capture-phase event handling\n\n### January 17 #28.1\n- **DOCX Import/Export**: New `@platejs/docx-io` package for Word document handling\n - `import-toolbar-button`: Import DOCX files with `importDocx`\n - `export-toolbar-button`: Export to DOCX with `exportToDocx`\n - `docx-export-kit`: DOCX-optimized components using `DocxExportPlugin.configure({ override: { components } })`\n- **DOCX Static Components**: Added to existing static files with `*Docx` naming pattern:\n - `callout-node-static`: `CalloutElementDocx`\n - `code-block-node-static`: `CodeBlockElementDocx`, `CodeLineElementDocx`, `CodeSyntaxLeafDocx`\n - `column-node-static`: `ColumnElementDocx`, `ColumnGroupElementDocx`\n - `equation-node-static`: `EquationElementDocx`, `InlineEquationElementDocx`\n - `toc-node-static`: `TocElementDocx`\n\n\n## December 2025 #27\n\n### December 23 #27.3\n- **`code-drawing-node`**: Added new code drawing component with inline editing support\n - Support for multiple diagram types: PlantUML, Graphviz, Flowchart, and Mermaid\n - Inline code editing with real-time preview (no popup dialog)\n - Multiple view modes: Both (code + preview), Code only, Image only\n - Responsive layout: horizontal on desktop, vertical on mobile\n - Floating toolbar with language selector, view mode selector, and download button\n - Debounced rendering (500ms) for optimal performance\n\n### December 23 #27.2\n- **AI Prompt System Refactoring**: Complete restructuring of AI command prompts for better maintainability\n - Split monolithic `prompts.ts` into focused modules: `getEditPrompt`, `getGeneratePrompt`, `getCommentPrompt`, `getEditTablePrompt`, `getChooseToolPrompt`\n - Added new `common.ts` for shared prompt utilities\n - Enhanced table cell editing capabilities with specialized prompts\n- **AI Table Cell Handling**: Improved support for editing single-cell tables\n - `use-chat`: Enhanced with parser options for better AI content processing\n - `cursor-overlay`: Fixed overlay positioning and behavior\n - Added tests for complex table markdown generation\n- **API Routes**: Updated AI command and copilot routes with improved prompt selection logic\n\n### December 16 #27.1\n- `table-node`: Fixed table row drag and drop - rows could be dragged but not dropped, and dropline wasn't showing. Added missing `nodeRef` to element ref composition.\n\n### November 30 #26.10\n- `inline-combobox`: Added Yjs collaboration support - combobox popover now only shows for the user who triggered it, preventing the popover from opening for all users in collaborative editing\n\n### October 21 #26.9\n- `suggestion-kit`: Remove `BlockSuggestion`use `SuggestionLineBreak` instead to fixes styles.\n- `use-chat`: Fix AI comment hiding when finished.\n\n### October 17 #26.8\n- **Static Components**: Updated all static component imports to use new `platejs/static` path\n - `*-node-static` components: Updated imports from `@platejs/core/react` to `platejs/static`\n - `editor-static`: Updated `PlateStatic` import path\n - `export-toolbar-button`: Updated static utilities import path\n - `import-toolbar-button`: Updated static utilities import path\n - `slate-to-html/page`: Updated static rendering imports\n - `comment-kit`, `suggestion-kit`: Updated static types imports\n\n### October 6 #26.7\n- `api/ai/command/route.ts`: Fix poor AI generation quality when blockSelecting.\n\n### October 5 #26.6\n- `ai-kit`: Removed unused `api` parameter from `useHooks` destructuring\n- `block-selection-kit`: Added keyboard shortcut handler to open AI menu with `mod+j` when blocks are selected\n\n### October 4 #26.5\n- `api/ai/command/route.ts`: fix #4669\n\n## September 2025 #26\n\n### September 28 #26.5\n- `transforms`: Fixed slash command duplicate block insertion - prevents creating duplicate blocks when selecting the same block type in empty blocks\n\n### September 20 #26.4\n- **AI Suggestions**: Major improvements to AI suggestion system with better content handling and UI enhancements\n - `ai-menu`: \n - Added new `AILoadingBar` component with animated spinner and stop functionality\n - Enhanced comment acceptance UI with Accept/Reject buttons\n - Improved context-aware menu states based on selection and operation mode\n - Better keyboard navigation with ESC to stop operations\n - `ai-toolbar-button`: Streamlined implementation\n - `api/ai/command/route.ts`: \n - Added multi-tool support (generate, edit, comment) with automatic intent classification\n - Switched to Google Gemini model (`gemini-2.5-flash`)\n - Enhanced prompt templates with placeholder support\n - Added MDX tag preservation\n - `markdown-joiner-transform`: Added smart buffering for smoother streaming of markdown content\n - `use-chat`: Simplified implementation with better error handling\n - `ai-kit`: Added markdown plugin to AI configuration\n - `markdown-kit`: Added AI plugin integration\n - `link-node`: Added AI-specific click handler functionality\n - `block-context-menu`: Removed redundant AI options (now handled by ai-menu)\n - `block-discussion`: Minor styling improvements\n - `fixed-toolbar-buttons`: Simplified AI button implementation\n\n### September 7 #26.3\n- `block-context-menu`: Fixed menu position sticking when triggered multiple times in different locations\n\n### September 5 #26.2\n- `block-draggable`: Fixed block selection to work with right-click events\n\n### September 4 #26.1\n- **AI Comments**: Added AI-powered comment functionality for document review and feedback\n - `use-chat`: Enhanced chat hook with AI comment support and improved streaming capabilities\n - `ai-menu`: Updated AI menu with comment generation options and improved UI\n - `ai-toolbar-button`: Added support for AI comment actions\n - `block-context-menu`: Integrated AI comment options into block context menu\n - `fixed-toolbar-buttons`: Added AI comment button to toolbar\n - `ai-kit`: remove all prompt templates, use directly in `api/ai/command/route.ts`.\n - `api/ai/command/route.ts`: Added comment functionality.\n\n## August 2025 #25\n\n\n### August 17 #25.2\n- `block-discussion`: Removed `useFocusedLast` check for showing discussion popover.\n\n### August 1 #25.1\n- **Floating toolbar improvements**: Multiple components now use the new `useFocusedLast` hook to only show their floating toolbars when their editor is the last focused editor, preventing toolbar conflicts in multi-editor scenarios:\n - `ai-menu`\n - `block-discussion`\n - `column-node`\n - `media-toolbar`\n - `table-node`\n- `block-draggable`: \n - Select list children on handle click\n - Focus selected blocks on handle click\n\n## July 2025 #24\n\n### July 29 #24.11\n- `block-draggable`: Fixed table drag and drop preview display with horizontal scroll compensation. Drag preview elements now correctly display content even when the original element has horizontal scroll\n- `block-draggable`: Added `isAboutToDrag` state to improve preview handling - tracks when drag is about to start (mousedown but not yet dragging) for better preview cleanup\n\n### July 27 #24.10\n- `ai-kit`: support custom node type\n- `indent-kit`: add `KEYS.img` to `IndentPlugin`\n- `list-kit`: add `KEYS.img` to `ListPlugin`\n- `markdown-joiner-transform.ts`: add `markdownJoinerTransform` to transform chunks like [**,bold,**] to [**bold**] make the md deserializer happy.\n- `api/ai/command/route.ts`: use `markdownJoinerTransform` to transform chunks.\n\n### July 26 #24.9\n- `list-classic-kit`: Added `ListPlugin` to restore List functionalities (indent with Tab / Shift+Tab, new item when pressing enter, ...).\n\n### July 25 #24.8\n- `block-draggable`: Added support for automatically selecting list item children when dragging. When dragging a list item, all nested items with bigger indent are now included in the drag operation\n\n### July 23 #24.7\n- `block-draggable`: Updated to use new `addOnContextMenu` API from BlockSelectionPlugin for cleaner context menu handling\n\n### July 18 #24.6\n- `block-context-menu`: Fixed context menu not opening when right-clicking on block margin areas\n- `block-draggable`: Added wrapper div with context menu handler to ensure block selection on margin clicks\n\n### July 14 #24.5\n- `block-draggable`: Added support for dragging multiple blocks using editor's native selection (previously only block-selection was supported)\n\n### July 3 #24.4\n- `slate-to-html`: Added `EditorViewDemo` component for static editor rendering using `createStaticEditor`\n### July 4 #24.3\n\n- `list-classic-node`: Fix styling that affects `TaskListElement` by force overriding list-style-type (set to none).\n\n### July 3 #24.2\n\n- **Task list support in list-classic**: Added task list functionality with checkboxes to the list-classic plugin\n - `list-classic-kit`: Added `TaskListPlugin` with `TaskListElement` component\n - `list-classic-node`: Added `TaskListElement` and `TaskListItemElement` components with checkbox support\n - `transforms-classic`: New file for classic list transforms\n - `insert-toolbar-classic-button`: New component for inserting classic list types (bulleted, numbered, task)\n - `turn-into-toolbar-classic-button`: New component for converting blocks to classic list types\n - `floating-toolbar-classic-buttons`: New component for floating toolbar with classic list support\n - `floating-toolbar-classic-kit`: New kit that includes classic list toolbar buttons\n\n### July 2 #24.1\n- `editor`: Added `EditorView` component using the new `PlateView` from `@platejs/core/react` for static editor rendering with copy functionality\n\n## June 2025 #23\n\n### June 29 #23.9\n- `link-node`: Remove `useLink`\n- `link-node-static`: missing `getLinkAttributes`\n- `media-image-node`: `attributes.alt` type casting\n\n### June 26 #23.7\n- `inline-combobox`: Fixed combobox not closing when clicking outside the editor\n\n### June 24 #23.6\n- `transform.ts`: add `toggleCodeBlock` to `setBlockMap`. Fix the structural error of the code_block created by `turn-into-toolbar-button.tsx`.\n\n### June 20 #23.5\n- [Drag and drop improvements](https://github.com/udecode/plate/pull/4385)\n- `block-draggable`: Fixed drag and drop functionality with multiple selected blocks and resolved drop positioning issues on margins.\n- `block-selection-kit`: It is now possible to select the entire table (table), but the rows (tr) will only be selected if your selection box is within the table.\n- `table-node`: Add block selection styles to the table.\n\n### June 18 #23.4\n\n- `table-node`: Fix bug affecting cursor position and improve performance\n\n### June 16 #23.3\n\n- `block-draggable`: use `getPluginByType` instead of `getContainerTypes`\n\n### June 13 #23.2\n\n- `editor`: Fix placeholder positioning `**:data-slate-placeholder:!top-1/2 **:data-slate-placeholder:-translate-y-1/2`.\n- `block-placeholder-kit`: Change placeholder color to `text-muted-foreground/80` to match `editor` one.\n\n### June 9 #23.1\n\n**Plate 49**\n\nMerging files, using a more consistent naming convention, and removing unused `export` statements.\n\nComponents:\n\n- Now that basic nodes have a default HTML element, you can remove `withProps(..., { as: '...' })` plugin components.\n- To improve decoupling, plugins are not imported anymore only for their keys. Import `KEYS` from `@udecode/plate` instead, as a unified source of keys.\n - `ParagraphPlugin.key` -> `KEYS.p`\n - `INDENT_LIST_KEYS.listStyleType` -> `KEYS.listType`\n - `ListStyleType.Decimal` -> `KEYS.ol`\n - `ListStyleType.Disc` -> `KEYS.ul`\n - `list` (classic) -> `KEYS.listClassic`\n - `ol` (classic) -> `KEYS.olClassic`\n - `ul` (classic) -> `KEYS.ulClassic`\n - `li` (classic) -> `KEYS.liClassic`\n - `action_item` (classic) -> `KEYS.listTodoClassic`\n- Rename all `*-element`, `*-leaf` files to `*-node` (and static versions)\n- Removed `ai-anchor-element`, merged into `ai-node`\n- Removed `ai-loading-bar`, merged into `ai-menu`\n- Removed `ai-menu-items`, merged into `ai-menu`\n- Renamed `align-dropdown-menu` to `align-toolbar-button`, `AlignDropdownMenu` to `AlignToolbarButton`\n- Renamed `api-ai` to `ai-api`\n- Renamed `api-uploadthing` to `media-uploadthing-api`\n- `BlockSelection`: fix block selection for tables\n- Removed `code-block-combobox`, merged into `code-block-node`\n- Removed `code-line-element`, merged into `code-block-node` (and static version)\n- Removed `code-syntax-leaf`, merged into `code-block-node` (and static version)\n- Rename `color-toolbar-button` to `font-color-toolbar-button`, `ColorDropdownMenu` to `FontColorToolbarButton`\n- Removed all `color-*` files, merged into `font-color-toolbar-button`\n - Rename `color-dropdown-menu` to `font-color-toolbar-button`\n- Removed `column-group-element`, merged into `column-node` (and static version)\n- Removed `comment-create-form`, merged into `comment`\n- Renamed `draggable` to `block-draggable`, `DraggableAboveNodes` to `BlockDraggable`\n- Renamed `emoji-input-element` to `emoji-node`\n- Removed all `emoji-*` files (except `emoji-input-node`), merged into `emoji-toolbar-button`\n - Rename `EmojiToolbarDropdown` to `EmojiPopover`, `EmojiDropdownMenu` to `EmojiToolbarButton`\n - `EmojiPicker` `icons` prop is now optional and defaulted to `emojiCategoryIcons` and `emojiSearchIcons`\n- Renamed `image-preview` to `media-preview-dialog`, `ImagePreview` to `MediaPreviewDialog`\n- Renamed `image-element` to `media-image-node`\n - Renamed `MediaFileElement` to `FileElement` (and static version)\n - Renamed `MediaAudioElement` to `AudioElement` (and static version)\n - Renamed `MediaVideoElement` to `VideoElement` (and static version)\n- Renamed `indent-list-toolbar-button` to `list-toolbar-button`\n - Renamed `BulletedIndentListToolbarButton` to `BulletedListToolbarButton`\n - Renamed `NumberedIndentListToolbarButton` to `NumberedListToolbarButton`\n- Renamed `indent-todo-marker` to `block-list`\n- Removed `indent-fire-marker`\n- Removed `indent-todo-toolbar-button`, merged into `list-toolbar-button`\n- Renamed `IndentTodoToolbarButton` into `TodoListToolbarButton`\n- Removed `inline-equation-element` and `equation-popover`, merged into `equation-node` (and static version)\n- Removed `inline-equation-toolbar-button`, merged into `equation-toolbar-button`\n- Renamed `insert-dropdown-menu` to `insert-toolbar-button`, `InsertDropdownMenu` to `InsertToolbarButton`\n- Renamed `line-height-dropdown-menu` to `line-height-toolbar-button`, `LineHeightDropdownMenu` to `LineHeightToolbarButton`\n- Rename `link-floating-toolbar` to `link-toolbar`\n- Removed `list-indent-toolbar-button`, merged into `list-classic-toolbar-button`\n- Renamed `ListIndentToolbarButton` to `IndentToolbarButton`\n- Renamed `list-node` to `list-classic-node`\n- Renamed `media-popover` to `media-toolbar`, `MediaPopover` to `MediaToolbar`\n- Renamed `mode-dropdown-menu` to `mode-toolbar-button`, `ModeDropdownMenu` to `ModeToolbarButton`\n- Renamed `more-dropdown-menu` to `more-toolbar-button`, `MoreDropdownMenu` to `MoreToolbarButton`\n- Removed `outdent-toolbar-button`, merged into `indent-toolbar-button`\n- `table-icons`: rename `Border*` to `Border*Icon`\n- Renamed `slash-input-element` to `slash-input-node`\n- Renamed `SuggestionBelowNodes` to `SuggestionLineBreak`\n- Removed `table-cell-element`, merged into `table-node` (and static version)\n- Removed `table-row-element`, merged into `table-node` (and static version)\n- Renamed `table-dropdown-menu` to `table-toolbar-button`, `TableDropdownMenu` to `TableToolbarButton`\n- Removed `todo-list-node`, merged into `list-classic-node`\n- Renamed `turn-into-dropdown-menu` to `turn-into-toolbar-button`, `TurnIntoDropdownMenu` to `TurnIntoToolbarButton`\n- `export-toolbar-button`, `indent-list-plugins`: remove fire from `listStyleTypes`\n- `useCommentEditor`: `usePlateEditor` instead of `useCreateEditor`\n- Removed `placeholder`, `withPlaceholder`. Migration: use `block-placeholder-kit`, `BlockPlaceholderPlugin` instead.\n- `line-height-toolbar-button`: remove `useLineHeightDropdownMenu` hook.\n- `font-color-toolbar-button`: remove `useColorInput` hook.\n\nPlugins:\n\n- Renamed all `*-plugin`, `*-plugins` files to `-kit`, and `*Plugin`, `*Plugins` to `*Kit`. A **plugin kit** is a collection of configured plugins.\n - Renamed `editor-plugins` to `editor-kit`\n - Renamed `equation-plugins` to `math-kit`, `equationPlugins` to `MathKit`\n - Renamed `indent-list-plugins` to `list-kit`, `indentListPlugins` to `ListKit`\n - Added `BlockList` component to `block-list`, used in `list-kit`\n - Removed `use-create-editor`, use `usePlateEditor` instead\n- `ai-kit`: add `show` shortcut. Remove `useHotkeys('mod+j')` from `ai-menu`\n- `comment-kit`: add `setDraft` transform, shortcut\n- `basic-marks-kit`, `basic-blocks-kit`: add shortcuts\n\n- `transforms`, `block-draggable`: remove `STRUCTURE_TYPES`, those are now inferred from `plugin.node.isContainer`. Use instead `editor.meta.containerTypes`.\n- Remove `structuralTypes` from `useSelectionFragmentProp` usages.\n\n## May 2025 #22\n\n### May 26 #22.7\n\n- [Fix combobox closing issue](https://github.com/udecode/plate/pull/4322)\n- `inline-combobox`: fix `insertPoint` not being updated when the combobox is closed.\n\n### May 15 #22.6\n\n- [Fix inline math keyboard behavior and style](https://github.com/udecode/plate/pull/4305)\n- `equation-popover`: Focus back to the editor when the popover is closed.\n- `inline-equation-element`: When selecting it should be highlighted.\n\n### May 11-12 #22.5\n\n- [Templates migration to Plate 48](https://github.com/udecode/plate/pull/4298/files)\n- Migration to shadcn v4: \n - Plate had a forked version of shadcn/ui primitives that could conflict with your existing components. Our components now **fully depend** on the original shadcn/ui primitives, easing the integration of Plate into your existing shadcn/ui set of components.\n - All components updated to [Tailwind v4](https://ui.shadcn.com/docs/tailwind-v4). \n - See the updated [installation guide](/docs/components/installation).\n- Migration to React 19. If you're using React 18, you may need to use `React.forwardRef` in a few places.\n- Migration to [shadcn CLI](https://ui.shadcn.com/docs/cli):\n - Remove `registries` from `components.json`\n - Use `npx shadcn` instead of `npx shadcx`\n- [MCP support](/docs/mcp)\n- Remove `withRef` from all components\n- Import `cn` from `@/lib/utils` instead of `@udecode/cn` to stay consistent with shadcn/ui\n- Remove unused `className`, `style` props from all element and leaf components\n- `draggable`:\n - Fix dnd in Firefox\n- `media-placeholder-element`: refactor to use `use-upload-file` hook instead of `uploadthing`\n - Migration: `npx shadcn@latest add @plate/api-uploadthing`\n\n### May 6 #22.3\n\n- `ai-chat-editor`: support none-standard markdown nodes.\n- `slash-input-element`: add callout support.\n- `block-selection-plugins.tsx`: fix block selection not working.\n\n### May 4 #22.2\n\n- `ai/command`: forked smoothStream from `ai` package now uses 30ms delay by default (only code blocks and tables use 100ms delay).\n\nv48 migration:\n- `PlateElement`, `PlateLeaf` and `PlateText` HTML attributes are moved from top-level props to `attributes` prop.\n- Remove `nodeProps` prop from `PlateElement`, `PlateLeaf`, `PlateText`. Use `attributes` prop instead.\n- Migrated components: \n - `block-discussion`\n - `comment-leaf`\n - `date-element`\n - `draggable`\n - `excalidraw-element`\n - `hr-element` + `-static`\n - `image-element` + `-static`\n - `link-element`\n - `media-audio-element`\n - `media-file-element`\n - `media-placeholder-element`\n - `media-video-element`\n - `mention-element`\n - `placeholder`\n - `suggestion-leaf`\n - `table-cell-element` + `-static`\n - `table-element`\n - `tag-element`\n\n### May 2 #22.1\n- `use-chat`: add `_abortFakeStream`.\n- `ai-menu`: Fix menu items are displayed incorrectly.\n- `ai-loading-bar`: Move esc keydown handler to `ai-menu`.\n- `ai/command`: add chunking delay to 100ms (Temporary workaround with performance issue).\n\n\n## April 2025 #21\n\n### April 30 #21.3\n\n- `autoformat-plugin`: allow starting a new indent list with numbers other than 1\n\n### April 29 #21.2\n\n- `ai-leaf`: add `aiIndicatorVariants` to display loading state.\n- `cursor-overlay`: hide when ai is streaming.\n- `api/ai/command`: fix chunking issue.\n\nAdd `discussion-plugin`:\n- add `discussionPlugin` to `editor-plugins`, remove `configure` from `suggestionPlugin`\n- refactor `block-suggestion`, `comment` to use `discussionPlugin`\n- fix `comment-create-form` to create discussion when none exists\n- style changes in `suggestion-leaf`\n- fix `link-floating-toolbar` to support internal links, and placement top when suggestion or comment is active\n\n### April 19 #21.1\n\n- `ai-anchor-element`: add `ai-anchor-element` component that is inserted before streaming, removed after streaming, and used for positioning the ai-menu\n- `ai-loading-bar`: add `ai-loading-bar` component that is used to display the loading progress of the insert mode streaming\n- `ai-menu`: migrate to latest `ai` package\n- `ai-menu-items`: add `generateMarkdownSample`\n- `ai-plugins`: Remove the single-paragraph limit from prompts\n- `editor`: introduce `PlateContainer` component\n\n### April 2 #21.1\n\n- `export-toolbar-button`: fix pdf export issue with `html2canvas-pro`\n- `import-toolbar-button`: fix sometimes unable to select the file\n\n## March 2025 #20\n\n### March 12 2025 #20.4\n\n- `ai-toolbar-button`: add missing `@udecode/plate-ai` dependency.\n- `comment-toolbar-button`: add missing `comments-plugin` registry dependency.\n- `font-size-toolbar-button`: add missing `popover` registry dependency.\n- `tooltip`: add missing `button` registry dependency.\n\n### March 10 #20.3\n- `block-context-menu`: Prevent opening context menu in read-only mode\n\n### March 2 #20.2\n\n- `block-suggestion`: fix styles\n- `suggestion-leaf-static`: add static versions\n\n### March 1 #20.1\n\nPlate 46 - new code block\n\n- Migrated from Prism.js to lowlight for syntax highlighting\n - `code-block-element-static`, `code-block-element`, `code-block-combobox`: Updated to use lowlight classes. Default to github theme.\n - `code-syntax-leaf-static`, `code-syntax-leaf`: Updated to use lowlight token classes\n - Removed `prismjs` dependency and related styles\n - Use `lowlight` plugin option instead of `prism` option\n - `code-block-combobox`: add `Auto` language option, change language values to match lowlight\n- `autoformat-plugin`: prevent autoformat on code blocks\n\n```tsx\nimport { all, createLowlight } from 'lowlight';\n\nconst lowlight = createLowlight(all);\n\nCodeBlockPlugin.configure({\n options: {\n lowlight,\n },\n});\n```\n\n### Feburary 21 #19.3\n\n- `image-preview`: prevent block menu on image preivew mask\n- `media-popover`: hide media popover when image preivew is open\n\n### February 18 #19.2\n\nPlate 45 - new comments & suggestions UI\n\n- NEW `block-discussion` as the main container, used in `plate-element`\n- NEW `comment` for individual comment display\n- NEW `comment-create-form` with minimal Plate editor for input\n- Removed legacy components:\n - `comments-popover`\n - `comment-avatar`\n - `comment-reply-items`\n - `comment-value`\n - `comment-resolve-button`\n- NEW `block-suggestion`\n- NEW `suggestion-leaf`\n- NEW `suggestion-line-break`\n- Remove `plate-element`, import `PlateElement` from `@udecode/plate/react` instead. Add in `block-selection-plugins`:\n```tsx\nrender: {\n belowRootNodes: (props) => {\n if (!props.className?.includes('slate-selectable')) return null;\n\n return ;\n },\n},\n```\n\n### February 3 #19.1\n\n- React 19\n- TailwindCSS 4\n- Plate 45\n- Jotai 2\n- Zustand 6\n- `comment-more-dropdown`: remove `useCommentEditButtonState`, `useCommentDeleteButtonState`\n- `image-element`, `media-embed-element`, `media-video-element`, `mode-dropdown-menu`\n - use `const width = useResizableValue('width')`\n- `image-preview`: remove `useScaleInputState`, `useImagePreviewState`\n- `floating-toolbar`: \n - replace `useEventEditorSelectors` with `useEventEditorValue`\n- `media-popover`: \n - replace `floatingMediaActions` with `FloatingMediaStore.set`, \n - replace `useFloatingMediaSelectors` with `useFloatingMediaValue`\n\n## January 2025 #18\n\n### January 23 #18.8\n\n- `table-element`: fix styles, show table border controls when collapsed\n- `table-row-element`: refactor\n- `table-cell-element`: selection bg-brand\n\n### January 21 #18.7\n\n- `table-element`, `table-row-element`: support row dnd and selection\n- `plate-element`: add `blockSelectionClassName` prop\n- `editor`: z-50 for selection area\n- `draggable`: \n - Replace `editor.api.blockSelection.replaceSelectedIds` with `editor.api.blockSelection.clear`\n - Use `TooltipButton` for drag handle\n - Block select on drag handle click\n - Hide drag handle in table cells\n- `column-element`, `table-cell-element`: add `isSelectionAreaVisible` check\n- `block-selection`: hide if dragging\n- Replace `editor.api.blockSelection.addSelectedRow` with `editor.api.blockSelection.set`:\n - `ai-menu`\n - `equation-popover`\n- `align-dropdown-menu`: deprecate \n\n\n### January 18 #18.6\n\n- `inline-equation-element` and `equation-popover`: Fix: When selecting an inline equation, the popover should not open, as it causes the selection to be lost.\n\n### January 17 #18.5\n\n- `emoji-picker-search-bar`: add `autoFocus`\n\n### January 16 #18.4\n\n- `import-toolbar-button` and `export-toolbar-button`: add `markdown` support\n\n### January 14 #18.3\n- `fixed-toolbar-buttons`: add `import-toolbar-button`\n- `indent-fire-marker.tsx` Add `data-plate-prevent-deserialization` to prevent deserialization of the fire marker. Change the `span` tag to `li`.\n- `indent-todo-marker.tsx` change the `span` tag to `li`.\n- `image-element-static.tsx` and `hr-element-static.tsx`: Fix `nodeProps` not being passed to `SlateElement`.\n- `ai-chat-editor`:\n```tsx\nconst aiEditor = usePlateEditor({ plugins });\nuseAIChatEditor(aiEditor, content);\n```\n\n### January 12 #18.2\n\n- `ai-plugins`: remove `createAIEditor`, it's now created in `ai-chat-editor`\n- `ai-chat-editor`: just use `useAIChatEditor` (v42.1)\n- `ai-menu`: avoid collisions, remove `aiEditorRef`\n- `command`: add `focus-visible:outline-none`\n- `editor-static`: update `aiChat` padding\n- `transforms`: fix `insertBlock` used by slash commands: it should insert a new block if the newly inserted block is of the same type as the command.\n- `block-selection-plugins`: update `BlockSelectionPlugin`\n\n```tsx\nBlockSelectionPlugin.configure(({ editor }) => ({\n options: {\n enableContextMenu: true,\n isSelectable: (element, path) => {\n return (\n !['code_line', 'column', 'td'].includes(element.type) &&\n !editor.api.block({ above: true, at: path, match: { type: 'tr' } })\n );\n },\n },\n}))\n```\n\n \n### January 8 #18.1\n\n- v42 migration\n- `table-element`, `table-element-static`\n - Move icons to `table-icons`\n - Remove `colgroup`, col width is now set in `table-cell-element`\n- `table-row-element`: remove `hideBorder` prop\n- `table-cell-element`, `table-cell-element-static`: \n - column hover/resizing state is now using Tailwind instead of JS\n - **Major performance improvement**: all table cells were re-rendering on a single cell change. This is now fixed.\n - React.memo\n- `table-dropdown-menu`:\n - dynamic table insert\n - merge/split cells\n - insert row/col before\n- `tooltip`: add `TooltipButton`\n- `indent-list-toolbar-button`: Remove `IndentListToolbarButton` use `NumberedIndentListToolbarButton` and `BulletedIndentListToolbarButton` instead.\n- `table-dropdown-menu`: new insert table interface.\n- `column-group-element`: fix `ColumnFloatingToolbar` onColumnChange\n\n## December 2024 #17\n\n### December 28 #17.8\n\n- `export-toolbar-button`: add `katex` support\n- `plate-element`: remove `relative` className\n- All components using the `PlateElement` have had redundant `relative` class names removed.\n### December 27 #17.7\n\n- `fixed-toolbar-buttons`: add `font-size-toolbar-button`\n- `floating-toolbar`: add `inline-equation-toolbar-button`\n- `turn-into-dropdown-menu`: Fix: after turn into other block, the editor should regain focus.\n- `insert-dropdown-menu`: add `inline equation` and `equation` & fix the focus issue\n- `slash-input-element`: add `equation` and `inline equation`\n\n### December 23 #17.5\n\n- `table-element`: fix selection\n- before: `isSelectingCell && '[&_*::selection]:bg-none'`\n- after: `isSelectingCell && '[&_*::selection]:!bg-transparent'`\n\n\n### December 21 #17.4\n\nUpdate `tailwind.config.cjs` for better font support in the HTML export:\n\n```ts\nfontFamily: {\n heading: [\n 'var(--font-heading)',\n 'ui-sans-serif',\n '-apple-system',\n 'BlinkMacSystemFont',\n 'Segoe UI Variable Display',\n 'Segoe UI',\n 'Helvetica',\n 'Apple Color Emoji',\n 'Arial',\n 'sans-serif',\n 'Segoe UI Emoji',\n 'Segoe UI Symbol',\n 'Noto Color Emoji',\n ],\n mono: ['var(--font-mono)', ...fontFamily.mono],\n sans: [\n 'var(--font-sans)',\n 'ui-sans-serif',\n '-apple-system',\n 'BlinkMacSystemFont',\n 'Segoe UI Variable Display',\n 'Segoe UI',\n 'Helvetica',\n 'Apple Color Emoji',\n 'Arial',\n 'sans-serif',\n 'Segoe UI Emoji',\n 'Segoe UI Symbol',\n 'Noto Color Emoji',\n ],\n```\n\n\n### December 20 #17.3\n\n- `insertColumnGroup`, `toggleColumnGroup`: use `columns` option instead of `layout` \n- Remove `with-draggables`. Add [`DraggableAboveNodes`](https://github.com/udecode/plate/pull/3878/files#diff-493c12ebed9c3ef9fd8c3a723909b18ad439a448c0132d2d93e5341ee0888ad2) to `draggable`. Add to `DndPlugin` config:\n```tsx\nDndPlugin.configure({ render: { aboveNodes: DraggableAboveNodes } }),\n```\n- `column-element`, `image-element`, `media-video-element`: Remove `useDraggableState`. Use `const { isDragging, previewRef, handleRef } = useDraggable`\n- `column-group-element`: Remove `useColumnState`. Use instead:\n```tsx\nconst columnGroupElement = useElement(ColumnPlugin.key);\n\nconst onColumnChange = (widths: string[]) => {\n setColumns(editor, {\n at: findNodePath(editor, columnGroupElement),\n widths,\n });\n};\n```\n- `export-toolbar-button`: add `exportToHtml`\n\n### December 19 #17.2\n\nPlate 41\n\n- New RSC components for element and leaf components, filename ending with `-static.tsx`. Those are now added along with the default client components.\n- `editor`: add `select-text` to `editorVariants`\n- `date-element`: remove popover when read-only\n- `indent-todo-marker`: use `SlateRenderElementProps` type instead of `PlateRenderElementProps`\n- `hr-element`, `media-audio-element`, `media-embed-element`, `mention-element`: improve cursor styling\n- `media-file-element`: use `` instead of `div` + `onClick`\n- all element and leaf components: `className` prop is now placed before inline prop.\n\n### December 16 #17.1\n\n- `column-element`:\n - Add drag and drop support for columns\n - Add drag handle with tooltip\n - Fix column spacing and padding\n\n- `column-group-element`:\n - Remove gap between columns\n - Remove margin top\n\n- `draggable`:\n - Remove `DraggableProvider` HOC\n - Remove `DropLine` children prop\n\n## November 2024 #16\n\n### November 26 #16.9\n\nhttps://github.com/udecode/plate/pull/3809/files\n- Add `select-editor`, `tag-element`, `label`, `form`\n- Replace `cmdk` dependency with `@udecode/cmdk`. It's a controllable version of `cmdk`.\n- `command`: add variants\n- `editor`: add `select` variant\n- `popover`: add `animate` variant\n\nhttps://github.com/udecode/plate/pull/3807/files\n- `toc-element`: remove `

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%0D1Te@IAFH1n$L#x?pbN=c6EepKf$uu3eR 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 literal 0 HcmV?d00001 From 6ee949e8d38efddee1a74ab93a2141d618411691 Mon Sep 17 00:00:00 2001 From: zbeyens Date: Thu, 26 Mar 2026 17:25:17 +0100 Subject: [PATCH 2/9] chore: update PR plan log EOF && command git push --- .../plans/2026-03-26-pr-and-comment-4900.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.claude/docs/plans/2026-03-26-pr-and-comment-4900.md b/.claude/docs/plans/2026-03-26-pr-and-comment-4900.md index c8ce3c690c..7030012c73 100644 --- a/.claude/docs/plans/2026-03-26-pr-and-comment-4900.md +++ b/.claude/docs/plans/2026-03-26-pr-and-comment-4900.md @@ -6,14 +6,19 @@ Open or update the PR for the current checkout, then update the existing GitHub ## Checklist -- [in_progress] Load the PR workflow and record the task plan -- [pending] Run `check` -- [pending] Inspect branch and PR state -- [pending] Commit and push the full current checkout -- [pending] Open or update the PR -- [pending] Update the existing `#4900` issue comment with the PR link +- [completed] Load the PR workflow and record the task plan +- [completed] Run `check` +- [completed] Inspect branch and PR state +- [completed] Commit and push the full current checkout +- [completed] Open or update the PR +- [completed] Update the existing `#4900` issue comment with the PR link ## Findings - Repo rules require `check` before any PR create or update. - Repo rules also require using the entire current checkout as-is, including unrelated changes. +- The first `check` run failed in `packages/ai/src/react/ai-chat/utils/aiChatActions.spec.ts` because `resetAIChat.ts` imported `clearAIStreamSnapshot` through the AI lib barrel, which pulled in markdown serializer exports the test mock did not provide. +- Narrowing that import to `../../../lib/transforms/aiStreamSnapshot` fixed the failing spec without changing behavior. +- `pnpm check` passed after the import fix. +- Opened PR: `https://github.com/udecode/plate/pull/4902` +- Updated issue comment: `https://github.com/udecode/plate/issues/4900#issuecomment-4136090707` From 720b018dfa02d3aa9245f152520b08ae69a04b02 Mon Sep 17 00:00:00 2001 From: zbeyens Date: Thu, 26 Mar 2026 17:26:24 +0100 Subject: [PATCH 3/9] chore: add PR browser proof --- tmp-pr-4902-editor-ai.png | Bin 0 -> 138132 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tmp-pr-4902-editor-ai.png diff --git a/tmp-pr-4902-editor-ai.png b/tmp-pr-4902-editor-ai.png new file mode 100644 index 0000000000000000000000000000000000000000..28bcf02630a1f1ce3d59b796e238520659916d5e GIT binary patch literal 138132 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 LXe+-~v Date: Thu, 26 Mar 2026 21:26:34 +0100 Subject: [PATCH 4/9] fix: localize ai preview rollback keep insert preview accept/cancel local preserve selection through accept undo redo stabilize ai chat specs on shared mocks --- ...026-03-26-ai-preview-localized-rollback.md | 53 +++ .../2026-03-26-ai-preview-tf-api-refactor.md | 22 ++ ...6-03-26-ai-stream-snapshot-design-grill.md | 17 + .../plans/2026-03-26-ignore-tmp-artifacts.md | 18 ++ ...w-should-snapshot-before-unsaved-chunks.md | 115 ------- ...g-preview-should-use-localized-rollback.md | 107 +++++++ .gitignore | 1 + apps/www/public/r/ai-kit.json | 2 +- .../__tests__/createTestEditor.tsx | 48 ++- .../ai-chat-streaming/streamHistory.slow.tsx | 54 +++- .../components/editor/plugins/ai-kit.tsx | 18 +- packages/ai/src/lib/BaseAIPlugin.ts | 40 ++- .../lib/transforms/aiStreamSnapshot.spec.ts | 302 ++++++++++++++++++ .../ai/src/lib/transforms/aiStreamSnapshot.ts | 240 ++++++++++++-- packages/ai/src/lib/transforms/index.ts | 1 - packages/ai/src/lib/transforms/undoAI.spec.ts | 72 +++++ packages/ai/src/lib/transforms/undoAI.ts | 6 +- packages/ai/src/react/ai-chat/AIChatPlugin.ts | 4 +- .../ai-chat/hooks/useAIChatEditor.spec.tsx | 27 +- .../ai-chat/hooks/useEditorChat.spec.tsx | 26 +- .../ai-chat/streaming/streamInsertChunk.ts | 95 ++++-- .../react/ai-chat/transforms/acceptAIChat.ts | 69 ++-- .../ai-chat/transforms/insertBelowAIChat.ts | 6 +- .../react/ai-chat/utils/aiChatActions.spec.ts | 66 +++- .../utils/getLastAssistantMessage.spec.ts | 29 +- .../ai/src/react/ai-chat/utils/resetAIChat.ts | 10 +- .../react/ai-chat/utils/submitAIChat.spec.ts | 27 +- .../src/react/ai-chat/utils/submitAIChat.ts | 4 +- packages/ai/src/react/ai-chat/withAIChat.ts | 6 +- packages/slate/src/slate-history/history.ts | 1 + .../src/slate-history/with-history.spec.tsx | 93 ++++++ .../slate/src/slate-history/with-history.ts | 27 +- tmp-issue-4900-editor-ai.png | Bin 138532 -> 0 bytes tmp-pr-4902-editor-ai.png | Bin 138132 -> 0 bytes 34 files changed, 1295 insertions(+), 311 deletions(-) create mode 100644 .claude/docs/plans/2026-03-26-ai-preview-localized-rollback.md create mode 100644 .claude/docs/plans/2026-03-26-ai-preview-tf-api-refactor.md create mode 100644 .claude/docs/plans/2026-03-26-ai-stream-snapshot-design-grill.md create mode 100644 .claude/docs/plans/2026-03-26-ignore-tmp-artifacts.md delete mode 100644 .claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-snapshot-before-unsaved-chunks.md create mode 100644 .claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-use-localized-rollback.md create mode 100644 packages/ai/src/lib/transforms/aiStreamSnapshot.spec.ts delete mode 100644 tmp-issue-4900-editor-ai.png delete mode 100644 tmp-pr-4902-editor-ai.png diff --git a/.claude/docs/plans/2026-03-26-ai-preview-localized-rollback.md b/.claude/docs/plans/2026-03-26-ai-preview-localized-rollback.md new file mode 100644 index 0000000000..40ea3858f0 --- /dev/null +++ b/.claude/docs/plans/2026-03-26-ai-preview-localized-rollback.md @@ -0,0 +1,53 @@ +# AI Preview Localized Rollback + +## Goal + +Replace full-document AI preview snapshotting with localized insert-mode rollback so preview accept/cancel only touch the preview block range, while preserving current undo/redo and selection behavior. + +## Checklist + +- [completed] Read current localized stream path, accept path, and preview tests +- [completed] Add failing tests for localized preview ownership and rollback +- [completed] Implement localized preview state and marker-based range handling +- [completed] Run targeted verification for touched packages and tests +- [blocked] Run `check`, then create or update the PR + +## Verification + +- `bun test packages/ai/src/lib/transforms/aiStreamSnapshot.spec.ts packages/ai/src/lib/transforms/undoAI.spec.ts apps/www/src/__tests__/package-integration/ai-chat-streaming/streamHistory.slow.tsx` +- `pnpm install` +- `pnpm turbo build --filter=./packages/ai --filter=./apps/www` +- `pnpm turbo typecheck --filter=./packages/ai` +- `pnpm build` +- `pnpm turbo typecheck --filter=./packages/ai --filter=./apps/www` after root build +- `pnpm lint:fix` +- `agent-browser open http://localhost:3100/blocks/editor-ai` + +## Blocker + +- `pnpm check` still fails outside this diff in existing fast AI chat tests: + - `packages/ai/src/react/ai-chat/hooks/useAIChatEditor.spec.tsx` + - `packages/ai/src/react/ai-chat/hooks/useEditorChat.spec.tsx` + - `packages/ai/src/react/ai-chat/utils/getLastAssistantMessage.spec.ts` +- The failure is a `SyntaxError` from missing exports in `packages/plate/src/react/index.tsx`, so PR creation is blocked by repo rules. + +## Agreed Design + +- Keep the public surface on `tf.ai.*` +- Optimize insert-mode preview only +- Keep preview state private and editor-scoped +- `beginPreview` accepts `{ originalBlocks }` +- `selectionBefore` is still captured inside `beginPreview` +- Preview-owned content is tracked by transient top-level block markers +- `cancelPreview` restores the exact original block slice plus selection +- `acceptPreview` localizes cleanup/commit and never rebuilds the whole document +- Untouched blocks should keep identity because preview accept/cancel stop using full-doc `setValue` + +## Open Implementation Notes + +- Mark preview-owned top-level blocks with `aiPreview: true` +- Do not mark the `aiChat` anchor block as preview-owned +- If preview starts by removing an empty paragraph, capture that exact block in `originalBlocks` +- If preview inserts after existing content, capture `[]` +- Derive the current preview range from contiguous marked top-level blocks +- If preview range is invalid/non-contiguous, fall back safely instead of silently guessing diff --git a/.claude/docs/plans/2026-03-26-ai-preview-tf-api-refactor.md b/.claude/docs/plans/2026-03-26-ai-preview-tf-api-refactor.md new file mode 100644 index 0000000000..d7698f1156 --- /dev/null +++ b/.claude/docs/plans/2026-03-26-ai-preview-tf-api-refactor.md @@ -0,0 +1,22 @@ +# AI Preview `tf.ai` Refactor + +## Goal + +Replace the low-level AI preview snapshot helper surface with `tf.ai.*` lifecycle transforms, keep the full-document snapshot strategy private, migrate insert-mode preview callers, and preserve the current no-history preview behavior. + +## Checklist + +- [completed] Gather current AI preview/history patterns and relevant learnings +- [completed] Add or update tests for the new preview lifecycle contract +- [completed] Implement `tf.ai.*` preview transforms in `BaseAIPlugin` +- [completed] Migrate AI chat preview callsites off direct snapshot helpers +- [completed] Run required verification for `packages/ai` and `apps/www` + +## Findings + +- The current preview storage lives in `packages/ai/src/lib/transforms/aiStreamSnapshot.ts` as a `WeakMap` keyed by editor. +- The current low-level helper surface is used directly by `acceptAIChat`, `undoAI`, `resetAIChat`, the editor AI kit, and the streaming integration test. +- The existing solution doc already established the correct behavior boundary: preview chunks stay out of history; accept commits one fresh batch; AI undo restores the pre-stream value while preview is active. +- `AIPlugin` already owns editor mutation semantics like `insertNodes`, `removeMarks`, `removeNodes`, and `undo`, so preview lifecycle belongs there too. +- The cleanest public surface here is `tf.ai.*`, while library internals and stricter callsites can still reach the same transforms through `editor.getTransforms(BaseAIPlugin).ai` where generic editor typing is narrower. +- Package-scoped verification passed for `@platejs/ai`; filtered `apps/www` typecheck still has unrelated workspace export/type failures after the required root `pnpm build`, so that debt remains outside this refactor. diff --git a/.claude/docs/plans/2026-03-26-ai-stream-snapshot-design-grill.md b/.claude/docs/plans/2026-03-26-ai-stream-snapshot-design-grill.md new file mode 100644 index 0000000000..6cedca6148 --- /dev/null +++ b/.claude/docs/plans/2026-03-26-ai-stream-snapshot-design-grill.md @@ -0,0 +1,17 @@ +# AI Stream Snapshot Design Grill + +## Goal + +Stress-test the next-step design for AI insert-mode preview state, especially whether snapshot state should live in plugin state, what the public surface should be, and how to avoid a performance regression on long documents. + +## Checklist + +- [in_progress] Inspect current AI/plugin state patterns in the repo +- [pending] Decide whether preview state should live in plugin state, transform state, or private module state +- [pending] Decide whether the public surface should be `api`, `tf`, or package-private helpers +- [pending] Walk the remaining design forks with explicit recommendations + +## Findings + +- The current implementation stores preview state in a module-level `WeakMap` keyed by editor. +- The current helper surface is low-level snapshot terminology, not workflow terminology. diff --git a/.claude/docs/plans/2026-03-26-ignore-tmp-artifacts.md b/.claude/docs/plans/2026-03-26-ignore-tmp-artifacts.md new file mode 100644 index 0000000000..9aaec87102 --- /dev/null +++ b/.claude/docs/plans/2026-03-26-ignore-tmp-artifacts.md @@ -0,0 +1,18 @@ +# Ignore Tmp Artifacts + +## Goal + +Stop root-level `tmp*` artifacts from being committed and remove the accidentally committed browser proof PNGs from the current PR branch. + +## Checklist + +- [in_progress] Inspect current ignore rules and tracked tmp artifacts +- [pending] Add ignore rule for root `tmp*` artifacts +- [pending] Remove tracked tmp PNGs from the branch diff +- [pending] Run the PR gate +- [pending] Commit and push the cleanup + +## Findings + +- `.gitignore` already ignores `/tmp`, but not root files like `tmp-issue-4900-editor-ai.png`. +- The current branch still tracks `tmp-issue-4900-editor-ai.png` and `tmp-pr-4902-editor-ai.png`. diff --git a/.claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-snapshot-before-unsaved-chunks.md b/.claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-snapshot-before-unsaved-chunks.md deleted file mode 100644 index 5cdea7651c..0000000000 --- a/.claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-snapshot-before-unsaved-chunks.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -module: AI -date: 2026-03-26 -problem_type: performance_issue -component: assistant -symptoms: - - "Long insert-mode AI streams make `tf.ai.undo()` slower as chunk count grows" - - "Accepting streamed AI output also gets slower after long responses" - - "The last AI undo batch contains one history entry but still stores a large number of underlying operations" -root_cause: logic_error -resolution_type: code_fix -severity: high -tags: - - ai - - streaming - - undo - - history - - withAIBatch - - streamInsertChunk - - performance ---- - -# AI streaming preview should snapshot before unsaved chunks - -## Problem - -Insert-mode AI streaming was wrapping every `streamInsertChunk` call in `withAIBatch`. - -That looked reasonable because it kept the whole preview in one undo batch, but the batch still accumulated every streamed operation. Undo cost therefore scaled with chunk count instead of the final accepted content. - -## Symptoms - -- `tf.ai.undo()` became progressively slower after long streamed responses. -- Accepting insert-mode AI output also slowed down after long streams. -- History looked compact at a glance because there was only one undo batch, but that batch still held a large operations array. - -## What Didn't Work - -Reading `withAIBatch` in isolation was misleading. It only does two things: - -1. merge into the current history batch -2. tag the batch as AI-generated - -It does not compact prior operations. - -Chasing `streamInsertChunk` alone was also the wrong level. The real problem was not the transform logic itself. The problem was treating streamed preview updates as normal history writes. - -## Solution - -Capture the editor state once before insert-mode streaming starts, stream preview chunks with `withoutSaving`, and only write history when the user accepts the final result. - -The implementation had three parts: - -### 1. Capture a pre-stream snapshot - -```ts -captureAIStreamSnapshot(editor); - -editor.tf.withoutSaving(() => { - editor.tf.insertNodes({ - children: [{ text: '' }], - type: getPluginType(editor, KEYS.aiChat), - }); -}); -``` - -### 2. Keep streamed preview out of history - -```ts -editor.tf.withoutSaving(() => { - if (!getOption('streaming')) return; - - editor.tf.withScrolling(() => { - streamInsertChunk(editor, chunk, { - textProps: { - [getPluginType(editor, KEYS.ai)]: true, - }, - }); - }); -}); -``` - -### 3. Accept by restoring the snapshot, then committing the final value once - -```ts -if (!commitAIStreamValue(editor, getAcceptedInsertValue(editor))) { - withAIBatch(editor, () => { - tf.ai.removeMarks(); - editor.getTransforms(AIChatPlugin).aiChat.removeAnchor(); - }); -} -``` - -`tf.ai.undo()` also gained a snapshot restore fallback. If there is no AI-tagged history batch but AI preview content still exists, it restores the captured pre-stream state instead of trying to replay chunk history. - -## Why This Works - -Preview streaming and accepted editor history have different jobs: - -- preview streaming needs responsive incremental rendering -- accepted editor history needs one sane undo step - -Using one mechanism for both creates the slowdown. A merged history batch is still a transcript of every chunk. Restoring a snapshot avoids that transcript entirely. - -The accept path then turns the preview into one fresh history entry whose cost scales with the final document diff, not with how many network chunks arrived on the way there. - -## Prevention - -- Do not use `withAIBatch` for insert-mode preview streaming. Use it for saved AI edits, not for chunk-by-chunk preview rendering. -- If streamed content is disposable preview state, snapshot first and stream with `withoutSaving`. -- When accept should remain undoable, restore the snapshot and commit the final accepted value in one new batch. -- Test both sides of the flow: - - preview streaming should leave history empty before accept - - accept should create one compact undoable batch - - `tf.ai.undo()` should restore the original pre-stream value when preview is still present diff --git a/.claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-use-localized-rollback.md b/.claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-use-localized-rollback.md new file mode 100644 index 0000000000..b264c96363 --- /dev/null +++ b/.claude/docs/solutions/performance-issues/2026-03-26-ai-streaming-preview-should-use-localized-rollback.md @@ -0,0 +1,107 @@ +--- +module: AI +date: 2026-03-26 +problem_type: performance_issue +component: assistant +symptoms: + - "Insert-mode AI streaming hitches on large documents before the first preview chunk appears" + - "Accepting or canceling a streamed preview can touch the whole document even when only one block changed" + - "Untouched blocks lose identity because preview accept/cancel rebuilds the entire editor value" +root_cause: logic_error +resolution_type: code_fix +severity: high +tags: + - ai + - streaming + - undo + - redo + - performance + - history + - selection + - streamInsertChunk +--- + +# AI streaming preview should use localized rollback + +## Problem + +Insert-mode AI preview was restoring and recommitting the whole editor value. + +That kept chunk history out of undo, but it still deep-cloned the full document and used full-document `setValue` on accept and cancel. Large documents therefore paid a document-sized cost for a paragraph-sized preview. + +## Symptoms + +- The first streamed insert chunk felt slower on long documents. +- Accept and cancel touched more editor state than the preview actually changed. +- Untouched blocks were more likely to lose identity because the whole tree was replaced. + +## Solution + +Treat insert-mode preview as a localized top-level block range instead of a full-document snapshot. + +### 1. Capture only the replaced slice + +`tf.ai.beginPreview` stores: + +- `originalBlocks`: the exact top-level blocks the preview overwrites +- `selectionBefore`: the original selection + +When streaming starts from an empty paragraph, `originalBlocks` is that paragraph. When streaming inserts after existing content, `originalBlocks` is `[]`. + +### 2. Mark preview-owned blocks during streaming + +`streamInsertChunk` tags preview-owned top-level blocks with `aiPreview: true` while keeping AI text leaves marked with the normal AI text prop. + +That makes the live preview range discoverable without relying on drifting paths. + +### 3. Cancel by restoring only the marked range + +`tf.ai.cancelPreview()`: + +- finds the contiguous top-level `aiPreview` range +- replaces only that range with `originalBlocks` +- removes the AI chat anchor +- restores `selectionBefore` + +All of that runs in `withoutSaving`, so preview cancel still stays out of history. + +### 4. Accept by localized restore-then-commit + +`tf.ai.acceptPreview()`: + +- clones only the marked preview blocks +- strips `aiPreview` and AI text marks from that local clone +- restores the original block slice with `withoutSaving` +- inserts the accepted local blocks in one fresh history batch +- stamps that batch with the original `selectionBefore` + +That produces a single undoable commit whose cost scales with the preview range, not the whole document. + +## Why This Works + +The preview and the committed edit need different behavior: + +- preview needs cheap incremental rendering with no history writes +- accept needs one real undoable edit + +The trick is not “snapshot everything once.” The trick is “remember only what this preview replaced, then commit only that region.” + +That keeps: + +- chunk history out of undo +- accept and cancel local +- undo restoring the original content and selection +- redo restoring the accepted content and selection + +## Prevention + +- Do not use full-document `setValue` for insert-mode preview accept or cancel. +- Store the overwritten top-level slice, not the entire editor value. +- Tag preview-owned streamed blocks so the current preview range can be found from the document itself. +- Keep anchor removal out of the committed batch. The original state did not contain the anchor. +- Test the full flow: + - preview stays out of history + - cancel restores exact content and selection + - accept creates one undoable batch + - undo restores original content and selection + - redo restores accepted content and selection diff --git a/.gitignore b/.gitignore index e59454bb5d..51d9960141 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ jspm_packages/ # compiled output /dist /tmp +/tmp* /out-tsc **/build diff --git a/apps/www/public/r/ai-kit.json b/apps/www/public/r/ai-kit.json index 4c2d06832d..f6901d0168 100644 --- a/apps/www/public/r/ai-kit.json +++ b/apps/www/public/r/ai-kit.json @@ -16,7 +16,7 @@ "files": [ { "path": "src/registry/components/editor/plugins/ai-kit.tsx", - "content": "'use client';\n\nimport { captureAIStreamSnapshot, withAIBatch } from '@platejs/ai';\nimport {\n AIChatPlugin,\n AIPlugin,\n applyAISuggestions,\n streamInsertChunk,\n useChatChunk,\n} from '@platejs/ai/react';\nimport { getPluginType, KEYS, PathApi } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nimport { AILoadingBar, AIMenu } from '@/registry/ui/ai-menu';\nimport { AIAnchorElement, AILeaf } from '@/registry/ui/ai-node';\n\nimport { useChat } from '../use-chat';\nimport { CursorOverlayKit } from './cursor-overlay-kit';\nimport { MarkdownKit } from './markdown-kit';\n\nexport const aiChatPlugin = AIChatPlugin.extend({\n options: {\n chatOptions: {\n api: '/api/ai/command',\n body: {},\n },\n },\n render: {\n afterContainer: AILoadingBar,\n afterEditable: AIMenu,\n node: AIAnchorElement,\n },\n shortcuts: { show: { keys: 'mod+j' } },\n useHooks: ({ editor, getOption }) => {\n useChat();\n\n const mode = usePluginOption(AIChatPlugin, 'mode');\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n useChatChunk({\n onChunk: ({ chunk, isFirst, nodes, text: content }) => {\n if (isFirst && mode === 'insert') {\n captureAIStreamSnapshot(editor);\n\n editor.tf.withoutSaving(() => {\n editor.tf.insertNodes(\n {\n children: [{ text: '' }],\n type: getPluginType(editor, KEYS.aiChat),\n },\n {\n at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),\n }\n );\n });\n editor.setOption(AIChatPlugin, 'streaming', true);\n }\n\n if (mode === 'insert' && nodes.length > 0) {\n editor.tf.withoutSaving(() => {\n if (!getOption('streaming')) return;\n\n editor.tf.withScrolling(() => {\n streamInsertChunk(editor, chunk, {\n textProps: {\n [getPluginType(editor, KEYS.ai)]: true,\n },\n });\n });\n });\n }\n\n if (toolName === 'edit' && mode === 'chat') {\n withAIBatch(\n editor,\n () => {\n applyAISuggestions(editor, content);\n },\n {\n split: isFirst,\n }\n );\n }\n },\n onFinish: () => {\n editor.setOption(AIChatPlugin, 'streaming', false);\n editor.setOption(AIChatPlugin, '_blockChunks', '');\n editor.setOption(AIChatPlugin, '_blockPath', null);\n editor.setOption(AIChatPlugin, '_mdxName', null);\n },\n });\n },\n});\n\nexport const AIKit = [\n ...CursorOverlayKit,\n ...MarkdownKit,\n AIPlugin.withComponent(AILeaf),\n aiChatPlugin,\n];\n", + "content": "'use client';\n\nimport cloneDeep from 'lodash/cloneDeep.js';\nimport { BaseAIPlugin, withAIBatch } from '@platejs/ai';\nimport {\n AIChatPlugin,\n AIPlugin,\n applyAISuggestions,\n getInsertPreviewStart,\n streamInsertChunk,\n useChatChunk,\n} from '@platejs/ai/react';\nimport { getPluginType, KEYS, PathApi } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nimport { AILoadingBar, AIMenu } from '@/registry/ui/ai-menu';\nimport { AIAnchorElement, AILeaf } from '@/registry/ui/ai-node';\n\nimport { useChat } from '../use-chat';\nimport { CursorOverlayKit } from './cursor-overlay-kit';\nimport { MarkdownKit } from './markdown-kit';\n\nexport const aiChatPlugin = AIChatPlugin.extend({\n options: {\n chatOptions: {\n api: '/api/ai/command',\n body: {},\n },\n },\n render: {\n afterContainer: AILoadingBar,\n afterEditable: AIMenu,\n node: AIAnchorElement,\n },\n shortcuts: { show: { keys: 'mod+j' } },\n useHooks: ({ editor, getOption }) => {\n useChat();\n\n const mode = usePluginOption(AIChatPlugin, 'mode');\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n useChatChunk({\n onChunk: ({ chunk, isFirst, nodes, text: content }) => {\n if (isFirst && mode === 'insert') {\n const { startBlock, startInEmptyParagraph } =\n getInsertPreviewStart(editor);\n\n editor.getTransforms(BaseAIPlugin).ai.beginPreview({\n originalBlocks:\n startInEmptyParagraph && startBlock ? [cloneDeep(startBlock)] : [],\n });\n\n editor.tf.withoutSaving(() => {\n editor.tf.insertNodes(\n {\n children: [{ text: '' }],\n type: getPluginType(editor, KEYS.aiChat),\n },\n {\n at: PathApi.next(editor.selection!.focus.path.slice(0, 1)),\n }\n );\n });\n editor.setOption(AIChatPlugin, 'streaming', true);\n }\n\n if (mode === 'insert' && nodes.length > 0) {\n editor.tf.withoutSaving(() => {\n if (!getOption('streaming')) return;\n\n editor.tf.withScrolling(() => {\n streamInsertChunk(editor, chunk, {\n textProps: {\n [getPluginType(editor, KEYS.ai)]: true,\n },\n });\n });\n });\n }\n\n if (toolName === 'edit' && mode === 'chat') {\n withAIBatch(\n editor,\n () => {\n applyAISuggestions(editor, content);\n },\n {\n split: isFirst,\n }\n );\n }\n },\n onFinish: () => {\n editor.setOption(AIChatPlugin, 'streaming', false);\n editor.setOption(AIChatPlugin, '_blockChunks', '');\n editor.setOption(AIChatPlugin, '_blockPath', null);\n editor.setOption(AIChatPlugin, '_mdxName', null);\n },\n });\n },\n});\n\nexport const AIKit = [\n ...CursorOverlayKit,\n ...MarkdownKit,\n AIPlugin.withComponent(AILeaf),\n aiChatPlugin,\n];\n", "type": "registry:component" } ] diff --git a/apps/www/src/__tests__/package-integration/ai-chat-streaming/__tests__/createTestEditor.tsx b/apps/www/src/__tests__/package-integration/ai-chat-streaming/__tests__/createTestEditor.tsx index 38f8463ab1..9fae07368c 100644 --- a/apps/www/src/__tests__/package-integration/ai-chat-streaming/__tests__/createTestEditor.tsx +++ b/apps/www/src/__tests__/package-integration/ai-chat-streaming/__tests__/createTestEditor.tsx @@ -1,28 +1,44 @@ /** @jsx jsxt */ -import { BasicMarksPlugin } from '@platejs/basic-nodes/react'; -import { ListPlugin } from '@platejs/list/react'; -import { IndentPlugin } from '@platejs/indent/react'; import { jsxt } from '@platejs/test-utils'; -import { ParagraphPlugin } from 'platejs/react'; -import { EquationPlugin, InlineEquationPlugin } from '@platejs/math/react'; -import { MarkdownKit } from '@/registry/components/editor/plugins/markdown-kit'; +import { KEYS, createSlateEditor, type SlateEditor } from 'platejs'; +import remarkGfm from 'remark-gfm'; +import remarkMath from 'remark-math'; // biome-ignore lint/nursery/noUnusedExpressions: required to prevent removal by compiler jsxt; -import { createSlateEditor, type SlateEditor } from 'platejs'; -import { AIPlugin } from '../../../../../../../packages/ai/src/react/ai/AIPlugin'; import { AIChatPlugin } from '../../../../../../../packages/ai/src/react/ai-chat/AIChatPlugin'; +import { BaseAIPlugin } from '../../../../../../../packages/ai/src/lib/BaseAIPlugin'; +import { BaseBasicMarksPlugin } from '../../../../../../../packages/basic-nodes/src/lib/BaseBasicMarksPlugin'; +import { BaseIndentPlugin } from '../../../../../../../packages/indent/src/lib/BaseIndentPlugin'; +import { BaseListPlugin } from '../../../../../../../packages/list/src/lib/BaseListPlugin'; +import { MarkdownPlugin } from '../../../../../../../packages/markdown/src/lib/MarkdownPlugin'; +import { + remarkMdx, + remarkMention, +} from '../../../../../../../packages/markdown/src/lib/plugins'; +import { + BaseEquationPlugin, + BaseInlineEquationPlugin, +} from '../../../../../../../packages/math/src/lib'; +import { BaseParagraphPlugin } from '../../../../../../../packages/core/src/lib/plugins/paragraph/BaseParagraphPlugin'; + +const markdownPlugin = MarkdownPlugin.configure({ + options: { + plainMarks: [KEYS.suggestion, KEYS.comment], + remarkPlugins: [remarkMath, remarkGfm, remarkMdx, remarkMention], + }, +}); // Helper function to create input and editor with common configuration export const defaultPlugins = [ - ParagraphPlugin, - BasicMarksPlugin, - IndentPlugin, - ListPlugin, - ...MarkdownKit, - EquationPlugin, - InlineEquationPlugin, - AIPlugin, + BaseParagraphPlugin, + BaseBasicMarksPlugin, + BaseIndentPlugin, + BaseListPlugin, + markdownPlugin, + BaseEquationPlugin, + BaseInlineEquationPlugin, + BaseAIPlugin, AIChatPlugin, ]; diff --git a/apps/www/src/__tests__/package-integration/ai-chat-streaming/streamHistory.slow.tsx b/apps/www/src/__tests__/package-integration/ai-chat-streaming/streamHistory.slow.tsx index 2d3d0f7827..b20f07f51d 100644 --- a/apps/www/src/__tests__/package-integration/ai-chat-streaming/streamHistory.slow.tsx +++ b/apps/www/src/__tests__/package-integration/ai-chat-streaming/streamHistory.slow.tsx @@ -1,20 +1,29 @@ import { ElementApi, KEYS, PathApi, getPluginType } from 'platejs'; -import { AIPlugin } from '../../../../../../packages/ai/src/react/ai/AIPlugin'; import { AIChatPlugin } from '../../../../../../packages/ai/src/react/ai-chat/AIChatPlugin'; -import { streamInsertChunk } from '../../../../../../packages/ai/src/react/ai-chat/streaming/streamInsertChunk'; +import { + getInsertPreviewStart, + streamInsertChunk, +} from '../../../../../../packages/ai/src/react/ai-chat/streaming/streamInsertChunk'; import { acceptAIChat } from '../../../../../../packages/ai/src/react/ai-chat/transforms/acceptAIChat'; -import { captureAIStreamSnapshot } from '../../../../../../packages/ai/src/lib/transforms/aiStreamSnapshot'; import { createTestEditor } from './__tests__/createTestEditor'; const streamPreview = (chunks: string[]) => { const { editor } = createTestEditor(); + const initialSelection = JSON.parse(JSON.stringify(editor.selection)); const initialValue = JSON.parse(JSON.stringify(editor.children)); editor.setOption(AIChatPlugin, 'mode', 'insert'); editor.setOption(AIChatPlugin, 'open', true); - captureAIStreamSnapshot(editor); + const { startBlock, startInEmptyParagraph } = getInsertPreviewStart(editor); + + editor.tf.ai.beginPreview({ + originalBlocks: + startInEmptyParagraph && startBlock && ElementApi.isElement(startBlock) + ? [structuredClone(startBlock)] + : [], + }); editor.tf.withoutSaving(() => { editor.tf.insertNodes( @@ -45,7 +54,7 @@ const streamPreview = (chunks: string[]) => { editor.setOption(AIChatPlugin, '_blockPath', null); editor.setOption(AIChatPlugin, '_mdxName', null); - return { editor, initialValue }; + return { editor, initialSelection, initialValue }; }; describe('ai chat streaming history', () => { @@ -54,7 +63,7 @@ describe('ai chat streaming history', () => { expect(editor.history.undos).toHaveLength(0); - editor.getTransforms(AIPlugin).ai.undo(); + editor.tf.ai.undo(); expect(editor.children).toEqual(initialValue); expect(editor.history.undos).toHaveLength(0); @@ -62,7 +71,7 @@ describe('ai chat streaming history', () => { it('accepts streamed preview as a compact undoable batch', () => { const chunks = Array.from({ length: 40 }, () => 'chunk '); - const { editor, initialValue } = streamPreview(chunks); + const { editor, initialSelection, initialValue } = streamPreview(chunks); acceptAIChat(editor); @@ -84,9 +93,40 @@ describe('ai chat streaming history', () => { match: (n: any) => !!n[getPluginType(editor, KEYS.ai)], }) ).toBe(false); + expect( + editor.api.some({ + at: [], + match: (n: any) => ElementApi.isElement(n) && !!n.aiPreview, + }) + ).toBe(false); editor.undo(); expect(editor.children).toEqual(initialValue); + expect(editor.selection).toEqual(initialSelection); + }); + + it('places the cursor at the end of the accepted preview', () => { + const { editor } = streamPreview(['hello', ' world']); + + acceptAIChat(editor); + + expect(editor.selection).toEqual({ + anchor: { offset: 11, path: [0, 0] }, + focus: { offset: 11, path: [0, 0] }, + }); + }); + + it('restores the accepted cursor on redo after undo', () => { + const { editor } = streamPreview(['hello', ' world']); + + acceptAIChat(editor); + editor.undo(); + editor.redo(); + + expect(editor.selection).toEqual({ + anchor: { offset: 11, path: [0, 0] }, + focus: { offset: 11, path: [0, 0] }, + }); }); }); diff --git a/apps/www/src/registry/components/editor/plugins/ai-kit.tsx b/apps/www/src/registry/components/editor/plugins/ai-kit.tsx index fbd87f7363..b176270cad 100644 --- a/apps/www/src/registry/components/editor/plugins/ai-kit.tsx +++ b/apps/www/src/registry/components/editor/plugins/ai-kit.tsx @@ -1,14 +1,16 @@ 'use client'; -import { captureAIStreamSnapshot, withAIBatch } from '@platejs/ai'; +import cloneDeep from 'lodash/cloneDeep.js'; +import { BaseAIPlugin, withAIBatch } from '@platejs/ai'; import { AIChatPlugin, AIPlugin, applyAISuggestions, + getInsertPreviewStart, streamInsertChunk, useChatChunk, } from '@platejs/ai/react'; -import { getPluginType, KEYS, PathApi } from 'platejs'; +import { ElementApi, getPluginType, KEYS, PathApi } from 'platejs'; import { usePluginOption } from 'platejs/react'; import { AILoadingBar, AIMenu } from '@/registry/ui/ai-menu'; @@ -39,7 +41,17 @@ export const aiChatPlugin = AIChatPlugin.extend({ useChatChunk({ onChunk: ({ chunk, isFirst, nodes, text: content }) => { if (isFirst && mode === 'insert') { - captureAIStreamSnapshot(editor); + const { startBlock, startInEmptyParagraph } = + getInsertPreviewStart(editor); + + editor.getTransforms(BaseAIPlugin).ai.beginPreview({ + originalBlocks: + startInEmptyParagraph && + startBlock && + ElementApi.isElement(startBlock) + ? [cloneDeep(startBlock)] + : [], + }); editor.tf.withoutSaving(() => { editor.tf.insertNodes( diff --git a/packages/ai/src/lib/BaseAIPlugin.ts b/packages/ai/src/lib/BaseAIPlugin.ts index 74492f382a..d6cd2d1087 100644 --- a/packages/ai/src/lib/BaseAIPlugin.ts +++ b/packages/ai/src/lib/BaseAIPlugin.ts @@ -1,11 +1,19 @@ import { type OmitFirst, type PluginConfig, + type SlateEditor, bindFirst, createTSlatePlugin, KEYS, } from 'platejs'; +import { + acceptAIPreview, + beginAIPreview, + cancelAIPreview, + discardAIPreview, + hasAIPreview, +} from './transforms/aiStreamSnapshot'; import { removeAIMarks, undoAI } from './transforms'; import { insertAINodes } from './transforms/insertAINodes'; import { removeAINodes } from './transforms/removeAINodes'; @@ -16,19 +24,41 @@ export type BaseAIPluginConfig = PluginConfig< {}, { ai: { + /** Commit the active preview as one fresh undoable batch. */ + acceptPreview: OmitFirst; + /** Capture the rollback slice and selection for AI preview. */ + beginPreview: OmitFirst; + /** Restore the rollback point and clear active preview state. */ + cancelPreview: OmitFirst; + /** Clear active preview bookkeeping without restoring content. */ + discardPreview: OmitFirst; + /** Report whether an AI preview rollback point is active. */ + hasPreview: OmitFirst; insertNodes: OmitFirst; removeMarks: OmitFirst; removeNodes: OmitFirst; + undo: OmitFirst; }; } >; -export const BaseAIPlugin = createTSlatePlugin({ - key: KEYS.ai, - node: { isDecoration: false, isLeaf: true }, -}).extendTransforms(({ editor }) => ({ +const getAITransforms = (editor: SlateEditor) => ({ + acceptPreview: bindFirst(acceptAIPreview, editor), + beginPreview: bindFirst(beginAIPreview, editor), + cancelPreview: bindFirst(cancelAIPreview, editor), + discardPreview: bindFirst(discardAIPreview, editor), + hasPreview: bindFirst(hasAIPreview, editor), insertNodes: bindFirst(insertAINodes, editor), removeMarks: bindFirst(removeAIMarks, editor), removeNodes: bindFirst(removeAINodes, editor), undo: bindFirst(undoAI, editor), -})); +}); + +export const BaseAIPlugin = createTSlatePlugin({ + key: KEYS.ai, + node: { isDecoration: false, isLeaf: true }, +}) + .extendTransforms(({ editor }) => getAITransforms(editor)) + .extendEditorTransforms(({ editor }) => ({ + ai: getAITransforms(editor), + })); diff --git a/packages/ai/src/lib/transforms/aiStreamSnapshot.spec.ts b/packages/ai/src/lib/transforms/aiStreamSnapshot.spec.ts new file mode 100644 index 0000000000..dbf0c6847c --- /dev/null +++ b/packages/ai/src/lib/transforms/aiStreamSnapshot.spec.ts @@ -0,0 +1,302 @@ +import { describe, expect, it, mock } from 'bun:test'; +import { + BaseParagraphPlugin, + KEYS, + createSlateEditor, + getPluginType, +} from 'platejs'; + +import { BaseAIPlugin } from '../BaseAIPlugin'; +import { + acceptAIPreview, + beginAIPreview, + cancelAIPreview, + discardAIPreview, + hasAIPreview, +} from './aiStreamSnapshot'; + +const AI_PREVIEW_KEY = 'aiPreview'; + +const createParagraph = ( + text: string, + { + element = {}, + text: textProps = {}, + }: { element?: Record; text?: Record } = {} +) => ({ + ...element, + children: [{ text, ...textProps }], + type: 'p', +}); + +const createAnchor = () => ({ + children: [{ text: '' }], + type: 'aiChat', +}); + +const createEditor = () => { + const removeNodeAtPath = (children: any[], path: number[]) => { + if (path.length !== 1) throw new Error(`Unsupported path: ${path}`); + + children.splice(path[0], 1); + }; + + const insertNodesAtPath = (children: any[], nodes: any[], path: number[]) => { + if (path.length !== 1) throw new Error(`Unsupported path: ${path}`); + + children.splice(path[0], 0, ...structuredClone(nodes)); + }; + + const unsetNodeProps = ( + node: any, + keys: string[], + match?: (node: any) => boolean + ) => { + if (!match || match(node)) { + for (const key of keys) { + delete node[key]; + } + } + + if (node.children) { + node.children.forEach((child: any) => { + unsetNodeProps(child, keys, match); + }); + } + }; + + const editor = { + children: [createParagraph('start'), createParagraph('untouched')], + getPlugin: ({ key }: { key: string }) => ({ + key, + node: { type: key }, + }), + history: { + redos: [], + undos: [], + }, + selection: { + anchor: { offset: 0, path: [0, 0] }, + focus: { offset: 0, path: [0, 0] }, + }, + tf: { + deselect: mock(() => { + editor.selection = null; + }), + insertNodes: mock((nodes: any, options: any = {}) => { + insertNodesAtPath( + editor.children, + Array.isArray(nodes) ? nodes : [nodes], + options.at ?? [editor.children.length] + ); + }), + removeNodes: mock((options: any = {}) => { + if (options.match) { + editor.children = editor.children.filter( + (node: any) => !options.match(node) + ); + + return; + } + + removeNodeAtPath(editor.children, options.at); + }), + select: mock((selection: any) => { + editor.selection = selection; + }), + setValue: mock((value: any) => { + editor.children = value; + }), + unsetNodes: mock((props: string | string[], options: any = {}) => { + const keys = Array.isArray(props) ? props : [props]; + const path = options.at; + + if (path) { + unsetNodeProps(editor.children[path[0]], keys, options.match); + + return; + } + + editor.children.forEach((node: any) => { + unsetNodeProps(node, keys, options.match); + }); + }), + withNewBatch: mock((fn: () => void) => { + fn(); + editor.history.undos.push({ operations: [{}] }); + }), + withoutSaving: mock((fn: () => void) => { + fn(); + }), + }, + } as any; + + return editor; +}; + +describe('ai preview transforms', () => { + it('captures once and keeps the original rollback point', () => { + const editor = createEditor(); + const initialValue = structuredClone(editor.children); + const initialSelection = structuredClone(editor.selection); + const originalBlocks = [structuredClone(editor.children[0])]; + + expect(beginAIPreview(editor, { originalBlocks })).toBe(true); + + editor.children = [ + createParagraph('preview', { + element: { [AI_PREVIEW_KEY]: true }, + text: { ai: true }, + }), + createAnchor(), + structuredClone(initialValue[1]), + ]; + editor.selection = { + anchor: { offset: 7, path: [0, 0] }, + focus: { offset: 7, path: [0, 0] }, + }; + + expect(beginAIPreview(editor, { originalBlocks: [] })).toBe(false); + expect(cancelAIPreview(editor)).toBe(true); + expect(editor.children).toEqual(initialValue); + expect(editor.selection).toEqual(initialSelection); + expect(editor.tf.setValue).not.toHaveBeenCalled(); + }); + + it('cancels safely when no preview exists', () => { + const editor = createEditor(); + + expect(hasAIPreview(editor)).toBe(false); + expect(cancelAIPreview(editor)).toBe(false); + expect(discardAIPreview(editor)).toBe(false); + expect( + acceptAIPreview(editor, [{ children: [{ text: 'done' }], type: 'p' }]) + ).toBe(false); + }); + + it('discards preview bookkeeping without restoring content', () => { + const editor = createEditor(); + + beginAIPreview(editor, { originalBlocks: [] }); + editor.children = [ + createParagraph('preview', { element: { [AI_PREVIEW_KEY]: true } }), + ]; + editor.selection = null; + + expect(discardAIPreview(editor)).toBe(true); + expect(hasAIPreview(editor)).toBe(false); + expect(editor.children).toEqual([ + createParagraph('preview', { element: { [AI_PREVIEW_KEY]: true } }), + ]); + expect(editor.selection).toBeNull(); + }); + + it('restores a null snapshot selection by deselecting', () => { + const editor = createEditor(); + + editor.selection = null; + beginAIPreview(editor, { + originalBlocks: [structuredClone(editor.children[0])], + }); + editor.selection = { + anchor: { offset: 7, path: [0, 0] }, + focus: { offset: 7, path: [0, 0] }, + }; + editor.children = [ + createParagraph('preview', { + element: { [AI_PREVIEW_KEY]: true }, + text: { ai: true }, + }), + createAnchor(), + createParagraph('untouched'), + ]; + + expect(cancelAIPreview(editor)).toBe(true); + expect(editor.tf.deselect).toHaveBeenCalledTimes(1); + expect(editor.selection).toBeNull(); + }); + + it('accepts preview as one localized batch and clears preview state', () => { + const editor = createEditor(); + const initialSelection = structuredClone(editor.selection); + + beginAIPreview(editor, { + originalBlocks: [structuredClone(editor.children[0])], + }); + editor.children = [ + createParagraph('accepted', { + element: { [AI_PREVIEW_KEY]: true }, + text: { ai: true }, + }), + createAnchor(), + createParagraph('untouched'), + ]; + + expect(acceptAIPreview(editor)).toBe(true); + expect(editor.tf.withNewBatch).toHaveBeenCalledTimes(1); + expect(editor.tf.setValue).not.toHaveBeenCalled(); + expect(editor.children).toEqual([ + createParagraph('accepted'), + createParagraph('untouched'), + ]); + expect(hasAIPreview(editor)).toBe(false); + expect(editor.history.undos.at(-1)?.selectionBefore).toEqual( + initialSelection + ); + }); + + it('registers the preview lifecycle on BaseAIPlugin transforms', () => { + const editor = createSlateEditor({ + plugins: [BaseParagraphPlugin, BaseAIPlugin], + selection: { + anchor: { offset: 5, path: [0, 0] }, + focus: { offset: 5, path: [0, 0] }, + }, + value: [{ children: [{ text: 'start' }], type: 'p' }], + }); + const initialValue = structuredClone(editor.children); + const ai = editor.getTransforms(BaseAIPlugin).ai; + const aiType = getPluginType(editor, KEYS.ai); + const aiChatType = getPluginType(editor, KEYS.aiChat); + + expect(ai.hasPreview()).toBe(false); + expect(ai.beginPreview({ originalBlocks: [] })).toBe(true); + + editor.tf.withoutSaving(() => { + editor.tf.insertNodes( + [ + { + children: [{ text: 'accepted', [aiType]: true }], + [AI_PREVIEW_KEY]: true, + type: 'p', + }, + { + children: [{ text: '' }], + type: aiChatType, + }, + ], + { at: [1] } + ); + }); + + expect(editor.history.undos).toHaveLength(0); + expect(ai.acceptPreview()).toBe(true); + expect(editor.children).toEqual([ + { children: [{ text: 'start' }], type: 'p' }, + { children: [{ text: 'accepted' }], type: 'p' }, + ]); + expect(editor.history.undos).toHaveLength(1); + expect(editor.history.undos[0]?.selectionBefore).toEqual({ + anchor: { offset: 5, path: [0, 0] }, + focus: { offset: 5, path: [0, 0] }, + }); + + editor.undo(); + + expect(editor.children).toEqual(initialValue); + expect(editor.selection).toEqual({ + anchor: { offset: 5, path: [0, 0] }, + focus: { offset: 5, path: [0, 0] }, + }); + }); +}); diff --git a/packages/ai/src/lib/transforms/aiStreamSnapshot.ts b/packages/ai/src/lib/transforms/aiStreamSnapshot.ts index 94dc2b4759..cdc22d22a7 100644 --- a/packages/ai/src/lib/transforms/aiStreamSnapshot.ts +++ b/packages/ai/src/lib/transforms/aiStreamSnapshot.ts @@ -1,58 +1,238 @@ import cloneDeep from 'lodash/cloneDeep.js'; -import type { SlateEditor, TRange, Value } from 'platejs'; +import { + ElementApi, + KEYS, + type SlateEditor, + type TRange, + type Value, + getPluginType, +} from 'platejs'; -type AIStreamSnapshot = { - children: Value; - selection: TRange | null; +type AIPreviewState = { + originalBlocks: Value; + selectionBefore: TRange | null; }; -const AI_STREAM_SNAPSHOT = new WeakMap(); +type BeginAIPreviewOptions = { + originalBlocks?: Value; +}; + +type PreviewRange = + | { kind: 'invalid' | 'none' } + | { + end: number; + kind: 'range'; + start: number; + }; + +export const AI_PREVIEW_KEY = 'aiPreview'; + +const AI_STREAM_SNAPSHOT = new WeakMap(); + +const clearAIPreview = (editor: SlateEditor) => { + AI_STREAM_SNAPSHOT.delete(editor); +}; + +const getAIPreview = (editor: SlateEditor) => AI_STREAM_SNAPSHOT.get(editor); + +const getAIPreviewRange = (editor: SlateEditor): PreviewRange => { + let closed = false; + let end = -1; + let invalid = false; + let start = -1; + + editor.children.forEach((node: any, index) => { + if (!node?.[AI_PREVIEW_KEY]) { + if (start !== -1) { + closed = true; + } + + return; + } + + if (closed) { + invalid = true; + return; + } + + if (start === -1) { + start = index; + } + + end = index; + }); + + if (invalid) return { kind: 'invalid' }; + if (start === -1 && end === -1) return { kind: 'none' }; -export const captureAIStreamSnapshot = ( + return { + end, + kind: 'range', + start, + }; +}; + +const removeAIPreviewAnchor = (editor: SlateEditor) => { + const aiChatType = getPluginType(editor, KEYS.aiChat); + + editor.tf.removeNodes({ + at: [], + match: (node) => ElementApi.isElement(node) && node.type === aiChatType, + }); +}; + +const restoreAIPreviewSelection = ( editor: SlateEditor, - snapshot: AIStreamSnapshot = { - children: cloneDeep(editor.children), - selection: cloneDeep(editor.selection), + selection: TRange | null +) => { + if (selection) { + editor.tf.select(cloneDeep(selection)); + + return; } + + editor.tf.deselect(); +}; + +const removePreviewRange = ( + editor: SlateEditor, + range: Extract ) => { - AI_STREAM_SNAPSHOT.set(editor, snapshot); + for (let index = range.end; index >= range.start; index--) { + editor.tf.removeNodes({ at: [index] }); + } +}; - return snapshot; +const replacePreviewRange = ( + editor: SlateEditor, + range: Extract, + blocks: Value +) => { + removePreviewRange(editor, range); + + if (blocks.length === 0) return; + + editor.tf.insertNodes(cloneDeep(blocks), { at: [range.start] }); }; -export const clearAIStreamSnapshot = (editor: SlateEditor) => { - AI_STREAM_SNAPSHOT.delete(editor); +const cloneAcceptedPreviewBlocks = ( + editor: SlateEditor, + range: Extract +) => { + const aiType = getPluginType(editor, KEYS.ai); + const blocks = cloneDeep(editor.children.slice(range.start, range.end + 1)); + + const stripNode = (node: any): any => { + if (ElementApi.isElement(node)) { + const { [AI_PREVIEW_KEY]: _preview, children, ...rest } = node; + + return { + ...rest, + children: children.map(stripNode), + }; + } + + const { [aiType]: _ai, ...rest } = node; + + return rest; + }; + + return blocks.map(stripNode); }; -export const getAIStreamSnapshot = (editor: SlateEditor) => - AI_STREAM_SNAPSHOT.get(editor); +export const beginAIPreview = ( + editor: SlateEditor, + { originalBlocks = [] }: BeginAIPreviewOptions = {} +) => { + if (getAIPreview(editor)) return false; -export const restoreAIStreamSnapshot = (editor: SlateEditor) => { - const snapshot = getAIStreamSnapshot(editor); + AI_STREAM_SNAPSHOT.set(editor, { + originalBlocks: cloneDeep(originalBlocks), + selectionBefore: cloneDeep(editor.selection), + }); - if (!snapshot) return false; + return true; +}; - editor.tf.withoutSaving(() => { - editor.tf.setValue(cloneDeep(snapshot.children)); +export const hasAIPreview = (editor: SlateEditor) => !!getAIPreview(editor); + +export const cancelAIPreview = (editor: SlateEditor) => { + const preview = getAIPreview(editor); - if (snapshot.selection) { - editor.tf.setSelection(cloneDeep(snapshot.selection)); - } else { - editor.tf.deselect(); + if (!preview) return false; + + const range = getAIPreviewRange(editor); + + if (range.kind === 'invalid') return false; + + editor.tf.withoutSaving(() => { + if (range.kind === 'range') { + replacePreviewRange(editor, range, preview.originalBlocks); } + + removeAIPreviewAnchor(editor); + restoreAIPreviewSelection(editor, preview.selectionBefore); }); - clearAIStreamSnapshot(editor); + clearAIPreview(editor); return true; }; -export const commitAIStreamValue = (editor: SlateEditor, value: Value) => { - if (!restoreAIStreamSnapshot(editor)) return false; +export const discardAIPreview = (editor: SlateEditor) => { + if (!getAIPreview(editor)) return false; - editor.tf.withNewBatch(() => { - editor.tf.setValue(cloneDeep(value)); - }); + clearAIPreview(editor); + + return true; +}; + +export const acceptAIPreview = (editor: SlateEditor, _value?: Value) => { + const preview = getAIPreview(editor); + + if (!preview) return false; + + const range = getAIPreviewRange(editor); + + if (range.kind === 'invalid') return false; + + if (range.kind === 'range') { + const acceptedBlocks = cloneAcceptedPreviewBlocks(editor, range); + + editor.tf.withoutSaving(() => { + replacePreviewRange(editor, range, preview.originalBlocks); + removeAIPreviewAnchor(editor); + restoreAIPreviewSelection(editor, preview.selectionBefore); + }); + + editor.tf.withNewBatch(() => { + if (preview.originalBlocks.length > 0) { + for ( + let index = preview.originalBlocks.length - 1; + index >= 0; + index-- + ) { + editor.tf.removeNodes({ at: [range.start + index] }); + } + } + + if (acceptedBlocks.length > 0) { + editor.tf.insertNodes(acceptedBlocks, { at: [range.start] }); + } + }); + + const lastBatch = editor.history?.undos.at(-1); + + if (lastBatch) { + lastBatch.selectionBefore = cloneDeep(preview.selectionBefore); + } + } else { + editor.tf.withoutSaving(() => { + removeAIPreviewAnchor(editor); + }); + } + + clearAIPreview(editor); return true; }; diff --git a/packages/ai/src/lib/transforms/index.ts b/packages/ai/src/lib/transforms/index.ts index 4b09f16ffc..e8489a6ecb 100644 --- a/packages/ai/src/lib/transforms/index.ts +++ b/packages/ai/src/lib/transforms/index.ts @@ -3,7 +3,6 @@ */ export * from './insertAINodes'; -export * from './aiStreamSnapshot'; export * from './removeAIMarks'; export * from './removeAINodes'; export * from './undoAI'; diff --git a/packages/ai/src/lib/transforms/undoAI.spec.ts b/packages/ai/src/lib/transforms/undoAI.spec.ts index 779499e6f2..d798aaf06a 100644 --- a/packages/ai/src/lib/transforms/undoAI.spec.ts +++ b/packages/ai/src/lib/transforms/undoAI.spec.ts @@ -1,5 +1,6 @@ import { getTransientSuggestionKey } from '@platejs/suggestion'; +import { AI_PREVIEW_KEY, beginAIPreview } from './aiStreamSnapshot'; import { undoAI } from './undoAI'; describe('undoAI', () => { @@ -47,4 +48,75 @@ describe('undoAI', () => { expect(editor.undo).toHaveBeenCalledTimes(1); expect(editor.history.redos.pop).toHaveBeenCalledTimes(1); }); + + it('cancels active preview before touching ai history', () => { + const editor = { + api: { some: mock(() => true) }, + children: [ + { children: [{ text: 'start' }], type: 'p' }, + { children: [{ text: 'untouched' }], type: 'p' }, + ], + getPlugin: ({ key }: { key: string }) => ({ + key, + node: { type: key }, + }), + history: { redos: { pop: mock(() => {}) }, undos: [{ ai: true }] }, + selection: { + anchor: { offset: 0, path: [0, 0] }, + focus: { offset: 0, path: [0, 0] }, + }, + tf: { + deselect: mock(() => { + editor.selection = null; + }), + insertNodes: mock((nodes: any, options: any = {}) => { + editor.children.splice( + options.at?.[0] ?? editor.children.length, + 0, + ...(Array.isArray(nodes) ? nodes : [nodes]) + ); + }), + removeNodes: mock((options: any = {}) => { + if (options.match) { + editor.children = editor.children.filter( + (node: any) => !options.match(node) + ); + + return; + } + + editor.children.splice(options.at[0], 1); + }), + select: mock((selection: any) => { + editor.selection = selection; + }), + withoutSaving: mock((fn: () => void) => { + fn(); + }), + }, + undo: mock(() => {}), + } as any; + + beginAIPreview(editor, { + originalBlocks: [{ children: [{ text: 'start' }], type: 'p' }], + }); + editor.children = [ + { + [AI_PREVIEW_KEY]: true, + children: [{ text: 'preview' }], + type: 'p', + }, + { children: [{ text: '' }], type: 'aiChat' }, + { children: [{ text: 'untouched' }], type: 'p' }, + ]; + + undoAI(editor); + + expect(editor.children).toEqual([ + { children: [{ text: 'start' }], type: 'p' }, + { children: [{ text: 'untouched' }], type: 'p' }, + ]); + expect(editor.undo).not.toHaveBeenCalled(); + expect(editor.history.redos.pop).not.toHaveBeenCalled(); + }); }); diff --git a/packages/ai/src/lib/transforms/undoAI.ts b/packages/ai/src/lib/transforms/undoAI.ts index 5ac825e2b3..589ef953aa 100644 --- a/packages/ai/src/lib/transforms/undoAI.ts +++ b/packages/ai/src/lib/transforms/undoAI.ts @@ -2,9 +2,11 @@ import type { SlateEditor } from 'platejs'; import { getTransientSuggestionKey } from '@platejs/suggestion'; -import { restoreAIStreamSnapshot } from './aiStreamSnapshot'; +import { cancelAIPreview, hasAIPreview } from './aiStreamSnapshot'; export const undoAI = (editor: SlateEditor) => { + if (hasAIPreview(editor) && cancelAIPreview(editor)) return; + const hasAINodeOrAISuggestion = editor.api.some({ at: [], @@ -23,6 +25,6 @@ export const undoAI = (editor: SlateEditor) => { } if (hasAINodeOrAISuggestion) { - restoreAIStreamSnapshot(editor); + cancelAIPreview(editor); } }; diff --git a/packages/ai/src/react/ai-chat/AIChatPlugin.ts b/packages/ai/src/react/ai-chat/AIChatPlugin.ts index e7fa6f6753..9acd1551e5 100644 --- a/packages/ai/src/react/ai-chat/AIChatPlugin.ts +++ b/packages/ai/src/react/ai-chat/AIChatPlugin.ts @@ -19,10 +19,10 @@ import { import { createTPlatePlugin } from 'platejs/react'; import type { AIBatch } from '../../lib'; +import { BaseAIPlugin } from '../../lib/BaseAIPlugin'; import type { AIMode, AIToolName } from '../../lib/types'; import type { ChatMessage } from './internal/types'; -import { AIPlugin } from '../ai/AIPlugin'; import { removeAnchorAIChat } from './transforms'; import { acceptAIChat } from './transforms/acceptAIChat'; import { insertBelowAIChat } from './transforms/insertBelowAIChat'; @@ -149,7 +149,7 @@ export const AIChatPlugin = createTPlatePlugin({ reload: () => { const { chat, chatNodes, chatSelection } = getOptions(); - editor.getTransforms(AIPlugin).ai.undo(); + editor.getTransforms(BaseAIPlugin).ai.undo(); if (chatSelection) { editor.tf.setSelection(chatSelection); diff --git a/packages/ai/src/react/ai-chat/hooks/useAIChatEditor.spec.tsx b/packages/ai/src/react/ai-chat/hooks/useAIChatEditor.spec.tsx index 818b97060b..56486c1d31 100644 --- a/packages/ai/src/react/ai-chat/hooks/useAIChatEditor.spec.tsx +++ b/packages/ai/src/react/ai-chat/hooks/useAIChatEditor.spec.tsx @@ -9,22 +9,37 @@ mock.module('@platejs/markdown', () => ({ deserializeMd: mock(), })); -mock.module('platejs/react', () => ({ - getEditorPlugin: getEditorPluginMock, - useEditorPlugin: useEditorPluginMock, - usePluginOption: usePluginOptionMock, -})); - mock.module('../AIChatPlugin', () => ({ AIChatPlugin: { key: 'aiChat' }, })); +mock.module('platejs/react', async () => { + const actual = await import( + '/Users/zbeyens/git/plate/packages/plate/dist/react/index.js' + ); + const getEditorPlugin = actual.getEditorPlugin as any; + const useEditorPlugin = actual.useEditorPlugin as any; + const usePluginOption = actual.usePluginOption as any; + + return { + ...actual, + getEditorPlugin: (...args: any[]) => + (getEditorPluginMock as any)(...args) ?? getEditorPlugin(...args), + useEditorPlugin: (...args: any[]) => + (useEditorPluginMock as any)(...args) ?? useEditorPlugin(...args), + usePluginOption: (...args: any[]) => + (usePluginOptionMock as any)(...args) ?? usePluginOption(...args), + }; +}); + const loadModule = async () => import(`./useAIChatEditor?test=${Math.random().toString(36).slice(2)}`); describe('useAIChatEditor', () => { beforeEach(() => { + getEditorPluginMock.mockReset(); useEditorPluginMock.mockReset(); + usePluginOptionMock.mockReset(); }); afterAll(() => { diff --git a/packages/ai/src/react/ai-chat/hooks/useEditorChat.spec.tsx b/packages/ai/src/react/ai-chat/hooks/useEditorChat.spec.tsx index f817b2f300..7df02b35b5 100644 --- a/packages/ai/src/react/ai-chat/hooks/useEditorChat.spec.tsx +++ b/packages/ai/src/react/ai-chat/hooks/useEditorChat.spec.tsx @@ -4,16 +4,29 @@ const useEditorPluginMock = mock(); const usePluginOptionMock = mock(); const getEditorPluginMock = mock(); -mock.module('platejs/react', () => ({ - getEditorPlugin: getEditorPluginMock, - useEditorPlugin: useEditorPluginMock, - usePluginOption: usePluginOptionMock, -})); - mock.module('../AIChatPlugin', () => ({ AIChatPlugin: { key: 'aiChat' }, })); +mock.module('platejs/react', async () => { + const actual = await import( + '/Users/zbeyens/git/plate/packages/plate/dist/react/index.js' + ); + const getEditorPlugin = actual.getEditorPlugin as any; + const useEditorPlugin = actual.useEditorPlugin as any; + const usePluginOption = actual.usePluginOption as any; + + return { + ...actual, + getEditorPlugin: (...args: any[]) => + (getEditorPluginMock as any)(...args) ?? getEditorPlugin(...args), + useEditorPlugin: (...args: any[]) => + (useEditorPluginMock as any)(...args) ?? useEditorPlugin(...args), + usePluginOption: (...args: any[]) => + (usePluginOptionMock as any)(...args) ?? usePluginOption(...args), + }; +}); + mock.module('@platejs/selection/react', () => ({ BlockSelectionPlugin: { key: 'blockSelection' }, })); @@ -23,6 +36,7 @@ const loadModule = async () => describe('useEditorChat', () => { beforeEach(() => { + getEditorPluginMock.mockReset(); useEditorPluginMock.mockReset(); usePluginOptionMock.mockReset(); }); diff --git a/packages/ai/src/react/ai-chat/streaming/streamInsertChunk.ts b/packages/ai/src/react/ai-chat/streaming/streamInsertChunk.ts index 68da664925..d86c446f7b 100644 --- a/packages/ai/src/react/ai-chat/streaming/streamInsertChunk.ts +++ b/packages/ai/src/react/ai-chat/streaming/streamInsertChunk.ts @@ -9,6 +9,10 @@ import { PathApi, } from 'platejs'; +import { + AI_PREVIEW_KEY, + hasAIPreview, +} from '../../../lib/transforms/aiStreamSnapshot'; import { AIChatPlugin } from '../AIChatPlugin'; import { streamDeserializeInlineMd } from './streamDeserializeInlineMd'; import { streamDeserializeMd } from './streamDeserializeMd'; @@ -30,22 +34,47 @@ const getNextPath = (path: Path, length: number) => { return result; }; +const withPreviewElementProps = ( + editor: PlateEditor, + options: SteamInsertChunkOptions +): SteamInsertChunkOptions => { + if (!hasAIPreview(editor)) return options; + + return { + ...options, + elementProps: { + ...options.elementProps, + [AI_PREVIEW_KEY]: true, + }, + }; +}; + +export const getInsertPreviewStart = (editor: SlateEditor) => { + const path = getCurrentBlockPath(editor); + const startBlock = editor.api.node(path)?.[0]; + + return { + path, + startBlock, + startInEmptyParagraph: + !!startBlock && + NodeApi.string(startBlock).length === 0 && + startBlock.type === getPluginType(editor, KEYS.p), + }; +}; + /** @experimental */ export function streamInsertChunk( editor: PlateEditor, chunk: string, options: SteamInsertChunkOptions = {} ) { + const insertOptions = withPreviewElementProps(editor, options); const { _blockChunks, _blockPath } = editor.getOptions(AIChatPlugin); if (_blockPath === null) { const blocks = streamDeserializeMd(editor, chunk); - const path = getCurrentBlockPath(editor); - const startBlock = editor.api.node(path)![0]; - - const startInEmptyParagraph = - NodeApi.string(startBlock).length === 0 && - startBlock.type === getPluginType(editor, KEYS.p); + const { path, startInEmptyParagraph } = getInsertPreviewStart(editor); // if start in empty paragraph, remove it if (startInEmptyParagraph) { @@ -53,11 +82,14 @@ export function streamInsertChunk( } if (blocks.length > 0) { - editor.tf.insertNodes(nodesWithProps(editor, [blocks[0]], options), { - at: path, - nextBlock: !startInEmptyParagraph, - select: true, - }); + editor.tf.insertNodes( + nodesWithProps(editor, [blocks[0]], insertOptions), + { + at: path, + nextBlock: !startInEmptyParagraph, + select: true, + } + ); editor.setOption(AIChatPlugin, '_blockPath', getCurrentBlockPath(editor)); editor.setOption(AIChatPlugin, '_blockChunks', chunk); @@ -67,11 +99,14 @@ export function streamInsertChunk( const nextPath = getCurrentBlockPath(editor); - editor.tf.insertNodes(nodesWithProps(editor, nextBlocks, options), { - at: nextPath, - nextBlock: true, - select: true, - }); + editor.tf.insertNodes( + nodesWithProps(editor, nextBlocks, insertOptions), + { + at: nextPath, + nextBlock: true, + select: true, + } + ); const lastBlock = editor.api.node( getNextPath(nextPath, nextBlocks.length) @@ -120,10 +155,13 @@ export function streamInsertChunk( const chunkNodes = streamDeserializeInlineMd(editor as any, chunk); // Deserialize the chunk and add it to the end of the current block - editor.tf.insertNodes(nodesWithProps(editor, chunkNodes, options), { - at: editor.api.end(_blockPath), - select: true, - }); + editor.tf.insertNodes( + nodesWithProps(editor, chunkNodes, insertOptions), + { + at: editor.api.end(_blockPath), + select: true, + } + ); const updatedBlock = editor.api.node(_blockPath)!; const serializedBlock = streamSerializeMd( @@ -144,7 +182,7 @@ export function streamInsertChunk( editor.setOption(AIChatPlugin, '_blockChunks', tempBlockChunks); } else { editor.tf.replaceNodes( - nodesWithProps(editor, [tempBlocks[0]], options), + nodesWithProps(editor, [tempBlocks[0]], insertOptions), { at: _blockPath, select: true, @@ -180,7 +218,7 @@ export function streamInsertChunk( ); editor.tf.replaceNodes( - nodesWithProps(editor, [tempBlocks[0]], options), + nodesWithProps(editor, [tempBlocks[0]], insertOptions), { at: _blockPath, select: true, @@ -190,16 +228,19 @@ export function streamInsertChunk( editor.setOption(AIChatPlugin, '_blockChunks', serializedBlock); } } else { - editor.tf.replaceNodes(nodesWithProps(editor, [tempBlocks[0]], options), { - at: _blockPath, - select: true, - }); + editor.tf.replaceNodes( + nodesWithProps(editor, [tempBlocks[0]], insertOptions), + { + at: _blockPath, + select: true, + } + ); if (tempBlocks.length > 1) { const newEndBlockPath = getNextPath(_blockPath, tempBlocks.length - 1); editor.tf.insertNodes( - nodesWithProps(editor, tempBlocks.slice(1), options), + nodesWithProps(editor, tempBlocks.slice(1), insertOptions), { at: PathApi.next(_blockPath), select: true, diff --git a/packages/ai/src/react/ai-chat/transforms/acceptAIChat.ts b/packages/ai/src/react/ai-chat/transforms/acceptAIChat.ts index d08e78cd13..78ab85785c 100644 --- a/packages/ai/src/react/ai-chat/transforms/acceptAIChat.ts +++ b/packages/ai/src/react/ai-chat/transforms/acceptAIChat.ts @@ -1,67 +1,54 @@ -import cloneDeep from 'lodash/cloneDeep.js'; -import { ElementApi, KEYS, TextApi, getPluginType } from 'platejs'; -import { type PlateEditor, getEditorPlugin } from 'platejs/react'; +import { ElementApi, KEYS, type Point } from 'platejs'; +import type { PlateEditor } from 'platejs/react'; -import { commitAIStreamValue, withAIBatch } from '../../../lib'; -import { AIPlugin } from '../../ai/AIPlugin'; +import { BaseAIPlugin } from '../../../lib/BaseAIPlugin'; +import { AI_PREVIEW_KEY } from '../../../lib/transforms/aiStreamSnapshot'; +import { withAIBatch } from '../../../lib/transforms/withAIBatch'; import { type AIChatPluginConfig, AIChatPlugin } from '../AIChatPlugin'; import { acceptAISuggestions } from '../utils/acceptAISuggestions'; -const getAcceptedInsertValue = (editor: PlateEditor) => { - const aiChatType = getPluginType(editor, KEYS.aiChat); - const aiType = getPluginType(editor, KEYS.ai); +const getAcceptedInsertFocusPoint = (editor: PlateEditor): Point | null => { + let endIndex: number | null = null; - const stripTracking = (node: any): any | null => { - if (ElementApi.isElement(node) && node.type === aiChatType) { - return null; + editor.children.forEach((node: any, index) => { + if (ElementApi.isElement(node) && node[AI_PREVIEW_KEY]) { + endIndex = index; } + }); - if (TextApi.isText(node)) { - const { [aiType]: _ai, ...rest } = node; + if (endIndex === null) return null; - return rest; - } - - if (!node.children) return node; - - return { - ...node, - children: node.children - .map((child: any) => stripTracking(child)) - .filter(Boolean), - }; - }; - - return cloneDeep(editor.children) - .map((node) => stripTracking(node)) - .filter(Boolean); + return editor.api.end([endIndex]) ?? null; }; export const acceptAIChat = (editor: PlateEditor) => { const mode = editor.getOption(AIChatPlugin, 'mode'); if (mode === 'insert') { - const { tf } = getEditorPlugin(editor, AIPlugin); + const ai = editor.getTransforms(BaseAIPlugin).ai; const api = editor.getApi({ key: KEYS.ai }); + const focusPoint = getAcceptedInsertFocusPoint(editor); - const lastAINodePath = api.aiChat.node({ at: [], reverse: true })![1]; - - if (!commitAIStreamValue(editor, getAcceptedInsertValue(editor))) { + if (!ai.acceptPreview()) { withAIBatch(editor, () => { - tf.ai.removeMarks(); + editor.tf.unsetNodes(AI_PREVIEW_KEY, { + at: [], + match: (node) => + ElementApi.isElement(node) && !!(node as any)[AI_PREVIEW_KEY], + }); + ai.removeMarks(); editor.getTransforms(AIChatPlugin).aiChat.removeAnchor(); }); } api.aiChat.hide(); editor.tf.focus(); - - const focusPoint = editor.api.end(lastAINodePath)!; - - editor.tf.setSelection({ - anchor: focusPoint, - focus: focusPoint, - }); + if (focusPoint) { + editor.tf.select({ + anchor: focusPoint, + focus: focusPoint, + }); + } } if (mode === 'chat') { diff --git a/packages/ai/src/react/ai-chat/transforms/insertBelowAIChat.ts b/packages/ai/src/react/ai-chat/transforms/insertBelowAIChat.ts index e0addcf898..61a322c97c 100644 --- a/packages/ai/src/react/ai-chat/transforms/insertBelowAIChat.ts +++ b/packages/ai/src/react/ai-chat/transforms/insertBelowAIChat.ts @@ -11,8 +11,8 @@ import { type TIdElement, } from 'platejs'; -import { withAIBatch } from '../../../lib'; -import { AIPlugin } from '../../ai/AIPlugin'; +import { BaseAIPlugin } from '../../../lib/BaseAIPlugin'; +import { withAIBatch } from '../../../lib/transforms/withAIBatch'; import { type AIChatPluginConfig, AIChatPlugin } from '../AIChatPlugin'; import { acceptAISuggestions } from '../utils'; import { createFormattedBlocks } from './replaceSelectionAIChat'; @@ -33,7 +33,7 @@ export const insertBelowAIChat = ( const selectedIds = editor.getOptions(BlockSelectionPlugin).selectedIds; - editor.getTransforms(AIPlugin).ai.undo(); + editor.getTransforms(BaseAIPlugin).ai.undo(); const insertBlocksAndSelect = editor.getTransforms(BlockSelectionPlugin).blockSelection diff --git a/packages/ai/src/react/ai-chat/utils/aiChatActions.spec.ts b/packages/ai/src/react/ai-chat/utils/aiChatActions.spec.ts index e993904dae..a89de96283 100644 --- a/packages/ai/src/react/ai-chat/utils/aiChatActions.spec.ts +++ b/packages/ai/src/react/ai-chat/utils/aiChatActions.spec.ts @@ -37,19 +37,24 @@ mock.module('@platejs/suggestion/react', () => ({ SuggestionPlugin: { key: 'suggestion' }, })); -mock.module('platejs/react', () => ({ - getEditorPlugin: getEditorPluginMock, - useEditorPlugin: useEditorPluginMock, - usePluginOption: usePluginOptionMock, -})); - -mock.module('../AIChatPlugin', () => ({ - AIChatPlugin: { key: 'aiChat' }, -})); +mock.module('platejs/react', async () => { + const actual = await import( + '/Users/zbeyens/git/plate/packages/plate/dist/react/index.js' + ); + const getEditorPlugin = actual.getEditorPlugin as any; + const useEditorPlugin = actual.useEditorPlugin as any; + const usePluginOption = actual.usePluginOption as any; -mock.module('../../ai/AIPlugin', () => ({ - AIPlugin: { key: 'ai' }, -})); + return { + ...actual, + getEditorPlugin: (...args: any[]) => + (getEditorPluginMock as any)(...args) ?? getEditorPlugin(...args), + useEditorPlugin: (...args: any[]) => + (useEditorPluginMock as any)(...args) ?? useEditorPlugin(...args), + usePluginOption: (...args: any[]) => + (usePluginOptionMock as any)(...args) ?? usePluginOption(...args), + }; +}); const loadApplyTableCellSuggestion = async () => import( @@ -188,6 +193,7 @@ describe('ai chat action utils', () => { const setMessages = mock(); const stop = mock(); const setOptions = mock(); + const discardPreview = mock(); const undo = mock(); getEditorPluginMock.mockReturnValue({ @@ -205,7 +211,7 @@ describe('ai chat action utils', () => { const editor = { getTransforms: () => ({ - ai: { undo }, + ai: { discardPreview, undo }, }), } as any; @@ -220,6 +226,40 @@ describe('ai chat action utils', () => { toolName: null, }); expect(undo).toHaveBeenCalled(); + expect(discardPreview).not.toHaveBeenCalled(); + }); + + it('discards preview bookkeeping instead of undoing when requested', async () => { + const { resetAIChat } = await loadReset(); + const stop = mock(); + const setOptions = mock(); + const discardPreview = mock(); + const undo = mock(); + + getEditorPluginMock.mockReturnValue({ + api: { + aiChat: { stop }, + }, + getOptions: () => ({ + chat: { + messages: [], + setMessages: mock(), + }, + }), + setOptions, + }); + + const editor = { + getTransforms: () => ({ + ai: { discardPreview, undo }, + }), + } as any; + + resetAIChat(editor, { undo: false }); + + expect(stop).toHaveBeenCalled(); + expect(undo).not.toHaveBeenCalled(); + expect(discardPreview).toHaveBeenCalled(); }); it('detects single-cell tables and extracts their cell children', async () => { diff --git a/packages/ai/src/react/ai-chat/utils/getLastAssistantMessage.spec.ts b/packages/ai/src/react/ai-chat/utils/getLastAssistantMessage.spec.ts index b9f18e677f..fceb9f54d1 100644 --- a/packages/ai/src/react/ai-chat/utils/getLastAssistantMessage.spec.ts +++ b/packages/ai/src/react/ai-chat/utils/getLastAssistantMessage.spec.ts @@ -4,18 +4,33 @@ const usePluginOptionMock = mock(); const getEditorPluginMock = mock(); const useEditorPluginMock = mock(); -mock.module('platejs/react', () => ({ - getEditorPlugin: getEditorPluginMock, - useEditorPlugin: useEditorPluginMock, - usePluginOption: usePluginOptionMock, -})); - mock.module('../AIChatPlugin', () => ({ AIChatPlugin: { key: 'aiChat' }, })); +mock.module('platejs/react', async () => { + const actual = await import( + '/Users/zbeyens/git/plate/packages/plate/dist/react/index.js' + ); + const getEditorPlugin = actual.getEditorPlugin as any; + const useEditorPlugin = actual.useEditorPlugin as any; + const usePluginOption = actual.usePluginOption as any; + + return { + ...actual, + getEditorPlugin: (...args: any[]) => + (getEditorPluginMock as any)(...args) ?? getEditorPlugin(...args), + useEditorPlugin: (...args: any[]) => + (useEditorPluginMock as any)(...args) ?? useEditorPlugin(...args), + usePluginOption: (...args: any[]) => + (usePluginOptionMock as any)(...args) ?? usePluginOption(...args), + }; +}); + describe('getLastAssistantMessage', () => { beforeEach(() => { + getEditorPluginMock.mockReset(); + useEditorPluginMock.mockReset(); usePluginOptionMock.mockReset(); }); @@ -47,7 +62,7 @@ describe('getLastAssistantMessage', () => { `./getLastAssistantMessage?test=${Math.random().toString(36).slice(2)}` ); - usePluginOptionMock.mockReturnValueOnce(undefined).mockReturnValueOnce({ + usePluginOptionMock.mockReturnValueOnce(false).mockReturnValueOnce({ messages: [ { role: 'assistant', text: 'a' }, { role: 'assistant', text: 'b' }, diff --git a/packages/ai/src/react/ai-chat/utils/resetAIChat.ts b/packages/ai/src/react/ai-chat/utils/resetAIChat.ts index 7ee7dac35b..4e29fa029c 100644 --- a/packages/ai/src/react/ai-chat/utils/resetAIChat.ts +++ b/packages/ai/src/react/ai-chat/utils/resetAIChat.ts @@ -1,11 +1,9 @@ import { KEYS } from 'platejs'; import { type PlateEditor, getEditorPlugin } from 'platejs/react'; -import { clearAIStreamSnapshot } from '../../../lib/transforms/aiStreamSnapshot'; +import { BaseAIPlugin } from '../../../lib/BaseAIPlugin'; import type { AIChatPluginConfig } from '../AIChatPlugin'; -import { AIPlugin } from '../../ai/AIPlugin'; - export const resetAIChat = ( editor: PlateEditor, { undo = true }: { undo?: boolean } = {} @@ -33,8 +31,8 @@ export const resetAIChat = ( }); if (undo) { - editor.getTransforms(AIPlugin).ai.undo(); + editor.getTransforms(BaseAIPlugin).ai.undo(); + } else { + editor.getTransforms(BaseAIPlugin).ai.discardPreview(); } - - clearAIStreamSnapshot(editor); }; diff --git a/packages/ai/src/react/ai-chat/utils/submitAIChat.spec.ts b/packages/ai/src/react/ai-chat/utils/submitAIChat.spec.ts index 2385a78368..dca8004f16 100644 --- a/packages/ai/src/react/ai-chat/utils/submitAIChat.spec.ts +++ b/packages/ai/src/react/ai-chat/utils/submitAIChat.spec.ts @@ -16,15 +16,24 @@ mock.module('../../../lib/utils/getEditorPrompt', () => ({ getEditorPrompt: getEditorPromptMock, })); -mock.module('../../ai/AIPlugin', () => ({ - AIPlugin: { key: 'ai' }, -})); - -mock.module('platejs/react', () => ({ - getEditorPlugin: getEditorPluginMock, - useEditorPlugin: useEditorPluginMock, - usePluginOption: usePluginOptionMock, -})); +mock.module('platejs/react', async () => { + const actual = await import( + '/Users/zbeyens/git/plate/packages/plate/dist/react/index.js' + ); + const getEditorPlugin = actual.getEditorPlugin as any; + const useEditorPlugin = actual.useEditorPlugin as any; + const usePluginOption = actual.usePluginOption as any; + + return { + ...actual, + getEditorPlugin: (...args: any[]) => + (getEditorPluginMock as any)(...args) ?? getEditorPlugin(...args), + useEditorPlugin: (...args: any[]) => + (useEditorPluginMock as any)(...args) ?? useEditorPlugin(...args), + usePluginOption: (...args: any[]) => + (usePluginOptionMock as any)(...args) ?? usePluginOption(...args), + }; +}); const loadModule = async () => import(`./submitAIChat?test=${Math.random().toString(36).slice(2)}`); diff --git a/packages/ai/src/react/ai-chat/utils/submitAIChat.ts b/packages/ai/src/react/ai-chat/utils/submitAIChat.ts index 8a16f92ef3..32d6bcd86e 100644 --- a/packages/ai/src/react/ai-chat/utils/submitAIChat.ts +++ b/packages/ai/src/react/ai-chat/utils/submitAIChat.ts @@ -14,11 +14,11 @@ import { type PlateEditor, getEditorPlugin } from 'platejs/react'; import type { AIMode, AIToolName } from '../../../lib/types'; import type { AIChatPluginConfig } from '../AIChatPlugin'; +import { BaseAIPlugin } from '../../../lib/BaseAIPlugin'; import { type EditorPrompt, getEditorPrompt, } from '../../../lib/utils/getEditorPrompt'; -import { AIPlugin } from '../../ai/AIPlugin'; export const submitAIChat = ( editor: PlateEditor, @@ -56,7 +56,7 @@ export const submitAIChat = ( mode = isSelecting(editor) ? 'chat' : 'insert'; } if (mode === 'insert') { - editor.getTransforms(AIPlugin).ai.undo(); + editor.getTransforms(BaseAIPlugin).ai.undo(); } setOption('mode', mode); diff --git a/packages/ai/src/react/ai-chat/withAIChat.ts b/packages/ai/src/react/ai-chat/withAIChat.ts index dbe636a45d..1c90eaa3ec 100644 --- a/packages/ai/src/react/ai-chat/withAIChat.ts +++ b/packages/ai/src/react/ai-chat/withAIChat.ts @@ -2,7 +2,7 @@ import type { OverrideEditor } from 'platejs/react'; import { ElementApi, KEYS } from 'platejs'; -import { AIPlugin } from '../ai/AIPlugin'; +import { BaseAIPlugin } from '../../lib/BaseAIPlugin'; import { type AIChatPluginConfig, AIChatPlugin } from './AIChatPlugin'; export const withAIChat: OverrideEditor = ({ @@ -12,7 +12,7 @@ export const withAIChat: OverrideEditor = ({ tf: { insertText, normalizeNode }, type, }) => { - const tf = editor.getTransforms(AIPlugin); + const ai = editor.getTransforms(BaseAIPlugin).ai; const matchesTrigger = (text: string) => { const { trigger } = getOptions(); @@ -68,7 +68,7 @@ export const withAIChat: OverrideEditor = ({ const [node, path] = entry; if (node[KEYS.ai] && !getOptions().open) { - tf.ai.removeMarks({ at: path }); + ai.removeMarks({ at: path }); return; } diff --git a/packages/slate/src/slate-history/history.ts b/packages/slate/src/slate-history/history.ts index 9fa51aa2f0..ca410179f5 100644 --- a/packages/slate/src/slate-history/history.ts +++ b/packages/slate/src/slate-history/history.ts @@ -124,5 +124,6 @@ export type History = { type Batch = { operations: Operation[]; + selectionAfter?: TRange | null; selectionBefore: TRange | null; }; diff --git a/packages/slate/src/slate-history/with-history.spec.tsx b/packages/slate/src/slate-history/with-history.spec.tsx index fc04f55c40..e625007b8b 100644 --- a/packages/slate/src/slate-history/with-history.spec.tsx +++ b/packages/slate/src/slate-history/with-history.spec.tsx @@ -224,6 +224,99 @@ describe('withHistory', () => { expect(editor.children).toEqual([{ children: [{ text: '' }], type: 'p' }]); }); + it('restores selection even when node operations leave it null', () => { + const editor = createHistoryEditor( + ( + + + one + + + + ) as any + ); + + editor.children = [{ children: [{ text: 'accepted' }], type: 'p' }] as any; + editor.history.undos.push({ + operations: [ + { + node: { children: [{ text: 'one' }], type: 'p' }, + path: [0], + type: 'remove_node', + }, + { + node: { children: [{ text: 'accepted' }], type: 'p' }, + path: [0], + type: 'insert_node', + }, + ], + selectionBefore: { + anchor: { offset: 3, path: [0, 0] }, + focus: { offset: 3, path: [0, 0] }, + }, + }); + editor.selection = null; + expect(editor.selection).toBeNull(); + + editor.undo(); + + expect(editor.children).toEqual([ + { children: [{ text: 'one' }], type: 'p' }, + ]); + expect(editor.selection).toEqual({ + anchor: { offset: 3, path: [0, 0] }, + focus: { offset: 3, path: [0, 0] }, + }); + }); + + it('restores redo selection when undo captured a null-selection batch', () => { + const editor = createHistoryEditor( + ( + + + one + + + + ) as any + ); + + editor.children = [{ children: [{ text: 'accepted' }], type: 'p' }] as any; + editor.history.undos.push({ + operations: [ + { + node: { children: [{ text: 'one' }], type: 'p' }, + path: [0], + type: 'remove_node', + }, + { + node: { children: [{ text: 'accepted' }], type: 'p' }, + path: [0], + type: 'insert_node', + }, + ], + selectionBefore: { + anchor: { offset: 3, path: [0, 0] }, + focus: { offset: 3, path: [0, 0] }, + }, + }); + editor.selection = { + anchor: { offset: 8, path: [0, 0] }, + focus: { offset: 8, path: [0, 0] }, + }; + + editor.undo(); + editor.redo(); + + expect(editor.children).toEqual([ + { children: [{ text: 'accepted' }], type: 'p' }, + ]); + expect(editor.selection).toEqual({ + anchor: { offset: 8, path: [0, 0] }, + focus: { offset: 8, path: [0, 0] }, + }); + }); + it('does not save operations wrapped in withoutSaving', () => { const editor = createHistoryEditor( ( diff --git a/packages/slate/src/slate-history/with-history.ts b/packages/slate/src/slate-history/with-history.ts index aeedc3124c..74d4d7ed43 100644 --- a/packages/slate/src/slate-history/with-history.ts +++ b/packages/slate/src/slate-history/with-history.ts @@ -4,9 +4,18 @@ import { type Operation, OperationApi, PathApi, + type TRange, } from '../interfaces/index'; import { syncLegacyMethods } from '../utils/assignLegacyTransforms'; +const cloneRange = (range: TRange | null | undefined) => + range + ? { + anchor: { ...range.anchor }, + focus: { ...range.focus }, + } + : null; + /** * The `withHistory` plugin keeps track of the operation history of a Slate * editor as operations are applied to it, using undo and redo stacks. @@ -23,10 +32,6 @@ export const withHistory = (editor: T) => { if (redos.length > 0) { const batch = redos.at(-1)!; - if (batch.selectionBefore) { - e.tf.setSelection(batch.selectionBefore); - } - e.tf.withoutSaving(() => { e.tf.withoutNormalizing(() => { for (const op of batch.operations) { @@ -35,6 +40,12 @@ export const withHistory = (editor: T) => { }); }); + const selectionAfter = batch.selectionAfter ?? batch.selectionBefore; + + if (selectionAfter) { + e.tf.select(selectionAfter); + } + history.redos.pop(); e.writeHistory('undos', batch); } @@ -46,6 +57,7 @@ export const withHistory = (editor: T) => { if (undos.length > 0) { const batch = undos.at(-1)!; + const selectionAfter = cloneRange(e.selection); e.tf.withoutSaving(() => { e.tf.withoutNormalizing(() => { @@ -58,12 +70,15 @@ export const withHistory = (editor: T) => { } if (batch.selectionBefore) { - e.tf.setSelection(batch.selectionBefore); + e.tf.select(batch.selectionBefore); } }); }); - e.writeHistory('redos', batch); + e.writeHistory('redos', { + ...batch, + selectionAfter, + }); history.undos.pop(); } }; diff --git a/tmp-issue-4900-editor-ai.png b/tmp-issue-4900-editor-ai.png deleted file mode 100644 index b5084557c1ae49e0e8615262641d1269050b2c63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138532 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