@platejs/ai 49.1.11 → 49.2.1
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/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +265 -206
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +249 -179
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +4 -2
- package/dist/react/index.d.ts +4 -2
- package/dist/react/index.js +71 -68
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +42 -38
- package/dist/react/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/index.ts","../../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/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/getEditorPrompt.ts","../../src/react/ai-chat/utils/getMarkdown.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/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":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from './ai/index';\nexport * from './ai-chat/index';\nexport * from './copilot/index';\n","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, TLocation } from 'platejs';\n\nexport const removeAIMarks = (\n editor: SlateEditor,\n { at = [] }: { at?: TLocation } = {}\n) => {\n editor.tf.unsetNodes('ai', {\n at,\n match: (n) => (n as any).ai,\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\nexport const undoAI = (editor: SlateEditor) => {\n if (\n (editor.history.undos.at(-1) as any)?.ai &&\n editor.api.some({\n at: [],\n match: (n) => !!(n as any).ai,\n })\n ) {\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 type { TriggerComboboxPluginOptions } from '@platejs/combobox';\nimport type { UseChatHelpers } from 'ai/react';\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 bindFirst,\n ElementApi,\n KEYS,\n} from 'platejs';\nimport { createTPlatePlugin } from 'platejs/react';\n\nimport type { AIBatch } from '../../lib';\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 {\n type EditorPromptParams,\n getEditorPrompt,\n} from './utils/getEditorPrompt';\nimport { resetAIChat } from './utils/resetAIChat';\nimport { submitAIChat } from './utils/submitAIChat';\nimport { withAIChat } from './withAIChat';\n\nexport type AIChatPluginConfig = PluginConfig<\n 'aiChat',\n {\n /** @private Using For streamInsertChunk */\n _blockChunks: string;\n _blockPath: Path | null;\n /** @private The Editor used to generate the AI response. */\n aiEditor: SlateEditor | null;\n chat: Partial<UseChatHelpers>;\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: 'chat' | 'insert';\n open: boolean;\n /** Whether the AI response is currently streaming. Cursor mode only. */\n streaming: boolean;\n /**\n * Template function for generating the user prompt. Supports the following\n * placeholders:\n *\n * - {block}: Replaced with the markdown of the blocks in selection.\n * - {editor}: Replaced with the markdown of the entire editor content.\n * - {selection}: Replaced with the markdown of the current selection.\n * - {prompt}: Replaced with the actual user prompt.\n */\n promptTemplate: (props: EditorPromptParams) => string;\n /**\n * Template function for generating the system message. Supports the same\n * placeholders as `promptTemplate`.\n */\n systemTemplate: (props: EditorPromptParams) => string | void;\n } & TriggerComboboxPluginOptions,\n {\n aiChat: {\n reset: OmitFirst<typeof resetAIChat>;\n submit: OmitFirst<typeof submitAIChat>;\n hide: () => 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 aiEditor: null,\n chat: { messages: [] } as any,\n experimental_lastTextId: null,\n mode: 'chat',\n open: false,\n streaming: false,\n trigger: ' ',\n triggerPreviousCharPattern: /^\\s?$/,\n promptTemplate: () => '{prompt}',\n systemTemplate: () => {},\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.ai,\n ...rest,\n });\n }\n\n return editor.api.node({\n match: (n) => n.ai,\n ...rest,\n });\n },\n reload: () => {\n const { chat, mode } = getOptions();\n\n if (mode === 'insert') {\n editor.getTransforms(AIPlugin).ai.undo();\n }\n\n void chat.reload?.({\n body: {\n system: getEditorPrompt(editor, {\n promptTemplate: getOptions().systemTemplate,\n }),\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 api.aiChat.reset();\n\n setOption('open', false);\n\n if (editor.getOption(BlockSelectionPlugin, 'isSelectingSome')) {\n // TODO\n // editor.getApi(BlockSelectionPlugin).blockSelection.focus();\n } else {\n editor.tf.focus();\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 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 { 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 { 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","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 type { AIChatPluginConfig } from '../AIChatPlugin';\n\nimport { createFormattedBlocks } from './replaceSelectionAIChat';\n\nexport const insertBelowAIChat = (\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 editor.tf.insertFragment(formattedBlocks);\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 { type RemoveNodesOptions, ElementApi, KEYS } 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) => ElementApi.isElement(n) && n.type === KEYS.aiChat,\n ...options,\n });\n });\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { isSelecting } from '@platejs/selection';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\n\nimport { getMarkdown } from './getMarkdown';\n\nexport type EditorPrompt =\n | ((params: EditorPromptParams) => string)\n | PromptConfig\n | string;\n\nexport interface EditorPromptParams {\n editor: PlateEditor;\n isBlockSelecting: boolean;\n isSelecting: boolean;\n}\n\nexport type MarkdownType = 'block' | 'editor' | 'selection';\n\nexport interface PromptConfig {\n default: string;\n blockSelecting?: string;\n selecting?: string;\n}\n\nconst replacePlaceholders = (\n editor: PlateEditor,\n text: string,\n {\n prompt,\n }: {\n prompt?: string;\n }\n): string => {\n let result = text.replace('{prompt}', prompt || '');\n\n const placeholders: Record<string, MarkdownType> = {\n '{block}': 'block',\n '{editor}': 'editor',\n '{selection}': 'selection',\n };\n\n Object.entries(placeholders).forEach(([placeholder, type]) => {\n if (result.includes(placeholder)) {\n result = result.replace(placeholder, getMarkdown(editor, type));\n }\n });\n\n return result;\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: PlateEditor,\n {\n prompt = '',\n promptTemplate = () => '{prompt}',\n }: {\n prompt?: EditorPrompt;\n promptTemplate?: (params: EditorPromptParams) => string | void;\n } = {}\n): string | undefined => {\n const params: EditorPromptParams = {\n editor,\n isBlockSelecting: editor.getOption(BlockSelectionPlugin, 'isSelectingSome'),\n isSelecting: isSelecting(editor),\n };\n\n const template = promptTemplate(params);\n\n if (!template) return;\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 replacePlaceholders(editor, template, {\n prompt: promptText,\n });\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { serializeMd } from '@platejs/markdown';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { type TElement, KEYS } from 'platejs';\n\n// Internal\nexport const getMarkdown = (\n editor: PlateEditor,\n type: 'block' | 'editor' | 'selection'\n) => {\n if (type === 'editor') {\n return serializeMd(editor);\n }\n if (type === 'block') {\n const blocks = editor.getOption(BlockSelectionPlugin, 'isSelectingSome')\n ? editor.getApi(BlockSelectionPlugin).blockSelection.getNodes()\n : editor.api.nodes({\n mode: 'highest',\n match: (n) => editor.api.isBlock(n),\n });\n\n const nodes = Array.from(blocks, (entry) => entry[0]);\n\n return serializeMd(editor, { value: nodes });\n }\n if (type === 'selection') {\n const fragment = editor.api.fragment<TElement>();\n\n // Remove any block formatting\n if (fragment.length === 1) {\n const modifiedFragment = [\n {\n children: fragment[0].children,\n type: KEYS.p,\n },\n ];\n\n return serializeMd(editor, { value: modifiedFragment });\n }\n\n return serializeMd(editor, { value: fragment });\n }\n\n return '';\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 = (editor: PlateEditor) => {\n const { api, getOptions } = getEditorPlugin<AIChatPluginConfig>(editor, {\n key: KEYS.aiChat,\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 editor.getTransforms(AIPlugin).ai.undo();\n};\n","import type { ChatRequestOptions } from 'ai';\n\nimport { isSelecting } from '@platejs/selection';\nimport { KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport type { AIChatPluginConfig } from '../AIChatPlugin';\n\nimport { AIPlugin } from '../../ai/AIPlugin';\nimport { type EditorPrompt, getEditorPrompt } from './getEditorPrompt';\n\nexport const submitAIChat = (\n editor: PlateEditor,\n {\n mode,\n options,\n prompt,\n system,\n }: {\n mode?: 'chat' | 'insert';\n options?: ChatRequestOptions;\n prompt?: EditorPrompt;\n system?: EditorPrompt;\n } = {}\n) => {\n const { getOptions, setOption } = getEditorPlugin<AIChatPluginConfig>(\n editor,\n {\n key: KEYS.aiChat,\n }\n );\n\n const { chat, promptTemplate, systemTemplate } = getOptions();\n\n if (!prompt && chat.input?.length === 0) {\n return;\n }\n if (!prompt) {\n prompt = chat.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 chat.setInput?.('');\n\n void chat.append?.(\n {\n content:\n getEditorPrompt(editor, {\n prompt,\n promptTemplate,\n }) ?? '',\n role: 'user',\n },\n {\n body: {\n system: getEditorPrompt(editor, {\n prompt: system,\n promptTemplate: systemTemplate,\n }),\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: { insertText, normalizeNode, setSelection },\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 { isLoading } = usePluginOption(\n { key: KEYS.aiChat } as AIChatPluginConfig,\n 'chat'\n );\n const content = useLastAssistantMessage()?.content;\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 chat = usePluginOption(AIChatPlugin, 'chat');\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/react';\nimport type { NodeEntry } from 'platejs';\n\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { useEditorPlugin, usePluginOption } from 'platejs/react';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\n\nexport type UseEditorChatOptions = {\n chat: UseChatHelpers;\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, setOption } = useEditorPlugin(AIChatPlugin);\n const open = usePluginOption(AIChatPlugin, 'open');\n\n // Sync useChat with AIChatPlugin\n useEffect(() => {\n setOption('chat', chat);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [chat.input, chat.messages, chat.isLoading, chat.data, chat.error]);\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","'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":["import_platejs","import_react","import_platejs","import_platejs","import_react","import_react","import_cloneDeep","import_platejs","import_react","import_platejs","cloneDeep","formattedBlocks","cloneDeep","import_platejs","import_react","import_react","import_platejs","isSelecting","import_platejs","import_react","import_selection","import_platejs","import_react","import_platejs","import_react","import_markdown","import_react","import_platejs","import_react","import_react","import_markdown","import_platejs","import_react","import_react","import_platejs","React","import_markdown","import_platejs","import_markdown","import_platejs","import_react","fetch","import_platejs","import_react","getNextWord","import_markdown","import_platejs","debounce"]}
|
|
1
|
+
{"version":3,"sources":["../../src/react/index.ts","../../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/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/getEditorPrompt.ts","../../src/react/ai-chat/utils/getMarkdown.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/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":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from './ai/index';\nexport * from './ai-chat/index';\nexport * from './copilot/index';\n","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\nexport const undoAI = (editor: SlateEditor) => {\n if (\n (editor.history.undos.at(-1) as any)?.ai &&\n editor.api.some({\n at: [],\n match: (n) => !!(n as any).ai,\n })\n ) {\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 type { TriggerComboboxPluginOptions } from '@platejs/combobox';\nimport type { UseChatHelpers } from 'ai/react';\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 bindFirst,\n ElementApi,\n getPluginType,\n KEYS,\n} from 'platejs';\nimport { createTPlatePlugin } from 'platejs/react';\n\nimport type { AIBatch } from '../../lib';\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 {\n type EditorPromptParams,\n getEditorPrompt,\n} from './utils/getEditorPrompt';\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 /** @private The Editor used to generate the AI response. */\n aiEditor: SlateEditor | null;\n chat: Partial<UseChatHelpers>;\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: 'chat' | 'insert';\n open: boolean;\n /** Whether the AI response is currently streaming. Cursor mode only. */\n streaming: boolean;\n /**\n * Template function for generating the user prompt. Supports the following\n * placeholders:\n *\n * - {block}: Replaced with the markdown of the blocks in selection.\n * - {editor}: Replaced with the markdown of the entire editor content.\n * - {selection}: Replaced with the markdown of the current selection.\n * - {prompt}: Replaced with the actual user prompt.\n */\n promptTemplate: (props: EditorPromptParams) => string;\n /**\n * Template function for generating the system message. Supports the same\n * placeholders as `promptTemplate`.\n */\n systemTemplate: (props: EditorPromptParams) => string | void;\n } & TriggerComboboxPluginOptions,\n {\n aiChat: {\n reset: OmitFirst<typeof resetAIChat>;\n submit: OmitFirst<typeof submitAIChat>;\n hide: () => 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 aiEditor: null,\n chat: { messages: [] } as any,\n experimental_lastTextId: null,\n mode: 'chat',\n open: false,\n streaming: false,\n trigger: ' ',\n triggerPreviousCharPattern: /^\\s?$/,\n promptTemplate: () => '{prompt}',\n systemTemplate: () => {},\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, mode } = getOptions();\n\n if (mode === 'insert') {\n editor.getTransforms(AIPlugin).ai.undo();\n }\n\n void chat.reload?.({\n body: {\n system: getEditorPrompt(editor, {\n promptTemplate: getOptions().systemTemplate,\n }),\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 api.aiChat.reset();\n\n setOption('open', false);\n\n if (editor.getOption(BlockSelectionPlugin, 'isSelectingSome')) {\n // TODO\n // editor.getApi(BlockSelectionPlugin).blockSelection.focus();\n } else {\n editor.tf.focus();\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 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 { 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 { 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","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 type { AIChatPluginConfig } from '../AIChatPlugin';\n\nimport { createFormattedBlocks } from './replaceSelectionAIChat';\n\nexport const insertBelowAIChat = (\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 editor.tf.insertFragment(formattedBlocks);\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 { type RemoveNodesOptions, ElementApi, getPluginType, KEYS } 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) => ElementApi.isElement(n) && n.type === getPluginType(editor, KEYS.aiChat),\n ...options,\n });\n });\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { isSelecting } from '@platejs/selection';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\n\nimport { getMarkdown } from './getMarkdown';\n\nexport type EditorPrompt =\n | ((params: EditorPromptParams) => string)\n | PromptConfig\n | string;\n\nexport interface EditorPromptParams {\n editor: PlateEditor;\n isBlockSelecting: boolean;\n isSelecting: boolean;\n}\n\nexport type MarkdownType = 'block' | 'editor' | 'selection';\n\nexport interface PromptConfig {\n default: string;\n blockSelecting?: string;\n selecting?: string;\n}\n\nconst replacePlaceholders = (\n editor: PlateEditor,\n text: string,\n {\n prompt,\n }: {\n prompt?: string;\n }\n): string => {\n let result = text.replace('{prompt}', prompt || '');\n\n const placeholders: Record<string, MarkdownType> = {\n '{block}': 'block',\n '{editor}': 'editor',\n '{selection}': 'selection',\n };\n\n Object.entries(placeholders).forEach(([placeholder, type]) => {\n if (result.includes(placeholder)) {\n result = result.replace(placeholder, getMarkdown(editor, type));\n }\n });\n\n return result;\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: PlateEditor,\n {\n prompt = '',\n promptTemplate = () => '{prompt}',\n }: {\n prompt?: EditorPrompt;\n promptTemplate?: (params: EditorPromptParams) => string | void;\n } = {}\n): string | undefined => {\n const params: EditorPromptParams = {\n editor,\n isBlockSelecting: editor.getOption(BlockSelectionPlugin, 'isSelectingSome'),\n isSelecting: isSelecting(editor),\n };\n\n const template = promptTemplate(params);\n\n if (!template) return;\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 replacePlaceholders(editor, template, {\n prompt: promptText,\n });\n};\n","import type { PlateEditor } from 'platejs/react';\n\nimport { serializeMd } from '@platejs/markdown';\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { type TElement, KEYS } from 'platejs';\n\n// Internal\nexport const getMarkdown = (\n editor: PlateEditor,\n type: 'block' | 'editor' | 'selection'\n) => {\n if (type === 'editor') {\n return serializeMd(editor);\n }\n if (type === 'block') {\n const blocks = editor.getOption(BlockSelectionPlugin, 'isSelectingSome')\n ? editor.getApi(BlockSelectionPlugin).blockSelection.getNodes()\n : editor.api.nodes({\n mode: 'highest',\n match: (n) => editor.api.isBlock(n),\n });\n\n const nodes = Array.from(blocks, (entry) => entry[0]);\n\n return serializeMd(editor, { value: nodes });\n }\n if (type === 'selection') {\n const fragment = editor.api.fragment<TElement>();\n\n // Remove any block formatting\n if (fragment.length === 1) {\n const modifiedFragment = [\n {\n children: fragment[0].children,\n type: KEYS.p,\n },\n ];\n\n return serializeMd(editor, { value: modifiedFragment });\n }\n\n return serializeMd(editor, { value: fragment });\n }\n\n return '';\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 = (editor: PlateEditor) => {\n const { api, getOptions } = getEditorPlugin<AIChatPluginConfig>(editor, {\n key: KEYS.aiChat,\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 editor.getTransforms(AIPlugin).ai.undo();\n};\n","import type { ChatRequestOptions } from 'ai';\n\nimport { isSelecting } from '@platejs/selection';\nimport { KEYS } from 'platejs';\nimport { type PlateEditor, getEditorPlugin } from 'platejs/react';\n\nimport type { AIChatPluginConfig } from '../AIChatPlugin';\n\nimport { AIPlugin } from '../../ai/AIPlugin';\nimport { type EditorPrompt, getEditorPrompt } from './getEditorPrompt';\n\nexport const submitAIChat = (\n editor: PlateEditor,\n {\n mode,\n options,\n prompt,\n system,\n }: {\n mode?: 'chat' | 'insert';\n options?: ChatRequestOptions;\n prompt?: EditorPrompt;\n system?: EditorPrompt;\n } = {}\n) => {\n const { getOptions, setOption } = getEditorPlugin<AIChatPluginConfig>(\n editor,\n {\n key: KEYS.aiChat,\n }\n );\n\n const { chat, promptTemplate, systemTemplate } = getOptions();\n\n if (!prompt && chat.input?.length === 0) {\n return;\n }\n if (!prompt) {\n prompt = chat.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 chat.setInput?.('');\n\n void chat.append?.(\n {\n content:\n getEditorPrompt(editor, {\n prompt,\n promptTemplate,\n }) ?? '',\n role: 'user',\n },\n {\n body: {\n system: getEditorPrompt(editor, {\n prompt: system,\n promptTemplate: systemTemplate,\n }),\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: { insertText, normalizeNode, setSelection },\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 { isLoading } = usePluginOption(\n { key: KEYS.aiChat } as AIChatPluginConfig,\n 'chat'\n );\n const content = useLastAssistantMessage()?.content;\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 chat = usePluginOption(AIChatPlugin, 'chat');\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/react';\nimport type { NodeEntry } from 'platejs';\n\nimport { BlockSelectionPlugin } from '@platejs/selection/react';\nimport { useEditorPlugin, usePluginOption } from 'platejs/react';\n\nimport { AIChatPlugin } from '../AIChatPlugin';\n\nexport type UseEditorChatOptions = {\n chat: UseChatHelpers;\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, setOption } = useEditorPlugin(AIChatPlugin);\n const open = usePluginOption(AIChatPlugin, 'open');\n\n // Sync useChat with AIChatPlugin\n useEffect(() => {\n setOption('chat', chat);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [chat.input, chat.messages, chat.isLoading, chat.data, chat.error]);\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","'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":["import_platejs","import_platejs","import_react","import_platejs","import_platejs","import_react","import_react","import_cloneDeep","import_platejs","import_react","import_platejs","cloneDeep","formattedBlocks","cloneDeep","import_platejs","import_react","import_react","import_platejs","isSelecting","import_platejs","import_react","import_selection","import_platejs","import_react","import_platejs","import_react","import_markdown","import_react","import_platejs","import_react","import_react","import_markdown","import_platejs","import_react","import_react","import_platejs","React","import_markdown","import_platejs","import_markdown","import_platejs","import_react","fetch","import_platejs","import_react","getNextWord","import_markdown","import_platejs","debounce"]}
|