@platejs/ai 50.3.4 → 50.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/react/index.d.mts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +19 -7
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +19 -7
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/ai/AIPlugin.ts","../../src/lib/BaseAIPlugin.ts","../../src/lib/transforms/insertAINodes.ts","../../src/lib/transforms/removeAIMarks.ts","../../src/lib/transforms/removeAINodes.ts","../../src/lib/transforms/undoAI.ts","../../src/lib/transforms/withAIBatch.ts","../../src/lib/utils/getEditorPrompt.ts","../../src/react/ai/utils/aiCommentToRange.ts","../../src/react/ai/utils/findTextRangeInBlock.tsx","../../src/react/ai-chat/AIChatPlugin.ts","../../src/react/ai-chat/transforms/acceptAIChat.ts","../../src/react/ai-chat/transforms/insertBelowAIChat.ts","../../src/react/ai-chat/transforms/replaceSelectionAIChat.ts","../../src/react/ai-chat/transforms/removeAnchorAIChat.ts","../../src/react/ai-chat/utils/resetAIChat.ts","../../src/react/ai-chat/utils/submitAIChat.ts","../../src/react/ai-chat/withAIChat.ts","../../src/react/ai-chat/hooks/useAIChatEditor.ts","../../src/react/ai-chat/hooks/useChatChunk.ts","../../src/react/ai-chat/utils/getLastAssistantMessage.ts","../../src/react/ai-chat/hooks/useEditorChat.ts","../../src/react/ai-chat/streaming/streamDeserializeInlineMd.ts","../../src/react/ai-chat/streaming/streamDeserializeMd.ts","../../src/react/ai-chat/streaming/utils/utils.ts","../../src/react/ai-chat/streaming/utils/escapeInput.ts","../../src/react/ai-chat/streaming/utils/getListNode.ts","../../src/react/ai-chat/streaming/utils/isSameNode.ts","../../src/react/ai-chat/streaming/utils/nodesWithProps.ts","../../src/react/ai-chat/streaming/streamInsertChunk.ts","../../src/react/ai-chat/streaming/streamSerializeMd.ts","../../src/react/ai-chat/utils/applyAISuggestions.ts","../../src/react/copilot/CopilotPlugin.tsx","../../src/react/copilot/renderCopilotBelowNodes.tsx","../../src/react/copilot/transforms/acceptCopilot.ts","../../src/react/copilot/transforms/acceptCopilotNextWord.ts","../../src/react/copilot/utils/callCompletionApi.ts","../../src/react/copilot/utils/getNextWord.ts","../../src/react/copilot/utils/triggerCopilotSuggestion.ts","../../src/react/copilot/utils/withoutAbort.ts","../../src/react/copilot/withCopilot.ts"],"sourcesContent":["import type { ExtendConfig } from 'platejs';\n\nimport { toPlatePlugin } from 'platejs/react';\n\nimport { type BaseAIPluginConfig, BaseAIPlugin } from '../../lib';\n\nexport type AIPluginConfig = ExtendConfig<BaseAIPluginConfig>;\n\nexport const AIPlugin = toPlatePlugin(BaseAIPlugin);\n","import {\n type OmitFirst,\n type PluginConfig,\n bindFirst,\n createTSlatePlugin,\n KEYS,\n} from 'platejs';\n\nimport { removeAIMarks, undoAI } from './transforms';\nimport { insertAINodes } from './transforms/insertAINodes';\nimport { removeAINodes } from './transforms/removeAINodes';\n\nexport type BaseAIPluginConfig = PluginConfig<\n 'ai',\n {},\n {},\n {\n ai: {\n insertNodes: OmitFirst<typeof insertAINodes>;\n removeMarks: OmitFirst<typeof removeAIMarks>;\n removeNodes: OmitFirst<typeof removeAINodes>;\n };\n }\n>;\n\nexport const BaseAIPlugin = createTSlatePlugin({\n key: KEYS.ai,\n node: { isDecoration: false, isLeaf: true },\n}).extendTransforms(({ editor }) => ({\n insertNodes: bindFirst(insertAINodes, editor),\n removeMarks: bindFirst(removeAIMarks, editor),\n removeNodes: bindFirst(removeAINodes, editor),\n undo: bindFirst(undoAI, editor),\n}));\n","import type { Descendant, Path, SlateEditor } from 'platejs';\n\nexport const insertAINodes = (\n editor: SlateEditor,\n nodes: Descendant[],\n {\n target,\n }: {\n target?: Path;\n } = {}\n) => {\n if (!target && !editor.selection?.focus.path) return;\n\n const aiNodes = nodes.map((node) => ({\n ...node,\n ai: true,\n }));\n\n editor.tf.withoutNormalizing(() => {\n editor.tf.insertNodes(aiNodes, {\n at: editor.api.end(target || editor.selection!.focus.path),\n select: true,\n });\n editor.tf.collapse({ edge: 'end' });\n });\n};\n","import { type SlateEditor, type TLocation, getPluginType, KEYS } from 'platejs';\n\nexport const removeAIMarks = (\n editor: SlateEditor,\n { at = [] }: { at?: TLocation } = {}\n) => {\n const nodeType = getPluginType(editor, KEYS.ai);\n\n editor.tf.unsetNodes(nodeType, {\n at,\n match: (n) => (n as any)[nodeType],\n });\n};\n","import { type Path, type SlateEditor, TextApi } from 'platejs';\n\nexport const removeAINodes = (\n editor: SlateEditor,\n { at = [] }: { at?: Path } = {}\n) => {\n editor.tf.removeNodes({\n at,\n match: (n) => TextApi.isText(n) && !!(n as any).ai,\n });\n};\n","import type { SlateEditor } from 'platejs';\n\nimport { getTransientSuggestionKey } from '@platejs/suggestion';\n\nexport const undoAI = (editor: SlateEditor) => {\n const hasAINodeOrAISuggestion =\n editor.api.some({\n at: [],\n match: (n) => !!(n as any).ai,\n }) ||\n editor.api.some({\n at: [],\n match: (n) => !!n[getTransientSuggestionKey()],\n });\n\n if ((editor.history.undos.at(-1) as any)?.ai && hasAINodeOrAISuggestion) {\n editor.undo();\n editor.history.redos.pop();\n }\n};\n","import type { History, SlateEditor } from 'platejs';\n\nexport type AIBatch = History['undos'][number] & { ai?: boolean };\n\nexport const withAIBatch = (\n editor: SlateEditor,\n fn: () => void,\n {\n split,\n }: {\n split?: boolean;\n } = {}\n) => {\n if (split) {\n editor.tf.withNewBatch(fn);\n } else {\n editor.tf.withMerging(fn);\n }\n\n const lastBatch = editor.history.undos?.at(-1) as AIBatch | undefined;\n\n if (lastBatch) {\n lastBatch.ai = true;\n }\n};\n","import { isSelecting } from '@platejs/selection';\nimport { type SlateEditor, KEYS } from 'platejs';\n\nexport type EditorPrompt =\n | ((params: EditorPromptParams) => string)\n | PromptConfig\n | string;\n\nexport interface EditorPromptParams {\n editor: SlateEditor;\n isBlockSelecting: boolean;\n isSelecting: boolean;\n}\n\nexport interface PromptConfig {\n default: string;\n blockSelecting?: string;\n selecting?: string;\n}\n\nconst createPromptFromConfig = (\n config: PromptConfig,\n params: EditorPromptParams\n): string => {\n const { isBlockSelecting, isSelecting } = params;\n\n if (isBlockSelecting && config.blockSelecting) {\n return config.blockSelecting ?? config.default;\n } else if (isSelecting && config.selecting) {\n return config.selecting ?? config.default;\n } else {\n return config.default;\n }\n};\n\nexport const getEditorPrompt = (\n editor: SlateEditor,\n {\n prompt = '',\n }: {\n prompt?: EditorPrompt;\n }\n): string => {\n const params: EditorPromptParams = {\n editor,\n isBlockSelecting: editor.getOption(\n { key: KEYS.blockSelection },\n 'isSelectingSome'\n ),\n isSelecting: isSelecting(editor),\n };\n\n let promptText = '';\n\n if (typeof prompt === 'function') {\n promptText = prompt(params);\n } else if (typeof prompt === 'object') {\n promptText = createPromptFromConfig(prompt, params);\n } else {\n promptText = prompt;\n }\n\n return promptText;\n};\n","import { deserializeMd } from '@platejs/markdown';\nimport {\n type NodeEntry,\n type Range,\n type SlateEditor,\n type TElement,\n NodeApi,\n} from 'platejs';\n\nimport type { TComment } from '../../ai-chat/internal/types';\n\nimport { findTextRangeInBlock } from './findTextRangeInBlock';\n\nexport const aiCommentToRange = (\n editor: SlateEditor,\n aiComment: TComment\n): Range | undefined => {\n const { blockId, content } = aiComment;\n\n const contentNodes = deserializeMd(editor, content);\n\n let firstBlock: NodeEntry<TElement> | undefined;\n\n const ranges: Range[] = [];\n contentNodes.forEach((node, index) => {\n let currentBlock: NodeEntry<TElement> | undefined;\n\n if (index === 0) {\n firstBlock = editor.api.node<TElement>({ id: blockId, at: [] });\n currentBlock = firstBlock;\n } else {\n if (!firstBlock) return;\n\n const [_, firstBlockPath] = firstBlock;\n\n const blockPath = [firstBlockPath[0] + index];\n currentBlock = editor.api.node(blockPath);\n }\n\n if (!currentBlock) return;\n\n const range = findTextRangeInBlock({\n block: currentBlock,\n findText: NodeApi.string(node),\n });\n\n if (!range) return;\n\n ranges.push(range);\n });\n\n if (ranges.length === 0) return;\n\n if (ranges.length > 1) {\n const startRange = ranges[0];\n const endRange = ranges.at(-1)!;\n\n return {\n anchor: startRange.anchor,\n focus: endRange.focus,\n };\n }\n\n if (ranges.length === 1) {\n return ranges[0];\n }\n};\n","import { distance } from 'fastest-levenshtein';\nimport { type NodeEntry, type Path, type Range, NodeApi } from 'platejs';\n\nfunction maxAllowedDistance(len: number): number {\n if (len <= 2) return 0;\n if (len <= 5) return 1;\n if (len <= 10) return 2;\n if (len <= 20) return 3;\n // Maximum allowed distance is 5, regardless of text length\n return 5;\n}\n\n/** Find text within a block, supporting fuzzy matching. */\nexport function findTextRangeInBlock({\n block,\n findText,\n}: {\n block: NodeEntry;\n findText: string;\n}): Range | null {\n const [blockNode, blockPath] = block;\n\n // Collect all text content and map positions\n const textSegments: { offset: number; path: Path; text: string }[] = [];\n let fullText = '';\n\n // Iterate through all text nodes in the block\n for (const [textNode, textPath] of NodeApi.texts(blockNode)) {\n const startOffset = fullText.length;\n // textPath is relative to blockNode, not absolute\n const absolutePath = [...blockPath, ...textPath];\n textSegments.push({\n offset: startOffset,\n path: absolutePath,\n text: textNode.text,\n });\n fullText += textNode.text;\n }\n\n if (!fullText) return null;\n\n // Try exact match first\n let matchStart = fullText.indexOf(findText);\n let matchEnd = matchStart >= 0 ? matchStart + findText.length : -1;\n\n // If no exact match, try fuzzy matching\n if (matchStart === -1) {\n const maxDist = maxAllowedDistance(findText.length);\n let bestMatch = { distance: Infinity, end: -1, start: -1 };\n\n // Sliding window to find best fuzzy match\n for (let i = 0; i <= fullText.length - findText.length; i++) {\n // Try different lengths around the target length\n for (let lenOffset = -maxDist; lenOffset <= maxDist; lenOffset++) {\n const len = findText.length + lenOffset;\n if (len <= 0 || i + len > fullText.length) continue;\n\n const candidate = fullText.slice(i, i + len);\n const dist = distance(candidate, findText);\n\n if (dist <= maxDist && dist < bestMatch.distance) {\n bestMatch = { distance: dist, end: i + len, start: i };\n }\n }\n }\n\n if (bestMatch.start !== -1) {\n matchStart = bestMatch.start;\n matchEnd = bestMatch.end;\n }\n }\n\n // If still no match, try prefix matching as fallback\n if (matchStart === -1) {\n // Find longest prefix match\n for (let prefixLen = findText.length - 1; prefixLen > 0; prefixLen--) {\n const prefix = findText.slice(0, Math.max(0, prefixLen));\n const idx = fullText.indexOf(prefix);\n if (idx !== -1) {\n matchStart = idx;\n matchEnd = idx + prefixLen;\n break;\n }\n }\n }\n\n if (matchStart === -1) return null;\n\n // Convert character offsets to Slate paths and offsets\n const findPoint = (\n charOffset: number,\n isEnd = false\n ): { offset: number; path: Path } => {\n const accumulated = 0;\n\n // For start positions, if offset lands exactly at the beginning of a segment, use that segment\n if (!isEnd) {\n for (const segment of textSegments) {\n if (charOffset === segment.offset) {\n return {\n offset: 0,\n path: segment.path,\n };\n }\n }\n }\n\n // Normal search through segments\n for (const segment of textSegments) {\n const segmentEnd = segment.offset + segment.text.length;\n\n if (charOffset >= segment.offset && charOffset <= segmentEnd) {\n const localOffset = charOffset - segment.offset;\n return {\n offset: localOffset,\n path: segment.path,\n };\n }\n }\n\n // Fallback to last position\n const lastSegment = textSegments.at(-1);\n if (!lastSegment) {\n return { offset: 0, path: blockPath };\n }\n return {\n offset: lastSegment.text.length,\n path: lastSegment.path,\n };\n };\n\n const anchor = findPoint(matchStart, false);\n const focus = findPoint(matchEnd, true);\n\n return {\n anchor,\n focus,\n };\n}\n","import type { UseChatHelpers } from '@ai-sdk/react';\nimport type { TriggerComboboxPluginOptions } from '@platejs/combobox';\n\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport {\n type EditorNodesOptions,\n type NodeEntry,\n type OmitFirst,\n type Path,\n type PluginConfig,\n type SlateEditor,\n type TIdElement,\n type TRange,\n bindFirst,\n ElementApi,\n getPluginType,\n KEYS,\n} from 'platejs';\nimport { createTPlatePlugin } from 'platejs/react';\n\nimport type { AIBatch } from '../../lib';\nimport type { AIMode, AIToolName } from '../../lib/types';\nimport type { ChatMessage } from './internal/types';\n\nimport { AIPlugin } from '../ai/AIPlugin';\nimport { removeAnchorAIChat } from './transforms';\nimport { acceptAIChat } from './transforms/acceptAIChat';\nimport { insertBelowAIChat } from './transforms/insertBelowAIChat';\nimport { replaceSelectionAIChat } from './transforms/replaceSelectionAIChat';\nimport { resetAIChat } from './utils/resetAIChat';\nimport { submitAIChat } from './utils/submitAIChat';\nimport { withAIChat } from './withAIChat';\n\nexport type AIChatPluginConfig = PluginConfig<\n 'aiChat',\n {\n _blockChunks: string;\n _blockPath: Path | null;\n /** @private Using For streamInsertChunk */\n _mdxName: string | null;\n _replaceIds: string[];\n /** @private The Editor used to generate the AI response. */\n aiEditor: SlateEditor | null;\n chat: UseChatHelpers<ChatMessage>;\n chatNodes: TIdElement[];\n chatSelection: TRange | null;\n /** @deprecated Use api.aiChat.node({streaming:true}) instead */\n experimental_lastTextId: string | null;\n /**\n * Specifies how the assistant message is handled:\n *\n * - 'insert': Directly inserts content into the editor without preview.\n * - 'chat': Initiates an interactive session to review and refine content\n * before insertion.\n */\n mode: AIMode;\n open: boolean;\n /** Whether the AI response is currently streaming. Cursor mode only. */\n streaming: boolean;\n toolName: AIToolName;\n } & TriggerComboboxPluginOptions,\n {\n aiChat: {\n reset: OmitFirst<typeof resetAIChat>;\n submit: OmitFirst<typeof submitAIChat>;\n hide: (options?: { focus?: boolean; undo?: boolean }) => void;\n node: (\n options?: EditorNodesOptions & { anchor?: boolean; streaming?: boolean }\n ) => NodeEntry | undefined;\n reload: () => void;\n show: () => void;\n stop: () => void;\n };\n },\n {\n aiChat: {\n accept: OmitFirst<typeof acceptAIChat>;\n insertBelow: OmitFirst<typeof insertBelowAIChat>;\n replaceSelection: OmitFirst<typeof replaceSelectionAIChat>;\n removeAnchor: (options?: EditorNodesOptions) => void;\n };\n }\n>;\n\nexport const AIChatPlugin = createTPlatePlugin<AIChatPluginConfig>({\n key: KEYS.aiChat,\n dependencies: ['ai'],\n node: {\n isElement: true,\n },\n options: {\n _blockChunks: '',\n _blockPath: null,\n _mdxName: null,\n _replaceIds: [],\n aiEditor: null,\n chat: { messages: [] } as unknown as UseChatHelpers<ChatMessage>,\n chatNodes: [],\n chatSelection: null,\n experimental_lastTextId: null,\n mode: 'insert',\n open: false,\n streaming: false,\n toolName: null,\n trigger: ' ',\n triggerPreviousCharPattern: /^\\s?$/,\n },\n})\n .overrideEditor(withAIChat)\n .extendApi<\n Pick<\n AIChatPluginConfig['api']['aiChat'],\n 'node' | 'reset' | 'stop' | 'submit'\n >\n >(({ editor, getOption, getOptions, setOption, type }) => {\n return {\n reset: bindFirst(resetAIChat, editor),\n submit: bindFirst(submitAIChat, editor),\n node: (options = {}) => {\n const { anchor = false, streaming = false, ...rest } = options;\n\n if (anchor) {\n return editor.api.node({\n at: [],\n match: (n) => ElementApi.isElement(n) && n.type === type,\n ...rest,\n });\n }\n\n if (streaming) {\n if (!getOption('streaming')) return;\n\n const path = getOption('_blockPath');\n if (!path) return;\n\n return editor.api.node({\n at: path,\n mode: 'lowest',\n reverse: true,\n match: (t) => !!t[getPluginType(editor, KEYS.ai)],\n ...rest,\n });\n }\n\n return editor.api.node({\n match: (n) => n[getPluginType(editor, KEYS.ai)],\n ...rest,\n });\n },\n reload: () => {\n const { chat, chatNodes, chatSelection } = getOptions();\n\n editor.getTransforms(AIPlugin).ai.undo();\n\n if (chatSelection) {\n editor.tf.setSelection(chatSelection);\n } else {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.set(chatNodes.map((node) => node.id as string));\n }\n\n const blocks = editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.getNodes();\n\n const selection =\n blocks.length > 0 ? editor.api.nodesRange(blocks) : editor.selection;\n\n const ctx = {\n children: editor.children,\n selection: selection ?? null,\n toolName: getOption('toolName'),\n };\n\n void chat.regenerate?.({\n body: {\n ctx,\n },\n });\n },\n stop: () => {\n setOption('streaming', false);\n getOptions().chat.stop?.();\n },\n };\n })\n .extendApi(({ api, editor, getOptions, setOption, tf, type }) => ({\n hide: ({\n focus = true,\n undo = true,\n }: { focus?: boolean; undo?: boolean } = {}) => {\n api.aiChat.reset({ undo });\n\n setOption('open', false);\n\n if (focus) {\n if (editor.getOption(BlockSelectionPlugin, 'isSelectingSome')) {\n editor.getApi(BlockSelectionPlugin).blockSelection.focus();\n } else {\n editor.tf.focus();\n }\n }\n\n const lastBatch = editor.history.undos.at(-1) as AIBatch;\n\n if (lastBatch?.ai) {\n delete lastBatch.ai;\n }\n\n tf.aiChat.removeAnchor();\n },\n show: () => {\n api.aiChat.reset();\n\n setOption('toolName', null);\n\n getOptions().chat.setMessages?.([]);\n\n setOption('open', true);\n },\n }))\n .extendTransforms(({ editor }) => ({\n accept: bindFirst(acceptAIChat, editor),\n insertBelow: bindFirst(insertBelowAIChat, editor),\n removeAnchor: bindFirst(removeAnchorAIChat, editor),\n replaceSelection: bindFirst(replaceSelectionAIChat, editor),\n }));\n","import {\n acceptSuggestion,\n getSuggestionKey,\n getTransientSuggestionKey,\n} from '@platejs/suggestion';\nimport { SuggestionPlugin } from '@platejs/suggestion/react';\nimport { KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport { withAIBatch } from '../../../lib';\nimport { AIPlugin } from '../../ai/AIPlugin';\nimport { type AIChatPluginConfig, AIChatPlugin } from '../AIChatPlugin';\n\nexport const acceptAIChat = (editor: PlateEditor) => {\n const mode = editor.getOption(AIChatPlugin, 'mode');\n\n if (mode === 'insert') {\n const { tf } = getEditorPlugin(editor, AIPlugin);\n const api = editor.getApi<AIChatPluginConfig>({ key: KEYS.ai });\n\n const lastAINodePath = api.aiChat.node({ at: [], reverse: true })![1];\n\n withAIBatch(editor, () => {\n tf.ai.removeMarks();\n editor.getTransforms(AIChatPlugin).aiChat.removeAnchor();\n });\n\n api.aiChat.hide();\n editor.tf.focus();\n\n const focusPoint = editor.api.end(lastAINodePath)!;\n\n editor.tf.setSelection({\n anchor: focusPoint,\n focus: focusPoint,\n });\n }\n\n if (mode === 'chat') {\n withAIBatch(editor, () => {\n acceptSuggestions(editor);\n });\n\n editor.getApi(AIChatPlugin).aiChat.hide();\n }\n};\n\nexport const acceptSuggestions = (editor: PlateEditor) => {\n const suggestions = editor.getApi(SuggestionPlugin).suggestion.nodes({\n transient: true,\n });\n\n suggestions.forEach(([suggestionNode]) => {\n const suggestionData = editor\n .getApi(SuggestionPlugin)\n .suggestion.suggestionData(suggestionNode);\n\n if (!suggestionData) return;\n\n const description = {\n createdAt: new Date(suggestionData.createdAt),\n keyId: getSuggestionKey(suggestionData.id),\n suggestionId: suggestionData.id,\n type: suggestionData.type,\n userId: suggestionData.userId,\n };\n\n acceptSuggestion(editor, description);\n });\n\n editor.tf.unsetNodes([getTransientSuggestionKey()], {\n at: [],\n mode: 'all',\n match: (n) => !!n[getTransientSuggestionKey()],\n });\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport cloneDeep from 'lodash/cloneDeep.js';\nimport { type SlateEditor, KEYS, PathApi, RangeApi } from 'platejs';\n\nimport { withAIBatch } from '../../../lib';\nimport { AIPlugin } from '../../ai/AIPlugin';\nimport { type AIChatPluginConfig, AIChatPlugin } from '../AIChatPlugin';\nimport { acceptSuggestions } from './acceptAIChat';\nimport { createFormattedBlocks } from './replaceSelectionAIChat';\n\nexport const insertBelowAIChat = (\n editor: PlateEditor,\n sourceEditor: SlateEditor,\n { format = 'single' }: { format?: 'all' | 'none' | 'single' } = {}\n) => {\n const { toolName } = editor.getOptions(AIChatPlugin);\n\n if (toolName === 'generate')\n return insertBelowGenerate(editor, sourceEditor, { format });\n\n const selectedBlocks = editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.getNodes();\n\n const selectedIds = editor.getOptions(BlockSelectionPlugin).selectedIds;\n\n editor.getTransforms(AIPlugin).ai.undo();\n\n const insertBlocksAndSelect =\n editor.getTransforms(BlockSelectionPlugin).blockSelection\n .insertBlocksAndSelect;\n\n if (!selectedIds || selectedIds.size === 0) return;\n\n const lastBlock = selectedBlocks.at(-1);\n\n if (!lastBlock) return;\n\n const nextPath = PathApi.next(lastBlock[1]);\n\n const nodes = selectedBlocks.map((block) => block[0]);\n\n insertBlocksAndSelect(nodes, {\n at: nextPath,\n insertedCallback: () => {\n withAIBatch(editor, () => {\n acceptSuggestions(editor);\n });\n },\n });\n\n editor.getApi(AIChatPlugin).aiChat.hide({ focus: false });\n};\n\nexport const insertBelowGenerate = (\n editor: PlateEditor,\n sourceEditor: SlateEditor,\n { format = 'single' }: { format?: 'all' | 'none' | 'single' } = {}\n) => {\n if (!sourceEditor || sourceEditor.api.isEmpty()) return;\n\n const isBlockSelecting = editor.getOption(\n BlockSelectionPlugin,\n 'isSelectingSome'\n );\n\n editor.getApi<AIChatPluginConfig>({ key: KEYS.ai }).aiChat.hide();\n\n const insertBlocksAndSelect =\n editor.getTransforms(BlockSelectionPlugin).blockSelection\n .insertBlocksAndSelect;\n\n if (isBlockSelecting) {\n const selectedBlocks = editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.getNodes();\n\n const selectedIds = editor.getOptions(BlockSelectionPlugin).selectedIds;\n\n if (!selectedIds || selectedIds.size === 0) return;\n\n const lastBlock = selectedBlocks.at(-1);\n\n if (!lastBlock) return;\n\n const nextPath = PathApi.next(lastBlock[1]);\n\n if (format === 'none') {\n insertBlocksAndSelect(cloneDeep(sourceEditor.children), {\n at: nextPath,\n });\n\n return;\n }\n\n const formattedBlocks = createFormattedBlocks({\n blocks: cloneDeep(sourceEditor.children),\n format,\n sourceBlock: lastBlock,\n });\n\n if (!formattedBlocks) return;\n\n insertBlocksAndSelect(formattedBlocks, {\n at: nextPath,\n });\n } else {\n const [, end] = RangeApi.edges(editor.selection!);\n const endPath = [end.path[0]];\n const currentBlock = editor.api.node({\n at: endPath,\n block: true,\n mode: 'lowest',\n });\n\n if (!currentBlock) return;\n if (format === 'none') {\n insertBlocksAndSelect(cloneDeep(sourceEditor.children), {\n at: PathApi.next(endPath),\n });\n\n return;\n }\n\n const formattedBlocks = createFormattedBlocks({\n blocks: cloneDeep(sourceEditor.children),\n format,\n sourceBlock: currentBlock,\n });\n\n if (!formattedBlocks) return;\n\n insertBlocksAndSelect(formattedBlocks, {\n at: PathApi.next(endPath),\n });\n }\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport {\n BlockSelectionPlugin,\n removeBlockSelectionNodes,\n} from '@platejs/selection/react';\nimport cloneDeep from 'lodash/cloneDeep.js';\nimport {\n type NodeEntry,\n type SlateEditor,\n type TElement,\n KEYS,\n NodeApi,\n TextApi,\n} from 'platejs';\n\nimport type { AIChatPluginConfig } from '../AIChatPlugin';\n\nexport const createFormattedBlocks = ({\n blocks,\n format,\n sourceBlock,\n}: {\n blocks: TElement[];\n format: 'all' | 'none' | 'single';\n sourceBlock: NodeEntry;\n}) => {\n if (format === 'none') return cloneDeep(blocks);\n\n const [sourceNode] = sourceBlock;\n const firstTextEntry = NodeApi.firstText(sourceNode);\n\n if (!firstTextEntry) return null;\n\n const blockProps = NodeApi.extractProps(sourceNode);\n const textProps = NodeApi.extractProps(firstTextEntry[0]);\n\n const applyTextFormatting = (node: any): any => {\n if (TextApi.isText(node)) {\n return { ...textProps, ...node };\n }\n if (node.children) {\n return {\n ...node,\n children: node.children.map(applyTextFormatting),\n };\n }\n\n return node;\n };\n\n return blocks.map((block, index) => {\n if (format === 'single' && index > 0) {\n return block;\n }\n\n return applyTextFormatting({\n ...block,\n ...blockProps,\n });\n });\n};\n\nexport const replaceSelectionAIChat = (\n editor: PlateEditor,\n sourceEditor: SlateEditor,\n { format = 'single' }: { format?: 'all' | 'none' | 'single' } = {}\n) => {\n if (!sourceEditor || sourceEditor.api.isEmpty()) return;\n\n const isBlockSelecting = editor.getOption(\n BlockSelectionPlugin,\n 'isSelectingSome'\n );\n\n editor.getApi<AIChatPluginConfig>({ key: KEYS.ai }).aiChat.hide();\n\n // If no blocks selected, treat it like a normal selection replacement\n if (!isBlockSelecting) {\n const firstBlock = editor.api.node({\n block: true,\n mode: 'lowest',\n });\n\n if (\n firstBlock &&\n editor.api.isSelected(firstBlock[1], { contains: true }) &&\n format !== 'none'\n ) {\n const formattedBlocks = createFormattedBlocks({\n blocks: cloneDeep(sourceEditor.children),\n format,\n sourceBlock: firstBlock,\n });\n\n if (!formattedBlocks) return;\n\n /** When user selection is cover the whole code block */\n if (\n firstBlock[0].type === KEYS.codeLine &&\n sourceEditor.children[0].type === KEYS.codeBlock &&\n sourceEditor.children.length === 1\n ) {\n editor.tf.insertFragment(formattedBlocks[0].children);\n } else {\n editor.tf.insertFragment(formattedBlocks);\n }\n\n editor.tf.focus();\n\n return;\n }\n\n editor.tf.insertFragment(sourceEditor.children);\n editor.tf.focus();\n\n return;\n }\n\n const blockSelectionApi = editor.getApi(BlockSelectionPlugin).blockSelection;\n const selectedBlocks = blockSelectionApi.getNodes();\n\n if (selectedBlocks.length === 0) return;\n // If format is 'none' or multiple blocks with 'single',\n // just insert the content as is\n if (format === 'none' || (format === 'single' && selectedBlocks.length > 1)) {\n editor.tf.withoutNormalizing(() => {\n removeBlockSelectionNodes(editor);\n\n editor.tf.withNewBatch(() => {\n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.insertBlocksAndSelect(\n cloneDeep(sourceEditor.children),\n {\n at: selectedBlocks[0][1],\n }\n );\n });\n });\n\n editor.getApi(BlockSelectionPlugin).blockSelection.focus();\n\n return;\n }\n\n // Apply formatting from first block when:\n // - formatting is 'all', or\n // - only one block is selected\n const [, firstBlockPath] = selectedBlocks[0];\n const formattedBlocks = createFormattedBlocks({\n blocks: cloneDeep(sourceEditor.children),\n format,\n sourceBlock: selectedBlocks[0],\n });\n\n if (!formattedBlocks) return;\n\n editor.tf.withoutNormalizing(() => {\n removeBlockSelectionNodes(editor);\n\n editor.tf.withNewBatch(() => {\n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.insertBlocksAndSelect(formattedBlocks, {\n at: firstBlockPath,\n });\n });\n });\n\n editor.getApi(BlockSelectionPlugin).blockSelection.focus();\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport {\n type RemoveNodesOptions,\n ElementApi,\n getPluginType,\n KEYS,\n} from 'platejs';\n\nexport const removeAnchorAIChat = (\n editor: PlateEditor,\n options?: RemoveNodesOptions\n) => {\n editor.tf.withoutSaving(() => {\n editor.tf.removeNodes({\n at: [],\n match: (n) =>\n ElementApi.isElement(n) &&\n n.type === getPluginType(editor, KEYS.aiChat),\n ...options,\n });\n });\n};\n","import { KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport type { AIChatPluginConfig } from '../AIChatPlugin';\n\nimport { AIPlugin } from '../../ai/AIPlugin';\n\nexport const resetAIChat = (\n editor: PlateEditor,\n { undo = true }: { undo?: boolean } = {}\n) => {\n const { api, getOptions, setOptions } = getEditorPlugin<AIChatPluginConfig>(\n editor,\n {\n key: KEYS.aiChat,\n }\n );\n\n api.aiChat.stop();\n\n const chat = getOptions().chat;\n\n if (chat.messages && chat.messages.length > 0) {\n chat.setMessages?.([]);\n }\n\n setOptions({\n _replaceIds: [],\n chatNodes: [],\n mode: 'insert',\n toolName: 'generate',\n });\n\n if (undo) {\n editor.getTransforms(AIPlugin).ai.undo();\n }\n};\n","import type { ChatRequestOptions } from 'ai';\n\nimport { isSelecting } from '@platejs/selection';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { type Descendant, type Range, type TIdElement, KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport type { AIMode, AIToolName } from '../../../lib/types';\nimport type { AIChatPluginConfig } from '../AIChatPlugin';\n\nimport {\n type EditorPrompt,\n getEditorPrompt,\n} from '../../../lib/utils/getEditorPrompt';\nimport { AIPlugin } from '../../ai/AIPlugin';\n\nexport const submitAIChat = (\n editor: PlateEditor,\n input: string,\n {\n mode,\n options,\n prompt,\n toolName,\n }: {\n mode?: AIMode;\n options?: ChatRequestOptions;\n prompt?: EditorPrompt;\n toolName?: AIToolName;\n } = {}\n) => {\n const { getOptions, setOption } = getEditorPlugin<AIChatPluginConfig>(\n editor,\n {\n key: KEYS.aiChat,\n }\n );\n\n const { chat } = getOptions();\n\n if (!prompt && input?.length === 0) {\n return;\n }\n if (!prompt) {\n prompt = input;\n }\n if (!mode) {\n mode = isSelecting(editor) ? 'chat' : 'insert';\n }\n if (mode === 'insert') {\n editor.getTransforms(AIPlugin).ai.undo();\n }\n\n setOption('mode', mode);\n\n setOption('toolName', toolName ?? null);\n\n const blocks = editor.getApi(BlockSelectionPlugin).blockSelection.getNodes();\n const blocksRange = editor.api.nodesRange(blocks);\n\n const promptText = getEditorPrompt(editor, {\n prompt,\n });\n\n const selection = blocks.length > 0 ? blocksRange : editor.selection;\n\n const chatNodes =\n blocks.length > 0\n ? blocks.map((block) => block[0])\n : editor.api.fragment<TIdElement>();\n\n setOption('chatNodes', chatNodes);\n setOption('chatSelection', blocks.length > 0 ? null : editor.selection);\n\n const ctx: {\n children: Descendant[];\n selection: Range | null;\n toolName: string | null;\n } = {\n children: editor.children,\n selection: selection ?? null,\n toolName: toolName ?? null,\n };\n\n void chat.sendMessage?.(\n {\n text: promptText,\n },\n {\n body: {\n ctx,\n },\n ...options,\n }\n );\n};\n","import type { OverrideEditor } from 'platejs/react';\n\nimport { ElementApi, KEYS } from 'platejs';\n\nimport { AIPlugin } from '../ai/AIPlugin';\nimport { type AIChatPluginConfig, AIChatPlugin } from './AIChatPlugin';\n\nexport const withAIChat: OverrideEditor<AIChatPluginConfig> = ({\n api,\n editor,\n getOptions,\n tf: { apply, insertText, normalizeNode },\n type,\n}) => {\n const tf = editor.getTransforms(AIPlugin);\n\n const matchesTrigger = (text: string) => {\n const { trigger } = getOptions();\n\n if (trigger instanceof RegExp) {\n return trigger.test(text);\n }\n if (Array.isArray(trigger)) {\n return trigger.includes(text);\n }\n\n return text === trigger;\n };\n\n return {\n transforms: {\n insertText(text, options) {\n const { triggerPreviousCharPattern, triggerQuery } = getOptions();\n\n const fn = () => {\n if (\n !editor.selection ||\n !matchesTrigger(text) ||\n (triggerQuery && !triggerQuery(editor))\n ) {\n return;\n }\n\n // Make sure an input is created at the beginning of line or after a whitespace\n const previousChar = editor.api.string(\n editor.api.range('before', editor.selection)\n );\n\n const matchesPreviousCharPattern =\n triggerPreviousCharPattern?.test(previousChar);\n\n if (!matchesPreviousCharPattern) return;\n\n const nodeEntry = editor.api.block({ highest: true });\n\n if (!nodeEntry || !editor.api.isEmpty(nodeEntry[0])) return;\n\n api.aiChat.show();\n\n return true;\n };\n\n if (fn()) return;\n\n return insertText(text, options);\n },\n normalizeNode(entry) {\n const [node, path] = entry;\n\n if (node[KEYS.ai] && !getOptions().open) {\n tf.ai.removeMarks({ at: path });\n\n return;\n }\n\n if (\n ElementApi.isElement(node) &&\n node.type === type &&\n !getOptions().open\n ) {\n editor.getTransforms(AIChatPlugin).aiChat.removeAnchor({ at: path });\n\n return;\n }\n\n return normalizeNode(entry);\n },\n },\n };\n};\n","import { useEffect, useMemo } from 'react';\n\nimport type { SlateEditor } from 'platejs';\n\nimport { type DeserializeMdOptions, MarkdownPlugin } from '@platejs/markdown';\nimport { useEditorPlugin } from 'platejs/react';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\n\n/**\n * Register an editor in the AI chat plugin, and deserializes the content into\n * `editor.children` with block-level memoization.\n */\nexport const useAIChatEditor = (\n editor: SlateEditor,\n content: string,\n { parser }: DeserializeMdOptions = {}\n) => {\n const { setOption } = useEditorPlugin(AIChatPlugin);\n\n editor.children = useMemo(\n () => {\n return editor.getApi(MarkdownPlugin).markdown.deserialize(content, {\n memoize: true,\n parser,\n });\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [content]\n );\n\n useEffect(() => {\n setOption('aiEditor', editor);\n }, [editor, setOption]);\n};\n","import { useEffect, useRef } from 'react';\n\nimport type { TText } from 'platejs';\n\nimport { KEYS } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nimport type { AIChatPluginConfig } from '../AIChatPlugin';\n\nimport { useLastAssistantMessage } from '../utils/getLastAssistantMessage';\n\nexport const useChatChunk = ({\n onChunk,\n onFinish,\n}: {\n onChunk: (chunk: {\n chunk: string;\n isFirst: boolean;\n nodes: TText[];\n text: string;\n }) => void;\n onFinish?: ({ content }: { content: string }) => void;\n}) => {\n const { status } = usePluginOption(\n { key: KEYS.aiChat } as AIChatPluginConfig,\n 'chat'\n );\n const isLoading = status === 'streaming' || status === 'submitted';\n\n const content = useLastAssistantMessage()?.parts.find(\n (part) => part.type === 'text'\n )?.text;\n\n const insertedTextRef = useRef<string>('');\n const prevIsLoadingRef = useRef(isLoading);\n\n useEffect(() => {\n if (!isLoading) {\n insertedTextRef.current = '';\n }\n if (prevIsLoadingRef.current && !isLoading) {\n onFinish?.({ content: content ?? '' });\n }\n\n prevIsLoadingRef.current = isLoading;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isLoading]);\n\n useEffect(() => {\n if (!content) {\n return;\n }\n\n const chunk = content.slice(insertedTextRef.current.length);\n\n const nodes: TText[] = [];\n\n if (chunk) {\n const isFirst = insertedTextRef.current === '';\n\n nodes.push({ text: chunk });\n onChunk({\n chunk,\n isFirst,\n nodes,\n text: content,\n });\n }\n\n insertedTextRef.current = content;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [content]);\n};\n","import { type PlateEditor, usePluginOption } from 'platejs/react';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\n\nexport function getLastAssistantMessage(editor: PlateEditor) {\n const messages = editor.getOptions(AIChatPlugin).chat.messages;\n\n return messages?.findLast((message) => message.role === 'assistant');\n}\n\nexport function useLastAssistantMessage() {\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n const chat = usePluginOption(AIChatPlugin, 'chat');\n\n if (toolName === 'comment') return;\n\n return chat.messages?.findLast((message) => message.role === 'assistant');\n}\n","'use client';\n\nimport { useEffect } from 'react';\n\nimport type { UseChatHelpers } from '@ai-sdk/react';\nimport type { NodeEntry } from 'platejs';\n\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { useEditorPlugin, usePluginOption } from 'platejs/react';\n\nimport type { ChatMessage } from '../internal/types';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\n\nexport type UseEditorChatOptions = {\n chat: UseChatHelpers<ChatMessage>;\n onOpenBlockSelection?: (blocks: NodeEntry[]) => void;\n onOpenChange?: (open: boolean) => void;\n onOpenCursor?: () => void;\n onOpenSelection?: () => void;\n};\n\nexport const useEditorChat = ({\n chat,\n onOpenBlockSelection,\n onOpenChange,\n onOpenCursor,\n onOpenSelection,\n}: UseEditorChatOptions) => {\n const { editor } = useEditorPlugin(AIChatPlugin);\n const open = usePluginOption(AIChatPlugin, 'open');\n\n useEffect(() => {\n onOpenChange?.(open);\n\n if (open) {\n if (onOpenBlockSelection) {\n const blockSelectionApi =\n editor.getApi(BlockSelectionPlugin).blockSelection;\n const isBlockSelecting = editor.getOption(\n BlockSelectionPlugin,\n 'isSelectingSome'\n );\n\n if (isBlockSelecting) {\n onOpenBlockSelection(blockSelectionApi.getNodes());\n\n return;\n }\n }\n if (onOpenCursor && editor.api.isCollapsed()) {\n onOpenCursor();\n\n return;\n }\n if (onOpenSelection && editor.api.isExpanded()) {\n onOpenSelection();\n\n return;\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { type DeserializeMdOptions, MarkdownPlugin } from '@platejs/markdown';\n\nexport const streamDeserializeInlineMd = (\n editor: PlateEditor,\n text: string,\n options?: DeserializeMdOptions\n) => {\n return editor\n .getApi(MarkdownPlugin)\n .markdown.deserializeInline(text, options);\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { type DeserializeMdOptions, MarkdownPlugin } from '@platejs/markdown';\nimport { type TElement, getPluginType, KEYS, TextApi } from 'platejs';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\nimport { getChunkTrimmed } from './utils';\nimport { escapeInput } from './utils/escapeInput';\n\nconst statMdxTagRegex = /<([A-Za-z][A-Za-z0-9._:-]*)(?:\\s[^>]*?)?(?<!\\/)>/;\n\nexport const streamDeserializeMd = (\n editor: PlateEditor,\n data: string,\n options?: DeserializeMdOptions\n) => {\n const input = escapeInput(data);\n\n const value = withoutDeserializeInMdx(editor, input);\n\n if (Array.isArray(value)) return value;\n\n let blocks = [];\n\n blocks = editor.getApi(MarkdownPlugin).markdown.deserialize(input, {\n ...options,\n preserveEmptyParagraphs: false,\n });\n\n const trimmedData = getChunkTrimmed(data);\n\n const lastBlock = blocks.at(-1) as TElement | undefined;\n\n const addNewLine = trimmedData === '\\n\\n';\n const unshiftNewLine =\n getChunkTrimmed(data, { direction: 'left' }) === '\\n\\n';\n\n const isCodeBlockOrTable =\n lastBlock?.type === 'code_block' || lastBlock?.type === 'table';\n\n let result = blocks;\n\n /**\n * Deserialize the sting like `123\\n\\n` will be `123` base on markdown spec\n * but we want to keep the `\\n\\n`\n */\n\n if (\n lastBlock &&\n !isCodeBlockOrTable &&\n trimmedData.length > 0 &&\n !addNewLine\n ) {\n const textNode = [\n {\n text: trimmedData,\n },\n ];\n\n const lastChild = lastBlock.children.at(-1);\n\n /** It’s like normalizing and merging the text nodes. */\n if (\n lastChild &&\n TextApi.isText(lastChild) &&\n Object.keys(lastChild).length === 1\n ) {\n lastBlock.children.pop();\n\n const textNode = [\n {\n text: lastChild.text + trimmedData,\n },\n ];\n\n lastBlock.children.push(...textNode);\n } else {\n lastBlock.children.push(...textNode);\n }\n\n result = [...blocks.slice(0, -1), lastBlock];\n }\n\n if (addNewLine && !isCodeBlockOrTable) {\n result.push({\n children: [{ text: '' }],\n type: KEYS.p,\n });\n }\n\n if (unshiftNewLine && !isCodeBlockOrTable) {\n result.unshift({\n children: [{ text: '' }],\n type: KEYS.p,\n });\n }\n\n return result;\n};\n\nconst withoutDeserializeInMdx = (editor: PlateEditor, input: string) => {\n const mdxName = editor.getOption(AIChatPlugin, '_mdxName');\n\n if (mdxName) {\n const isMdxEnd = input.includes(`</${mdxName}>`);\n\n if (isMdxEnd) {\n editor.setOption(AIChatPlugin, '_mdxName', null);\n return false;\n } else {\n return [\n {\n children: [\n {\n text: input,\n },\n ],\n type: getPluginType(editor, KEYS.p),\n },\n ];\n }\n } else {\n const newMdxName = statMdxTagRegex.exec(input)?.[1];\n\n // Avoid incorrect detection in the code block\n if (input.startsWith(`<${newMdxName}`)) {\n editor.setOption(AIChatPlugin, '_mdxName', newMdxName ?? null);\n }\n }\n};\n","export const getChunkTrimmed = (\n chunk: string,\n {\n direction = 'right',\n }: {\n direction?: 'left' | 'right';\n } = {}\n) => {\n const str = direction === 'right' ? chunk.trimEnd() : chunk.trimStart();\n\n if (direction === 'right') {\n return chunk.slice(str.length);\n } else {\n return chunk.slice(0, chunk.length - str.length);\n }\n};\n\nexport function isCompleteCodeBlock(str: string) {\n const trimmed = str.trim();\n\n const startsWithCodeBlock = trimmed.startsWith('```');\n const endsWithCodeBlock = trimmed.endsWith('```');\n\n return startsWithCodeBlock && endsWithCodeBlock;\n}\n\nexport function isCompleteMath(str: string) {\n const trimmed = str.trim();\n\n const startsWithMath = trimmed.startsWith('$$');\n const endsWithMath = trimmed.endsWith('$$');\n\n return startsWithMath && endsWithMath;\n}\n","import { isCompleteMath } from './utils';\n\nexport const escapeInput = (data: string) => {\n let res = data;\n\n // test case: should correctly handle inline math\n if (\n data.startsWith('$$') &&\n !data.startsWith('$$\\n') &&\n !isCompleteMath(data)\n ) {\n res = data.replace('$$', String.raw`\\$\\$`);\n }\n\n return res;\n};\n","import type { TElement } from 'platejs';\nimport type { PlateEditor } from 'platejs/react';\n\nexport const getListNode = (editor: PlateEditor, node: TElement): TElement => {\n if (node.listStyleType && node.listStart) {\n const previousNode = editor.api.previous({\n at: editor.selection?.focus,\n })?.[0];\n\n // if previous node is also an indent list, don't need to do additional work\n if (previousNode?.listStyleType && previousNode?.listStart) {\n return node;\n } else {\n if (node.listStart === 1) return node;\n\n return {\n ...node,\n listRestartPolite: node.listStart,\n };\n }\n }\n\n return node;\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { type TElement, type TText, isDefined, KEYS } from 'platejs';\n\nconst LIST_STYLE_TYPE = 'listStyleType';\n\nexport const isSameNode = (\n editor: PlateEditor,\n node1: TElement | TText,\n node2: TElement | TText\n) => {\n if (\n node1.type !== editor.getType(KEYS.p) ||\n node2.type !== editor.getType(KEYS.p)\n )\n return node1.type === node2.type;\n\n if (isDefined(node1[LIST_STYLE_TYPE]) || isDefined(node2[LIST_STYLE_TYPE])) {\n return node1[LIST_STYLE_TYPE] === node2[LIST_STYLE_TYPE];\n }\n\n return node1.type === node2.type;\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { type Descendant, ElementApi } from 'platejs';\n\nimport type { SteamInsertChunkOptions } from '../streamInsertChunk';\n\nimport { getListNode } from './getListNode';\n\nexport const nodesWithProps = (\n editor: PlateEditor,\n nodes: Descendant[],\n options: SteamInsertChunkOptions\n): Descendant[] => {\n return nodes.map((node): Descendant => {\n if (ElementApi.isElement(node)) {\n return {\n ...getListNode(editor, node),\n ...options.elementProps,\n children: nodesWithProps(editor, node.children, options),\n };\n } else {\n return {\n ...options.textProps,\n ...node,\n text: node.text,\n };\n }\n });\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport {\n type Path,\n type SlateEditor,\n getPluginType,\n KEYS,\n NodeApi,\n PathApi,\n} from 'platejs';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\nimport { streamDeserializeInlineMd } from './streamDeserializeInlineMd';\nimport { streamDeserializeMd } from './streamDeserializeMd';\nimport { streamSerializeMd } from './streamSerializeMd';\nimport { isSameNode } from './utils/isSameNode';\nimport { nodesWithProps } from './utils/nodesWithProps';\n\nexport interface SteamInsertChunkOptions {\n elementProps?: any;\n textProps?: any;\n}\n\nconst getNextPath = (path: Path, length: number) => {\n let result = path;\n\n for (let i = 0; i < length; i++) {\n result = PathApi.next(result);\n }\n return result;\n};\n\n/** @experimental */\nexport function streamInsertChunk(\n editor: PlateEditor,\n chunk: string,\n options: SteamInsertChunkOptions = {}\n) {\n const { _blockChunks, _blockPath } = editor.getOptions(AIChatPlugin);\n\n if (_blockPath === null) {\n const blocks = streamDeserializeMd(editor, chunk);\n const path = getCurrentBlockPath(editor);\n const startBlock = editor.api.node(path)![0];\n\n const startInEmptyParagraph =\n NodeApi.string(startBlock).length === 0 &&\n startBlock.type === getPluginType(editor, KEYS.p);\n\n // if start in empty paragraph, remove it\n if (startInEmptyParagraph) {\n editor.tf.removeNodes({ at: path });\n }\n\n if (blocks.length > 0) {\n editor.tf.insertNodes(nodesWithProps(editor, [blocks[0]], options), {\n at: path,\n nextBlock: !startInEmptyParagraph,\n select: true,\n });\n\n editor.setOption(AIChatPlugin, '_blockPath', getCurrentBlockPath(editor));\n editor.setOption(AIChatPlugin, '_blockChunks', chunk);\n\n if (blocks.length > 1) {\n const nextBlocks = blocks.slice(1);\n\n const nextPath = getCurrentBlockPath(editor);\n\n editor.tf.insertNodes(nodesWithProps(editor, nextBlocks, options), {\n at: nextPath,\n nextBlock: true,\n select: true,\n });\n\n const lastBlock = editor.api.node(\n getNextPath(nextPath, nextBlocks.length)\n )!;\n\n editor.setOption(AIChatPlugin, '_blockPath', lastBlock[1]);\n\n const lastBlockChunks = streamSerializeMd(\n editor,\n {\n value: [lastBlock[0]],\n },\n chunk\n );\n\n editor.setOption(AIChatPlugin, '_blockChunks', lastBlockChunks);\n }\n }\n } else {\n const tempBlockChunks = _blockChunks + chunk;\n const tempBlocks = streamDeserializeMd(editor, tempBlockChunks);\n\n // console.log(\n // JSON.stringify(chunk),\n // 'chunk',\n // '-------------------------------------------------------------------------------------------'\n // );\n // console.log(\n // '🚀 ~ Streaming ~ tempBlockChunks:',\n // JSON.stringify(tempBlockChunks)\n // );\n\n // console.log('🚀 ~ Streaming ~ tempBlocks:', JSON.stringify(tempBlocks));\n\n if (tempBlocks.length === 0) {\n return console.warn(\n `unsupport md nodes: ${JSON.stringify(tempBlockChunks)}`\n );\n }\n\n if (tempBlocks.length === 1) {\n const currentBlock = editor.api.node(_blockPath)![0];\n\n // If the types are the same\n if (isSameNode(editor, currentBlock, tempBlocks[0])) {\n const chunkNodes = streamDeserializeInlineMd(editor as any, chunk);\n\n // Deserialize the chunk and add it to the end of the current block\n editor.tf.insertNodes(nodesWithProps(editor, chunkNodes, options), {\n at: editor.api.end(_blockPath),\n select: true,\n });\n\n const updatedBlock = editor.api.node(_blockPath)!;\n const serializedBlock = streamSerializeMd(\n editor,\n {\n value: [updatedBlock[0]],\n },\n tempBlockChunks\n );\n\n const blockText = NodeApi.string(tempBlocks[0]);\n\n // Verify if the editor content matches the chunk\n if (\n serializedBlock === tempBlockChunks &&\n blockText === serializedBlock\n ) {\n editor.setOption(AIChatPlugin, '_blockChunks', tempBlockChunks);\n } else {\n editor.tf.replaceNodes(\n nodesWithProps(editor, [tempBlocks[0]], options),\n {\n at: _blockPath,\n select: true,\n }\n );\n\n const serializedBlock = streamSerializeMd(\n editor,\n {\n value: [tempBlocks[0]],\n },\n tempBlockChunks\n );\n\n editor.setOption(\n AIChatPlugin,\n '_blockChunks',\n // one block includes multiple children\n tempBlocks[0].type === getPluginType(editor, KEYS.codeBlock) ||\n tempBlocks[0].type === getPluginType(editor, KEYS.table) ||\n tempBlocks[0].type === getPluginType(editor, KEYS.equation)\n ? tempBlockChunks\n : serializedBlock\n );\n }\n } else {\n const serializedBlock = streamSerializeMd(\n editor,\n {\n value: [tempBlocks[0]],\n },\n tempBlockChunks\n );\n\n editor.tf.replaceNodes(\n nodesWithProps(editor, [tempBlocks[0]], options),\n {\n at: _blockPath,\n select: true,\n }\n );\n\n editor.setOption(AIChatPlugin, '_blockChunks', serializedBlock);\n }\n } else {\n editor.tf.replaceNodes(nodesWithProps(editor, [tempBlocks[0]], options), {\n at: _blockPath,\n select: true,\n });\n\n if (tempBlocks.length > 1) {\n const newEndBlockPath = getNextPath(_blockPath, tempBlocks.length - 1);\n\n editor.tf.insertNodes(\n nodesWithProps(editor, tempBlocks.slice(1), options),\n {\n at: PathApi.next(_blockPath),\n select: true,\n }\n );\n\n editor.setOption(AIChatPlugin, '_blockPath', newEndBlockPath);\n\n const endBlock = editor.api.node(newEndBlockPath)![0];\n\n const serializedBlock = streamSerializeMd(\n editor,\n {\n value: [endBlock],\n },\n tempBlockChunks\n );\n\n editor.setOption(AIChatPlugin, '_blockChunks', serializedBlock);\n }\n }\n }\n}\n\nexport const getCurrentBlockPath = (editor: SlateEditor) => {\n const getAnchorPreviousPath = (editor: SlateEditor): Path | undefined => {\n const anchorNode = editor\n .getApi(AIChatPlugin)\n .aiChat.node({ anchor: true });\n\n if (anchorNode) {\n return PathApi.previous(anchorNode[1])!;\n }\n };\n\n const getFocusPath = (editor: SlateEditor): Path | undefined => {\n return editor.selection?.focus.path.slice(0, 1);\n };\n\n const path = getAnchorPreviousPath(editor) ?? getFocusPath(editor) ?? [0];\n\n const entry = editor.api.node(path);\n\n // streaming in table or columns shouldn't remove them\n if (\n entry &&\n (entry[0].type === getPluginType(editor, KEYS.columnGroup) ||\n entry[0].type === getPluginType(editor, KEYS.table))\n ) {\n return editor.api.above()?.[1] ?? path;\n }\n\n return path;\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { type SerializeMdOptions, MarkdownPlugin } from '@platejs/markdown';\nimport {\n type Descendant,\n ElementApi,\n getPluginKey,\n KEYS,\n TextApi,\n} from 'platejs';\n\nimport {\n getChunkTrimmed,\n isCompleteCodeBlock,\n isCompleteMath,\n} from './utils/utils';\n\n// fixes test: should serialize heading with tailing line break\n// fixes test: incomplete line breaks\nconst trimEndHeading = (\n editor: PlateEditor,\n value: Descendant[]\n): { trimmedText: string; value: Descendant[] } => {\n const headingKeys = new Set([\n KEYS.h1,\n KEYS.h2,\n KEYS.h3,\n KEYS.h4,\n KEYS.h5,\n KEYS.h6,\n ]);\n const lastBlock = value.at(-1);\n\n if (\n lastBlock &&\n headingKeys.has(\n (getPluginKey(editor, lastBlock.type as string) ?? lastBlock.type) as any\n ) &&\n ElementApi.isElement(lastBlock)\n ) {\n const lastTextNode = lastBlock.children.at(-1);\n\n if (TextApi.isText(lastTextNode)) {\n const trimmedText = getChunkTrimmed(lastTextNode?.text as string);\n\n // Create a new lastBlock with immutable operations\n const newChildren = [\n ...lastBlock.children.slice(0, -1),\n { text: lastTextNode.text.trimEnd() },\n ];\n\n const newLastBlock = {\n ...lastBlock,\n children: newChildren,\n };\n\n return {\n trimmedText: trimmedText,\n value: [...value.slice(0, -1), newLastBlock],\n };\n }\n }\n\n return { trimmedText: '', value };\n};\n\nexport const streamSerializeMd = (\n editor: PlateEditor,\n options: SerializeMdOptions,\n chunk: string\n) => {\n const { value: optionsValue, ...restOptions } = options;\n const { value } = trimEndHeading(editor, optionsValue ?? editor.children);\n\n let result = '';\n\n result = editor.getApi(MarkdownPlugin).markdown.serialize({\n value: value,\n ...restOptions,\n });\n\n const trimmedChunk = getChunkTrimmed(chunk);\n\n if (isCompleteCodeBlock(result) && !chunk.endsWith('```')) {\n result = result.trimEnd().slice(0, -3) + trimmedChunk;\n }\n\n if (isCompleteMath(result) && !chunk.endsWith('$$')) {\n result = result.trimEnd().slice(0, -3) + trimmedChunk;\n }\n\n // clean HTML spaces and zero-width characters\n result = result.replace(/ /g, ' ');\n result = result.replace(/​/g, ' ');\n result = result.replace(/\\u200B/g, '');\n\n // remove extra \\n but not include \\n itself\n // FIXME maybe failed when chunk is more than two'\\n'\n if (trimmedChunk !== '\\n\\n') {\n result = result.trimEnd() + trimmedChunk;\n }\n\n // Handle empty paragraph case for streaming\n if (chunk.endsWith('\\n\\n')) {\n if (result === '\\n') {\n // Single empty paragraph case\n result = '';\n } else if (result.endsWith('\\n\\n')) {\n // Multiple paragraphs ending with empty paragraph\n result = result.slice(0, -1);\n }\n }\n\n // replace   to real space\n\n // remove Markdown escape characters (including those potentially added in the chunk)\n result = result.replace(/\\\\([\\\\`*_{}\\\\[\\]()#+\\-\\\\.!~<>|$])/g, '$1');\n\n return result;\n};\n","import { deserializeMd } from '@platejs/markdown';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport {\n diffToSuggestions,\n getTransientSuggestionKey,\n SkipSuggestionDeletes,\n} from '@platejs/suggestion';\nimport {\n type Descendant,\n type SlateEditor,\n type TElement,\n type TIdElement,\n type TSuggestionData,\n type TSuggestionElement,\n ElementApi,\n KEYS,\n nanoid,\n TextApi,\n} from 'platejs';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\n\nexport const applyAISuggestions = (editor: SlateEditor, content: string) => {\n const isBlockSelecting = editor.getOption(\n BlockSelectionPlugin,\n 'isSelectingSome'\n );\n\n const { chatNodes } = editor.getOptions(AIChatPlugin);\n\n if (isBlockSelecting) {\n const setReplaceIds = (ids: string[]) => {\n editor.setOption(AIChatPlugin, '_replaceIds', ids);\n };\n\n if (editor.getOption(AIChatPlugin, '_replaceIds').length === 0) {\n setReplaceIds(chatNodes.map((node) => node.id as string));\n }\n\n const diffNodes = getDiffNodes(editor, content);\n\n const replaceNodes = Array.from(\n editor.api.nodes<TIdElement>({\n at: [],\n match: (n: TIdElement) =>\n ElementApi.isElement(n) &&\n editor.getOption(AIChatPlugin, '_replaceIds').includes(n.id),\n })\n );\n\n replaceNodes.forEach(([node, path], index) => {\n const replaceNode = node as unknown as TSuggestionElement;\n const diffNode = diffNodes[index] as unknown as TSuggestionElement;\n\n const isSameString =\n SkipSuggestionDeletes(editor, replaceNode) ===\n SkipSuggestionDeletes(editor, diffNode);\n\n const isSameSuggestion =\n (replaceNode.suggestion as TSuggestionData | undefined)?.type ===\n (diffNode.suggestion as TSuggestionData | undefined)?.type;\n\n if (\n index === replaceNodes.length - 1 &&\n diffNodes.length > replaceNodes.length\n ) {\n editor.tf.replaceNodes(diffNodes.slice(index), {\n at: path,\n });\n }\n // Performance optimization\n if (isSameString && isSameSuggestion && node.id == diffNode.id) {\n return;\n }\n\n editor.tf.replaceNodes(diffNode, {\n at: path,\n });\n });\n\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.set(diffNodes.map((node) => node.id as string));\n setReplaceIds(diffNodes.map((node) => node.id as string));\n } else {\n const diffNodes = getDiffNodes(editor, content);\n\n editor.tf.insertFragment(diffNodes);\n\n const nodes = Array.from(\n editor.api.nodes({\n at: [],\n mode: 'lowest',\n match: (n) => TextApi.isText(n) && !!n[getTransientSuggestionKey()],\n })\n );\n\n const range = editor.api.nodesRange(nodes);\n\n editor.tf.setSelection(range!);\n\n return;\n }\n};\n\nconst withProps = (\n diffNodes: Descendant[],\n chatNodes: Descendant[]\n): Descendant[] => {\n return diffNodes.map((node, index) => {\n if (!ElementApi.isElement(node)) return node;\n\n const originalNode = chatNodes?.[index] as TElement | undefined;\n\n return {\n ...node,\n ...(originalNode ?? { id: nanoid() }),\n children: node.children,\n };\n });\n};\n\nconst withTransient = (diffNodes: Descendant[]): Descendant[] => {\n return diffNodes.map((node) => {\n if (TextApi.isText(node)) {\n return {\n ...node,\n [getTransientSuggestionKey()]: true,\n };\n } else {\n return {\n ...node,\n children: withTransient(node.children),\n [getTransientSuggestionKey()]: true,\n };\n }\n });\n};\n\nconst withoutSuggestionAndComments = (nodes: Descendant[]): Descendant[] => {\n return nodes.map((node) => {\n if (TextApi.isText(node)) {\n if (node[KEYS.suggestion] || node[KEYS.comment]) {\n return {\n text: node.text,\n };\n }\n\n return node;\n }\n if (ElementApi.isElement(node)) {\n if (node[KEYS.suggestion]) {\n const nodeWithoutSuggestion: any = {};\n\n Object.keys(node).forEach((key) => {\n if (key !== KEYS.suggestion && !key.startsWith(KEYS.suggestion)) {\n nodeWithoutSuggestion[key] = node[key];\n }\n });\n\n return {\n ...nodeWithoutSuggestion,\n children: withoutSuggestionAndComments(node.children),\n };\n }\n\n return {\n ...node,\n children: withoutSuggestionAndComments(node.children),\n };\n }\n\n return node;\n });\n};\nconst getDiffNodes = (editor: SlateEditor, aiContent: string) => {\n /** Original document nodes */\n const chatNodes = withoutSuggestionAndComments(\n editor.getOption(AIChatPlugin, 'chatNodes')\n );\n\n const aiNodes = withProps(deserializeMd(editor, aiContent), chatNodes);\n\n const diffNodes = withTransient(\n diffToSuggestions(editor, chatNodes, aiNodes, {\n ignoreProps: ['id', 'listStart'],\n })\n );\n\n return diffNodes;\n};\n","'use client';\n\nimport type React from 'react';\n\nimport type { DebouncedFunc } from 'lodash';\n\nimport { serializeMd } from '@platejs/markdown';\nimport debounce from 'lodash/debounce.js';\nimport {\n type OmitFirst,\n type PluginConfig,\n type TElement,\n bindFirst,\n KEYS,\n NodeApi,\n} from 'platejs';\nimport { type PlateEditor, createTPlatePlugin } from 'platejs/react';\n\nimport type { CompleteOptions } from './utils/callCompletionApi';\n\nimport { renderCopilotBelowNodes } from './renderCopilotBelowNodes';\nimport { acceptCopilot } from './transforms/acceptCopilot';\nimport { acceptCopilotNextWord } from './transforms/acceptCopilotNextWord';\nimport { type GetNextWord, getNextWord } from './utils/getNextWord';\nimport { triggerCopilotSuggestion } from './utils/triggerCopilotSuggestion';\nimport { withCopilot } from './withCopilot';\n\nexport type CopilotPluginConfig = PluginConfig<\n 'copilot',\n CompletionState & {\n /**\n * AI completion options. See:\n * {@link https://sdk.vercel.ai/docs/reference/ai-sdk-ui/use-completion#parameters | AI SDK UI useCompletion Parameters}\n */\n completeOptions?: Partial<CompleteOptions>;\n /**\n * Debounce delay for auto triggering AI completion.\n *\n * @default 0\n */\n debounceDelay?: number;\n /** Get the next word to be inserted. */\n getNextWord?: GetNextWord;\n /** Render the ghost text. */\n renderGhostText?: (() => React.ReactNode) | null;\n shouldAbort?: boolean;\n /** The node id where the suggestion is located. */\n suggestionNodeId?: string | null;\n /** The text of the suggestion. */\n suggestionText?: string | null;\n /**\n * Conditions to auto trigger copilot, used in addition to triggerQuery.\n * Disabling defaults to:\n *\n * - Block above is empty\n * - Block above ends with a space\n * - There is already a suggestion\n */\n autoTriggerQuery?: (options: { editor: PlateEditor }) => boolean;\n /**\n * Get the prompt for AI completion.\n *\n * @default serializeMdNodes(editor.api.block({ highest: true }))\n */\n getPrompt?: (options: { editor: PlateEditor }) => string;\n /**\n * Conditions to trigger copilot. Disabling defaults to:\n *\n * - Selection is expanded\n * - Selection is not at the end of block\n */\n triggerQuery?: (options: { editor: PlateEditor }) => boolean;\n // query?: QueryEditorOptions;\n },\n {\n copilot: {\n triggerSuggestion: OmitFirst<typeof triggerCopilotSuggestion>;\n // Function to abort the current API request and reject the completion state.\n reject: () => false | undefined;\n setBlockSuggestion: (options: { text: string; id?: string }) => void;\n // Function to abort the current API request.\n stop: () => void;\n };\n },\n {\n copilot: {\n accept: OmitFirst<typeof acceptCopilot>;\n acceptNextWord: OmitFirst<typeof acceptCopilotNextWord>;\n };\n },\n {\n isSuggested?: (id: string) => boolean;\n }\n>;\n\ntype CompletionState = {\n abortController?: AbortController | null;\n // The current text completion.\n completion?: string | null;\n // The error thrown during the completion process, if any.\n error?: Error | null;\n // Boolean flag indicating whether a fetch operation is currently in progress.\n isLoading?: boolean;\n};\n\nexport const CopilotPlugin = createTPlatePlugin<CopilotPluginConfig>({\n key: KEYS.copilot,\n handlers: {\n onBlur: ({ api }) => {\n api.copilot.reject();\n },\n onMouseDown: ({ api }) => {\n api.copilot.reject();\n },\n },\n options: {\n abortController: null,\n completeOptions: {},\n completion: '',\n debounceDelay: 0,\n error: null,\n getNextWord: getNextWord,\n isLoading: false,\n renderGhostText: null,\n shouldAbort: true,\n suggestionNodeId: null,\n suggestionText: null,\n autoTriggerQuery: ({ editor }) => {\n if (\n editor.getOptions<CopilotPluginConfig>({ key: KEYS.copilot })\n .suggestionText\n ) {\n return false;\n }\n\n const isEmpty = editor.api.isEmpty(editor.selection, { block: true });\n\n if (isEmpty) return false;\n\n const blockAbove = editor.api.block();\n\n if (!blockAbove) return false;\n\n const blockString = NodeApi.string(blockAbove[0]);\n\n return blockString.at(-1) === ' ';\n },\n getPrompt: ({ editor }) => {\n const contextEntry = editor.api.block({ highest: true });\n\n if (!contextEntry) return '';\n\n return serializeMd(editor, {\n value: [contextEntry[0] as TElement],\n });\n },\n triggerQuery: ({ editor }) => {\n if (editor.api.isExpanded()) return false;\n\n const isEnd = editor.api.isAt({ end: true });\n\n if (!isEnd) return false;\n\n return true;\n },\n },\n})\n .overrideEditor(withCopilot)\n .extendSelectors<CopilotPluginConfig['selectors']>(({ getOptions }) => ({\n isSuggested: (id) => getOptions().suggestionNodeId === id,\n }))\n .extendTransforms(({ editor }) => ({\n accept: bindFirst(acceptCopilot, editor),\n acceptNextWord: bindFirst(acceptCopilotNextWord, editor),\n }))\n .extendApi<Omit<CopilotPluginConfig['api']['copilot'], 'reject'>>(\n ({ api, editor, getOptions, setOption, setOptions }) => {\n const debounceDelay = getOptions().debounceDelay;\n\n let triggerSuggestion = bindFirst(triggerCopilotSuggestion, editor);\n\n if (debounceDelay) {\n triggerSuggestion = debounce(\n bindFirst(triggerCopilotSuggestion, editor),\n debounceDelay\n ) as any;\n }\n\n return {\n triggerSuggestion,\n setBlockSuggestion: ({ id = getOptions().suggestionNodeId, text }) => {\n if (!id) {\n id = editor.api.block()![0].id as string;\n }\n\n setOptions({\n suggestionNodeId: id,\n suggestionText: text,\n });\n },\n stop: () => {\n const { abortController } = getOptions();\n\n (api.copilot.triggerSuggestion as DebouncedFunc<any>)?.cancel();\n\n if (abortController) {\n abortController.abort();\n setOption('abortController', null);\n }\n },\n };\n }\n )\n .extendApi(({ api, getOptions, setOptions }) => ({\n reject: () => {\n if (!getOptions().suggestionText?.length) return false;\n\n api.copilot.stop();\n\n setOptions({\n completion: null,\n suggestionNodeId: null,\n suggestionText: null,\n });\n },\n }))\n .extend({\n render: {\n belowNodes: renderCopilotBelowNodes,\n },\n shortcuts: {\n accept: {\n keys: 'tab',\n },\n reject: {\n keys: 'escape',\n },\n },\n });\n","'use client';\n\nimport React from 'react';\n\nimport { KEYS } from 'platejs';\nimport { type RenderNodeWrapperProps, getEditorPlugin } from 'platejs/react';\n\nimport type { CopilotPluginConfig } from './CopilotPlugin';\n\nexport const renderCopilotBelowNodes = ({\n editor,\n}: RenderNodeWrapperProps<CopilotPluginConfig>) => {\n const copilot = getEditorPlugin<CopilotPluginConfig>(editor, {\n key: KEYS.copilot,\n });\n\n const { renderGhostText: GhostText } = copilot.getOptions();\n\n if (!GhostText) return;\n\n return ({ children }: { children: React.ReactNode }) => {\n return (\n <React.Fragment>\n {children}\n\n <GhostText />\n </React.Fragment>\n );\n };\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { deserializeInlineMd } from '@platejs/markdown';\nimport { KEYS } from 'platejs';\n\nimport type { CopilotPluginConfig } from '../CopilotPlugin';\n\nexport const acceptCopilot = (editor: PlateEditor) => {\n const { suggestionText } = editor.getOptions<CopilotPluginConfig>({\n key: KEYS.copilot,\n });\n\n if (!suggestionText?.length) return false;\n\n editor.tf.insertFragment(deserializeInlineMd(editor, suggestionText));\n};\n","import { deserializeInlineMd } from '@platejs/markdown';\nimport { KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport type { CopilotPluginConfig } from '../CopilotPlugin';\n\nimport { withoutAbort } from '../utils';\n\nexport const acceptCopilotNextWord = (editor: PlateEditor) => {\n const { api, getOptions } = getEditorPlugin<CopilotPluginConfig>(editor, {\n key: KEYS.copilot,\n });\n\n const { getNextWord, suggestionText } = getOptions();\n\n if (!suggestionText?.length) {\n return false;\n }\n\n const { firstWord, remainingText } = getNextWord!({ text: suggestionText });\n\n api.copilot.setBlockSuggestion({\n text: remainingText,\n });\n\n withoutAbort(editor, () => {\n editor.tf.insertFragment(deserializeInlineMd(editor, firstWord));\n });\n};\n","// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nexport type CallCompletionApiOptions = {\n prompt: string;\n api?: string;\n body?: Record<string, any>;\n credentials?: RequestCredentials | undefined;\n fetch?: ReturnType<typeof getOriginalFetch> | undefined;\n headers?: HeadersInit | undefined;\n setAbortController?: (abortController: AbortController | null) => void;\n setCompletion?: (completion: string) => void;\n setError?: (error: Error | null) => void;\n setLoading?: (loading: boolean) => void;\n onError?: ((error: Error) => void) | undefined;\n onFinish?: ((prompt: string, completion: string) => void) | undefined;\n onResponse?: ((response: Response) => Promise<void> | void) | undefined;\n};\n\nexport type CompleteOptions = Omit<\n CallCompletionApiOptions,\n 'setAbortController' | 'setCompletion' | 'setError' | 'setLoading'\n>;\n\n// https://github.com/vercel/ai/blob/main/packages/ui-utils/src/call-completion-api.ts\n// https://github.com/vercel/ai/blob/642ba22ee33723f3aae9669c7e075322cffca2f3/packages/react/src/use-completion.ts\nexport async function callCompletionApi({\n api = '/api/completion',\n body,\n credentials,\n fetch = getOriginalFetch(),\n headers,\n prompt,\n setAbortController = () => {},\n setCompletion = () => {},\n setError = () => {},\n setLoading = () => {},\n onError,\n onFinish,\n onResponse,\n}: CallCompletionApiOptions) {\n try {\n setLoading(true);\n setError(null);\n\n const abortController = new AbortController();\n setAbortController(abortController);\n\n // Empty the completion immediately.\n setCompletion('');\n\n const res = await fetch(api, {\n body: JSON.stringify({\n prompt,\n ...body,\n }),\n credentials,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n method: 'POST',\n signal: abortController.signal,\n }).catch((error) => {\n throw error;\n });\n\n if (onResponse) {\n await onResponse(res);\n }\n if (!res.ok) {\n throw new Error(\n (await res.text()) || 'Failed to fetch the chat response.'\n );\n }\n if (!res.body) {\n throw new Error('The response body is empty.');\n }\n\n const { text } = await res.json();\n\n if (!text) {\n throw new Error('The response does not contain a text field.');\n }\n\n setCompletion(text);\n\n if (onFinish) {\n onFinish(prompt, text);\n }\n\n setAbortController(null);\n\n return text as string;\n } catch (error) {\n // Ignore abort errors as they are expected.\n if ((error as any).name === 'AbortError') {\n setAbortController(null);\n\n return null;\n }\n if (error instanceof Error && onError) {\n onError(error);\n }\n\n setError(error as Error);\n } finally {\n setLoading(false);\n }\n}\n","export type GetNextWord = (options: { text: string }) => {\n firstWord: string;\n remainingText: string;\n};\n\nexport const getNextWord: GetNextWord = ({ text }) => {\n if (!text) return { firstWord: '', remainingText: '' };\n\n // Check if the first non-space character is a CJK character\n const nonSpaceMatch = /^\\s*(\\S)/.exec(text);\n\n if (!nonSpaceMatch) return { firstWord: '', remainingText: '' };\n\n const firstNonSpaceChar = nonSpaceMatch[1];\n\n // Regular expression for matching CJK characters\n // 1. [\\u4E00-\\u9FA5] - Chinese Characters\n // 2. [\\u3040-\\u309F] - Japanese Hiragana\n // 3. [\\u30A0-\\u30FF] - Japanese Katakana\n // 4. [\\u3400-\\u4DBF] - CJK Extension A\n // 5. [\\u4E00-\\u9FFF] - CJK Unified Ideographs\n // 6. [\\uF900-\\uFAFF] - CJK Compatibility Ideographs\n // 7. [\\uAC00-\\uD7AF] - Korean Syllables\n // 8. [\\u1100-\\u11FF] - Korean Jamo\n const isCJKChar =\n /[\\u1100-\\u11FF\\u3040-\\u30FF\\u3400-\\u4DBF\\u4E00-\\u9FFF\\uAC00-\\uD7AF\\uF900-\\uFAFF]/.test(\n firstNonSpaceChar\n );\n\n let firstWord, remainingText;\n\n if (isCJKChar) {\n // CJK characters: match leading spaces + first character + optional punctuation\n const match =\n /^(\\s*)([\\u1100-\\u11FF\\u3040-\\u30FF\\u3400-\\u4DBF\\u4E00-\\u9FFF\\uAC00-\\uD7AF\\uF900-\\uFAFF])([\\u3000-\\u303F\\uFF00-\\uFFEF])?/.exec(\n text\n );\n\n if (match) {\n const [fullMatch, spaces = '', char = '', punctuation = ''] = match;\n firstWord = spaces + char + punctuation;\n remainingText = text.slice(firstWord.length);\n } else {\n firstWord = '';\n remainingText = text;\n }\n } else {\n // For non-CJK text (including mixed content), match until space or CJK char\n const match =\n /^(\\s*\\S+?)(?=[\\s\\u1100-\\u11FF\\u3040-\\u30FF\\u3400-\\u4DBF\\u4E00-\\u9FFF\\uAC00-\\uD7AF\\uF900-\\uFAFF]|$)/.exec(\n text\n );\n\n if (match) {\n firstWord = match[0];\n remainingText = text.slice(firstWord.length);\n } else {\n firstWord = text;\n remainingText = '';\n }\n }\n\n return { firstWord, remainingText };\n};\n","import { KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport type { CopilotPluginConfig } from '../CopilotPlugin';\n\nimport { callCompletionApi } from './callCompletionApi';\n\nexport const triggerCopilotSuggestion = async (editor: PlateEditor) => {\n const { api, getOptions, setOption } = getEditorPlugin<CopilotPluginConfig>(\n editor,\n {\n key: KEYS.copilot,\n }\n );\n\n const { completeOptions, getPrompt, isLoading, triggerQuery } = getOptions();\n\n if (isLoading || editor.getOptions({ key: KEYS.aiChat }).chat?.isLoading) {\n return false;\n }\n if (!triggerQuery!({ editor })) return false;\n\n // if (query && !queryEditor(editor, query)) return;\n\n const prompt = getPrompt!({ editor });\n\n if (prompt.length === 0) return false;\n\n api.copilot.stop();\n\n await callCompletionApi({\n prompt,\n onFinish: (_, completion) => {\n api.copilot.setBlockSuggestion({ text: completion });\n },\n ...completeOptions,\n setAbortController: (controller) =>\n setOption('abortController', controller),\n setCompletion: (completion) => setOption('completion', completion),\n setError: (error) => setOption('error', error),\n setLoading: (loading) => setOption('isLoading', loading),\n onError: (error) => {\n setOption('error', error);\n completeOptions?.onError?.(error);\n },\n });\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { CopilotPlugin } from '..';\n\nexport const withoutAbort = (editor: PlateEditor, fn: () => void) => {\n editor.setOption(CopilotPlugin, 'shouldAbort', false);\n fn();\n editor.setOption(CopilotPlugin, 'shouldAbort', true);\n};\n","import type { OverrideEditor, PlateEditor } from 'platejs/react';\n\nimport { serializeInlineMd } from '@platejs/markdown';\nimport {\n type Operation,\n type SlateEditor,\n type TRange,\n RangeApi,\n} from 'platejs';\n\nimport type { CopilotPluginConfig } from './CopilotPlugin';\n\nimport { withoutAbort } from './utils/withoutAbort';\n\ntype CopilotBatch = PlateEditor['history']['undos'][number] & {\n shouldAbort: boolean;\n};\n\nconst getPatchString = (editor: SlateEditor, operations: Operation[]) => {\n let string = '';\n\n for (const operation of operations) {\n if (operation.type === 'insert_node') {\n const node = operation.node;\n const text = serializeInlineMd(editor, { value: [node] });\n string += text;\n } else if (operation.type === 'insert_text') {\n string += operation.text;\n }\n }\n\n return string;\n};\n\nexport const withCopilot: OverrideEditor<CopilotPluginConfig> = ({\n api,\n editor,\n getOptions,\n setOption,\n tf: { apply, insertText, redo, setSelection, undo, writeHistory },\n}) => {\n let prevSelection: TRange | null = null;\n\n return {\n transforms: {\n apply(operation) {\n const { shouldAbort } = getOptions();\n\n if (shouldAbort) {\n api.copilot.reject();\n }\n\n apply(operation);\n },\n insertText(text, options) {\n const suggestionText = getOptions().suggestionText;\n\n // When using IME input, it's possible to enter two characters at once.\n if (suggestionText?.startsWith(text)) {\n withoutAbort(editor, () => {\n editor.tf.withoutMerging(() => {\n const newText = suggestionText?.slice(text.length);\n setOption('suggestionText', newText);\n insertText(text);\n });\n });\n\n return;\n }\n\n insertText(text, options);\n },\n\n redo() {\n if (!getOptions().suggestionText) return redo();\n\n const topRedo = editor.history.redos.at(-1) as CopilotBatch;\n const prevSuggestion = getOptions().suggestionText;\n\n if (topRedo && topRedo.shouldAbort === false && prevSuggestion) {\n withoutAbort(editor, () => {\n const shouldRemoveText = getPatchString(editor, topRedo.operations);\n\n const newText = prevSuggestion.slice(shouldRemoveText.length);\n setOption('suggestionText', newText);\n\n redo();\n });\n\n return;\n }\n\n return redo();\n },\n\n setSelection(props) {\n setSelection(props);\n\n if (\n editor.selection &&\n (!prevSelection ||\n !RangeApi.equals(prevSelection, editor.selection)) &&\n getOptions().autoTriggerQuery!({ editor }) &&\n editor.api.isFocused()\n ) {\n void api.copilot.triggerSuggestion();\n }\n\n prevSelection = editor.selection;\n },\n\n undo() {\n if (!getOptions().suggestionText) return undo();\n\n const lastUndos = editor.history.undos.at(-1) as CopilotBatch;\n const oldText = getOptions().suggestionText;\n\n if (lastUndos && lastUndos.shouldAbort === false && oldText) {\n withoutAbort(editor, () => {\n const shouldInsertText = getPatchString(\n editor,\n lastUndos.operations\n );\n\n const newText = shouldInsertText + oldText;\n setOption('suggestionText', newText);\n\n undo();\n });\n\n return;\n }\n\n return undo();\n },\n\n writeHistory(stacks, batch) {\n if (!getOptions().isLoading) {\n batch.shouldAbort = getOptions().shouldAbort;\n }\n\n return writeHistory(stacks, batch);\n },\n },\n };\n};\n"],"mappings":"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","names":["KEYS","KEYS","KEYS","isSelecting","NodeApi","NodeApi","BlockSelectionPlugin","bindFirst","ElementApi","getPluginType","KEYS","getTransientSuggestionKey","KEYS","KEYS","getTransientSuggestionKey","BlockSelectionPlugin","cloneDeep","KEYS","KEYS","NodeApi","TextApi","formattedBlocks","BlockSelectionPlugin","KEYS","cloneDeep","getPluginType","KEYS","KEYS","getEditorPlugin","getEditorPlugin","KEYS","isSelecting","BlockSelectionPlugin","KEYS","getEditorPlugin","getEditorPlugin","KEYS","isSelecting","BlockSelectionPlugin","ElementApi","KEYS","KEYS","ElementApi","KEYS","bindFirst","ElementApi","getPluginType","BlockSelectionPlugin","useEffect","KEYS","usePluginOption","usePluginOption","KEYS","useEffect","useEffect","BlockSelectionPlugin","useEditorPlugin","usePluginOption","useEditorPlugin","usePluginOption","useEffect","BlockSelectionPlugin","MarkdownPlugin","MarkdownPlugin","getPluginType","KEYS","TextApi","KEYS","ElementApi","ElementApi","MarkdownPlugin","TextApi","textNode","KEYS","getPluginType","getPluginType","KEYS","NodeApi","PathApi","MarkdownPlugin","ElementApi","KEYS","TextApi","KEYS","ElementApi","TextApi","MarkdownPlugin","PathApi","NodeApi","getPluginType","KEYS","serializedBlock","editor","deserializeMd","BlockSelectionPlugin","getTransientSuggestionKey","ElementApi","KEYS","TextApi","BlockSelectionPlugin","ElementApi","TextApi","getTransientSuggestionKey","KEYS","deserializeMd","bindFirst","KEYS","NodeApi","createTPlatePlugin","KEYS","getEditorPlugin","KEYS","deserializeInlineMd","KEYS","getEditorPlugin","fetch","KEYS","getEditorPlugin","getEditorPlugin","KEYS","getEditorPlugin","KEYS","getNextWord","deserializeInlineMd","RangeApi","RangeApi","createTPlatePlugin","KEYS","NodeApi","bindFirst"]}
|
|
1
|
+
{"version":3,"sources":["../../src/react/ai/AIPlugin.ts","../../src/lib/BaseAIPlugin.ts","../../src/lib/transforms/insertAINodes.ts","../../src/lib/transforms/removeAIMarks.ts","../../src/lib/transforms/removeAINodes.ts","../../src/lib/transforms/undoAI.ts","../../src/lib/transforms/withAIBatch.ts","../../src/lib/utils/getEditorPrompt.ts","../../src/react/ai/utils/aiCommentToRange.ts","../../src/react/ai/utils/findTextRangeInBlock.tsx","../../src/react/ai-chat/AIChatPlugin.ts","../../src/react/ai-chat/transforms/acceptAIChat.ts","../../src/react/ai-chat/transforms/insertBelowAIChat.ts","../../src/react/ai-chat/transforms/replaceSelectionAIChat.ts","../../src/react/ai-chat/transforms/removeAnchorAIChat.ts","../../src/react/ai-chat/utils/resetAIChat.ts","../../src/react/ai-chat/utils/submitAIChat.ts","../../src/react/ai-chat/withAIChat.ts","../../src/react/ai-chat/hooks/useAIChatEditor.ts","../../src/react/ai-chat/hooks/useChatChunk.ts","../../src/react/ai-chat/utils/getLastAssistantMessage.ts","../../src/react/ai-chat/hooks/useEditorChat.ts","../../src/react/ai-chat/streaming/streamDeserializeInlineMd.ts","../../src/react/ai-chat/streaming/streamDeserializeMd.ts","../../src/react/ai-chat/streaming/utils/utils.ts","../../src/react/ai-chat/streaming/utils/escapeInput.ts","../../src/react/ai-chat/streaming/utils/getListNode.ts","../../src/react/ai-chat/streaming/utils/isSameNode.ts","../../src/react/ai-chat/streaming/utils/nodesWithProps.ts","../../src/react/ai-chat/streaming/streamInsertChunk.ts","../../src/react/ai-chat/streaming/streamSerializeMd.ts","../../src/react/ai-chat/utils/applyAISuggestions.ts","../../src/react/copilot/CopilotPlugin.tsx","../../src/react/copilot/renderCopilotBelowNodes.tsx","../../src/react/copilot/transforms/acceptCopilot.ts","../../src/react/copilot/transforms/acceptCopilotNextWord.ts","../../src/react/copilot/utils/callCompletionApi.ts","../../src/react/copilot/utils/getNextWord.ts","../../src/react/copilot/utils/triggerCopilotSuggestion.ts","../../src/react/copilot/utils/withoutAbort.ts","../../src/react/copilot/withCopilot.ts"],"sourcesContent":["import type { ExtendConfig } from 'platejs';\n\nimport { toPlatePlugin } from 'platejs/react';\n\nimport { type BaseAIPluginConfig, BaseAIPlugin } from '../../lib';\n\nexport type AIPluginConfig = ExtendConfig<BaseAIPluginConfig>;\n\nexport const AIPlugin = toPlatePlugin(BaseAIPlugin);\n","import {\n type OmitFirst,\n type PluginConfig,\n bindFirst,\n createTSlatePlugin,\n KEYS,\n} from 'platejs';\n\nimport { removeAIMarks, undoAI } from './transforms';\nimport { insertAINodes } from './transforms/insertAINodes';\nimport { removeAINodes } from './transforms/removeAINodes';\n\nexport type BaseAIPluginConfig = PluginConfig<\n 'ai',\n {},\n {},\n {\n ai: {\n insertNodes: OmitFirst<typeof insertAINodes>;\n removeMarks: OmitFirst<typeof removeAIMarks>;\n removeNodes: OmitFirst<typeof removeAINodes>;\n };\n }\n>;\n\nexport const BaseAIPlugin = createTSlatePlugin({\n key: KEYS.ai,\n node: { isDecoration: false, isLeaf: true },\n}).extendTransforms(({ editor }) => ({\n insertNodes: bindFirst(insertAINodes, editor),\n removeMarks: bindFirst(removeAIMarks, editor),\n removeNodes: bindFirst(removeAINodes, editor),\n undo: bindFirst(undoAI, editor),\n}));\n","import type { Descendant, Path, SlateEditor } from 'platejs';\n\nexport const insertAINodes = (\n editor: SlateEditor,\n nodes: Descendant[],\n {\n target,\n }: {\n target?: Path;\n } = {}\n) => {\n if (!target && !editor.selection?.focus.path) return;\n\n const aiNodes = nodes.map((node) => ({\n ...node,\n ai: true,\n }));\n\n editor.tf.withoutNormalizing(() => {\n editor.tf.insertNodes(aiNodes, {\n at: editor.api.end(target || editor.selection!.focus.path),\n select: true,\n });\n editor.tf.collapse({ edge: 'end' });\n });\n};\n","import { type SlateEditor, type TLocation, getPluginType, KEYS } from 'platejs';\n\nexport const removeAIMarks = (\n editor: SlateEditor,\n { at = [] }: { at?: TLocation } = {}\n) => {\n const nodeType = getPluginType(editor, KEYS.ai);\n\n editor.tf.unsetNodes(nodeType, {\n at,\n match: (n) => (n as any)[nodeType],\n });\n};\n","import { type Path, type SlateEditor, TextApi } from 'platejs';\n\nexport const removeAINodes = (\n editor: SlateEditor,\n { at = [] }: { at?: Path } = {}\n) => {\n editor.tf.removeNodes({\n at,\n match: (n) => TextApi.isText(n) && !!(n as any).ai,\n });\n};\n","import type { SlateEditor } from 'platejs';\n\nimport { getTransientSuggestionKey } from '@platejs/suggestion';\n\nexport const undoAI = (editor: SlateEditor) => {\n const hasAINodeOrAISuggestion =\n editor.api.some({\n at: [],\n match: (n) => !!(n as any).ai,\n }) ||\n editor.api.some({\n at: [],\n match: (n) => !!n[getTransientSuggestionKey()],\n });\n\n if ((editor.history.undos.at(-1) as any)?.ai && hasAINodeOrAISuggestion) {\n editor.undo();\n editor.history.redos.pop();\n }\n};\n","import type { History, SlateEditor } from 'platejs';\n\nexport type AIBatch = History['undos'][number] & { ai?: boolean };\n\nexport const withAIBatch = (\n editor: SlateEditor,\n fn: () => void,\n {\n split,\n }: {\n split?: boolean;\n } = {}\n) => {\n if (split) {\n editor.tf.withNewBatch(fn);\n } else {\n editor.tf.withMerging(fn);\n }\n\n const lastBatch = editor.history.undos?.at(-1) as AIBatch | undefined;\n\n if (lastBatch) {\n lastBatch.ai = true;\n }\n};\n","import { isSelecting } from '@platejs/selection';\nimport { type SlateEditor, KEYS } from 'platejs';\n\nexport type EditorPrompt =\n | ((params: EditorPromptParams) => string)\n | PromptConfig\n | string;\n\nexport interface EditorPromptParams {\n editor: SlateEditor;\n isBlockSelecting: boolean;\n isSelecting: boolean;\n}\n\nexport interface PromptConfig {\n default: string;\n blockSelecting?: string;\n selecting?: string;\n}\n\nconst createPromptFromConfig = (\n config: PromptConfig,\n params: EditorPromptParams\n): string => {\n const { isBlockSelecting, isSelecting } = params;\n\n if (isBlockSelecting && config.blockSelecting) {\n return config.blockSelecting ?? config.default;\n } else if (isSelecting && config.selecting) {\n return config.selecting ?? config.default;\n } else {\n return config.default;\n }\n};\n\nexport const getEditorPrompt = (\n editor: SlateEditor,\n {\n prompt = '',\n }: {\n prompt?: EditorPrompt;\n }\n): string => {\n const params: EditorPromptParams = {\n editor,\n isBlockSelecting: editor.getOption(\n { key: KEYS.blockSelection },\n 'isSelectingSome'\n ),\n isSelecting: isSelecting(editor),\n };\n\n let promptText = '';\n\n if (typeof prompt === 'function') {\n promptText = prompt(params);\n } else if (typeof prompt === 'object') {\n promptText = createPromptFromConfig(prompt, params);\n } else {\n promptText = prompt;\n }\n\n return promptText;\n};\n","import { deserializeMd } from '@platejs/markdown';\nimport {\n type NodeEntry,\n type Range,\n type SlateEditor,\n type TElement,\n NodeApi,\n} from 'platejs';\n\nimport type { TComment } from '../../ai-chat/internal/types';\n\nimport { findTextRangeInBlock } from './findTextRangeInBlock';\n\nexport const aiCommentToRange = (\n editor: SlateEditor,\n aiComment: TComment\n): Range | undefined => {\n const { blockId, content } = aiComment;\n\n const contentNodes = deserializeMd(editor, content);\n\n let firstBlock: NodeEntry<TElement> | undefined;\n\n const ranges: Range[] = [];\n contentNodes.forEach((node, index) => {\n let currentBlock: NodeEntry<TElement> | undefined;\n\n if (index === 0) {\n firstBlock = editor.api.node<TElement>({ id: blockId, at: [] });\n currentBlock = firstBlock;\n } else {\n if (!firstBlock) return;\n\n const [_, firstBlockPath] = firstBlock;\n\n const blockPath = [firstBlockPath[0] + index];\n currentBlock = editor.api.node(blockPath);\n }\n\n if (!currentBlock) return;\n\n const range = findTextRangeInBlock({\n block: currentBlock,\n findText: NodeApi.string(node),\n });\n\n if (!range) return;\n\n ranges.push(range);\n });\n\n if (ranges.length === 0) return;\n\n if (ranges.length > 1) {\n const startRange = ranges[0];\n const endRange = ranges.at(-1)!;\n\n return {\n anchor: startRange.anchor,\n focus: endRange.focus,\n };\n }\n\n if (ranges.length === 1) {\n return ranges[0];\n }\n};\n","import { distance } from 'fastest-levenshtein';\nimport { type NodeEntry, type Path, type Range, NodeApi } from 'platejs';\n\nfunction maxAllowedDistance(len: number): number {\n if (len <= 2) return 0;\n if (len <= 5) return 1;\n if (len <= 10) return 2;\n if (len <= 20) return 3;\n // Maximum allowed distance is 5, regardless of text length\n return 5;\n}\n\n/** Find text within a block, supporting fuzzy matching. */\nexport function findTextRangeInBlock({\n block,\n findText,\n}: {\n block: NodeEntry;\n findText: string;\n}): Range | null {\n const [blockNode, blockPath] = block;\n\n // Collect all text content and map positions\n const textSegments: { offset: number; path: Path; text: string }[] = [];\n let fullText = '';\n\n // Iterate through all text nodes in the block\n for (const [textNode, textPath] of NodeApi.texts(blockNode)) {\n const startOffset = fullText.length;\n // textPath is relative to blockNode, not absolute\n const absolutePath = [...blockPath, ...textPath];\n textSegments.push({\n offset: startOffset,\n path: absolutePath,\n text: textNode.text,\n });\n fullText += textNode.text;\n }\n\n if (!fullText) return null;\n\n // Try exact match first\n let matchStart = fullText.indexOf(findText);\n let matchEnd = matchStart >= 0 ? matchStart + findText.length : -1;\n\n // If no exact match, try fuzzy matching\n if (matchStart === -1) {\n const maxDist = maxAllowedDistance(findText.length);\n let bestMatch = { distance: Infinity, end: -1, start: -1 };\n\n // Sliding window to find best fuzzy match\n for (let i = 0; i <= fullText.length - findText.length; i++) {\n // Try different lengths around the target length\n for (let lenOffset = -maxDist; lenOffset <= maxDist; lenOffset++) {\n const len = findText.length + lenOffset;\n if (len <= 0 || i + len > fullText.length) continue;\n\n const candidate = fullText.slice(i, i + len);\n const dist = distance(candidate, findText);\n\n if (dist <= maxDist && dist < bestMatch.distance) {\n bestMatch = { distance: dist, end: i + len, start: i };\n }\n }\n }\n\n if (bestMatch.start !== -1) {\n matchStart = bestMatch.start;\n matchEnd = bestMatch.end;\n }\n }\n\n // If still no match, try prefix matching as fallback\n if (matchStart === -1) {\n // Find longest prefix match\n for (let prefixLen = findText.length - 1; prefixLen > 0; prefixLen--) {\n const prefix = findText.slice(0, Math.max(0, prefixLen));\n const idx = fullText.indexOf(prefix);\n if (idx !== -1) {\n matchStart = idx;\n matchEnd = idx + prefixLen;\n break;\n }\n }\n }\n\n if (matchStart === -1) return null;\n\n // Convert character offsets to Slate paths and offsets\n const findPoint = (\n charOffset: number,\n isEnd = false\n ): { offset: number; path: Path } => {\n const accumulated = 0;\n\n // For start positions, if offset lands exactly at the beginning of a segment, use that segment\n if (!isEnd) {\n for (const segment of textSegments) {\n if (charOffset === segment.offset) {\n return {\n offset: 0,\n path: segment.path,\n };\n }\n }\n }\n\n // Normal search through segments\n for (const segment of textSegments) {\n const segmentEnd = segment.offset + segment.text.length;\n\n if (charOffset >= segment.offset && charOffset <= segmentEnd) {\n const localOffset = charOffset - segment.offset;\n return {\n offset: localOffset,\n path: segment.path,\n };\n }\n }\n\n // Fallback to last position\n const lastSegment = textSegments.at(-1);\n if (!lastSegment) {\n return { offset: 0, path: blockPath };\n }\n return {\n offset: lastSegment.text.length,\n path: lastSegment.path,\n };\n };\n\n const anchor = findPoint(matchStart, false);\n const focus = findPoint(matchEnd, true);\n\n return {\n anchor,\n focus,\n };\n}\n","import type { UseChatHelpers } from '@ai-sdk/react';\nimport type { TriggerComboboxPluginOptions } from '@platejs/combobox';\n\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport {\n type EditorNodesOptions,\n type NodeEntry,\n type OmitFirst,\n type Path,\n type PluginConfig,\n type SlateEditor,\n type TIdElement,\n type TRange,\n bindFirst,\n ElementApi,\n getPluginType,\n KEYS,\n} from 'platejs';\nimport { createTPlatePlugin } from 'platejs/react';\n\nimport type { AIBatch } from '../../lib';\nimport type { AIMode, AIToolName } from '../../lib/types';\nimport type { ChatMessage } from './internal/types';\n\nimport { AIPlugin } from '../ai/AIPlugin';\nimport { removeAnchorAIChat } from './transforms';\nimport { acceptAIChat } from './transforms/acceptAIChat';\nimport { insertBelowAIChat } from './transforms/insertBelowAIChat';\nimport { replaceSelectionAIChat } from './transforms/replaceSelectionAIChat';\nimport { resetAIChat } from './utils/resetAIChat';\nimport { submitAIChat } from './utils/submitAIChat';\nimport { withAIChat } from './withAIChat';\n\nexport type AIChatPluginConfig = PluginConfig<\n 'aiChat',\n {\n _blockChunks: string;\n _blockPath: Path | null;\n /** @private Using For streamInsertChunk */\n _mdxName: string | null;\n _replaceIds: string[];\n /** @private The Editor used to generate the AI response. */\n aiEditor: SlateEditor | null;\n chat: UseChatHelpers<ChatMessage>;\n chatNodes: TIdElement[];\n chatSelection: TRange | null;\n /** @deprecated Use api.aiChat.node({streaming:true}) instead */\n experimental_lastTextId: string | null;\n /**\n * Specifies how the assistant message is handled:\n *\n * - 'insert': Directly inserts content into the editor without preview.\n * - 'chat': Initiates an interactive session to review and refine content\n * before insertion.\n */\n mode: AIMode;\n open: boolean;\n /** Whether the AI response is currently streaming. Cursor mode only. */\n streaming: boolean;\n toolName: AIToolName;\n } & TriggerComboboxPluginOptions,\n {\n aiChat: {\n reset: OmitFirst<typeof resetAIChat>;\n submit: OmitFirst<typeof submitAIChat>;\n hide: (options?: { focus?: boolean; undo?: boolean }) => void;\n node: (\n options?: EditorNodesOptions & { anchor?: boolean; streaming?: boolean }\n ) => NodeEntry | undefined;\n reload: () => void;\n show: () => void;\n stop: () => void;\n };\n },\n {\n aiChat: {\n accept: OmitFirst<typeof acceptAIChat>;\n insertBelow: OmitFirst<typeof insertBelowAIChat>;\n replaceSelection: OmitFirst<typeof replaceSelectionAIChat>;\n removeAnchor: (options?: EditorNodesOptions) => void;\n };\n }\n>;\n\nexport const AIChatPlugin = createTPlatePlugin<AIChatPluginConfig>({\n key: KEYS.aiChat,\n dependencies: ['ai'],\n node: {\n isElement: true,\n },\n options: {\n _blockChunks: '',\n _blockPath: null,\n _mdxName: null,\n _replaceIds: [],\n aiEditor: null,\n chat: { messages: [] } as unknown as UseChatHelpers<ChatMessage>,\n chatNodes: [],\n chatSelection: null,\n experimental_lastTextId: null,\n mode: 'insert',\n open: false,\n streaming: false,\n toolName: null,\n trigger: ' ',\n triggerPreviousCharPattern: /^\\s?$/,\n },\n})\n .overrideEditor(withAIChat)\n .extendApi<\n Pick<\n AIChatPluginConfig['api']['aiChat'],\n 'node' | 'reset' | 'stop' | 'submit'\n >\n >(({ editor, getOption, getOptions, setOption, type }) => {\n return {\n reset: bindFirst(resetAIChat, editor),\n submit: bindFirst(submitAIChat, editor),\n node: (options = {}) => {\n const { anchor = false, streaming = false, ...rest } = options;\n\n if (anchor) {\n return editor.api.node({\n at: [],\n match: (n) => ElementApi.isElement(n) && n.type === type,\n ...rest,\n });\n }\n\n if (streaming) {\n if (!getOption('streaming')) return;\n\n const path = getOption('_blockPath');\n if (!path) return;\n\n return editor.api.node({\n at: path,\n mode: 'lowest',\n reverse: true,\n match: (t) => !!t[getPluginType(editor, KEYS.ai)],\n ...rest,\n });\n }\n\n return editor.api.node({\n match: (n) => n[getPluginType(editor, KEYS.ai)],\n ...rest,\n });\n },\n reload: () => {\n const { chat, chatNodes, chatSelection } = getOptions();\n\n editor.getTransforms(AIPlugin).ai.undo();\n\n if (chatSelection) {\n editor.tf.setSelection(chatSelection);\n } else {\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.set(chatNodes.map((node) => node.id as string));\n }\n\n const blocks = editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.getNodes();\n\n const selection =\n blocks.length > 0 ? editor.api.nodesRange(blocks) : editor.selection;\n\n const ctx = {\n children: editor.children,\n selection: selection ?? null,\n toolName: getOption('toolName'),\n };\n\n void chat.regenerate?.({\n body: {\n ctx,\n },\n });\n },\n stop: () => {\n setOption('streaming', false);\n getOptions().chat.stop?.();\n },\n };\n })\n .extendApi(({ api, editor, getOptions, setOption, tf, type }) => ({\n hide: ({\n focus = true,\n undo = true,\n }: { focus?: boolean; undo?: boolean } = {}) => {\n api.aiChat.reset({ undo });\n\n setOption('open', false);\n\n if (focus) {\n if (editor.getOption(BlockSelectionPlugin, 'isSelectingSome')) {\n editor.getApi(BlockSelectionPlugin).blockSelection.focus();\n } else {\n editor.tf.focus();\n }\n }\n\n const lastBatch = editor.history.undos.at(-1) as AIBatch;\n\n if (lastBatch?.ai) {\n delete lastBatch.ai;\n }\n\n tf.aiChat.removeAnchor();\n },\n show: () => {\n api.aiChat.reset();\n\n setOption('toolName', null);\n\n getOptions().chat.setMessages?.([]);\n\n setOption('open', true);\n },\n }))\n .extendTransforms(({ editor }) => ({\n accept: bindFirst(acceptAIChat, editor),\n insertBelow: bindFirst(insertBelowAIChat, editor),\n removeAnchor: bindFirst(removeAnchorAIChat, editor),\n replaceSelection: bindFirst(replaceSelectionAIChat, editor),\n }));\n","import {\n acceptSuggestion,\n getSuggestionKey,\n getTransientSuggestionKey,\n} from '@platejs/suggestion';\nimport { SuggestionPlugin } from '@platejs/suggestion/react';\nimport { KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport { withAIBatch } from '../../../lib';\nimport { AIPlugin } from '../../ai/AIPlugin';\nimport { type AIChatPluginConfig, AIChatPlugin } from '../AIChatPlugin';\n\nexport const acceptAIChat = (editor: PlateEditor) => {\n const mode = editor.getOption(AIChatPlugin, 'mode');\n\n if (mode === 'insert') {\n const { tf } = getEditorPlugin(editor, AIPlugin);\n const api = editor.getApi<AIChatPluginConfig>({ key: KEYS.ai });\n\n const lastAINodePath = api.aiChat.node({ at: [], reverse: true })![1];\n\n withAIBatch(editor, () => {\n tf.ai.removeMarks();\n editor.getTransforms(AIChatPlugin).aiChat.removeAnchor();\n });\n\n api.aiChat.hide();\n editor.tf.focus();\n\n const focusPoint = editor.api.end(lastAINodePath)!;\n\n editor.tf.setSelection({\n anchor: focusPoint,\n focus: focusPoint,\n });\n }\n\n if (mode === 'chat') {\n withAIBatch(editor, () => {\n acceptSuggestions(editor);\n });\n\n editor.getApi(AIChatPlugin).aiChat.hide();\n }\n};\n\nexport const acceptSuggestions = (editor: PlateEditor) => {\n const suggestions = editor.getApi(SuggestionPlugin).suggestion.nodes({\n transient: true,\n });\n\n suggestions.forEach(([suggestionNode]) => {\n const suggestionData = editor\n .getApi(SuggestionPlugin)\n .suggestion.suggestionData(suggestionNode);\n\n if (!suggestionData) return;\n\n const description = {\n createdAt: new Date(suggestionData.createdAt),\n keyId: getSuggestionKey(suggestionData.id),\n suggestionId: suggestionData.id,\n type: suggestionData.type,\n userId: suggestionData.userId,\n };\n\n acceptSuggestion(editor, description);\n });\n\n editor.tf.unsetNodes([getTransientSuggestionKey()], {\n at: [],\n mode: 'all',\n match: (n) => !!n[getTransientSuggestionKey()],\n });\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport cloneDeep from 'lodash/cloneDeep.js';\nimport { type SlateEditor, KEYS, PathApi, RangeApi } from 'platejs';\n\nimport { withAIBatch } from '../../../lib';\nimport { AIPlugin } from '../../ai/AIPlugin';\nimport { type AIChatPluginConfig, AIChatPlugin } from '../AIChatPlugin';\nimport { acceptSuggestions } from './acceptAIChat';\nimport { createFormattedBlocks } from './replaceSelectionAIChat';\n\nexport const insertBelowAIChat = (\n editor: PlateEditor,\n sourceEditor: SlateEditor,\n { format = 'single' }: { format?: 'all' | 'none' | 'single' } = {}\n) => {\n const { toolName } = editor.getOptions(AIChatPlugin);\n\n if (toolName === 'generate')\n return insertBelowGenerate(editor, sourceEditor, { format });\n\n const selectedBlocks = editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.getNodes();\n\n const selectedIds = editor.getOptions(BlockSelectionPlugin).selectedIds;\n\n editor.getTransforms(AIPlugin).ai.undo();\n\n const insertBlocksAndSelect =\n editor.getTransforms(BlockSelectionPlugin).blockSelection\n .insertBlocksAndSelect;\n\n if (!selectedIds || selectedIds.size === 0) return;\n\n const lastBlock = selectedBlocks.at(-1);\n\n if (!lastBlock) return;\n\n const nextPath = PathApi.next(lastBlock[1]);\n\n const nodes = selectedBlocks.map((block) => block[0]);\n\n insertBlocksAndSelect(nodes, {\n at: nextPath,\n insertedCallback: () => {\n withAIBatch(editor, () => {\n acceptSuggestions(editor);\n });\n },\n });\n\n editor.getApi(AIChatPlugin).aiChat.hide({ focus: false });\n};\n\nexport const insertBelowGenerate = (\n editor: PlateEditor,\n sourceEditor: SlateEditor,\n { format = 'single' }: { format?: 'all' | 'none' | 'single' } = {}\n) => {\n if (!sourceEditor || sourceEditor.api.isEmpty()) return;\n\n const isBlockSelecting = editor.getOption(\n BlockSelectionPlugin,\n 'isSelectingSome'\n );\n\n editor.getApi<AIChatPluginConfig>({ key: KEYS.ai }).aiChat.hide();\n\n const insertBlocksAndSelect =\n editor.getTransforms(BlockSelectionPlugin).blockSelection\n .insertBlocksAndSelect;\n\n if (isBlockSelecting) {\n const selectedBlocks = editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.getNodes();\n\n const selectedIds = editor.getOptions(BlockSelectionPlugin).selectedIds;\n\n if (!selectedIds || selectedIds.size === 0) return;\n\n const lastBlock = selectedBlocks.at(-1);\n\n if (!lastBlock) return;\n\n const nextPath = PathApi.next(lastBlock[1]);\n\n if (format === 'none') {\n insertBlocksAndSelect(cloneDeep(sourceEditor.children), {\n at: nextPath,\n });\n\n return;\n }\n\n const formattedBlocks = createFormattedBlocks({\n blocks: cloneDeep(sourceEditor.children),\n format,\n sourceBlock: lastBlock,\n });\n\n if (!formattedBlocks) return;\n\n insertBlocksAndSelect(formattedBlocks, {\n at: nextPath,\n });\n } else {\n const [, end] = RangeApi.edges(editor.selection!);\n const endPath = [end.path[0]];\n const currentBlock = editor.api.node({\n at: endPath,\n block: true,\n mode: 'lowest',\n });\n\n if (!currentBlock) return;\n if (format === 'none') {\n insertBlocksAndSelect(cloneDeep(sourceEditor.children), {\n at: PathApi.next(endPath),\n });\n\n return;\n }\n\n const formattedBlocks = createFormattedBlocks({\n blocks: cloneDeep(sourceEditor.children),\n format,\n sourceBlock: currentBlock,\n });\n\n if (!formattedBlocks) return;\n\n insertBlocksAndSelect(formattedBlocks, {\n at: PathApi.next(endPath),\n });\n }\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport {\n BlockSelectionPlugin,\n removeBlockSelectionNodes,\n} from '@platejs/selection/react';\nimport cloneDeep from 'lodash/cloneDeep.js';\nimport {\n type NodeEntry,\n type SlateEditor,\n type TElement,\n KEYS,\n NodeApi,\n TextApi,\n} from 'platejs';\n\nimport type { AIChatPluginConfig } from '../AIChatPlugin';\n\nexport const createFormattedBlocks = ({\n blocks,\n format,\n sourceBlock,\n}: {\n blocks: TElement[];\n format: 'all' | 'none' | 'single';\n sourceBlock: NodeEntry;\n}) => {\n if (format === 'none') return cloneDeep(blocks);\n\n const [sourceNode] = sourceBlock;\n const firstTextEntry = NodeApi.firstText(sourceNode);\n\n if (!firstTextEntry) return null;\n\n const blockProps = NodeApi.extractProps(sourceNode);\n const textProps = NodeApi.extractProps(firstTextEntry[0]);\n\n const applyTextFormatting = (node: any): any => {\n if (TextApi.isText(node)) {\n return { ...textProps, ...node };\n }\n if (node.children) {\n return {\n ...node,\n children: node.children.map(applyTextFormatting),\n };\n }\n\n return node;\n };\n\n return blocks.map((block, index) => {\n if (format === 'single' && index > 0) {\n return block;\n }\n\n return applyTextFormatting({\n ...block,\n ...blockProps,\n });\n });\n};\n\nexport const replaceSelectionAIChat = (\n editor: PlateEditor,\n sourceEditor: SlateEditor,\n { format = 'single' }: { format?: 'all' | 'none' | 'single' } = {}\n) => {\n if (!sourceEditor || sourceEditor.api.isEmpty()) return;\n\n const isBlockSelecting = editor.getOption(\n BlockSelectionPlugin,\n 'isSelectingSome'\n );\n\n editor.getApi<AIChatPluginConfig>({ key: KEYS.ai }).aiChat.hide();\n\n // If no blocks selected, treat it like a normal selection replacement\n if (!isBlockSelecting) {\n const firstBlock = editor.api.node({\n block: true,\n mode: 'lowest',\n });\n\n if (\n firstBlock &&\n editor.api.isSelected(firstBlock[1], { contains: true }) &&\n format !== 'none'\n ) {\n const formattedBlocks = createFormattedBlocks({\n blocks: cloneDeep(sourceEditor.children),\n format,\n sourceBlock: firstBlock,\n });\n\n if (!formattedBlocks) return;\n\n /** When user selection is cover the whole code block */\n if (\n firstBlock[0].type === KEYS.codeLine &&\n sourceEditor.children[0].type === KEYS.codeBlock &&\n sourceEditor.children.length === 1\n ) {\n editor.tf.insertFragment(formattedBlocks[0].children);\n } else {\n editor.tf.insertFragment(formattedBlocks);\n }\n\n editor.tf.focus();\n\n return;\n }\n\n editor.tf.insertFragment(sourceEditor.children);\n editor.tf.focus();\n\n return;\n }\n\n const blockSelectionApi = editor.getApi(BlockSelectionPlugin).blockSelection;\n const selectedBlocks = blockSelectionApi.getNodes();\n\n if (selectedBlocks.length === 0) return;\n // If format is 'none' or multiple blocks with 'single',\n // just insert the content as is\n if (format === 'none' || (format === 'single' && selectedBlocks.length > 1)) {\n editor.tf.withoutNormalizing(() => {\n removeBlockSelectionNodes(editor);\n\n editor.tf.withNewBatch(() => {\n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.insertBlocksAndSelect(\n cloneDeep(sourceEditor.children),\n {\n at: selectedBlocks[0][1],\n }\n );\n });\n });\n\n editor.getApi(BlockSelectionPlugin).blockSelection.focus();\n\n return;\n }\n\n // Apply formatting from first block when:\n // - formatting is 'all', or\n // - only one block is selected\n const [, firstBlockPath] = selectedBlocks[0];\n const formattedBlocks = createFormattedBlocks({\n blocks: cloneDeep(sourceEditor.children),\n format,\n sourceBlock: selectedBlocks[0],\n });\n\n if (!formattedBlocks) return;\n\n editor.tf.withoutNormalizing(() => {\n removeBlockSelectionNodes(editor);\n\n editor.tf.withNewBatch(() => {\n editor\n .getTransforms(BlockSelectionPlugin)\n .blockSelection.insertBlocksAndSelect(formattedBlocks, {\n at: firstBlockPath,\n });\n });\n });\n\n editor.getApi(BlockSelectionPlugin).blockSelection.focus();\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport {\n type RemoveNodesOptions,\n ElementApi,\n getPluginType,\n KEYS,\n} from 'platejs';\n\nexport const removeAnchorAIChat = (\n editor: PlateEditor,\n options?: RemoveNodesOptions\n) => {\n editor.tf.withoutSaving(() => {\n editor.tf.removeNodes({\n at: [],\n match: (n) =>\n ElementApi.isElement(n) &&\n n.type === getPluginType(editor, KEYS.aiChat),\n ...options,\n });\n });\n};\n","import { KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport type { AIChatPluginConfig } from '../AIChatPlugin';\n\nimport { AIPlugin } from '../../ai/AIPlugin';\n\nexport const resetAIChat = (\n editor: PlateEditor,\n { undo = true }: { undo?: boolean } = {}\n) => {\n const { api, getOptions, setOptions } = getEditorPlugin<AIChatPluginConfig>(\n editor,\n {\n key: KEYS.aiChat,\n }\n );\n\n api.aiChat.stop();\n\n const chat = getOptions().chat;\n\n if (chat.messages && chat.messages.length > 0) {\n chat.setMessages?.([]);\n }\n\n setOptions({\n _replaceIds: [],\n chatNodes: [],\n mode: 'insert',\n toolName: null,\n });\n\n if (undo) {\n editor.getTransforms(AIPlugin).ai.undo();\n }\n};\n","import type { ChatRequestOptions } from 'ai';\n\nimport { isSelecting } from '@platejs/selection';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { type Descendant, type Range, type TIdElement, KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport type { AIMode, AIToolName } from '../../../lib/types';\nimport type { AIChatPluginConfig } from '../AIChatPlugin';\n\nimport {\n type EditorPrompt,\n getEditorPrompt,\n} from '../../../lib/utils/getEditorPrompt';\nimport { AIPlugin } from '../../ai/AIPlugin';\n\nexport const submitAIChat = (\n editor: PlateEditor,\n input: string,\n {\n mode,\n options,\n prompt,\n toolName: toolNameProps,\n }: {\n mode?: AIMode;\n options?: ChatRequestOptions;\n prompt?: EditorPrompt;\n toolName?: AIToolName;\n } = {}\n) => {\n const { getOptions, setOption } = getEditorPlugin<AIChatPluginConfig>(\n editor,\n {\n key: KEYS.aiChat,\n }\n );\n\n const { chat, toolName: toolNameOption } = getOptions();\n\n const toolName = toolNameProps ?? toolNameOption ?? null;\n\n if (!prompt && input?.length === 0) {\n return;\n }\n if (!prompt) {\n prompt = input;\n }\n if (!mode) {\n mode = isSelecting(editor) ? 'chat' : 'insert';\n }\n if (mode === 'insert') {\n editor.getTransforms(AIPlugin).ai.undo();\n }\n\n setOption('mode', mode);\n\n setOption('toolName', toolName);\n\n const blocks = editor.getApi(BlockSelectionPlugin).blockSelection.getNodes();\n const blocksRange = editor.api.nodesRange(blocks);\n\n const promptText = getEditorPrompt(editor, {\n prompt,\n });\n\n const selection = blocks.length > 0 ? blocksRange : editor.selection;\n\n let chatNodes;\n\n if (blocks.length > 0) {\n chatNodes = blocks.map((block) => block[0]);\n } else {\n const selectionBlocks = editor.api.blocks({ mode: 'highest' });\n\n if (selectionBlocks.length > 1) {\n chatNodes = selectionBlocks.map((block) => block[0]) as TIdElement[];\n } else {\n chatNodes = editor.api.fragment<TIdElement>();\n }\n }\n\n setOption('chatNodes', chatNodes);\n setOption('chatSelection', blocks.length > 0 ? null : editor.selection);\n\n const ctx: {\n children: Descendant[];\n selection: Range | null;\n toolName: string | null;\n } = {\n children: editor.children,\n selection: selection ?? null,\n toolName: toolName,\n };\n\n void chat.sendMessage?.(\n {\n text: promptText,\n },\n {\n body: {\n ctx,\n },\n ...options,\n }\n );\n};\n","import type { OverrideEditor } from 'platejs/react';\n\nimport { ElementApi, KEYS } from 'platejs';\n\nimport { AIPlugin } from '../ai/AIPlugin';\nimport { type AIChatPluginConfig, AIChatPlugin } from './AIChatPlugin';\n\nexport const withAIChat: OverrideEditor<AIChatPluginConfig> = ({\n api,\n editor,\n getOptions,\n tf: { apply, insertText, normalizeNode },\n type,\n}) => {\n const tf = editor.getTransforms(AIPlugin);\n\n const matchesTrigger = (text: string) => {\n const { trigger } = getOptions();\n\n if (trigger instanceof RegExp) {\n return trigger.test(text);\n }\n if (Array.isArray(trigger)) {\n return trigger.includes(text);\n }\n\n return text === trigger;\n };\n\n return {\n transforms: {\n insertText(text, options) {\n const { triggerPreviousCharPattern, triggerQuery } = getOptions();\n\n const fn = () => {\n if (\n !editor.selection ||\n !matchesTrigger(text) ||\n (triggerQuery && !triggerQuery(editor))\n ) {\n return;\n }\n\n // Make sure an input is created at the beginning of line or after a whitespace\n const previousChar = editor.api.string(\n editor.api.range('before', editor.selection)\n );\n\n const matchesPreviousCharPattern =\n triggerPreviousCharPattern?.test(previousChar);\n\n if (!matchesPreviousCharPattern) return;\n\n const nodeEntry = editor.api.block({ highest: true });\n\n if (!nodeEntry || !editor.api.isEmpty(nodeEntry[0])) return;\n\n api.aiChat.show();\n\n return true;\n };\n\n if (fn()) return;\n\n return insertText(text, options);\n },\n normalizeNode(entry) {\n const [node, path] = entry;\n\n if (node[KEYS.ai] && !getOptions().open) {\n tf.ai.removeMarks({ at: path });\n\n return;\n }\n\n if (\n ElementApi.isElement(node) &&\n node.type === type &&\n !getOptions().open\n ) {\n editor.getTransforms(AIChatPlugin).aiChat.removeAnchor({ at: path });\n\n return;\n }\n\n return normalizeNode(entry);\n },\n },\n };\n};\n","import { useEffect, useMemo } from 'react';\n\nimport type { SlateEditor } from 'platejs';\n\nimport { type DeserializeMdOptions, MarkdownPlugin } from '@platejs/markdown';\nimport { useEditorPlugin } from 'platejs/react';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\n\n/**\n * Register an editor in the AI chat plugin, and deserializes the content into\n * `editor.children` with block-level memoization.\n */\nexport const useAIChatEditor = (\n editor: SlateEditor,\n content: string,\n { parser }: DeserializeMdOptions = {}\n) => {\n const { setOption } = useEditorPlugin(AIChatPlugin);\n\n editor.children = useMemo(\n () => {\n return editor.getApi(MarkdownPlugin).markdown.deserialize(content, {\n memoize: true,\n parser,\n });\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [content]\n );\n\n useEffect(() => {\n setOption('aiEditor', editor);\n }, [editor, setOption]);\n};\n","import { useEffect, useRef } from 'react';\n\nimport type { TText } from 'platejs';\n\nimport { KEYS } from 'platejs';\nimport { usePluginOption } from 'platejs/react';\n\nimport type { AIChatPluginConfig } from '../AIChatPlugin';\n\nimport { useLastAssistantMessage } from '../utils/getLastAssistantMessage';\n\nexport const useChatChunk = ({\n onChunk,\n onFinish,\n}: {\n onChunk: (chunk: {\n chunk: string;\n isFirst: boolean;\n nodes: TText[];\n text: string;\n }) => void;\n onFinish?: ({ content }: { content: string }) => void;\n}) => {\n const { status } = usePluginOption(\n { key: KEYS.aiChat } as AIChatPluginConfig,\n 'chat'\n );\n const isLoading = status === 'streaming' || status === 'submitted';\n\n const content = useLastAssistantMessage()?.parts.find(\n (part) => part.type === 'text'\n )?.text;\n\n const insertedTextRef = useRef<string>('');\n const prevIsLoadingRef = useRef(isLoading);\n\n useEffect(() => {\n if (!isLoading) {\n insertedTextRef.current = '';\n }\n if (prevIsLoadingRef.current && !isLoading) {\n onFinish?.({ content: content ?? '' });\n }\n\n prevIsLoadingRef.current = isLoading;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isLoading]);\n\n useEffect(() => {\n if (!content) {\n return;\n }\n\n const chunk = content.slice(insertedTextRef.current.length);\n\n const nodes: TText[] = [];\n\n if (chunk) {\n const isFirst = insertedTextRef.current === '';\n\n nodes.push({ text: chunk });\n onChunk({\n chunk,\n isFirst,\n nodes,\n text: content,\n });\n }\n\n insertedTextRef.current = content;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [content]);\n};\n","import { type PlateEditor, usePluginOption } from 'platejs/react';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\n\nexport function getLastAssistantMessage(editor: PlateEditor) {\n const messages = editor.getOptions(AIChatPlugin).chat.messages;\n\n return messages?.findLast((message) => message.role === 'assistant');\n}\n\nexport function useLastAssistantMessage() {\n const toolName = usePluginOption(AIChatPlugin, 'toolName');\n const chat = usePluginOption(AIChatPlugin, 'chat');\n\n if (toolName === 'comment') return;\n\n return chat.messages?.findLast((message) => message.role === 'assistant');\n}\n","'use client';\n\nimport { useEffect } from 'react';\n\nimport type { UseChatHelpers } from '@ai-sdk/react';\nimport type { NodeEntry } from 'platejs';\n\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { useEditorPlugin, usePluginOption } from 'platejs/react';\n\nimport type { ChatMessage } from '../internal/types';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\n\nexport type UseEditorChatOptions = {\n chat: UseChatHelpers<ChatMessage>;\n onOpenBlockSelection?: (blocks: NodeEntry[]) => void;\n onOpenChange?: (open: boolean) => void;\n onOpenCursor?: () => void;\n onOpenSelection?: () => void;\n};\n\nexport const useEditorChat = ({\n chat,\n onOpenBlockSelection,\n onOpenChange,\n onOpenCursor,\n onOpenSelection,\n}: UseEditorChatOptions) => {\n const { editor } = useEditorPlugin(AIChatPlugin);\n const open = usePluginOption(AIChatPlugin, 'open');\n\n useEffect(() => {\n onOpenChange?.(open);\n\n if (open) {\n if (onOpenBlockSelection) {\n const blockSelectionApi =\n editor.getApi(BlockSelectionPlugin).blockSelection;\n const isBlockSelecting = editor.getOption(\n BlockSelectionPlugin,\n 'isSelectingSome'\n );\n\n if (isBlockSelecting) {\n onOpenBlockSelection(blockSelectionApi.getNodes());\n\n return;\n }\n }\n if (onOpenCursor && editor.api.isCollapsed()) {\n onOpenCursor();\n\n return;\n }\n if (onOpenSelection && editor.api.isExpanded()) {\n onOpenSelection();\n\n return;\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { type DeserializeMdOptions, MarkdownPlugin } from '@platejs/markdown';\n\nexport const streamDeserializeInlineMd = (\n editor: PlateEditor,\n text: string,\n options?: DeserializeMdOptions\n) => {\n return editor\n .getApi(MarkdownPlugin)\n .markdown.deserializeInline(text, options);\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { type DeserializeMdOptions, MarkdownPlugin } from '@platejs/markdown';\nimport { type TElement, getPluginType, KEYS, TextApi } from 'platejs';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\nimport { getChunkTrimmed } from './utils';\nimport { escapeInput } from './utils/escapeInput';\n\nconst statMdxTagRegex = /<([A-Za-z][A-Za-z0-9._:-]*)(?:\\s[^>]*?)?(?<!\\/)>/;\n\nexport const streamDeserializeMd = (\n editor: PlateEditor,\n data: string,\n options?: DeserializeMdOptions\n) => {\n const input = escapeInput(data);\n\n const value = withoutDeserializeInMdx(editor, input);\n\n if (Array.isArray(value)) return value;\n\n let blocks = [];\n\n blocks = editor.getApi(MarkdownPlugin).markdown.deserialize(input, {\n ...options,\n preserveEmptyParagraphs: false,\n });\n\n const trimmedData = getChunkTrimmed(data);\n\n const lastBlock = blocks.at(-1) as TElement | undefined;\n\n const addNewLine = trimmedData === '\\n\\n';\n const unshiftNewLine =\n getChunkTrimmed(data, { direction: 'left' }) === '\\n\\n';\n\n const isCodeBlockOrTable =\n lastBlock?.type === 'code_block' || lastBlock?.type === 'table';\n\n let result = blocks;\n\n /**\n * Deserialize the sting like `123\\n\\n` will be `123` base on markdown spec\n * but we want to keep the `\\n\\n`\n */\n\n if (\n lastBlock &&\n !isCodeBlockOrTable &&\n trimmedData.length > 0 &&\n !addNewLine\n ) {\n const textNode = [\n {\n text: trimmedData,\n },\n ];\n\n const lastChild = lastBlock.children.at(-1);\n\n /** It’s like normalizing and merging the text nodes. */\n if (\n lastChild &&\n TextApi.isText(lastChild) &&\n Object.keys(lastChild).length === 1\n ) {\n lastBlock.children.pop();\n\n const textNode = [\n {\n text: lastChild.text + trimmedData,\n },\n ];\n\n lastBlock.children.push(...textNode);\n } else {\n lastBlock.children.push(...textNode);\n }\n\n result = [...blocks.slice(0, -1), lastBlock];\n }\n\n if (addNewLine && !isCodeBlockOrTable) {\n result.push({\n children: [{ text: '' }],\n type: KEYS.p,\n });\n }\n\n if (unshiftNewLine && !isCodeBlockOrTable) {\n result.unshift({\n children: [{ text: '' }],\n type: KEYS.p,\n });\n }\n\n return result;\n};\n\nconst withoutDeserializeInMdx = (editor: PlateEditor, input: string) => {\n const mdxName = editor.getOption(AIChatPlugin, '_mdxName');\n\n if (mdxName) {\n const isMdxEnd = input.includes(`</${mdxName}>`);\n\n if (isMdxEnd) {\n editor.setOption(AIChatPlugin, '_mdxName', null);\n return false;\n } else {\n return [\n {\n children: [\n {\n text: input,\n },\n ],\n type: getPluginType(editor, KEYS.p),\n },\n ];\n }\n } else {\n const newMdxName = statMdxTagRegex.exec(input)?.[1];\n\n // Avoid incorrect detection in the code block\n if (input.startsWith(`<${newMdxName}`)) {\n editor.setOption(AIChatPlugin, '_mdxName', newMdxName ?? null);\n }\n }\n};\n","export const getChunkTrimmed = (\n chunk: string,\n {\n direction = 'right',\n }: {\n direction?: 'left' | 'right';\n } = {}\n) => {\n const str = direction === 'right' ? chunk.trimEnd() : chunk.trimStart();\n\n if (direction === 'right') {\n return chunk.slice(str.length);\n } else {\n return chunk.slice(0, chunk.length - str.length);\n }\n};\n\nexport function isCompleteCodeBlock(str: string) {\n const trimmed = str.trim();\n\n const startsWithCodeBlock = trimmed.startsWith('```');\n const endsWithCodeBlock = trimmed.endsWith('```');\n\n return startsWithCodeBlock && endsWithCodeBlock;\n}\n\nexport function isCompleteMath(str: string) {\n const trimmed = str.trim();\n\n const startsWithMath = trimmed.startsWith('$$');\n const endsWithMath = trimmed.endsWith('$$');\n\n return startsWithMath && endsWithMath;\n}\n","import { isCompleteMath } from './utils';\n\nexport const escapeInput = (data: string) => {\n let res = data;\n\n // test case: should correctly handle inline math\n if (\n data.startsWith('$$') &&\n !data.startsWith('$$\\n') &&\n !isCompleteMath(data)\n ) {\n res = data.replace('$$', String.raw`\\$\\$`);\n }\n\n return res;\n};\n","import type { TElement } from 'platejs';\nimport type { PlateEditor } from 'platejs/react';\n\nexport const getListNode = (editor: PlateEditor, node: TElement): TElement => {\n if (node.listStyleType && node.listStart) {\n const previousNode = editor.api.previous({\n at: editor.selection?.focus,\n })?.[0];\n\n // if previous node is also an indent list, don't need to do additional work\n if (previousNode?.listStyleType && previousNode?.listStart) {\n return node;\n } else {\n if (node.listStart === 1) return node;\n\n return {\n ...node,\n listRestartPolite: node.listStart,\n };\n }\n }\n\n return node;\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { type TElement, type TText, isDefined, KEYS } from 'platejs';\n\nconst LIST_STYLE_TYPE = 'listStyleType';\n\nexport const isSameNode = (\n editor: PlateEditor,\n node1: TElement | TText,\n node2: TElement | TText\n) => {\n if (\n node1.type !== editor.getType(KEYS.p) ||\n node2.type !== editor.getType(KEYS.p)\n )\n return node1.type === node2.type;\n\n if (isDefined(node1[LIST_STYLE_TYPE]) || isDefined(node2[LIST_STYLE_TYPE])) {\n return node1[LIST_STYLE_TYPE] === node2[LIST_STYLE_TYPE];\n }\n\n return node1.type === node2.type;\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { type Descendant, ElementApi } from 'platejs';\n\nimport type { SteamInsertChunkOptions } from '../streamInsertChunk';\n\nimport { getListNode } from './getListNode';\n\nexport const nodesWithProps = (\n editor: PlateEditor,\n nodes: Descendant[],\n options: SteamInsertChunkOptions\n): Descendant[] => {\n return nodes.map((node): Descendant => {\n if (ElementApi.isElement(node)) {\n return {\n ...getListNode(editor, node),\n ...options.elementProps,\n children: nodesWithProps(editor, node.children, options),\n };\n } else {\n return {\n ...options.textProps,\n ...node,\n text: node.text,\n };\n }\n });\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport {\n type Path,\n type SlateEditor,\n getPluginType,\n KEYS,\n NodeApi,\n PathApi,\n} from 'platejs';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\nimport { streamDeserializeInlineMd } from './streamDeserializeInlineMd';\nimport { streamDeserializeMd } from './streamDeserializeMd';\nimport { streamSerializeMd } from './streamSerializeMd';\nimport { isSameNode } from './utils/isSameNode';\nimport { nodesWithProps } from './utils/nodesWithProps';\n\nexport interface SteamInsertChunkOptions {\n elementProps?: any;\n textProps?: any;\n}\n\nconst getNextPath = (path: Path, length: number) => {\n let result = path;\n\n for (let i = 0; i < length; i++) {\n result = PathApi.next(result);\n }\n return result;\n};\n\n/** @experimental */\nexport function streamInsertChunk(\n editor: PlateEditor,\n chunk: string,\n options: SteamInsertChunkOptions = {}\n) {\n const { _blockChunks, _blockPath } = editor.getOptions(AIChatPlugin);\n\n if (_blockPath === null) {\n const blocks = streamDeserializeMd(editor, chunk);\n const path = getCurrentBlockPath(editor);\n const startBlock = editor.api.node(path)![0];\n\n const startInEmptyParagraph =\n NodeApi.string(startBlock).length === 0 &&\n startBlock.type === getPluginType(editor, KEYS.p);\n\n // if start in empty paragraph, remove it\n if (startInEmptyParagraph) {\n editor.tf.removeNodes({ at: path });\n }\n\n if (blocks.length > 0) {\n editor.tf.insertNodes(nodesWithProps(editor, [blocks[0]], options), {\n at: path,\n nextBlock: !startInEmptyParagraph,\n select: true,\n });\n\n editor.setOption(AIChatPlugin, '_blockPath', getCurrentBlockPath(editor));\n editor.setOption(AIChatPlugin, '_blockChunks', chunk);\n\n if (blocks.length > 1) {\n const nextBlocks = blocks.slice(1);\n\n const nextPath = getCurrentBlockPath(editor);\n\n editor.tf.insertNodes(nodesWithProps(editor, nextBlocks, options), {\n at: nextPath,\n nextBlock: true,\n select: true,\n });\n\n const lastBlock = editor.api.node(\n getNextPath(nextPath, nextBlocks.length)\n )!;\n\n editor.setOption(AIChatPlugin, '_blockPath', lastBlock[1]);\n\n const lastBlockChunks = streamSerializeMd(\n editor,\n {\n value: [lastBlock[0]],\n },\n chunk\n );\n\n editor.setOption(AIChatPlugin, '_blockChunks', lastBlockChunks);\n }\n }\n } else {\n const tempBlockChunks = _blockChunks + chunk;\n const tempBlocks = streamDeserializeMd(editor, tempBlockChunks);\n\n // console.log(\n // JSON.stringify(chunk),\n // 'chunk',\n // '-------------------------------------------------------------------------------------------'\n // );\n // console.log(\n // '🚀 ~ Streaming ~ tempBlockChunks:',\n // JSON.stringify(tempBlockChunks)\n // );\n\n // console.log('🚀 ~ Streaming ~ tempBlocks:', JSON.stringify(tempBlocks));\n\n if (tempBlocks.length === 0) {\n return console.warn(\n `unsupport md nodes: ${JSON.stringify(tempBlockChunks)}`\n );\n }\n\n if (tempBlocks.length === 1) {\n const currentBlock = editor.api.node(_blockPath)![0];\n\n // If the types are the same\n if (isSameNode(editor, currentBlock, tempBlocks[0])) {\n const chunkNodes = streamDeserializeInlineMd(editor as any, chunk);\n\n // Deserialize the chunk and add it to the end of the current block\n editor.tf.insertNodes(nodesWithProps(editor, chunkNodes, options), {\n at: editor.api.end(_blockPath),\n select: true,\n });\n\n const updatedBlock = editor.api.node(_blockPath)!;\n const serializedBlock = streamSerializeMd(\n editor,\n {\n value: [updatedBlock[0]],\n },\n tempBlockChunks\n );\n\n const blockText = NodeApi.string(tempBlocks[0]);\n\n // Verify if the editor content matches the chunk\n if (\n serializedBlock === tempBlockChunks &&\n blockText === serializedBlock\n ) {\n editor.setOption(AIChatPlugin, '_blockChunks', tempBlockChunks);\n } else {\n editor.tf.replaceNodes(\n nodesWithProps(editor, [tempBlocks[0]], options),\n {\n at: _blockPath,\n select: true,\n }\n );\n\n const serializedBlock = streamSerializeMd(\n editor,\n {\n value: [tempBlocks[0]],\n },\n tempBlockChunks\n );\n\n editor.setOption(\n AIChatPlugin,\n '_blockChunks',\n // one block includes multiple children\n tempBlocks[0].type === getPluginType(editor, KEYS.codeBlock) ||\n tempBlocks[0].type === getPluginType(editor, KEYS.table) ||\n tempBlocks[0].type === getPluginType(editor, KEYS.equation)\n ? tempBlockChunks\n : serializedBlock\n );\n }\n } else {\n const serializedBlock = streamSerializeMd(\n editor,\n {\n value: [tempBlocks[0]],\n },\n tempBlockChunks\n );\n\n editor.tf.replaceNodes(\n nodesWithProps(editor, [tempBlocks[0]], options),\n {\n at: _blockPath,\n select: true,\n }\n );\n\n editor.setOption(AIChatPlugin, '_blockChunks', serializedBlock);\n }\n } else {\n editor.tf.replaceNodes(nodesWithProps(editor, [tempBlocks[0]], options), {\n at: _blockPath,\n select: true,\n });\n\n if (tempBlocks.length > 1) {\n const newEndBlockPath = getNextPath(_blockPath, tempBlocks.length - 1);\n\n editor.tf.insertNodes(\n nodesWithProps(editor, tempBlocks.slice(1), options),\n {\n at: PathApi.next(_blockPath),\n select: true,\n }\n );\n\n editor.setOption(AIChatPlugin, '_blockPath', newEndBlockPath);\n\n const endBlock = editor.api.node(newEndBlockPath)![0];\n\n const serializedBlock = streamSerializeMd(\n editor,\n {\n value: [endBlock],\n },\n tempBlockChunks\n );\n\n editor.setOption(AIChatPlugin, '_blockChunks', serializedBlock);\n }\n }\n }\n}\n\nexport const getCurrentBlockPath = (editor: SlateEditor) => {\n const getAnchorPreviousPath = (editor: SlateEditor): Path | undefined => {\n const anchorNode = editor\n .getApi(AIChatPlugin)\n .aiChat.node({ anchor: true });\n\n if (anchorNode) {\n return PathApi.previous(anchorNode[1])!;\n }\n };\n\n const getFocusPath = (editor: SlateEditor): Path | undefined => {\n return editor.selection?.focus.path.slice(0, 1);\n };\n\n const path = getAnchorPreviousPath(editor) ?? getFocusPath(editor) ?? [0];\n\n const entry = editor.api.node(path);\n\n // streaming in table or columns shouldn't remove them\n if (\n entry &&\n (entry[0].type === getPluginType(editor, KEYS.columnGroup) ||\n entry[0].type === getPluginType(editor, KEYS.table))\n ) {\n return editor.api.above()?.[1] ?? path;\n }\n\n return path;\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { type SerializeMdOptions, MarkdownPlugin } from '@platejs/markdown';\nimport {\n type Descendant,\n ElementApi,\n getPluginKey,\n KEYS,\n TextApi,\n} from 'platejs';\n\nimport {\n getChunkTrimmed,\n isCompleteCodeBlock,\n isCompleteMath,\n} from './utils/utils';\n\n// fixes test: should serialize heading with tailing line break\n// fixes test: incomplete line breaks\nconst trimEndHeading = (\n editor: PlateEditor,\n value: Descendant[]\n): { trimmedText: string; value: Descendant[] } => {\n const headingKeys = new Set([\n KEYS.h1,\n KEYS.h2,\n KEYS.h3,\n KEYS.h4,\n KEYS.h5,\n KEYS.h6,\n ]);\n const lastBlock = value.at(-1);\n\n if (\n lastBlock &&\n headingKeys.has(\n (getPluginKey(editor, lastBlock.type as string) ?? lastBlock.type) as any\n ) &&\n ElementApi.isElement(lastBlock)\n ) {\n const lastTextNode = lastBlock.children.at(-1);\n\n if (TextApi.isText(lastTextNode)) {\n const trimmedText = getChunkTrimmed(lastTextNode?.text as string);\n\n // Create a new lastBlock with immutable operations\n const newChildren = [\n ...lastBlock.children.slice(0, -1),\n { text: lastTextNode.text.trimEnd() },\n ];\n\n const newLastBlock = {\n ...lastBlock,\n children: newChildren,\n };\n\n return {\n trimmedText: trimmedText,\n value: [...value.slice(0, -1), newLastBlock],\n };\n }\n }\n\n return { trimmedText: '', value };\n};\n\nexport const streamSerializeMd = (\n editor: PlateEditor,\n options: SerializeMdOptions,\n chunk: string\n) => {\n const { value: optionsValue, ...restOptions } = options;\n const { value } = trimEndHeading(editor, optionsValue ?? editor.children);\n\n let result = '';\n\n result = editor.getApi(MarkdownPlugin).markdown.serialize({\n value: value,\n ...restOptions,\n });\n\n const trimmedChunk = getChunkTrimmed(chunk);\n\n if (isCompleteCodeBlock(result) && !chunk.endsWith('```')) {\n result = result.trimEnd().slice(0, -3) + trimmedChunk;\n }\n\n if (isCompleteMath(result) && !chunk.endsWith('$$')) {\n result = result.trimEnd().slice(0, -3) + trimmedChunk;\n }\n\n // clean HTML spaces and zero-width characters\n result = result.replace(/ /g, ' ');\n result = result.replace(/​/g, ' ');\n result = result.replace(/\\u200B/g, '');\n\n // remove extra \\n but not include \\n itself\n // FIXME maybe failed when chunk is more than two'\\n'\n if (trimmedChunk !== '\\n\\n') {\n result = result.trimEnd() + trimmedChunk;\n }\n\n // Handle empty paragraph case for streaming\n if (chunk.endsWith('\\n\\n')) {\n if (result === '\\n') {\n // Single empty paragraph case\n result = '';\n } else if (result.endsWith('\\n\\n')) {\n // Multiple paragraphs ending with empty paragraph\n result = result.slice(0, -1);\n }\n }\n\n // replace   to real space\n\n // remove Markdown escape characters (including those potentially added in the chunk)\n result = result.replace(/\\\\([\\\\`*_{}\\\\[\\]()#+\\-\\\\.!~<>|$])/g, '$1');\n\n return result;\n};\n","import { deserializeMd } from '@platejs/markdown';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport {\n diffToSuggestions,\n getTransientSuggestionKey,\n SkipSuggestionDeletes,\n} from '@platejs/suggestion';\nimport {\n type Descendant,\n type SlateEditor,\n type TElement,\n type TIdElement,\n type TSuggestionData,\n type TSuggestionElement,\n ElementApi,\n KEYS,\n nanoid,\n TextApi,\n} from 'platejs';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\n\nexport const applyAISuggestions = (editor: SlateEditor, content: string) => {\n /** Conflict with block selection */\n editor\n .getApi({ key: KEYS.cursorOverlay })?.cursorOverlay?.removeCursor('selection');\n\n const isBlockSelecting = editor.getOption(\n BlockSelectionPlugin,\n 'isSelectingSome'\n );\n\n const { chatNodes } = editor.getOptions(AIChatPlugin);\n\n if (isBlockSelecting || editor.api.blocks({ mode: 'highest' }).length > 1) {\n const setReplaceIds = (ids: string[]) => {\n editor.setOption(AIChatPlugin, '_replaceIds', ids);\n };\n\n if (editor.getOption(AIChatPlugin, '_replaceIds').length === 0) {\n setReplaceIds(chatNodes.map((node) => node.id as string));\n }\n\n const diffNodes = getDiffNodes(editor, content);\n\n const replaceNodes = Array.from(\n editor.api.nodes<TIdElement>({\n at: [],\n match: (n: TIdElement) =>\n ElementApi.isElement(n) &&\n editor.getOption(AIChatPlugin, '_replaceIds').includes(n.id),\n })\n );\n\n replaceNodes.forEach(([node, path], index) => {\n const replaceNode = node as unknown as TSuggestionElement;\n const diffNode = diffNodes[index] as unknown as TSuggestionElement;\n\n const isSameString =\n SkipSuggestionDeletes(editor, replaceNode) ===\n SkipSuggestionDeletes(editor, diffNode);\n\n const isSameSuggestion =\n (replaceNode.suggestion as TSuggestionData | undefined)?.type ===\n (diffNode.suggestion as TSuggestionData | undefined)?.type;\n\n if (\n index === replaceNodes.length - 1 &&\n diffNodes.length > replaceNodes.length\n ) {\n editor.tf.replaceNodes(diffNodes.slice(index), {\n at: path,\n });\n }\n // Performance optimization\n if (isSameString && isSameSuggestion && node.id == diffNode.id) {\n return;\n }\n\n editor.tf.replaceNodes(diffNode, {\n at: path,\n });\n });\n\n editor\n .getApi(BlockSelectionPlugin)\n .blockSelection.set(diffNodes.map((node) => node.id as string));\n setReplaceIds(diffNodes.map((node) => node.id as string));\n } else {\n const diffNodes = getDiffNodes(editor, content);\n\n editor.tf.insertFragment(diffNodes);\n\n const nodes = Array.from(\n editor.api.nodes({\n at: [],\n mode: 'lowest',\n match: (n) => TextApi.isText(n) && !!n[getTransientSuggestionKey()],\n })\n );\n\n const range = editor.api.nodesRange(nodes);\n\n editor.tf.setSelection(range!);\n\n return;\n }\n};\n\nconst withProps = (\n diffNodes: Descendant[],\n chatNodes: Descendant[]\n): Descendant[] => {\n return diffNodes.map((node, index) => {\n if (!ElementApi.isElement(node)) return node;\n\n const originalNode = chatNodes?.[index] as TElement | undefined;\n\n return {\n ...node,\n ...(originalNode ?? { id: nanoid() }),\n children: node.children,\n };\n });\n};\n\nconst withTransient = (diffNodes: Descendant[]): Descendant[] => {\n return diffNodes.map((node) => {\n if (TextApi.isText(node)) {\n return {\n ...node,\n [getTransientSuggestionKey()]: true,\n };\n } else {\n return {\n ...node,\n children: withTransient(node.children),\n [getTransientSuggestionKey()]: true,\n };\n }\n });\n};\n\nconst withoutSuggestionAndComments = (nodes: Descendant[]): Descendant[] => {\n return nodes.map((node) => {\n if (TextApi.isText(node)) {\n if (node[KEYS.suggestion] || node[KEYS.comment]) {\n return {\n text: node.text,\n };\n }\n\n return node;\n }\n if (ElementApi.isElement(node)) {\n if (node[KEYS.suggestion]) {\n const nodeWithoutSuggestion: any = {};\n\n Object.keys(node).forEach((key) => {\n if (key !== KEYS.suggestion && !key.startsWith(KEYS.suggestion)) {\n nodeWithoutSuggestion[key] = node[key];\n }\n });\n\n return {\n ...nodeWithoutSuggestion,\n children: withoutSuggestionAndComments(node.children),\n };\n }\n\n return {\n ...node,\n children: withoutSuggestionAndComments(node.children),\n };\n }\n\n return node;\n });\n};\nconst getDiffNodes = (editor: SlateEditor, aiContent: string) => {\n /** Original document nodes */\n const chatNodes = withoutSuggestionAndComments(\n editor.getOption(AIChatPlugin, 'chatNodes')\n );\n\n const aiNodes = withProps(deserializeMd(editor, aiContent), chatNodes);\n\n const diffNodes = withTransient(\n diffToSuggestions(editor, chatNodes, aiNodes, {\n ignoreProps: ['id', 'listStart'],\n })\n );\n\n return diffNodes;\n};\n","'use client';\n\nimport type React from 'react';\n\nimport type { DebouncedFunc } from 'lodash';\n\nimport { serializeMd } from '@platejs/markdown';\nimport debounce from 'lodash/debounce.js';\nimport {\n type OmitFirst,\n type PluginConfig,\n type TElement,\n bindFirst,\n KEYS,\n NodeApi,\n} from 'platejs';\nimport { type PlateEditor, createTPlatePlugin } from 'platejs/react';\n\nimport type { CompleteOptions } from './utils/callCompletionApi';\n\nimport { renderCopilotBelowNodes } from './renderCopilotBelowNodes';\nimport { acceptCopilot } from './transforms/acceptCopilot';\nimport { acceptCopilotNextWord } from './transforms/acceptCopilotNextWord';\nimport { type GetNextWord, getNextWord } from './utils/getNextWord';\nimport { triggerCopilotSuggestion } from './utils/triggerCopilotSuggestion';\nimport { withCopilot } from './withCopilot';\n\nexport type CopilotPluginConfig = PluginConfig<\n 'copilot',\n CompletionState & {\n /**\n * AI completion options. See:\n * {@link https://sdk.vercel.ai/docs/reference/ai-sdk-ui/use-completion#parameters | AI SDK UI useCompletion Parameters}\n */\n completeOptions?: Partial<CompleteOptions>;\n /**\n * Debounce delay for auto triggering AI completion.\n *\n * @default 0\n */\n debounceDelay?: number;\n /** Get the next word to be inserted. */\n getNextWord?: GetNextWord;\n /** Render the ghost text. */\n renderGhostText?: (() => React.ReactNode) | null;\n shouldAbort?: boolean;\n /** The node id where the suggestion is located. */\n suggestionNodeId?: string | null;\n /** The text of the suggestion. */\n suggestionText?: string | null;\n /**\n * Conditions to auto trigger copilot, used in addition to triggerQuery.\n * Disabling defaults to:\n *\n * - Block above is empty\n * - Block above ends with a space\n * - There is already a suggestion\n */\n autoTriggerQuery?: (options: { editor: PlateEditor }) => boolean;\n /**\n * Get the prompt for AI completion.\n *\n * @default serializeMdNodes(editor.api.block({ highest: true }))\n */\n getPrompt?: (options: { editor: PlateEditor }) => string;\n /**\n * Conditions to trigger copilot. Disabling defaults to:\n *\n * - Selection is expanded\n * - Selection is not at the end of block\n */\n triggerQuery?: (options: { editor: PlateEditor }) => boolean;\n // query?: QueryEditorOptions;\n },\n {\n copilot: {\n triggerSuggestion: OmitFirst<typeof triggerCopilotSuggestion>;\n // Function to abort the current API request and reject the completion state.\n reject: () => false | undefined;\n setBlockSuggestion: (options: { text: string; id?: string }) => void;\n // Function to abort the current API request.\n stop: () => void;\n };\n },\n {\n copilot: {\n accept: OmitFirst<typeof acceptCopilot>;\n acceptNextWord: OmitFirst<typeof acceptCopilotNextWord>;\n };\n },\n {\n isSuggested?: (id: string) => boolean;\n }\n>;\n\ntype CompletionState = {\n abortController?: AbortController | null;\n // The current text completion.\n completion?: string | null;\n // The error thrown during the completion process, if any.\n error?: Error | null;\n // Boolean flag indicating whether a fetch operation is currently in progress.\n isLoading?: boolean;\n};\n\nexport const CopilotPlugin = createTPlatePlugin<CopilotPluginConfig>({\n key: KEYS.copilot,\n handlers: {\n onBlur: ({ api }) => {\n api.copilot.reject();\n },\n onMouseDown: ({ api }) => {\n api.copilot.reject();\n },\n },\n options: {\n abortController: null,\n completeOptions: {},\n completion: '',\n debounceDelay: 0,\n error: null,\n getNextWord: getNextWord,\n isLoading: false,\n renderGhostText: null,\n shouldAbort: true,\n suggestionNodeId: null,\n suggestionText: null,\n autoTriggerQuery: ({ editor }) => {\n if (\n editor.getOptions<CopilotPluginConfig>({ key: KEYS.copilot })\n .suggestionText\n ) {\n return false;\n }\n\n const isEmpty = editor.api.isEmpty(editor.selection, { block: true });\n\n if (isEmpty) return false;\n\n const blockAbove = editor.api.block();\n\n if (!blockAbove) return false;\n\n const blockString = NodeApi.string(blockAbove[0]);\n\n return blockString.at(-1) === ' ';\n },\n getPrompt: ({ editor }) => {\n const contextEntry = editor.api.block({ highest: true });\n\n if (!contextEntry) return '';\n\n return serializeMd(editor, {\n value: [contextEntry[0] as TElement],\n });\n },\n triggerQuery: ({ editor }) => {\n if (editor.api.isExpanded()) return false;\n\n const isEnd = editor.api.isAt({ end: true });\n\n if (!isEnd) return false;\n\n return true;\n },\n },\n})\n .overrideEditor(withCopilot)\n .extendSelectors<CopilotPluginConfig['selectors']>(({ getOptions }) => ({\n isSuggested: (id) => getOptions().suggestionNodeId === id,\n }))\n .extendTransforms(({ editor }) => ({\n accept: bindFirst(acceptCopilot, editor),\n acceptNextWord: bindFirst(acceptCopilotNextWord, editor),\n }))\n .extendApi<Omit<CopilotPluginConfig['api']['copilot'], 'reject'>>(\n ({ api, editor, getOptions, setOption, setOptions }) => {\n const debounceDelay = getOptions().debounceDelay;\n\n let triggerSuggestion = bindFirst(triggerCopilotSuggestion, editor);\n\n if (debounceDelay) {\n triggerSuggestion = debounce(\n bindFirst(triggerCopilotSuggestion, editor),\n debounceDelay\n ) as any;\n }\n\n return {\n triggerSuggestion,\n setBlockSuggestion: ({ id = getOptions().suggestionNodeId, text }) => {\n if (!id) {\n id = editor.api.block()![0].id as string;\n }\n\n setOptions({\n suggestionNodeId: id,\n suggestionText: text,\n });\n },\n stop: () => {\n const { abortController } = getOptions();\n\n (api.copilot.triggerSuggestion as DebouncedFunc<any>)?.cancel();\n\n if (abortController) {\n abortController.abort();\n setOption('abortController', null);\n }\n },\n };\n }\n )\n .extendApi(({ api, getOptions, setOptions }) => ({\n reject: () => {\n if (!getOptions().suggestionText?.length) return false;\n\n api.copilot.stop();\n\n setOptions({\n completion: null,\n suggestionNodeId: null,\n suggestionText: null,\n });\n },\n }))\n .extend({\n render: {\n belowNodes: renderCopilotBelowNodes,\n },\n shortcuts: {\n accept: {\n keys: 'tab',\n },\n reject: {\n keys: 'escape',\n },\n },\n });\n","'use client';\n\nimport React from 'react';\n\nimport { KEYS } from 'platejs';\nimport { type RenderNodeWrapperProps, getEditorPlugin } from 'platejs/react';\n\nimport type { CopilotPluginConfig } from './CopilotPlugin';\n\nexport const renderCopilotBelowNodes = ({\n editor,\n}: RenderNodeWrapperProps<CopilotPluginConfig>) => {\n const copilot = getEditorPlugin<CopilotPluginConfig>(editor, {\n key: KEYS.copilot,\n });\n\n const { renderGhostText: GhostText } = copilot.getOptions();\n\n if (!GhostText) return;\n\n return ({ children }: { children: React.ReactNode }) => {\n return (\n <React.Fragment>\n {children}\n\n <GhostText />\n </React.Fragment>\n );\n };\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { deserializeInlineMd } from '@platejs/markdown';\nimport { KEYS } from 'platejs';\n\nimport type { CopilotPluginConfig } from '../CopilotPlugin';\n\nexport const acceptCopilot = (editor: PlateEditor) => {\n const { suggestionText } = editor.getOptions<CopilotPluginConfig>({\n key: KEYS.copilot,\n });\n\n if (!suggestionText?.length) return false;\n\n editor.tf.insertFragment(deserializeInlineMd(editor, suggestionText));\n};\n","import { deserializeInlineMd } from '@platejs/markdown';\nimport { KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport type { CopilotPluginConfig } from '../CopilotPlugin';\n\nimport { withoutAbort } from '../utils';\n\nexport const acceptCopilotNextWord = (editor: PlateEditor) => {\n const { api, getOptions } = getEditorPlugin<CopilotPluginConfig>(editor, {\n key: KEYS.copilot,\n });\n\n const { getNextWord, suggestionText } = getOptions();\n\n if (!suggestionText?.length) {\n return false;\n }\n\n const { firstWord, remainingText } = getNextWord!({ text: suggestionText });\n\n api.copilot.setBlockSuggestion({\n text: remainingText,\n });\n\n withoutAbort(editor, () => {\n editor.tf.insertFragment(deserializeInlineMd(editor, firstWord));\n });\n};\n","// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nexport type CallCompletionApiOptions = {\n prompt: string;\n api?: string;\n body?: Record<string, any>;\n credentials?: RequestCredentials | undefined;\n fetch?: ReturnType<typeof getOriginalFetch> | undefined;\n headers?: HeadersInit | undefined;\n setAbortController?: (abortController: AbortController | null) => void;\n setCompletion?: (completion: string) => void;\n setError?: (error: Error | null) => void;\n setLoading?: (loading: boolean) => void;\n onError?: ((error: Error) => void) | undefined;\n onFinish?: ((prompt: string, completion: string) => void) | undefined;\n onResponse?: ((response: Response) => Promise<void> | void) | undefined;\n};\n\nexport type CompleteOptions = Omit<\n CallCompletionApiOptions,\n 'setAbortController' | 'setCompletion' | 'setError' | 'setLoading'\n>;\n\n// https://github.com/vercel/ai/blob/main/packages/ui-utils/src/call-completion-api.ts\n// https://github.com/vercel/ai/blob/642ba22ee33723f3aae9669c7e075322cffca2f3/packages/react/src/use-completion.ts\nexport async function callCompletionApi({\n api = '/api/completion',\n body,\n credentials,\n fetch = getOriginalFetch(),\n headers,\n prompt,\n setAbortController = () => {},\n setCompletion = () => {},\n setError = () => {},\n setLoading = () => {},\n onError,\n onFinish,\n onResponse,\n}: CallCompletionApiOptions) {\n try {\n setLoading(true);\n setError(null);\n\n const abortController = new AbortController();\n setAbortController(abortController);\n\n // Empty the completion immediately.\n setCompletion('');\n\n const res = await fetch(api, {\n body: JSON.stringify({\n prompt,\n ...body,\n }),\n credentials,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n method: 'POST',\n signal: abortController.signal,\n }).catch((error) => {\n throw error;\n });\n\n if (onResponse) {\n await onResponse(res);\n }\n if (!res.ok) {\n throw new Error(\n (await res.text()) || 'Failed to fetch the chat response.'\n );\n }\n if (!res.body) {\n throw new Error('The response body is empty.');\n }\n\n const { text } = await res.json();\n\n if (!text) {\n throw new Error('The response does not contain a text field.');\n }\n\n setCompletion(text);\n\n if (onFinish) {\n onFinish(prompt, text);\n }\n\n setAbortController(null);\n\n return text as string;\n } catch (error) {\n // Ignore abort errors as they are expected.\n if ((error as any).name === 'AbortError') {\n setAbortController(null);\n\n return null;\n }\n if (error instanceof Error && onError) {\n onError(error);\n }\n\n setError(error as Error);\n } finally {\n setLoading(false);\n }\n}\n","export type GetNextWord = (options: { text: string }) => {\n firstWord: string;\n remainingText: string;\n};\n\nexport const getNextWord: GetNextWord = ({ text }) => {\n if (!text) return { firstWord: '', remainingText: '' };\n\n // Check if the first non-space character is a CJK character\n const nonSpaceMatch = /^\\s*(\\S)/.exec(text);\n\n if (!nonSpaceMatch) return { firstWord: '', remainingText: '' };\n\n const firstNonSpaceChar = nonSpaceMatch[1];\n\n // Regular expression for matching CJK characters\n // 1. [\\u4E00-\\u9FA5] - Chinese Characters\n // 2. [\\u3040-\\u309F] - Japanese Hiragana\n // 3. [\\u30A0-\\u30FF] - Japanese Katakana\n // 4. [\\u3400-\\u4DBF] - CJK Extension A\n // 5. [\\u4E00-\\u9FFF] - CJK Unified Ideographs\n // 6. [\\uF900-\\uFAFF] - CJK Compatibility Ideographs\n // 7. [\\uAC00-\\uD7AF] - Korean Syllables\n // 8. [\\u1100-\\u11FF] - Korean Jamo\n const isCJKChar =\n /[\\u1100-\\u11FF\\u3040-\\u30FF\\u3400-\\u4DBF\\u4E00-\\u9FFF\\uAC00-\\uD7AF\\uF900-\\uFAFF]/.test(\n firstNonSpaceChar\n );\n\n let firstWord, remainingText;\n\n if (isCJKChar) {\n // CJK characters: match leading spaces + first character + optional punctuation\n const match =\n /^(\\s*)([\\u1100-\\u11FF\\u3040-\\u30FF\\u3400-\\u4DBF\\u4E00-\\u9FFF\\uAC00-\\uD7AF\\uF900-\\uFAFF])([\\u3000-\\u303F\\uFF00-\\uFFEF])?/.exec(\n text\n );\n\n if (match) {\n const [fullMatch, spaces = '', char = '', punctuation = ''] = match;\n firstWord = spaces + char + punctuation;\n remainingText = text.slice(firstWord.length);\n } else {\n firstWord = '';\n remainingText = text;\n }\n } else {\n // For non-CJK text (including mixed content), match until space or CJK char\n const match =\n /^(\\s*\\S+?)(?=[\\s\\u1100-\\u11FF\\u3040-\\u30FF\\u3400-\\u4DBF\\u4E00-\\u9FFF\\uAC00-\\uD7AF\\uF900-\\uFAFF]|$)/.exec(\n text\n );\n\n if (match) {\n firstWord = match[0];\n remainingText = text.slice(firstWord.length);\n } else {\n firstWord = text;\n remainingText = '';\n }\n }\n\n return { firstWord, remainingText };\n};\n","import { KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport type { CopilotPluginConfig } from '../CopilotPlugin';\n\nimport { callCompletionApi } from './callCompletionApi';\n\nexport const triggerCopilotSuggestion = async (editor: PlateEditor) => {\n const { api, getOptions, setOption } = getEditorPlugin<CopilotPluginConfig>(\n editor,\n {\n key: KEYS.copilot,\n }\n );\n\n const { completeOptions, getPrompt, isLoading, triggerQuery } = getOptions();\n\n if (isLoading || editor.getOptions({ key: KEYS.aiChat }).chat?.isLoading) {\n return false;\n }\n if (!triggerQuery!({ editor })) return false;\n\n // if (query && !queryEditor(editor, query)) return;\n\n const prompt = getPrompt!({ editor });\n\n if (prompt.length === 0) return false;\n\n api.copilot.stop();\n\n await callCompletionApi({\n prompt,\n onFinish: (_, completion) => {\n api.copilot.setBlockSuggestion({ text: completion });\n },\n ...completeOptions,\n setAbortController: (controller) =>\n setOption('abortController', controller),\n setCompletion: (completion) => setOption('completion', completion),\n setError: (error) => setOption('error', error),\n setLoading: (loading) => setOption('isLoading', loading),\n onError: (error) => {\n setOption('error', error);\n completeOptions?.onError?.(error);\n },\n });\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { CopilotPlugin } from '..';\n\nexport const withoutAbort = (editor: PlateEditor, fn: () => void) => {\n editor.setOption(CopilotPlugin, 'shouldAbort', false);\n fn();\n editor.setOption(CopilotPlugin, 'shouldAbort', true);\n};\n","import type { OverrideEditor, PlateEditor } from 'platejs/react';\n\nimport { serializeInlineMd } from '@platejs/markdown';\nimport {\n type Operation,\n type SlateEditor,\n type TRange,\n RangeApi,\n} from 'platejs';\n\nimport type { CopilotPluginConfig } from './CopilotPlugin';\n\nimport { withoutAbort } from './utils/withoutAbort';\n\ntype CopilotBatch = PlateEditor['history']['undos'][number] & {\n shouldAbort: boolean;\n};\n\nconst getPatchString = (editor: SlateEditor, operations: Operation[]) => {\n let string = '';\n\n for (const operation of operations) {\n if (operation.type === 'insert_node') {\n const node = operation.node;\n const text = serializeInlineMd(editor, { value: [node] });\n string += text;\n } else if (operation.type === 'insert_text') {\n string += operation.text;\n }\n }\n\n return string;\n};\n\nexport const withCopilot: OverrideEditor<CopilotPluginConfig> = ({\n api,\n editor,\n getOptions,\n setOption,\n tf: { apply, insertText, redo, setSelection, undo, writeHistory },\n}) => {\n let prevSelection: TRange | null = null;\n\n return {\n transforms: {\n apply(operation) {\n const { shouldAbort } = getOptions();\n\n if (shouldAbort) {\n api.copilot.reject();\n }\n\n apply(operation);\n },\n insertText(text, options) {\n const suggestionText = getOptions().suggestionText;\n\n // When using IME input, it's possible to enter two characters at once.\n if (suggestionText?.startsWith(text)) {\n withoutAbort(editor, () => {\n editor.tf.withoutMerging(() => {\n const newText = suggestionText?.slice(text.length);\n setOption('suggestionText', newText);\n insertText(text);\n });\n });\n\n return;\n }\n\n insertText(text, options);\n },\n\n redo() {\n if (!getOptions().suggestionText) return redo();\n\n const topRedo = editor.history.redos.at(-1) as CopilotBatch;\n const prevSuggestion = getOptions().suggestionText;\n\n if (topRedo && topRedo.shouldAbort === false && prevSuggestion) {\n withoutAbort(editor, () => {\n const shouldRemoveText = getPatchString(editor, topRedo.operations);\n\n const newText = prevSuggestion.slice(shouldRemoveText.length);\n setOption('suggestionText', newText);\n\n redo();\n });\n\n return;\n }\n\n return redo();\n },\n\n setSelection(props) {\n setSelection(props);\n\n if (\n editor.selection &&\n (!prevSelection ||\n !RangeApi.equals(prevSelection, editor.selection)) &&\n getOptions().autoTriggerQuery!({ editor }) &&\n editor.api.isFocused()\n ) {\n void api.copilot.triggerSuggestion();\n }\n\n prevSelection = editor.selection;\n },\n\n undo() {\n if (!getOptions().suggestionText) return undo();\n\n const lastUndos = editor.history.undos.at(-1) as CopilotBatch;\n const oldText = getOptions().suggestionText;\n\n if (lastUndos && lastUndos.shouldAbort === false && oldText) {\n withoutAbort(editor, () => {\n const shouldInsertText = getPatchString(\n editor,\n lastUndos.operations\n );\n\n const newText = shouldInsertText + oldText;\n setOption('suggestionText', newText);\n\n undo();\n });\n\n return;\n }\n\n return undo();\n },\n\n writeHistory(stacks, batch) {\n if (!getOptions().isLoading) {\n batch.shouldAbort = getOptions().shouldAbort;\n }\n\n return writeHistory(stacks, batch);\n },\n },\n };\n};\n"],"mappings":"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","names":["KEYS","KEYS","KEYS","isSelecting","NodeApi","NodeApi","BlockSelectionPlugin","bindFirst","ElementApi","getPluginType","KEYS","getTransientSuggestionKey","KEYS","KEYS","getTransientSuggestionKey","BlockSelectionPlugin","cloneDeep","KEYS","KEYS","NodeApi","TextApi","formattedBlocks","BlockSelectionPlugin","KEYS","cloneDeep","getPluginType","KEYS","KEYS","getEditorPlugin","getEditorPlugin","KEYS","isSelecting","BlockSelectionPlugin","KEYS","getEditorPlugin","getEditorPlugin","KEYS","isSelecting","BlockSelectionPlugin","ElementApi","KEYS","KEYS","ElementApi","KEYS","bindFirst","ElementApi","getPluginType","BlockSelectionPlugin","useEffect","KEYS","usePluginOption","usePluginOption","KEYS","useEffect","useEffect","BlockSelectionPlugin","useEditorPlugin","usePluginOption","useEditorPlugin","usePluginOption","useEffect","BlockSelectionPlugin","MarkdownPlugin","MarkdownPlugin","getPluginType","KEYS","TextApi","KEYS","ElementApi","ElementApi","MarkdownPlugin","TextApi","textNode","KEYS","getPluginType","getPluginType","KEYS","NodeApi","PathApi","MarkdownPlugin","ElementApi","KEYS","TextApi","KEYS","ElementApi","TextApi","MarkdownPlugin","PathApi","NodeApi","getPluginType","KEYS","serializedBlock","editor","deserializeMd","BlockSelectionPlugin","getTransientSuggestionKey","ElementApi","KEYS","TextApi","KEYS","BlockSelectionPlugin","ElementApi","TextApi","getTransientSuggestionKey","deserializeMd","bindFirst","KEYS","NodeApi","createTPlatePlugin","KEYS","getEditorPlugin","KEYS","deserializeInlineMd","KEYS","getEditorPlugin","fetch","KEYS","getEditorPlugin","getEditorPlugin","KEYS","getEditorPlugin","KEYS","getNextWord","deserializeInlineMd","RangeApi","RangeApi","createTPlatePlugin","KEYS","NodeApi","bindFirst"]}
|