@platejs/ai 51.0.0 → 51.0.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.
@@ -34,9 +34,9 @@ __export(react_exports, {
34
34
  AIPlugin: () => AIPlugin,
35
35
  CopilotPlugin: () => CopilotPlugin,
36
36
  acceptAIChat: () => acceptAIChat,
37
+ acceptAISuggestions: () => acceptAISuggestions,
37
38
  acceptCopilot: () => acceptCopilot,
38
39
  acceptCopilotNextWord: () => acceptCopilotNextWord,
39
- acceptSuggestions: () => acceptSuggestions,
40
40
  aiCommentToRange: () => aiCommentToRange,
41
41
  applyAISuggestions: () => applyAISuggestions,
42
42
  callCompletionApi: () => callCompletionApi,
@@ -54,6 +54,7 @@ __export(react_exports, {
54
54
  isCompleteMath: () => isCompleteMath,
55
55
  isSameNode: () => isSameNode,
56
56
  nodesWithProps: () => nodesWithProps,
57
+ rejectAISuggestions: () => rejectAISuggestions,
57
58
  removeAnchorAIChat: () => removeAnchorAIChat,
58
59
  renderCopilotBelowNodes: () => renderCopilotBelowNodes,
59
60
  replaceSelectionAIChat: () => replaceSelectionAIChat,
@@ -341,15 +342,41 @@ var aiCommentToRange = (editor, aiComment) => {
341
342
  };
342
343
 
343
344
  // src/react/ai-chat/AIChatPlugin.ts
344
- var import_react9 = require("@platejs/selection/react");
345
- var import_platejs14 = require("platejs");
346
- var import_react10 = require("platejs/react");
345
+ var import_react12 = require("@platejs/selection/react");
346
+ var import_platejs15 = require("platejs");
347
+ var import_react13 = require("platejs/react");
347
348
 
348
349
  // src/react/ai-chat/transforms/acceptAIChat.ts
349
- var import_suggestion2 = require("@platejs/suggestion");
350
- var import_react2 = require("@platejs/suggestion/react");
351
350
  var import_platejs7 = require("platejs");
352
351
  var import_react3 = require("platejs/react");
352
+
353
+ // src/react/ai-chat/utils/acceptAISuggestions.ts
354
+ var import_suggestion2 = require("@platejs/suggestion");
355
+ var import_react2 = require("@platejs/suggestion/react");
356
+ var acceptAISuggestions = (editor) => {
357
+ const suggestions = editor.getApi(import_react2.SuggestionPlugin).suggestion.nodes({
358
+ transient: true
359
+ });
360
+ suggestions.forEach(([suggestionNode]) => {
361
+ const suggestionData = editor.getApi(import_react2.SuggestionPlugin).suggestion.suggestionData(suggestionNode);
362
+ if (!suggestionData) return;
363
+ const description = {
364
+ createdAt: new Date(suggestionData.createdAt),
365
+ keyId: (0, import_suggestion2.getSuggestionKey)(suggestionData.id),
366
+ suggestionId: suggestionData.id,
367
+ type: suggestionData.type,
368
+ userId: suggestionData.userId
369
+ };
370
+ (0, import_suggestion2.acceptSuggestion)(editor, description);
371
+ });
372
+ editor.tf.unsetNodes([(0, import_suggestion2.getTransientSuggestionKey)()], {
373
+ at: [],
374
+ mode: "all",
375
+ match: (n) => !!n[(0, import_suggestion2.getTransientSuggestionKey)()]
376
+ });
377
+ };
378
+
379
+ // src/react/ai-chat/transforms/acceptAIChat.ts
353
380
  var acceptAIChat = (editor) => {
354
381
  const mode = editor.getOption(AIChatPlugin, "mode");
355
382
  if (mode === "insert") {
@@ -370,43 +397,287 @@ var acceptAIChat = (editor) => {
370
397
  }
371
398
  if (mode === "chat") {
372
399
  withAIBatch(editor, () => {
373
- acceptSuggestions(editor);
400
+ acceptAISuggestions(editor);
374
401
  });
375
402
  editor.getApi(AIChatPlugin).aiChat.hide();
376
403
  }
377
404
  };
378
- var acceptSuggestions = (editor) => {
379
- const suggestions = editor.getApi(import_react2.SuggestionPlugin).suggestion.nodes({
405
+
406
+ // src/react/ai-chat/transforms/insertBelowAIChat.ts
407
+ var import_react11 = require("@platejs/selection/react");
408
+ var import_cloneDeep2 = __toESM(require("lodash/cloneDeep.js"));
409
+ var import_platejs12 = require("platejs");
410
+
411
+ // src/react/ai-chat/utils/applyAISuggestions.ts
412
+ var import_markdown2 = require("@platejs/markdown");
413
+ var import_react4 = require("@platejs/selection/react");
414
+ var import_suggestion3 = require("@platejs/suggestion");
415
+ var import_platejs8 = require("platejs");
416
+ var applyAISuggestions = (editor, content) => {
417
+ editor.getApi({ key: import_platejs8.KEYS.cursorOverlay })?.cursorOverlay?.removeCursor("selection");
418
+ const isBlockSelecting = editor.getOption(
419
+ import_react4.BlockSelectionPlugin,
420
+ "isSelectingSome"
421
+ );
422
+ const { chatNodes } = editor.getOptions(AIChatPlugin);
423
+ if (isBlockSelecting || editor.api.blocks({ mode: "highest" }).length > 1) {
424
+ const setReplaceIds = (ids) => {
425
+ editor.setOption(AIChatPlugin, "_replaceIds", ids);
426
+ };
427
+ if (editor.getOption(AIChatPlugin, "_replaceIds").length === 0) {
428
+ setReplaceIds(chatNodes.map((node) => node.id));
429
+ }
430
+ const diffNodes = getDiffNodes(editor, content);
431
+ const replaceNodes = Array.from(
432
+ editor.api.nodes({
433
+ at: [],
434
+ match: (n) => import_platejs8.ElementApi.isElement(n) && editor.getOption(AIChatPlugin, "_replaceIds").includes(n.id)
435
+ })
436
+ );
437
+ replaceNodes.forEach(([node, path], index) => {
438
+ const replaceNode = node;
439
+ const diffNode = diffNodes[index];
440
+ const isSameString = (0, import_suggestion3.SkipSuggestionDeletes)(editor, replaceNode) === (0, import_suggestion3.SkipSuggestionDeletes)(editor, diffNode);
441
+ const isSameSuggestion = replaceNode.suggestion?.type === diffNode.suggestion?.type;
442
+ if (index === replaceNodes.length - 1 && diffNodes.length > replaceNodes.length) {
443
+ editor.tf.replaceNodes(diffNodes.slice(index), {
444
+ at: path
445
+ });
446
+ }
447
+ if (isSameString && isSameSuggestion && node.id == diffNode.id) {
448
+ return;
449
+ }
450
+ editor.tf.replaceNodes(diffNode, {
451
+ at: path
452
+ });
453
+ });
454
+ editor.getApi(import_react4.BlockSelectionPlugin).blockSelection.set(diffNodes.map((node) => node.id));
455
+ setReplaceIds(diffNodes.map((node) => node.id));
456
+ } else {
457
+ const diffNodes = getDiffNodes(editor, content);
458
+ editor.tf.insertFragment(diffNodes);
459
+ const nodes = Array.from(
460
+ editor.api.nodes({
461
+ at: [],
462
+ mode: "lowest",
463
+ match: (n) => import_platejs8.TextApi.isText(n) && !!n[(0, import_suggestion3.getTransientSuggestionKey)()]
464
+ })
465
+ );
466
+ const range = editor.api.nodesRange(nodes);
467
+ editor.tf.setSelection(range);
468
+ return;
469
+ }
470
+ };
471
+ var withProps = (diffNodes, chatNodes) => {
472
+ return diffNodes.map((node, index) => {
473
+ if (!import_platejs8.ElementApi.isElement(node)) return node;
474
+ const originalNode = chatNodes?.[index];
475
+ return {
476
+ ...node,
477
+ ...originalNode ?? { id: (0, import_platejs8.nanoid)() },
478
+ children: node.children
479
+ };
480
+ });
481
+ };
482
+ var withTransient = (diffNodes) => {
483
+ return diffNodes.map((node) => {
484
+ if (import_platejs8.TextApi.isText(node)) {
485
+ return {
486
+ ...node,
487
+ [(0, import_suggestion3.getTransientSuggestionKey)()]: true
488
+ };
489
+ } else {
490
+ return {
491
+ ...node,
492
+ children: withTransient(node.children),
493
+ [(0, import_suggestion3.getTransientSuggestionKey)()]: true
494
+ };
495
+ }
496
+ });
497
+ };
498
+ var withoutSuggestionAndComments = (nodes) => {
499
+ return nodes.map((node) => {
500
+ if (import_platejs8.TextApi.isText(node)) {
501
+ if (node[import_platejs8.KEYS.suggestion] || node[import_platejs8.KEYS.comment]) {
502
+ return {
503
+ text: node.text
504
+ };
505
+ }
506
+ return node;
507
+ }
508
+ if (import_platejs8.ElementApi.isElement(node)) {
509
+ if (node[import_platejs8.KEYS.suggestion]) {
510
+ const nodeWithoutSuggestion = {};
511
+ Object.keys(node).forEach((key) => {
512
+ if (key !== import_platejs8.KEYS.suggestion && !key.startsWith(import_platejs8.KEYS.suggestion)) {
513
+ nodeWithoutSuggestion[key] = node[key];
514
+ }
515
+ });
516
+ return {
517
+ ...nodeWithoutSuggestion,
518
+ children: withoutSuggestionAndComments(node.children)
519
+ };
520
+ }
521
+ return {
522
+ ...node,
523
+ children: withoutSuggestionAndComments(node.children)
524
+ };
525
+ }
526
+ return node;
527
+ });
528
+ };
529
+ var getDiffNodes = (editor, aiContent) => {
530
+ const chatNodes = withoutSuggestionAndComments(
531
+ editor.getOption(AIChatPlugin, "chatNodes")
532
+ );
533
+ const aiNodes = withProps((0, import_markdown2.deserializeMd)(editor, aiContent), chatNodes);
534
+ const diffNodes = withTransient(
535
+ (0, import_suggestion3.diffToSuggestions)(editor, chatNodes, aiNodes, {
536
+ ignoreProps: ["id", "listStart"]
537
+ })
538
+ );
539
+ return diffNodes;
540
+ };
541
+
542
+ // src/react/ai-chat/utils/getLastAssistantMessage.ts
543
+ var import_react5 = require("platejs/react");
544
+ function getLastAssistantMessage(editor) {
545
+ const messages = editor.getOptions(AIChatPlugin).chat.messages;
546
+ return messages?.findLast((message) => message.role === "assistant");
547
+ }
548
+ function useLastAssistantMessage() {
549
+ const toolName = (0, import_react5.usePluginOption)(AIChatPlugin, "toolName");
550
+ const chat = (0, import_react5.usePluginOption)(AIChatPlugin, "chat");
551
+ if (toolName === "comment") return;
552
+ return chat.messages?.findLast((message) => message.role === "assistant");
553
+ }
554
+
555
+ // src/react/ai-chat/utils/rejectAISuggestions.ts
556
+ var import_suggestion4 = require("@platejs/suggestion");
557
+ var import_react6 = require("@platejs/suggestion/react");
558
+ var rejectAISuggestions = (editor) => {
559
+ const suggestions = editor.getApi(import_react6.SuggestionPlugin).suggestion.nodes({
380
560
  transient: true
381
561
  });
382
562
  suggestions.forEach(([suggestionNode]) => {
383
- const suggestionData = editor.getApi(import_react2.SuggestionPlugin).suggestion.suggestionData(suggestionNode);
563
+ const suggestionData = editor.getApi(import_react6.SuggestionPlugin).suggestion.suggestionData(suggestionNode);
384
564
  if (!suggestionData) return;
385
565
  const description = {
386
566
  createdAt: new Date(suggestionData.createdAt),
387
- keyId: (0, import_suggestion2.getSuggestionKey)(suggestionData.id),
567
+ keyId: (0, import_suggestion4.getSuggestionKey)(suggestionData.id),
388
568
  suggestionId: suggestionData.id,
389
569
  type: suggestionData.type,
390
570
  userId: suggestionData.userId
391
571
  };
392
- (0, import_suggestion2.acceptSuggestion)(editor, description);
572
+ (0, import_suggestion4.rejectSuggestion)(editor, description);
393
573
  });
394
- editor.tf.unsetNodes([(0, import_suggestion2.getTransientSuggestionKey)()], {
574
+ editor.tf.unsetNodes([(0, import_suggestion4.getTransientSuggestionKey)()], {
395
575
  at: [],
396
576
  mode: "all",
397
- match: (n) => !!n[(0, import_suggestion2.getTransientSuggestionKey)()]
577
+ match: (n) => !!n[(0, import_suggestion4.getTransientSuggestionKey)()]
398
578
  });
399
579
  };
400
580
 
401
- // src/react/ai-chat/transforms/insertBelowAIChat.ts
402
- var import_react5 = require("@platejs/selection/react");
403
- var import_cloneDeep2 = __toESM(require("lodash/cloneDeep.js"));
581
+ // src/react/ai-chat/utils/resetAIChat.ts
404
582
  var import_platejs9 = require("platejs");
583
+ var import_react7 = require("platejs/react");
584
+ var resetAIChat = (editor, { undo = true } = {}) => {
585
+ const { api, getOptions, setOptions } = (0, import_react7.getEditorPlugin)(
586
+ editor,
587
+ {
588
+ key: import_platejs9.KEYS.aiChat
589
+ }
590
+ );
591
+ api.aiChat.stop();
592
+ const chat = getOptions().chat;
593
+ if (chat.messages && chat.messages.length > 0) {
594
+ chat.setMessages?.([]);
595
+ }
596
+ setOptions({
597
+ _replaceIds: [],
598
+ chatNodes: [],
599
+ mode: "insert",
600
+ toolName: null
601
+ });
602
+ if (undo) {
603
+ editor.getTransforms(AIPlugin).ai.undo();
604
+ }
605
+ };
606
+
607
+ // src/react/ai-chat/utils/submitAIChat.ts
608
+ var import_selection2 = require("@platejs/selection");
609
+ var import_react8 = require("@platejs/selection/react");
610
+ var import_platejs10 = require("platejs");
611
+ var import_react9 = require("platejs/react");
612
+ var submitAIChat = (editor, input, {
613
+ mode,
614
+ options,
615
+ prompt,
616
+ toolName: toolNameProps
617
+ } = {}) => {
618
+ const { getOptions, setOption } = (0, import_react9.getEditorPlugin)(
619
+ editor,
620
+ {
621
+ key: import_platejs10.KEYS.aiChat
622
+ }
623
+ );
624
+ const { chat, toolName: toolNameOption } = getOptions();
625
+ const toolName = toolNameProps ?? toolNameOption ?? null;
626
+ if (!prompt && input?.length === 0) {
627
+ return;
628
+ }
629
+ if (!prompt) {
630
+ prompt = input;
631
+ }
632
+ if (!mode) {
633
+ mode = (0, import_selection2.isSelecting)(editor) ? "chat" : "insert";
634
+ }
635
+ if (mode === "insert") {
636
+ editor.getTransforms(AIPlugin).ai.undo();
637
+ }
638
+ setOption("mode", mode);
639
+ setOption("toolName", toolName);
640
+ const blocks = editor.getApi(import_react8.BlockSelectionPlugin).blockSelection.getNodes();
641
+ const blocksRange = editor.api.nodesRange(blocks);
642
+ const promptText = getEditorPrompt(editor, {
643
+ prompt
644
+ });
645
+ const selection = blocks.length > 0 ? blocksRange : editor.selection;
646
+ let chatNodes;
647
+ if (blocks.length > 0) {
648
+ chatNodes = blocks.map((block) => block[0]);
649
+ } else {
650
+ const selectionBlocks = editor.api.blocks({ mode: "highest" });
651
+ if (selectionBlocks.length > 1) {
652
+ chatNodes = selectionBlocks.map((block) => block[0]);
653
+ } else {
654
+ chatNodes = editor.api.fragment();
655
+ }
656
+ }
657
+ setOption("chatNodes", chatNodes);
658
+ setOption("chatSelection", blocks.length > 0 ? null : editor.selection);
659
+ const ctx = {
660
+ children: editor.children,
661
+ selection: selection ?? null,
662
+ toolName
663
+ };
664
+ void chat.sendMessage?.(
665
+ {
666
+ text: promptText
667
+ },
668
+ {
669
+ body: {
670
+ ctx
671
+ },
672
+ ...options
673
+ }
674
+ );
675
+ };
405
676
 
406
677
  // src/react/ai-chat/transforms/replaceSelectionAIChat.ts
407
- var import_react4 = require("@platejs/selection/react");
678
+ var import_react10 = require("@platejs/selection/react");
408
679
  var import_cloneDeep = __toESM(require("lodash/cloneDeep.js"));
409
- var import_platejs8 = require("platejs");
680
+ var import_platejs11 = require("platejs");
410
681
  var createFormattedBlocks = ({
411
682
  blocks,
412
683
  format,
@@ -414,12 +685,12 @@ var createFormattedBlocks = ({
414
685
  }) => {
415
686
  if (format === "none") return (0, import_cloneDeep.default)(blocks);
416
687
  const [sourceNode] = sourceBlock;
417
- const firstTextEntry = import_platejs8.NodeApi.firstText(sourceNode);
688
+ const firstTextEntry = import_platejs11.NodeApi.firstText(sourceNode);
418
689
  if (!firstTextEntry) return null;
419
- const blockProps = import_platejs8.NodeApi.extractProps(sourceNode);
420
- const textProps = import_platejs8.NodeApi.extractProps(firstTextEntry[0]);
690
+ const blockProps = import_platejs11.NodeApi.extractProps(sourceNode);
691
+ const textProps = import_platejs11.NodeApi.extractProps(firstTextEntry[0]);
421
692
  const applyTextFormatting = (node) => {
422
- if (import_platejs8.TextApi.isText(node)) {
693
+ if (import_platejs11.TextApi.isText(node)) {
423
694
  return { ...textProps, ...node };
424
695
  }
425
696
  if (node.children) {
@@ -443,10 +714,10 @@ var createFormattedBlocks = ({
443
714
  var replaceSelectionAIChat = (editor, sourceEditor, { format = "single" } = {}) => {
444
715
  if (!sourceEditor || sourceEditor.api.isEmpty()) return;
445
716
  const isBlockSelecting = editor.getOption(
446
- import_react4.BlockSelectionPlugin,
717
+ import_react10.BlockSelectionPlugin,
447
718
  "isSelectingSome"
448
719
  );
449
- editor.getApi({ key: import_platejs8.KEYS.ai }).aiChat.hide();
720
+ editor.getApi({ key: import_platejs11.KEYS.ai }).aiChat.hide();
450
721
  if (!isBlockSelecting) {
451
722
  const firstBlock = editor.api.node({
452
723
  block: true,
@@ -459,7 +730,7 @@ var replaceSelectionAIChat = (editor, sourceEditor, { format = "single" } = {})
459
730
  sourceBlock: firstBlock
460
731
  });
461
732
  if (!formattedBlocks2) return;
462
- if (firstBlock[0].type === import_platejs8.KEYS.codeLine && sourceEditor.children[0].type === import_platejs8.KEYS.codeBlock && sourceEditor.children.length === 1) {
733
+ if (firstBlock[0].type === import_platejs11.KEYS.codeLine && sourceEditor.children[0].type === import_platejs11.KEYS.codeBlock && sourceEditor.children.length === 1) {
463
734
  editor.tf.insertFragment(formattedBlocks2[0].children);
464
735
  } else {
465
736
  editor.tf.insertFragment(formattedBlocks2);
@@ -471,14 +742,14 @@ var replaceSelectionAIChat = (editor, sourceEditor, { format = "single" } = {})
471
742
  editor.tf.focus();
472
743
  return;
473
744
  }
474
- const blockSelectionApi = editor.getApi(import_react4.BlockSelectionPlugin).blockSelection;
745
+ const blockSelectionApi = editor.getApi(import_react10.BlockSelectionPlugin).blockSelection;
475
746
  const selectedBlocks = blockSelectionApi.getNodes();
476
747
  if (selectedBlocks.length === 0) return;
477
748
  if (format === "none" || format === "single" && selectedBlocks.length > 1) {
478
749
  editor.tf.withoutNormalizing(() => {
479
- (0, import_react4.removeBlockSelectionNodes)(editor);
750
+ (0, import_react10.removeBlockSelectionNodes)(editor);
480
751
  editor.tf.withNewBatch(() => {
481
- editor.getTransforms(import_react4.BlockSelectionPlugin).blockSelection.insertBlocksAndSelect(
752
+ editor.getTransforms(import_react10.BlockSelectionPlugin).blockSelection.insertBlocksAndSelect(
482
753
  (0, import_cloneDeep.default)(sourceEditor.children),
483
754
  {
484
755
  at: selectedBlocks[0][1]
@@ -486,7 +757,7 @@ var replaceSelectionAIChat = (editor, sourceEditor, { format = "single" } = {})
486
757
  );
487
758
  });
488
759
  });
489
- editor.getApi(import_react4.BlockSelectionPlugin).blockSelection.focus();
760
+ editor.getApi(import_react10.BlockSelectionPlugin).blockSelection.focus();
490
761
  return;
491
762
  }
492
763
  const [, firstBlockPath] = selectedBlocks[0];
@@ -497,14 +768,14 @@ var replaceSelectionAIChat = (editor, sourceEditor, { format = "single" } = {})
497
768
  });
498
769
  if (!formattedBlocks) return;
499
770
  editor.tf.withoutNormalizing(() => {
500
- (0, import_react4.removeBlockSelectionNodes)(editor);
771
+ (0, import_react10.removeBlockSelectionNodes)(editor);
501
772
  editor.tf.withNewBatch(() => {
502
- editor.getTransforms(import_react4.BlockSelectionPlugin).blockSelection.insertBlocksAndSelect(formattedBlocks, {
773
+ editor.getTransforms(import_react10.BlockSelectionPlugin).blockSelection.insertBlocksAndSelect(formattedBlocks, {
503
774
  at: firstBlockPath
504
775
  });
505
776
  });
506
777
  });
507
- editor.getApi(import_react4.BlockSelectionPlugin).blockSelection.focus();
778
+ editor.getApi(import_react10.BlockSelectionPlugin).blockSelection.focus();
508
779
  };
509
780
 
510
781
  // src/react/ai-chat/transforms/insertBelowAIChat.ts
@@ -512,192 +783,96 @@ var insertBelowAIChat = (editor, sourceEditor, { format = "single" } = {}) => {
512
783
  const { toolName } = editor.getOptions(AIChatPlugin);
513
784
  if (toolName === "generate")
514
785
  return insertBelowGenerate(editor, sourceEditor, { format });
515
- const selectedBlocks = editor.getApi(import_react5.BlockSelectionPlugin).blockSelection.getNodes();
516
- const selectedIds = editor.getOptions(import_react5.BlockSelectionPlugin).selectedIds;
786
+ const selectedBlocks = editor.getApi(import_react11.BlockSelectionPlugin).blockSelection.getNodes();
787
+ const selectedIds = editor.getOptions(import_react11.BlockSelectionPlugin).selectedIds;
517
788
  editor.getTransforms(AIPlugin).ai.undo();
518
- const insertBlocksAndSelect = editor.getTransforms(import_react5.BlockSelectionPlugin).blockSelection.insertBlocksAndSelect;
789
+ const insertBlocksAndSelect = editor.getTransforms(import_react11.BlockSelectionPlugin).blockSelection.insertBlocksAndSelect;
519
790
  if (!selectedIds || selectedIds.size === 0) return;
520
791
  const lastBlock = selectedBlocks.at(-1);
521
792
  if (!lastBlock) return;
522
- const nextPath = import_platejs9.PathApi.next(lastBlock[1]);
793
+ const nextPath = import_platejs12.PathApi.next(lastBlock[1]);
523
794
  const nodes = selectedBlocks.map((block) => block[0]);
524
795
  insertBlocksAndSelect(nodes, {
525
796
  at: nextPath,
526
- insertedCallback: () => {
527
- withAIBatch(editor, () => {
528
- acceptSuggestions(editor);
529
- });
530
- }
531
- });
532
- editor.getApi(AIChatPlugin).aiChat.hide({ focus: false });
533
- };
534
- var insertBelowGenerate = (editor, sourceEditor, { format = "single" } = {}) => {
535
- if (!sourceEditor || sourceEditor.api.isEmpty()) return;
536
- const isBlockSelecting = editor.getOption(
537
- import_react5.BlockSelectionPlugin,
538
- "isSelectingSome"
539
- );
540
- editor.getApi({ key: import_platejs9.KEYS.ai }).aiChat.hide();
541
- const insertBlocksAndSelect = editor.getTransforms(import_react5.BlockSelectionPlugin).blockSelection.insertBlocksAndSelect;
542
- if (isBlockSelecting) {
543
- const selectedBlocks = editor.getApi(import_react5.BlockSelectionPlugin).blockSelection.getNodes();
544
- const selectedIds = editor.getOptions(import_react5.BlockSelectionPlugin).selectedIds;
545
- if (!selectedIds || selectedIds.size === 0) return;
546
- const lastBlock = selectedBlocks.at(-1);
547
- if (!lastBlock) return;
548
- const nextPath = import_platejs9.PathApi.next(lastBlock[1]);
549
- if (format === "none") {
550
- insertBlocksAndSelect((0, import_cloneDeep2.default)(sourceEditor.children), {
551
- at: nextPath
552
- });
553
- return;
554
- }
555
- const formattedBlocks = createFormattedBlocks({
556
- blocks: (0, import_cloneDeep2.default)(sourceEditor.children),
557
- format,
558
- sourceBlock: lastBlock
559
- });
560
- if (!formattedBlocks) return;
561
- insertBlocksAndSelect(formattedBlocks, {
562
- at: nextPath
563
- });
564
- } else {
565
- const [, end] = import_platejs9.RangeApi.edges(editor.selection);
566
- const endPath = [end.path[0]];
567
- const currentBlock = editor.api.node({
568
- at: endPath,
569
- block: true,
570
- mode: "lowest"
571
- });
572
- if (!currentBlock) return;
573
- if (format === "none") {
574
- insertBlocksAndSelect((0, import_cloneDeep2.default)(sourceEditor.children), {
575
- at: import_platejs9.PathApi.next(endPath)
576
- });
577
- return;
578
- }
579
- const formattedBlocks = createFormattedBlocks({
580
- blocks: (0, import_cloneDeep2.default)(sourceEditor.children),
581
- format,
582
- sourceBlock: currentBlock
583
- });
584
- if (!formattedBlocks) return;
585
- insertBlocksAndSelect(formattedBlocks, {
586
- at: import_platejs9.PathApi.next(endPath)
587
- });
588
- }
589
- };
590
-
591
- // src/react/ai-chat/transforms/removeAnchorAIChat.ts
592
- var import_platejs10 = require("platejs");
593
- var removeAnchorAIChat = (editor, options) => {
594
- editor.tf.withoutSaving(() => {
595
- editor.tf.removeNodes({
596
- at: [],
597
- match: (n) => import_platejs10.ElementApi.isElement(n) && n.type === (0, import_platejs10.getPluginType)(editor, import_platejs10.KEYS.aiChat),
598
- ...options
599
- });
600
- });
601
- };
602
-
603
- // src/react/ai-chat/utils/resetAIChat.ts
604
- var import_platejs11 = require("platejs");
605
- var import_react6 = require("platejs/react");
606
- var resetAIChat = (editor, { undo = true } = {}) => {
607
- const { api, getOptions, setOptions } = (0, import_react6.getEditorPlugin)(
608
- editor,
609
- {
610
- key: import_platejs11.KEYS.aiChat
611
- }
612
- );
613
- api.aiChat.stop();
614
- const chat = getOptions().chat;
615
- if (chat.messages && chat.messages.length > 0) {
616
- chat.setMessages?.([]);
617
- }
618
- setOptions({
619
- _replaceIds: [],
620
- chatNodes: [],
621
- mode: "insert",
622
- toolName: null
623
- });
624
- if (undo) {
625
- editor.getTransforms(AIPlugin).ai.undo();
626
- }
627
- };
628
-
629
- // src/react/ai-chat/utils/submitAIChat.ts
630
- var import_selection2 = require("@platejs/selection");
631
- var import_react7 = require("@platejs/selection/react");
632
- var import_platejs12 = require("platejs");
633
- var import_react8 = require("platejs/react");
634
- var submitAIChat = (editor, input, {
635
- mode,
636
- options,
637
- prompt,
638
- toolName: toolNameProps
639
- } = {}) => {
640
- const { getOptions, setOption } = (0, import_react8.getEditorPlugin)(
641
- editor,
642
- {
643
- key: import_platejs12.KEYS.aiChat
644
- }
645
- );
646
- const { chat, toolName: toolNameOption } = getOptions();
647
- const toolName = toolNameProps ?? toolNameOption ?? null;
648
- if (!prompt && input?.length === 0) {
649
- return;
650
- }
651
- if (!prompt) {
652
- prompt = input;
653
- }
654
- if (!mode) {
655
- mode = (0, import_selection2.isSelecting)(editor) ? "chat" : "insert";
656
- }
657
- if (mode === "insert") {
658
- editor.getTransforms(AIPlugin).ai.undo();
659
- }
660
- setOption("mode", mode);
661
- setOption("toolName", toolName);
662
- const blocks = editor.getApi(import_react7.BlockSelectionPlugin).blockSelection.getNodes();
663
- const blocksRange = editor.api.nodesRange(blocks);
664
- const promptText = getEditorPrompt(editor, {
665
- prompt
797
+ insertedCallback: () => {
798
+ withAIBatch(editor, () => {
799
+ acceptAISuggestions(editor);
800
+ });
801
+ }
666
802
  });
667
- const selection = blocks.length > 0 ? blocksRange : editor.selection;
668
- let chatNodes;
669
- if (blocks.length > 0) {
670
- chatNodes = blocks.map((block) => block[0]);
803
+ editor.getApi(AIChatPlugin).aiChat.hide({ focus: false });
804
+ };
805
+ var insertBelowGenerate = (editor, sourceEditor, { format = "single" } = {}) => {
806
+ if (!sourceEditor || sourceEditor.api.isEmpty()) return;
807
+ const isBlockSelecting = editor.getOption(
808
+ import_react11.BlockSelectionPlugin,
809
+ "isSelectingSome"
810
+ );
811
+ editor.getApi({ key: import_platejs12.KEYS.ai }).aiChat.hide();
812
+ const insertBlocksAndSelect = editor.getTransforms(import_react11.BlockSelectionPlugin).blockSelection.insertBlocksAndSelect;
813
+ if (isBlockSelecting) {
814
+ const selectedBlocks = editor.getApi(import_react11.BlockSelectionPlugin).blockSelection.getNodes();
815
+ const selectedIds = editor.getOptions(import_react11.BlockSelectionPlugin).selectedIds;
816
+ if (!selectedIds || selectedIds.size === 0) return;
817
+ const lastBlock = selectedBlocks.at(-1);
818
+ if (!lastBlock) return;
819
+ const nextPath = import_platejs12.PathApi.next(lastBlock[1]);
820
+ if (format === "none") {
821
+ insertBlocksAndSelect((0, import_cloneDeep2.default)(sourceEditor.children), {
822
+ at: nextPath
823
+ });
824
+ return;
825
+ }
826
+ const formattedBlocks = createFormattedBlocks({
827
+ blocks: (0, import_cloneDeep2.default)(sourceEditor.children),
828
+ format,
829
+ sourceBlock: lastBlock
830
+ });
831
+ if (!formattedBlocks) return;
832
+ insertBlocksAndSelect(formattedBlocks, {
833
+ at: nextPath
834
+ });
671
835
  } else {
672
- const selectionBlocks = editor.api.blocks({ mode: "highest" });
673
- if (selectionBlocks.length > 1) {
674
- chatNodes = selectionBlocks.map((block) => block[0]);
675
- } else {
676
- chatNodes = editor.api.fragment();
836
+ const [, end] = import_platejs12.RangeApi.edges(editor.selection);
837
+ const endPath = [end.path[0]];
838
+ const currentBlock = editor.api.node({
839
+ at: endPath,
840
+ block: true,
841
+ mode: "lowest"
842
+ });
843
+ if (!currentBlock) return;
844
+ if (format === "none") {
845
+ insertBlocksAndSelect((0, import_cloneDeep2.default)(sourceEditor.children), {
846
+ at: import_platejs12.PathApi.next(endPath)
847
+ });
848
+ return;
677
849
  }
850
+ const formattedBlocks = createFormattedBlocks({
851
+ blocks: (0, import_cloneDeep2.default)(sourceEditor.children),
852
+ format,
853
+ sourceBlock: currentBlock
854
+ });
855
+ if (!formattedBlocks) return;
856
+ insertBlocksAndSelect(formattedBlocks, {
857
+ at: import_platejs12.PathApi.next(endPath)
858
+ });
678
859
  }
679
- setOption("chatNodes", chatNodes);
680
- setOption("chatSelection", blocks.length > 0 ? null : editor.selection);
681
- const ctx = {
682
- children: editor.children,
683
- selection: selection ?? null,
684
- toolName
685
- };
686
- void chat.sendMessage?.(
687
- {
688
- text: promptText
689
- },
690
- {
691
- body: {
692
- ctx
693
- },
860
+ };
861
+
862
+ // src/react/ai-chat/transforms/removeAnchorAIChat.ts
863
+ var import_platejs13 = require("platejs");
864
+ var removeAnchorAIChat = (editor, options) => {
865
+ editor.tf.withoutSaving(() => {
866
+ editor.tf.removeNodes({
867
+ at: [],
868
+ match: (n) => import_platejs13.ElementApi.isElement(n) && n.type === (0, import_platejs13.getPluginType)(editor, import_platejs13.KEYS.aiChat),
694
869
  ...options
695
- }
696
- );
870
+ });
871
+ });
697
872
  };
698
873
 
699
874
  // src/react/ai-chat/withAIChat.ts
700
- var import_platejs13 = require("platejs");
875
+ var import_platejs14 = require("platejs");
701
876
  var withAIChat = ({
702
877
  api,
703
878
  editor,
@@ -739,11 +914,11 @@ var withAIChat = ({
739
914
  },
740
915
  normalizeNode(entry) {
741
916
  const [node, path] = entry;
742
- if (node[import_platejs13.KEYS.ai] && !getOptions().open) {
917
+ if (node[import_platejs14.KEYS.ai] && !getOptions().open) {
743
918
  tf.ai.removeMarks({ at: path });
744
919
  return;
745
920
  }
746
- if (import_platejs13.ElementApi.isElement(node) && node.type === type && !getOptions().open) {
921
+ if (import_platejs14.ElementApi.isElement(node) && node.type === type && !getOptions().open) {
747
922
  editor.getTransforms(AIChatPlugin).aiChat.removeAnchor({ at: path });
748
923
  return;
749
924
  }
@@ -754,8 +929,8 @@ var withAIChat = ({
754
929
  };
755
930
 
756
931
  // src/react/ai-chat/AIChatPlugin.ts
757
- var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
758
- key: import_platejs14.KEYS.aiChat,
932
+ var AIChatPlugin = (0, import_react13.createTPlatePlugin)({
933
+ key: import_platejs15.KEYS.aiChat,
759
934
  dependencies: ["ai"],
760
935
  node: {
761
936
  isElement: true
@@ -779,14 +954,14 @@ var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
779
954
  }
780
955
  }).overrideEditor(withAIChat).extendApi(({ editor, getOption, getOptions, setOption, type }) => {
781
956
  return {
782
- reset: (0, import_platejs14.bindFirst)(resetAIChat, editor),
783
- submit: (0, import_platejs14.bindFirst)(submitAIChat, editor),
957
+ reset: (0, import_platejs15.bindFirst)(resetAIChat, editor),
958
+ submit: (0, import_platejs15.bindFirst)(submitAIChat, editor),
784
959
  node: (options = {}) => {
785
960
  const { anchor = false, streaming = false, ...rest } = options;
786
961
  if (anchor) {
787
962
  return editor.api.node({
788
963
  at: [],
789
- match: (n) => import_platejs14.ElementApi.isElement(n) && n.type === type,
964
+ match: (n) => import_platejs15.ElementApi.isElement(n) && n.type === type,
790
965
  ...rest
791
966
  });
792
967
  }
@@ -798,12 +973,12 @@ var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
798
973
  at: path,
799
974
  mode: "lowest",
800
975
  reverse: true,
801
- match: (t) => !!t[(0, import_platejs14.getPluginType)(editor, import_platejs14.KEYS.ai)],
976
+ match: (t) => !!t[(0, import_platejs15.getPluginType)(editor, import_platejs15.KEYS.ai)],
802
977
  ...rest
803
978
  });
804
979
  }
805
980
  return editor.api.node({
806
- match: (n) => n[(0, import_platejs14.getPluginType)(editor, import_platejs14.KEYS.ai)],
981
+ match: (n) => n[(0, import_platejs15.getPluginType)(editor, import_platejs15.KEYS.ai)],
807
982
  ...rest
808
983
  });
809
984
  },
@@ -813,9 +988,9 @@ var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
813
988
  if (chatSelection) {
814
989
  editor.tf.setSelection(chatSelection);
815
990
  } else {
816
- editor.getApi(import_react9.BlockSelectionPlugin).blockSelection.set(chatNodes.map((node) => node.id));
991
+ editor.getApi(import_react12.BlockSelectionPlugin).blockSelection.set(chatNodes.map((node) => node.id));
817
992
  }
818
- const blocks = editor.getApi(import_react9.BlockSelectionPlugin).blockSelection.getNodes();
993
+ const blocks = editor.getApi(import_react12.BlockSelectionPlugin).blockSelection.getNodes();
819
994
  const selection = blocks.length > 0 ? editor.api.nodesRange(blocks) : editor.selection;
820
995
  const ctx = {
821
996
  children: editor.children,
@@ -841,8 +1016,8 @@ var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
841
1016
  api.aiChat.reset({ undo });
842
1017
  setOption("open", false);
843
1018
  if (focus) {
844
- if (editor.getOption(import_react9.BlockSelectionPlugin, "isSelectingSome")) {
845
- editor.getApi(import_react9.BlockSelectionPlugin).blockSelection.focus();
1019
+ if (editor.getOption(import_react12.BlockSelectionPlugin, "isSelectingSome")) {
1020
+ editor.getApi(import_react12.BlockSelectionPlugin).blockSelection.focus();
846
1021
  } else {
847
1022
  editor.tf.focus();
848
1023
  }
@@ -860,21 +1035,21 @@ var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
860
1035
  setOption("open", true);
861
1036
  }
862
1037
  })).extendTransforms(({ editor }) => ({
863
- accept: (0, import_platejs14.bindFirst)(acceptAIChat, editor),
864
- insertBelow: (0, import_platejs14.bindFirst)(insertBelowAIChat, editor),
865
- removeAnchor: (0, import_platejs14.bindFirst)(removeAnchorAIChat, editor),
866
- replaceSelection: (0, import_platejs14.bindFirst)(replaceSelectionAIChat, editor)
1038
+ accept: (0, import_platejs15.bindFirst)(acceptAIChat, editor),
1039
+ insertBelow: (0, import_platejs15.bindFirst)(insertBelowAIChat, editor),
1040
+ removeAnchor: (0, import_platejs15.bindFirst)(removeAnchorAIChat, editor),
1041
+ replaceSelection: (0, import_platejs15.bindFirst)(replaceSelectionAIChat, editor)
867
1042
  }));
868
1043
 
869
1044
  // src/react/ai-chat/hooks/useAIChatEditor.ts
870
- var import_react11 = require("react");
871
- var import_markdown2 = require("@platejs/markdown");
872
- var import_react12 = require("platejs/react");
1045
+ var import_react14 = require("react");
1046
+ var import_markdown3 = require("@platejs/markdown");
1047
+ var import_react15 = require("platejs/react");
873
1048
  var useAIChatEditor = (editor, content, { parser } = {}) => {
874
- const { setOption } = (0, import_react12.useEditorPlugin)(AIChatPlugin);
875
- editor.children = (0, import_react11.useMemo)(
1049
+ const { setOption } = (0, import_react15.useEditorPlugin)(AIChatPlugin);
1050
+ editor.children = (0, import_react14.useMemo)(
876
1051
  () => {
877
- return editor.getApi(import_markdown2.MarkdownPlugin).markdown.deserialize(content, {
1052
+ return editor.getApi(import_markdown3.MarkdownPlugin).markdown.deserialize(content, {
878
1053
  memoize: true,
879
1054
  parser
880
1055
  });
@@ -882,45 +1057,30 @@ var useAIChatEditor = (editor, content, { parser } = {}) => {
882
1057
  // eslint-disable-next-line react-hooks/exhaustive-deps
883
1058
  [content]
884
1059
  );
885
- (0, import_react11.useEffect)(() => {
1060
+ (0, import_react14.useEffect)(() => {
886
1061
  setOption("aiEditor", editor);
887
1062
  }, [editor, setOption]);
888
1063
  };
889
1064
 
890
1065
  // src/react/ai-chat/hooks/useChatChunk.ts
891
- var import_react14 = require("react");
892
- var import_platejs15 = require("platejs");
893
- var import_react15 = require("platejs/react");
894
-
895
- // src/react/ai-chat/utils/getLastAssistantMessage.ts
896
- var import_react13 = require("platejs/react");
897
- function getLastAssistantMessage(editor) {
898
- const messages = editor.getOptions(AIChatPlugin).chat.messages;
899
- return messages?.findLast((message) => message.role === "assistant");
900
- }
901
- function useLastAssistantMessage() {
902
- const toolName = (0, import_react13.usePluginOption)(AIChatPlugin, "toolName");
903
- const chat = (0, import_react13.usePluginOption)(AIChatPlugin, "chat");
904
- if (toolName === "comment") return;
905
- return chat.messages?.findLast((message) => message.role === "assistant");
906
- }
907
-
908
- // src/react/ai-chat/hooks/useChatChunk.ts
1066
+ var import_react16 = require("react");
1067
+ var import_platejs16 = require("platejs");
1068
+ var import_react17 = require("platejs/react");
909
1069
  var useChatChunk = ({
910
1070
  onChunk,
911
1071
  onFinish
912
1072
  }) => {
913
- const { status } = (0, import_react15.usePluginOption)(
914
- { key: import_platejs15.KEYS.aiChat },
1073
+ const { status } = (0, import_react17.usePluginOption)(
1074
+ { key: import_platejs16.KEYS.aiChat },
915
1075
  "chat"
916
1076
  );
917
1077
  const isLoading = status === "streaming" || status === "submitted";
918
1078
  const content = useLastAssistantMessage()?.parts.find(
919
1079
  (part) => part.type === "text"
920
1080
  )?.text;
921
- const insertedTextRef = (0, import_react14.useRef)("");
922
- const prevIsLoadingRef = (0, import_react14.useRef)(isLoading);
923
- (0, import_react14.useEffect)(() => {
1081
+ const insertedTextRef = (0, import_react16.useRef)("");
1082
+ const prevIsLoadingRef = (0, import_react16.useRef)(isLoading);
1083
+ (0, import_react16.useEffect)(() => {
924
1084
  if (!isLoading) {
925
1085
  insertedTextRef.current = "";
926
1086
  }
@@ -929,7 +1089,7 @@ var useChatChunk = ({
929
1089
  }
930
1090
  prevIsLoadingRef.current = isLoading;
931
1091
  }, [isLoading]);
932
- (0, import_react14.useEffect)(() => {
1092
+ (0, import_react16.useEffect)(() => {
933
1093
  if (!content) {
934
1094
  return;
935
1095
  }
@@ -950,9 +1110,9 @@ var useChatChunk = ({
950
1110
  };
951
1111
 
952
1112
  // src/react/ai-chat/hooks/useEditorChat.ts
953
- var import_react16 = require("react");
954
- var import_react17 = require("@platejs/selection/react");
955
- var import_react18 = require("platejs/react");
1113
+ var import_react18 = require("react");
1114
+ var import_react19 = require("@platejs/selection/react");
1115
+ var import_react20 = require("platejs/react");
956
1116
  var useEditorChat = ({
957
1117
  chat,
958
1118
  onOpenBlockSelection,
@@ -960,15 +1120,15 @@ var useEditorChat = ({
960
1120
  onOpenCursor,
961
1121
  onOpenSelection
962
1122
  }) => {
963
- const { editor } = (0, import_react18.useEditorPlugin)(AIChatPlugin);
964
- const open = (0, import_react18.usePluginOption)(AIChatPlugin, "open");
965
- (0, import_react16.useEffect)(() => {
1123
+ const { editor } = (0, import_react20.useEditorPlugin)(AIChatPlugin);
1124
+ const open = (0, import_react20.usePluginOption)(AIChatPlugin, "open");
1125
+ (0, import_react18.useEffect)(() => {
966
1126
  onOpenChange?.(open);
967
1127
  if (open) {
968
1128
  if (onOpenBlockSelection) {
969
- const blockSelectionApi = editor.getApi(import_react17.BlockSelectionPlugin).blockSelection;
1129
+ const blockSelectionApi = editor.getApi(import_react19.BlockSelectionPlugin).blockSelection;
970
1130
  const isBlockSelecting = editor.getOption(
971
- import_react17.BlockSelectionPlugin,
1131
+ import_react19.BlockSelectionPlugin,
972
1132
  "isSelectingSome"
973
1133
  );
974
1134
  if (isBlockSelecting) {
@@ -989,14 +1149,14 @@ var useEditorChat = ({
989
1149
  };
990
1150
 
991
1151
  // src/react/ai-chat/streaming/streamDeserializeInlineMd.ts
992
- var import_markdown3 = require("@platejs/markdown");
1152
+ var import_markdown4 = require("@platejs/markdown");
993
1153
  var streamDeserializeInlineMd = (editor, text, options) => {
994
- return editor.getApi(import_markdown3.MarkdownPlugin).markdown.deserializeInline(text, options);
1154
+ return editor.getApi(import_markdown4.MarkdownPlugin).markdown.deserializeInline(text, options);
995
1155
  };
996
1156
 
997
1157
  // src/react/ai-chat/streaming/streamDeserializeMd.ts
998
- var import_markdown4 = require("@platejs/markdown");
999
- var import_platejs18 = require("platejs");
1158
+ var import_markdown5 = require("@platejs/markdown");
1159
+ var import_platejs19 = require("platejs");
1000
1160
 
1001
1161
  // src/react/ai-chat/streaming/utils/utils.ts
1002
1162
  var getChunkTrimmed = (chunk, {
@@ -1051,22 +1211,22 @@ var getListNode = (editor, node) => {
1051
1211
  };
1052
1212
 
1053
1213
  // src/react/ai-chat/streaming/utils/isSameNode.ts
1054
- var import_platejs16 = require("platejs");
1214
+ var import_platejs17 = require("platejs");
1055
1215
  var LIST_STYLE_TYPE = "listStyleType";
1056
1216
  var isSameNode = (editor, node1, node2) => {
1057
- if (node1.type !== editor.getType(import_platejs16.KEYS.p) || node2.type !== editor.getType(import_platejs16.KEYS.p))
1217
+ if (node1.type !== editor.getType(import_platejs17.KEYS.p) || node2.type !== editor.getType(import_platejs17.KEYS.p))
1058
1218
  return node1.type === node2.type;
1059
- if ((0, import_platejs16.isDefined)(node1[LIST_STYLE_TYPE]) || (0, import_platejs16.isDefined)(node2[LIST_STYLE_TYPE])) {
1219
+ if ((0, import_platejs17.isDefined)(node1[LIST_STYLE_TYPE]) || (0, import_platejs17.isDefined)(node2[LIST_STYLE_TYPE])) {
1060
1220
  return node1[LIST_STYLE_TYPE] === node2[LIST_STYLE_TYPE];
1061
1221
  }
1062
1222
  return node1.type === node2.type;
1063
1223
  };
1064
1224
 
1065
1225
  // src/react/ai-chat/streaming/utils/nodesWithProps.ts
1066
- var import_platejs17 = require("platejs");
1226
+ var import_platejs18 = require("platejs");
1067
1227
  var nodesWithProps = (editor, nodes, options) => {
1068
1228
  return nodes.map((node) => {
1069
- if (import_platejs17.ElementApi.isElement(node)) {
1229
+ if (import_platejs18.ElementApi.isElement(node)) {
1070
1230
  return {
1071
1231
  ...getListNode(editor, node),
1072
1232
  ...options.elementProps,
@@ -1089,7 +1249,7 @@ var streamDeserializeMd = (editor, data, options) => {
1089
1249
  const value = withoutDeserializeInMdx(editor, input);
1090
1250
  if (Array.isArray(value)) return value;
1091
1251
  let blocks = [];
1092
- blocks = editor.getApi(import_markdown4.MarkdownPlugin).markdown.deserialize(input, {
1252
+ blocks = editor.getApi(import_markdown5.MarkdownPlugin).markdown.deserialize(input, {
1093
1253
  ...options,
1094
1254
  preserveEmptyParagraphs: false
1095
1255
  });
@@ -1106,7 +1266,7 @@ var streamDeserializeMd = (editor, data, options) => {
1106
1266
  }
1107
1267
  ];
1108
1268
  const lastChild = lastBlock.children.at(-1);
1109
- if (lastChild && import_platejs18.TextApi.isText(lastChild) && Object.keys(lastChild).length === 1) {
1269
+ if (lastChild && import_platejs19.TextApi.isText(lastChild) && Object.keys(lastChild).length === 1) {
1110
1270
  lastBlock.children.pop();
1111
1271
  const textNode2 = [
1112
1272
  {
@@ -1122,13 +1282,13 @@ var streamDeserializeMd = (editor, data, options) => {
1122
1282
  if (addNewLine && !isCodeBlockOrTable) {
1123
1283
  result.push({
1124
1284
  children: [{ text: "" }],
1125
- type: import_platejs18.KEYS.p
1285
+ type: import_platejs19.KEYS.p
1126
1286
  });
1127
1287
  }
1128
1288
  if (unshiftNewLine && !isCodeBlockOrTable) {
1129
1289
  result.unshift({
1130
1290
  children: [{ text: "" }],
1131
- type: import_platejs18.KEYS.p
1291
+ type: import_platejs19.KEYS.p
1132
1292
  });
1133
1293
  }
1134
1294
  return result;
@@ -1148,7 +1308,7 @@ var withoutDeserializeInMdx = (editor, input) => {
1148
1308
  text: input
1149
1309
  }
1150
1310
  ],
1151
- type: (0, import_platejs18.getPluginType)(editor, import_platejs18.KEYS.p)
1311
+ type: (0, import_platejs19.getPluginType)(editor, import_platejs19.KEYS.p)
1152
1312
  }
1153
1313
  ];
1154
1314
  }
@@ -1161,26 +1321,26 @@ var withoutDeserializeInMdx = (editor, input) => {
1161
1321
  };
1162
1322
 
1163
1323
  // src/react/ai-chat/streaming/streamInsertChunk.ts
1164
- var import_platejs20 = require("platejs");
1324
+ var import_platejs21 = require("platejs");
1165
1325
 
1166
1326
  // src/react/ai-chat/streaming/streamSerializeMd.ts
1167
- var import_markdown5 = require("@platejs/markdown");
1168
- var import_platejs19 = require("platejs");
1327
+ var import_markdown6 = require("@platejs/markdown");
1328
+ var import_platejs20 = require("platejs");
1169
1329
  var trimEndHeading = (editor, value) => {
1170
1330
  const headingKeys = /* @__PURE__ */ new Set([
1171
- import_platejs19.KEYS.h1,
1172
- import_platejs19.KEYS.h2,
1173
- import_platejs19.KEYS.h3,
1174
- import_platejs19.KEYS.h4,
1175
- import_platejs19.KEYS.h5,
1176
- import_platejs19.KEYS.h6
1331
+ import_platejs20.KEYS.h1,
1332
+ import_platejs20.KEYS.h2,
1333
+ import_platejs20.KEYS.h3,
1334
+ import_platejs20.KEYS.h4,
1335
+ import_platejs20.KEYS.h5,
1336
+ import_platejs20.KEYS.h6
1177
1337
  ]);
1178
1338
  const lastBlock = value.at(-1);
1179
1339
  if (lastBlock && headingKeys.has(
1180
- (0, import_platejs19.getPluginKey)(editor, lastBlock.type) ?? lastBlock.type
1181
- ) && import_platejs19.ElementApi.isElement(lastBlock)) {
1340
+ (0, import_platejs20.getPluginKey)(editor, lastBlock.type) ?? lastBlock.type
1341
+ ) && import_platejs20.ElementApi.isElement(lastBlock)) {
1182
1342
  const lastTextNode = lastBlock.children.at(-1);
1183
- if (import_platejs19.TextApi.isText(lastTextNode)) {
1343
+ if (import_platejs20.TextApi.isText(lastTextNode)) {
1184
1344
  const trimmedText = getChunkTrimmed(lastTextNode?.text);
1185
1345
  const newChildren = [
1186
1346
  ...lastBlock.children.slice(0, -1),
@@ -1202,7 +1362,7 @@ var streamSerializeMd = (editor, options, chunk) => {
1202
1362
  const { value: optionsValue, ...restOptions } = options;
1203
1363
  const { value } = trimEndHeading(editor, optionsValue ?? editor.children);
1204
1364
  let result = "";
1205
- result = editor.getApi(import_markdown5.MarkdownPlugin).markdown.serialize({
1365
+ result = editor.getApi(import_markdown6.MarkdownPlugin).markdown.serialize({
1206
1366
  value,
1207
1367
  ...restOptions
1208
1368
  });
@@ -1234,7 +1394,7 @@ var streamSerializeMd = (editor, options, chunk) => {
1234
1394
  var getNextPath = (path, length) => {
1235
1395
  let result = path;
1236
1396
  for (let i = 0; i < length; i++) {
1237
- result = import_platejs20.PathApi.next(result);
1397
+ result = import_platejs21.PathApi.next(result);
1238
1398
  }
1239
1399
  return result;
1240
1400
  };
@@ -1244,7 +1404,7 @@ function streamInsertChunk(editor, chunk, options = {}) {
1244
1404
  const blocks = streamDeserializeMd(editor, chunk);
1245
1405
  const path = getCurrentBlockPath(editor);
1246
1406
  const startBlock = editor.api.node(path)[0];
1247
- const startInEmptyParagraph = import_platejs20.NodeApi.string(startBlock).length === 0 && startBlock.type === (0, import_platejs20.getPluginType)(editor, import_platejs20.KEYS.p);
1407
+ const startInEmptyParagraph = import_platejs21.NodeApi.string(startBlock).length === 0 && startBlock.type === (0, import_platejs21.getPluginType)(editor, import_platejs21.KEYS.p);
1248
1408
  if (startInEmptyParagraph) {
1249
1409
  editor.tf.removeNodes({ at: path });
1250
1410
  }
@@ -1302,7 +1462,7 @@ function streamInsertChunk(editor, chunk, options = {}) {
1302
1462
  },
1303
1463
  tempBlockChunks
1304
1464
  );
1305
- const blockText = import_platejs20.NodeApi.string(tempBlocks[0]);
1465
+ const blockText = import_platejs21.NodeApi.string(tempBlocks[0]);
1306
1466
  if (serializedBlock === tempBlockChunks && blockText === serializedBlock) {
1307
1467
  editor.setOption(AIChatPlugin, "_blockChunks", tempBlockChunks);
1308
1468
  } else {
@@ -1324,7 +1484,7 @@ function streamInsertChunk(editor, chunk, options = {}) {
1324
1484
  AIChatPlugin,
1325
1485
  "_blockChunks",
1326
1486
  // one block includes multiple children
1327
- tempBlocks[0].type === (0, import_platejs20.getPluginType)(editor, import_platejs20.KEYS.codeBlock) || tempBlocks[0].type === (0, import_platejs20.getPluginType)(editor, import_platejs20.KEYS.table) || tempBlocks[0].type === (0, import_platejs20.getPluginType)(editor, import_platejs20.KEYS.equation) ? tempBlockChunks : serializedBlock2
1487
+ tempBlocks[0].type === (0, import_platejs21.getPluginType)(editor, import_platejs21.KEYS.codeBlock) || tempBlocks[0].type === (0, import_platejs21.getPluginType)(editor, import_platejs21.KEYS.table) || tempBlocks[0].type === (0, import_platejs21.getPluginType)(editor, import_platejs21.KEYS.equation) ? tempBlockChunks : serializedBlock2
1328
1488
  );
1329
1489
  }
1330
1490
  } else {
@@ -1354,7 +1514,7 @@ function streamInsertChunk(editor, chunk, options = {}) {
1354
1514
  editor.tf.insertNodes(
1355
1515
  nodesWithProps(editor, tempBlocks.slice(1), options),
1356
1516
  {
1357
- at: import_platejs20.PathApi.next(_blockPath),
1517
+ at: import_platejs21.PathApi.next(_blockPath),
1358
1518
  select: true
1359
1519
  }
1360
1520
  );
@@ -1376,7 +1536,7 @@ var getCurrentBlockPath = (editor) => {
1376
1536
  const getAnchorPreviousPath = (editor2) => {
1377
1537
  const anchorNode = editor2.getApi(AIChatPlugin).aiChat.node({ anchor: true });
1378
1538
  if (anchorNode) {
1379
- return import_platejs20.PathApi.previous(anchorNode[1]);
1539
+ return import_platejs21.PathApi.previous(anchorNode[1]);
1380
1540
  }
1381
1541
  };
1382
1542
  const getFocusPath = (editor2) => {
@@ -1384,163 +1544,32 @@ var getCurrentBlockPath = (editor) => {
1384
1544
  };
1385
1545
  const path = getAnchorPreviousPath(editor) ?? getFocusPath(editor) ?? [0];
1386
1546
  const entry = editor.api.node(path);
1387
- if (entry && (entry[0].type === (0, import_platejs20.getPluginType)(editor, import_platejs20.KEYS.columnGroup) || entry[0].type === (0, import_platejs20.getPluginType)(editor, import_platejs20.KEYS.table))) {
1547
+ if (entry && (entry[0].type === (0, import_platejs21.getPluginType)(editor, import_platejs21.KEYS.columnGroup) || entry[0].type === (0, import_platejs21.getPluginType)(editor, import_platejs21.KEYS.table))) {
1388
1548
  return editor.api.above()?.[1] ?? path;
1389
1549
  }
1390
1550
  return path;
1391
1551
  };
1392
1552
 
1393
- // src/react/ai-chat/utils/applyAISuggestions.ts
1394
- var import_markdown6 = require("@platejs/markdown");
1395
- var import_react19 = require("@platejs/selection/react");
1396
- var import_suggestion3 = require("@platejs/suggestion");
1397
- var import_platejs21 = require("platejs");
1398
- var applyAISuggestions = (editor, content) => {
1399
- editor.getApi({ key: import_platejs21.KEYS.cursorOverlay })?.cursorOverlay?.removeCursor("selection");
1400
- const isBlockSelecting = editor.getOption(
1401
- import_react19.BlockSelectionPlugin,
1402
- "isSelectingSome"
1403
- );
1404
- const { chatNodes } = editor.getOptions(AIChatPlugin);
1405
- if (isBlockSelecting || editor.api.blocks({ mode: "highest" }).length > 1) {
1406
- const setReplaceIds = (ids) => {
1407
- editor.setOption(AIChatPlugin, "_replaceIds", ids);
1408
- };
1409
- if (editor.getOption(AIChatPlugin, "_replaceIds").length === 0) {
1410
- setReplaceIds(chatNodes.map((node) => node.id));
1411
- }
1412
- const diffNodes = getDiffNodes(editor, content);
1413
- const replaceNodes = Array.from(
1414
- editor.api.nodes({
1415
- at: [],
1416
- match: (n) => import_platejs21.ElementApi.isElement(n) && editor.getOption(AIChatPlugin, "_replaceIds").includes(n.id)
1417
- })
1418
- );
1419
- replaceNodes.forEach(([node, path], index) => {
1420
- const replaceNode = node;
1421
- const diffNode = diffNodes[index];
1422
- const isSameString = (0, import_suggestion3.SkipSuggestionDeletes)(editor, replaceNode) === (0, import_suggestion3.SkipSuggestionDeletes)(editor, diffNode);
1423
- const isSameSuggestion = replaceNode.suggestion?.type === diffNode.suggestion?.type;
1424
- if (index === replaceNodes.length - 1 && diffNodes.length > replaceNodes.length) {
1425
- editor.tf.replaceNodes(diffNodes.slice(index), {
1426
- at: path
1427
- });
1428
- }
1429
- if (isSameString && isSameSuggestion && node.id == diffNode.id) {
1430
- return;
1431
- }
1432
- editor.tf.replaceNodes(diffNode, {
1433
- at: path
1434
- });
1435
- });
1436
- editor.getApi(import_react19.BlockSelectionPlugin).blockSelection.set(diffNodes.map((node) => node.id));
1437
- setReplaceIds(diffNodes.map((node) => node.id));
1438
- } else {
1439
- const diffNodes = getDiffNodes(editor, content);
1440
- editor.tf.insertFragment(diffNodes);
1441
- const nodes = Array.from(
1442
- editor.api.nodes({
1443
- at: [],
1444
- mode: "lowest",
1445
- match: (n) => import_platejs21.TextApi.isText(n) && !!n[(0, import_suggestion3.getTransientSuggestionKey)()]
1446
- })
1447
- );
1448
- const range = editor.api.nodesRange(nodes);
1449
- editor.tf.setSelection(range);
1450
- return;
1451
- }
1452
- };
1453
- var withProps = (diffNodes, chatNodes) => {
1454
- return diffNodes.map((node, index) => {
1455
- if (!import_platejs21.ElementApi.isElement(node)) return node;
1456
- const originalNode = chatNodes?.[index];
1457
- return {
1458
- ...node,
1459
- ...originalNode ?? { id: (0, import_platejs21.nanoid)() },
1460
- children: node.children
1461
- };
1462
- });
1463
- };
1464
- var withTransient = (diffNodes) => {
1465
- return diffNodes.map((node) => {
1466
- if (import_platejs21.TextApi.isText(node)) {
1467
- return {
1468
- ...node,
1469
- [(0, import_suggestion3.getTransientSuggestionKey)()]: true
1470
- };
1471
- } else {
1472
- return {
1473
- ...node,
1474
- children: withTransient(node.children),
1475
- [(0, import_suggestion3.getTransientSuggestionKey)()]: true
1476
- };
1477
- }
1478
- });
1479
- };
1480
- var withoutSuggestionAndComments = (nodes) => {
1481
- return nodes.map((node) => {
1482
- if (import_platejs21.TextApi.isText(node)) {
1483
- if (node[import_platejs21.KEYS.suggestion] || node[import_platejs21.KEYS.comment]) {
1484
- return {
1485
- text: node.text
1486
- };
1487
- }
1488
- return node;
1489
- }
1490
- if (import_platejs21.ElementApi.isElement(node)) {
1491
- if (node[import_platejs21.KEYS.suggestion]) {
1492
- const nodeWithoutSuggestion = {};
1493
- Object.keys(node).forEach((key) => {
1494
- if (key !== import_platejs21.KEYS.suggestion && !key.startsWith(import_platejs21.KEYS.suggestion)) {
1495
- nodeWithoutSuggestion[key] = node[key];
1496
- }
1497
- });
1498
- return {
1499
- ...nodeWithoutSuggestion,
1500
- children: withoutSuggestionAndComments(node.children)
1501
- };
1502
- }
1503
- return {
1504
- ...node,
1505
- children: withoutSuggestionAndComments(node.children)
1506
- };
1507
- }
1508
- return node;
1509
- });
1510
- };
1511
- var getDiffNodes = (editor, aiContent) => {
1512
- const chatNodes = withoutSuggestionAndComments(
1513
- editor.getOption(AIChatPlugin, "chatNodes")
1514
- );
1515
- const aiNodes = withProps((0, import_markdown6.deserializeMd)(editor, aiContent), chatNodes);
1516
- const diffNodes = withTransient(
1517
- (0, import_suggestion3.diffToSuggestions)(editor, chatNodes, aiNodes, {
1518
- ignoreProps: ["id", "listStart"]
1519
- })
1520
- );
1521
- return diffNodes;
1522
- };
1523
-
1524
1553
  // src/react/copilot/CopilotPlugin.tsx
1525
1554
  var import_markdown10 = require("@platejs/markdown");
1526
1555
  var import_debounce = __toESM(require("lodash/debounce.js"));
1527
1556
  var import_platejs27 = require("platejs");
1528
- var import_react24 = require("platejs/react");
1557
+ var import_react25 = require("platejs/react");
1529
1558
 
1530
1559
  // src/react/copilot/renderCopilotBelowNodes.tsx
1531
- var import_react20 = __toESM(require("react"));
1560
+ var import_react21 = __toESM(require("react"));
1532
1561
  var import_platejs22 = require("platejs");
1533
- var import_react21 = require("platejs/react");
1562
+ var import_react22 = require("platejs/react");
1534
1563
  var renderCopilotBelowNodes = ({
1535
1564
  editor
1536
1565
  }) => {
1537
- const copilot = (0, import_react21.getEditorPlugin)(editor, {
1566
+ const copilot = (0, import_react22.getEditorPlugin)(editor, {
1538
1567
  key: import_platejs22.KEYS.copilot
1539
1568
  });
1540
1569
  const { renderGhostText: GhostText } = copilot.getOptions();
1541
1570
  if (!GhostText) return;
1542
1571
  return ({ children }) => {
1543
- return /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, children, /* @__PURE__ */ import_react20.default.createElement(GhostText, null));
1572
+ return /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, children, /* @__PURE__ */ import_react21.default.createElement(GhostText, null));
1544
1573
  };
1545
1574
  };
1546
1575
 
@@ -1558,7 +1587,7 @@ var acceptCopilot = (editor) => {
1558
1587
  // src/react/copilot/transforms/acceptCopilotNextWord.ts
1559
1588
  var import_markdown8 = require("@platejs/markdown");
1560
1589
  var import_platejs25 = require("platejs");
1561
- var import_react23 = require("platejs/react");
1590
+ var import_react24 = require("platejs/react");
1562
1591
 
1563
1592
  // src/react/copilot/utils/callCompletionApi.ts
1564
1593
  var getOriginalFetch = () => fetch;
@@ -1676,9 +1705,9 @@ var getNextWord = ({ text }) => {
1676
1705
 
1677
1706
  // src/react/copilot/utils/triggerCopilotSuggestion.ts
1678
1707
  var import_platejs24 = require("platejs");
1679
- var import_react22 = require("platejs/react");
1708
+ var import_react23 = require("platejs/react");
1680
1709
  var triggerCopilotSuggestion = async (editor) => {
1681
- const { api, getOptions, setOption } = (0, import_react22.getEditorPlugin)(
1710
+ const { api, getOptions, setOption } = (0, import_react23.getEditorPlugin)(
1682
1711
  editor,
1683
1712
  {
1684
1713
  key: import_platejs24.KEYS.copilot
@@ -1718,7 +1747,7 @@ var withoutAbort = (editor, fn) => {
1718
1747
 
1719
1748
  // src/react/copilot/transforms/acceptCopilotNextWord.ts
1720
1749
  var acceptCopilotNextWord = (editor) => {
1721
- const { api, getOptions } = (0, import_react23.getEditorPlugin)(editor, {
1750
+ const { api, getOptions } = (0, import_react24.getEditorPlugin)(editor, {
1722
1751
  key: import_platejs25.KEYS.copilot
1723
1752
  });
1724
1753
  const { getNextWord: getNextWord2, suggestionText } = getOptions();
@@ -1832,7 +1861,7 @@ var withCopilot = ({
1832
1861
  };
1833
1862
 
1834
1863
  // src/react/copilot/CopilotPlugin.tsx
1835
- var CopilotPlugin = (0, import_react24.createTPlatePlugin)({
1864
+ var CopilotPlugin = (0, import_react25.createTPlatePlugin)({
1836
1865
  key: import_platejs27.KEYS.copilot,
1837
1866
  handlers: {
1838
1867
  onBlur: ({ api }) => {
@@ -1944,9 +1973,9 @@ var CopilotPlugin = (0, import_react24.createTPlatePlugin)({
1944
1973
  AIPlugin,
1945
1974
  CopilotPlugin,
1946
1975
  acceptAIChat,
1976
+ acceptAISuggestions,
1947
1977
  acceptCopilot,
1948
1978
  acceptCopilotNextWord,
1949
- acceptSuggestions,
1950
1979
  aiCommentToRange,
1951
1980
  applyAISuggestions,
1952
1981
  callCompletionApi,
@@ -1964,6 +1993,7 @@ var CopilotPlugin = (0, import_react24.createTPlatePlugin)({
1964
1993
  isCompleteMath,
1965
1994
  isSameNode,
1966
1995
  nodesWithProps,
1996
+ rejectAISuggestions,
1967
1997
  removeAnchorAIChat,
1968
1998
  renderCopilotBelowNodes,
1969
1999
  replaceSelectionAIChat,