@platejs/ai 49.1.12 → 49.2.4
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 +4 -4
package/dist/index.js
CHANGED
|
@@ -52,7 +52,7 @@ __export(index_exports, {
|
|
|
52
52
|
module.exports = __toCommonJS(index_exports);
|
|
53
53
|
|
|
54
54
|
// src/lib/BaseAIPlugin.ts
|
|
55
|
-
var
|
|
55
|
+
var import_platejs3 = require("platejs");
|
|
56
56
|
|
|
57
57
|
// src/lib/transforms/insertAINodes.ts
|
|
58
58
|
var insertAINodes = (editor, nodes, {
|
|
@@ -73,19 +73,21 @@ var insertAINodes = (editor, nodes, {
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
// src/lib/transforms/removeAIMarks.ts
|
|
76
|
+
var import_platejs = require("platejs");
|
|
76
77
|
var removeAIMarks = (editor, { at = [] } = {}) => {
|
|
77
|
-
editor.
|
|
78
|
+
const nodeType = (0, import_platejs.getPluginType)(editor, import_platejs.KEYS.ai);
|
|
79
|
+
editor.tf.unsetNodes(nodeType, {
|
|
78
80
|
at,
|
|
79
|
-
match: (n) => n
|
|
81
|
+
match: (n) => n[nodeType]
|
|
80
82
|
});
|
|
81
83
|
};
|
|
82
84
|
|
|
83
85
|
// src/lib/transforms/removeAINodes.ts
|
|
84
|
-
var
|
|
86
|
+
var import_platejs2 = require("platejs");
|
|
85
87
|
var removeAINodes = (editor, { at = [] } = {}) => {
|
|
86
88
|
editor.tf.removeNodes({
|
|
87
89
|
at,
|
|
88
|
-
match: (n) =>
|
|
90
|
+
match: (n) => import_platejs2.TextApi.isText(n) && !!n.ai
|
|
89
91
|
});
|
|
90
92
|
};
|
|
91
93
|
|
|
@@ -116,14 +118,14 @@ var withAIBatch = (editor, fn, {
|
|
|
116
118
|
};
|
|
117
119
|
|
|
118
120
|
// src/lib/BaseAIPlugin.ts
|
|
119
|
-
var BaseAIPlugin = (0,
|
|
120
|
-
key:
|
|
121
|
+
var BaseAIPlugin = (0, import_platejs3.createTSlatePlugin)({
|
|
122
|
+
key: import_platejs3.KEYS.ai,
|
|
121
123
|
node: { isDecoration: false, isLeaf: true }
|
|
122
124
|
}).extendTransforms(({ editor }) => ({
|
|
123
|
-
insertNodes: (0,
|
|
124
|
-
removeMarks: (0,
|
|
125
|
-
removeNodes: (0,
|
|
126
|
-
undo: (0,
|
|
125
|
+
insertNodes: (0, import_platejs3.bindFirst)(insertAINodes, editor),
|
|
126
|
+
removeMarks: (0, import_platejs3.bindFirst)(removeAIMarks, editor),
|
|
127
|
+
removeNodes: (0, import_platejs3.bindFirst)(removeAINodes, editor),
|
|
128
|
+
undo: (0, import_platejs3.bindFirst)(undoAI, editor)
|
|
127
129
|
}));
|
|
128
130
|
|
|
129
131
|
// src/lib/streaming/streamDeserializeInlineMd.ts
|
|
@@ -133,144 +135,8 @@ var streamDeserializeInlineMd = (editor, text, options) => {
|
|
|
133
135
|
};
|
|
134
136
|
|
|
135
137
|
// src/lib/streaming/streamDeserializeMd.ts
|
|
136
|
-
var
|
|
137
|
-
var
|
|
138
|
-
|
|
139
|
-
// src/lib/streaming/utils/escapeInput.ts
|
|
140
|
-
var escapeInput = (data) => {
|
|
141
|
-
let res = data;
|
|
142
|
-
if (data.startsWith("$$") && !data.startsWith("$$\n") && !isCompleteMath(data)) {
|
|
143
|
-
res = data.replace("$$", String.raw`\$\$`);
|
|
144
|
-
}
|
|
145
|
-
return res;
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
// src/lib/streaming/utils/getListNode.ts
|
|
149
|
-
var getListNode = (editor, node) => {
|
|
150
|
-
if (node.listStyleType && node.listStart) {
|
|
151
|
-
const previousNode = editor.api.previous({
|
|
152
|
-
at: editor.selection?.focus
|
|
153
|
-
})?.[0];
|
|
154
|
-
if (previousNode?.listStyleType && previousNode?.listStart) {
|
|
155
|
-
return node;
|
|
156
|
-
} else {
|
|
157
|
-
if (node.listStart === 1) return node;
|
|
158
|
-
return {
|
|
159
|
-
...node,
|
|
160
|
-
listRestartPolite: node.listStart
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return node;
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
// src/lib/streaming/utils/isSameNode.ts
|
|
168
|
-
var import_platejs3 = require("platejs");
|
|
169
|
-
var LIST_STYLE_TYPE = "listStyleType";
|
|
170
|
-
var isSameNode = (editor, node1, node2) => {
|
|
171
|
-
if (node1.type !== editor.getType(import_platejs3.KEYS.p) || node2.type !== editor.getType(import_platejs3.KEYS.p))
|
|
172
|
-
return node1.type === node2.type;
|
|
173
|
-
if ((0, import_platejs3.isDefined)(node1[LIST_STYLE_TYPE]) || (0, import_platejs3.isDefined)(node2[LIST_STYLE_TYPE])) {
|
|
174
|
-
return node1[LIST_STYLE_TYPE] === node2[LIST_STYLE_TYPE];
|
|
175
|
-
}
|
|
176
|
-
return node1.type === node2.type;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
// src/lib/streaming/utils/nodesWithProps.ts
|
|
180
|
-
var import_platejs4 = require("platejs");
|
|
181
|
-
var nodesWithProps = (editor, nodes, options) => {
|
|
182
|
-
return nodes.map((node) => {
|
|
183
|
-
if (import_platejs4.ElementApi.isElement(node)) {
|
|
184
|
-
return {
|
|
185
|
-
...getListNode(editor, node),
|
|
186
|
-
...options.elementProps,
|
|
187
|
-
children: nodesWithProps(editor, node.children, options)
|
|
188
|
-
};
|
|
189
|
-
} else {
|
|
190
|
-
return {
|
|
191
|
-
...options.textProps,
|
|
192
|
-
...node,
|
|
193
|
-
text: node.text
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
// src/lib/streaming/utils/utils.ts
|
|
200
|
-
var getChunkTrimmed = (chunk, {
|
|
201
|
-
direction = "right"
|
|
202
|
-
} = {}) => {
|
|
203
|
-
const str = direction === "right" ? chunk.trimEnd() : chunk.trimStart();
|
|
204
|
-
if (direction === "right") {
|
|
205
|
-
return chunk.slice(str.length);
|
|
206
|
-
} else {
|
|
207
|
-
return chunk.slice(0, chunk.length - str.length);
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
function isCompleteCodeBlock(str) {
|
|
211
|
-
const trimmed = str.trim();
|
|
212
|
-
const startsWithCodeBlock = trimmed.startsWith("```");
|
|
213
|
-
const endsWithCodeBlock = trimmed.endsWith("```");
|
|
214
|
-
return startsWithCodeBlock && endsWithCodeBlock;
|
|
215
|
-
}
|
|
216
|
-
function isCompleteMath(str) {
|
|
217
|
-
const trimmed = str.trim();
|
|
218
|
-
const startsWithMath = trimmed.startsWith("$$");
|
|
219
|
-
const endsWithMath = trimmed.endsWith("$$");
|
|
220
|
-
return startsWithMath && endsWithMath;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// src/lib/streaming/streamDeserializeMd.ts
|
|
224
|
-
var streamDeserializeMd = (editor, data, options) => {
|
|
225
|
-
const input = escapeInput(data);
|
|
226
|
-
let blocks = [];
|
|
227
|
-
blocks = editor.getApi(import_markdown2.MarkdownPlugin).markdown.deserialize(input, {
|
|
228
|
-
...options,
|
|
229
|
-
preserveEmptyParagraphs: false
|
|
230
|
-
});
|
|
231
|
-
const trimmedData = getChunkTrimmed(data);
|
|
232
|
-
const lastBlock = blocks.at(-1);
|
|
233
|
-
const addNewLine = trimmedData === "\n\n";
|
|
234
|
-
const unshiftNewLine = getChunkTrimmed(data, { direction: "left" }) === "\n\n";
|
|
235
|
-
const isCodeBlockOrTable = lastBlock?.type === "code_block" || lastBlock?.type === "table";
|
|
236
|
-
let result = blocks;
|
|
237
|
-
if (lastBlock && !isCodeBlockOrTable && trimmedData.length > 0 && !addNewLine) {
|
|
238
|
-
const textNode = [
|
|
239
|
-
{
|
|
240
|
-
text: trimmedData
|
|
241
|
-
}
|
|
242
|
-
];
|
|
243
|
-
const lastChild = lastBlock.children.at(-1);
|
|
244
|
-
if (lastChild && import_platejs5.TextApi.isText(lastChild) && Object.keys(lastChild).length === 1) {
|
|
245
|
-
lastBlock.children.pop();
|
|
246
|
-
const textNode2 = [
|
|
247
|
-
{
|
|
248
|
-
text: lastChild.text + trimmedData
|
|
249
|
-
}
|
|
250
|
-
];
|
|
251
|
-
lastBlock.children.push(...textNode2);
|
|
252
|
-
} else {
|
|
253
|
-
lastBlock.children.push(...textNode);
|
|
254
|
-
}
|
|
255
|
-
result = [...blocks.slice(0, -1), lastBlock];
|
|
256
|
-
}
|
|
257
|
-
if (addNewLine && !isCodeBlockOrTable) {
|
|
258
|
-
result.push({
|
|
259
|
-
children: [{ text: "" }],
|
|
260
|
-
type: import_platejs5.KEYS.p
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
if (unshiftNewLine && !isCodeBlockOrTable) {
|
|
264
|
-
result.unshift({
|
|
265
|
-
children: [{ text: "" }],
|
|
266
|
-
type: import_platejs5.KEYS.p
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
return result;
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
// src/lib/streaming/streamInsertChunk.ts
|
|
273
|
-
var import_platejs16 = require("platejs");
|
|
138
|
+
var import_markdown3 = require("@platejs/markdown");
|
|
139
|
+
var import_platejs15 = require("platejs");
|
|
274
140
|
|
|
275
141
|
// src/react/ai/AIPlugin.ts
|
|
276
142
|
var import_react = require("platejs/react");
|
|
@@ -278,15 +144,15 @@ var AIPlugin = (0, import_react.toPlatePlugin)(BaseAIPlugin);
|
|
|
278
144
|
|
|
279
145
|
// src/react/ai-chat/AIChatPlugin.ts
|
|
280
146
|
var import_react9 = require("@platejs/selection/react");
|
|
281
|
-
var
|
|
147
|
+
var import_platejs12 = require("platejs");
|
|
282
148
|
var import_react10 = require("platejs/react");
|
|
283
149
|
|
|
284
150
|
// src/react/ai-chat/transforms/acceptAIChat.ts
|
|
285
|
-
var
|
|
151
|
+
var import_platejs4 = require("platejs");
|
|
286
152
|
var import_react2 = require("platejs/react");
|
|
287
153
|
var acceptAIChat = (editor) => {
|
|
288
154
|
const { tf } = (0, import_react2.getEditorPlugin)(editor, AIPlugin);
|
|
289
|
-
const api = editor.getApi({ key:
|
|
155
|
+
const api = editor.getApi({ key: import_platejs4.KEYS.ai });
|
|
290
156
|
const lastAINodePath = api.aiChat.node({ at: [], reverse: true })[1];
|
|
291
157
|
withAIBatch(editor, () => {
|
|
292
158
|
tf.ai.removeMarks();
|
|
@@ -304,12 +170,12 @@ var acceptAIChat = (editor) => {
|
|
|
304
170
|
// src/react/ai-chat/transforms/insertBelowAIChat.ts
|
|
305
171
|
var import_react4 = require("@platejs/selection/react");
|
|
306
172
|
var import_cloneDeep2 = __toESM(require("lodash/cloneDeep.js"));
|
|
307
|
-
var
|
|
173
|
+
var import_platejs6 = require("platejs");
|
|
308
174
|
|
|
309
175
|
// src/react/ai-chat/transforms/replaceSelectionAIChat.ts
|
|
310
176
|
var import_react3 = require("@platejs/selection/react");
|
|
311
177
|
var import_cloneDeep = __toESM(require("lodash/cloneDeep.js"));
|
|
312
|
-
var
|
|
178
|
+
var import_platejs5 = require("platejs");
|
|
313
179
|
var createFormattedBlocks = ({
|
|
314
180
|
blocks,
|
|
315
181
|
format,
|
|
@@ -317,12 +183,12 @@ var createFormattedBlocks = ({
|
|
|
317
183
|
}) => {
|
|
318
184
|
if (format === "none") return (0, import_cloneDeep.default)(blocks);
|
|
319
185
|
const [sourceNode] = sourceBlock;
|
|
320
|
-
const firstTextEntry =
|
|
186
|
+
const firstTextEntry = import_platejs5.NodeApi.firstText(sourceNode);
|
|
321
187
|
if (!firstTextEntry) return null;
|
|
322
|
-
const blockProps =
|
|
323
|
-
const textProps =
|
|
188
|
+
const blockProps = import_platejs5.NodeApi.extractProps(sourceNode);
|
|
189
|
+
const textProps = import_platejs5.NodeApi.extractProps(firstTextEntry[0]);
|
|
324
190
|
const applyTextFormatting = (node) => {
|
|
325
|
-
if (
|
|
191
|
+
if (import_platejs5.TextApi.isText(node)) {
|
|
326
192
|
return { ...textProps, ...node };
|
|
327
193
|
}
|
|
328
194
|
if (node.children) {
|
|
@@ -349,7 +215,7 @@ var replaceSelectionAIChat = (editor, sourceEditor, { format = "single" } = {})
|
|
|
349
215
|
import_react3.BlockSelectionPlugin,
|
|
350
216
|
"isSelectingSome"
|
|
351
217
|
);
|
|
352
|
-
editor.getApi({ key:
|
|
218
|
+
editor.getApi({ key: import_platejs5.KEYS.ai }).aiChat.hide();
|
|
353
219
|
if (!isBlockSelecting) {
|
|
354
220
|
const firstBlock = editor.api.node({
|
|
355
221
|
block: true,
|
|
@@ -413,7 +279,7 @@ var insertBelowAIChat = (editor, sourceEditor, { format = "single" } = {}) => {
|
|
|
413
279
|
import_react4.BlockSelectionPlugin,
|
|
414
280
|
"isSelectingSome"
|
|
415
281
|
);
|
|
416
|
-
editor.getApi({ key:
|
|
282
|
+
editor.getApi({ key: import_platejs6.KEYS.ai }).aiChat.hide();
|
|
417
283
|
const insertBlocksAndSelect = editor.getTransforms(import_react4.BlockSelectionPlugin).blockSelection.insertBlocksAndSelect;
|
|
418
284
|
if (isBlockSelecting) {
|
|
419
285
|
const selectedBlocks = editor.getApi(import_react4.BlockSelectionPlugin).blockSelection.getNodes();
|
|
@@ -421,7 +287,7 @@ var insertBelowAIChat = (editor, sourceEditor, { format = "single" } = {}) => {
|
|
|
421
287
|
if (!selectedIds || selectedIds.size === 0) return;
|
|
422
288
|
const lastBlock = selectedBlocks.at(-1);
|
|
423
289
|
if (!lastBlock) return;
|
|
424
|
-
const nextPath =
|
|
290
|
+
const nextPath = import_platejs6.PathApi.next(lastBlock[1]);
|
|
425
291
|
if (format === "none") {
|
|
426
292
|
insertBlocksAndSelect((0, import_cloneDeep2.default)(sourceEditor.children), {
|
|
427
293
|
at: nextPath
|
|
@@ -438,7 +304,7 @@ var insertBelowAIChat = (editor, sourceEditor, { format = "single" } = {}) => {
|
|
|
438
304
|
at: nextPath
|
|
439
305
|
});
|
|
440
306
|
} else {
|
|
441
|
-
const [, end] =
|
|
307
|
+
const [, end] = import_platejs6.RangeApi.edges(editor.selection);
|
|
442
308
|
const endPath = [end.path[0]];
|
|
443
309
|
const currentBlock = editor.api.node({
|
|
444
310
|
at: endPath,
|
|
@@ -448,7 +314,7 @@ var insertBelowAIChat = (editor, sourceEditor, { format = "single" } = {}) => {
|
|
|
448
314
|
if (!currentBlock) return;
|
|
449
315
|
if (format === "none") {
|
|
450
316
|
insertBlocksAndSelect((0, import_cloneDeep2.default)(sourceEditor.children), {
|
|
451
|
-
at:
|
|
317
|
+
at: import_platejs6.PathApi.next(endPath)
|
|
452
318
|
});
|
|
453
319
|
return;
|
|
454
320
|
}
|
|
@@ -459,18 +325,18 @@ var insertBelowAIChat = (editor, sourceEditor, { format = "single" } = {}) => {
|
|
|
459
325
|
});
|
|
460
326
|
if (!formattedBlocks) return;
|
|
461
327
|
insertBlocksAndSelect(formattedBlocks, {
|
|
462
|
-
at:
|
|
328
|
+
at: import_platejs6.PathApi.next(endPath)
|
|
463
329
|
});
|
|
464
330
|
}
|
|
465
331
|
};
|
|
466
332
|
|
|
467
333
|
// src/react/ai-chat/transforms/removeAnchorAIChat.ts
|
|
468
|
-
var
|
|
334
|
+
var import_platejs7 = require("platejs");
|
|
469
335
|
var removeAnchorAIChat = (editor, options) => {
|
|
470
336
|
editor.tf.withoutSaving(() => {
|
|
471
337
|
editor.tf.removeNodes({
|
|
472
338
|
at: [],
|
|
473
|
-
match: (n) =>
|
|
339
|
+
match: (n) => import_platejs7.ElementApi.isElement(n) && n.type === (0, import_platejs7.getPluginType)(editor, import_platejs7.KEYS.aiChat),
|
|
474
340
|
...options
|
|
475
341
|
});
|
|
476
342
|
});
|
|
@@ -481,12 +347,12 @@ var import_selection = require("@platejs/selection");
|
|
|
481
347
|
var import_react6 = require("@platejs/selection/react");
|
|
482
348
|
|
|
483
349
|
// src/react/ai-chat/utils/getMarkdown.ts
|
|
484
|
-
var
|
|
350
|
+
var import_markdown2 = require("@platejs/markdown");
|
|
485
351
|
var import_react5 = require("@platejs/selection/react");
|
|
486
|
-
var
|
|
352
|
+
var import_platejs8 = require("platejs");
|
|
487
353
|
var getMarkdown = (editor, type) => {
|
|
488
354
|
if (type === "editor") {
|
|
489
|
-
return (0,
|
|
355
|
+
return (0, import_markdown2.serializeMd)(editor);
|
|
490
356
|
}
|
|
491
357
|
if (type === "block") {
|
|
492
358
|
const blocks = editor.getOption(import_react5.BlockSelectionPlugin, "isSelectingSome") ? editor.getApi(import_react5.BlockSelectionPlugin).blockSelection.getNodes() : editor.api.nodes({
|
|
@@ -494,7 +360,7 @@ var getMarkdown = (editor, type) => {
|
|
|
494
360
|
match: (n) => editor.api.isBlock(n)
|
|
495
361
|
});
|
|
496
362
|
const nodes = Array.from(blocks, (entry) => entry[0]);
|
|
497
|
-
return (0,
|
|
363
|
+
return (0, import_markdown2.serializeMd)(editor, { value: nodes });
|
|
498
364
|
}
|
|
499
365
|
if (type === "selection") {
|
|
500
366
|
const fragment = editor.api.fragment();
|
|
@@ -502,12 +368,12 @@ var getMarkdown = (editor, type) => {
|
|
|
502
368
|
const modifiedFragment = [
|
|
503
369
|
{
|
|
504
370
|
children: fragment[0].children,
|
|
505
|
-
type:
|
|
371
|
+
type: import_platejs8.KEYS.p
|
|
506
372
|
}
|
|
507
373
|
];
|
|
508
|
-
return (0,
|
|
374
|
+
return (0, import_markdown2.serializeMd)(editor, { value: modifiedFragment });
|
|
509
375
|
}
|
|
510
|
-
return (0,
|
|
376
|
+
return (0, import_markdown2.serializeMd)(editor, { value: fragment });
|
|
511
377
|
}
|
|
512
378
|
return "";
|
|
513
379
|
};
|
|
@@ -564,11 +430,11 @@ var getEditorPrompt = (editor, {
|
|
|
564
430
|
};
|
|
565
431
|
|
|
566
432
|
// src/react/ai-chat/utils/resetAIChat.ts
|
|
567
|
-
var
|
|
433
|
+
var import_platejs9 = require("platejs");
|
|
568
434
|
var import_react7 = require("platejs/react");
|
|
569
435
|
var resetAIChat = (editor) => {
|
|
570
436
|
const { api, getOptions } = (0, import_react7.getEditorPlugin)(editor, {
|
|
571
|
-
key:
|
|
437
|
+
key: import_platejs9.KEYS.aiChat
|
|
572
438
|
});
|
|
573
439
|
api.aiChat.stop();
|
|
574
440
|
const chat = getOptions().chat;
|
|
@@ -580,7 +446,7 @@ var resetAIChat = (editor) => {
|
|
|
580
446
|
|
|
581
447
|
// src/react/ai-chat/utils/submitAIChat.ts
|
|
582
448
|
var import_selection2 = require("@platejs/selection");
|
|
583
|
-
var
|
|
449
|
+
var import_platejs10 = require("platejs");
|
|
584
450
|
var import_react8 = require("platejs/react");
|
|
585
451
|
var submitAIChat = (editor, {
|
|
586
452
|
mode,
|
|
@@ -591,7 +457,7 @@ var submitAIChat = (editor, {
|
|
|
591
457
|
const { getOptions, setOption } = (0, import_react8.getEditorPlugin)(
|
|
592
458
|
editor,
|
|
593
459
|
{
|
|
594
|
-
key:
|
|
460
|
+
key: import_platejs10.KEYS.aiChat
|
|
595
461
|
}
|
|
596
462
|
);
|
|
597
463
|
const { chat, promptTemplate, systemTemplate } = getOptions();
|
|
@@ -630,7 +496,7 @@ var submitAIChat = (editor, {
|
|
|
630
496
|
};
|
|
631
497
|
|
|
632
498
|
// src/react/ai-chat/withAIChat.ts
|
|
633
|
-
var
|
|
499
|
+
var import_platejs11 = require("platejs");
|
|
634
500
|
var withAIChat = ({
|
|
635
501
|
api,
|
|
636
502
|
editor,
|
|
@@ -672,11 +538,11 @@ var withAIChat = ({
|
|
|
672
538
|
},
|
|
673
539
|
normalizeNode(entry) {
|
|
674
540
|
const [node, path] = entry;
|
|
675
|
-
if (node[
|
|
541
|
+
if (node[import_platejs11.KEYS.ai] && !getOptions().open) {
|
|
676
542
|
tf.ai.removeMarks({ at: path });
|
|
677
543
|
return;
|
|
678
544
|
}
|
|
679
|
-
if (
|
|
545
|
+
if (import_platejs11.ElementApi.isElement(node) && node.type === type && !getOptions().open) {
|
|
680
546
|
editor.getTransforms(AIChatPlugin).aiChat.removeAnchor({ at: path });
|
|
681
547
|
return;
|
|
682
548
|
}
|
|
@@ -688,7 +554,7 @@ var withAIChat = ({
|
|
|
688
554
|
|
|
689
555
|
// src/react/ai-chat/AIChatPlugin.ts
|
|
690
556
|
var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
|
|
691
|
-
key:
|
|
557
|
+
key: import_platejs12.KEYS.aiChat,
|
|
692
558
|
dependencies: ["ai"],
|
|
693
559
|
node: {
|
|
694
560
|
isElement: true
|
|
@@ -696,6 +562,7 @@ var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
|
|
|
696
562
|
options: {
|
|
697
563
|
_blockChunks: "",
|
|
698
564
|
_blockPath: null,
|
|
565
|
+
_mdxName: null,
|
|
699
566
|
aiEditor: null,
|
|
700
567
|
chat: { messages: [] },
|
|
701
568
|
experimental_lastTextId: null,
|
|
@@ -710,14 +577,14 @@ var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
|
|
|
710
577
|
}
|
|
711
578
|
}).overrideEditor(withAIChat).extendApi(({ editor, getOption, getOptions, setOption, type }) => {
|
|
712
579
|
return {
|
|
713
|
-
reset: (0,
|
|
714
|
-
submit: (0,
|
|
580
|
+
reset: (0, import_platejs12.bindFirst)(resetAIChat, editor),
|
|
581
|
+
submit: (0, import_platejs12.bindFirst)(submitAIChat, editor),
|
|
715
582
|
node: (options = {}) => {
|
|
716
583
|
const { anchor = false, streaming = false, ...rest } = options;
|
|
717
584
|
if (anchor) {
|
|
718
585
|
return editor.api.node({
|
|
719
586
|
at: [],
|
|
720
|
-
match: (n) =>
|
|
587
|
+
match: (n) => import_platejs12.ElementApi.isElement(n) && n.type === type,
|
|
721
588
|
...rest
|
|
722
589
|
});
|
|
723
590
|
}
|
|
@@ -729,12 +596,12 @@ var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
|
|
|
729
596
|
at: path,
|
|
730
597
|
mode: "lowest",
|
|
731
598
|
reverse: true,
|
|
732
|
-
match: (t) => !!t.ai,
|
|
599
|
+
match: (t) => !!t[(0, import_platejs12.getPluginType)(editor, import_platejs12.KEYS.ai)],
|
|
733
600
|
...rest
|
|
734
601
|
});
|
|
735
602
|
}
|
|
736
603
|
return editor.api.node({
|
|
737
|
-
match: (n) => n.ai,
|
|
604
|
+
match: (n) => n[(0, import_platejs12.getPluginType)(editor, import_platejs12.KEYS.ai)],
|
|
738
605
|
...rest
|
|
739
606
|
});
|
|
740
607
|
},
|
|
@@ -776,21 +643,195 @@ var AIChatPlugin = (0, import_react10.createTPlatePlugin)({
|
|
|
776
643
|
setOption("open", true);
|
|
777
644
|
}
|
|
778
645
|
})).extendTransforms(({ editor }) => ({
|
|
779
|
-
accept: (0,
|
|
780
|
-
insertBelow: (0,
|
|
781
|
-
removeAnchor: (0,
|
|
782
|
-
replaceSelection: (0,
|
|
646
|
+
accept: (0, import_platejs12.bindFirst)(acceptAIChat, editor),
|
|
647
|
+
insertBelow: (0, import_platejs12.bindFirst)(insertBelowAIChat, editor),
|
|
648
|
+
removeAnchor: (0, import_platejs12.bindFirst)(removeAnchorAIChat, editor),
|
|
649
|
+
replaceSelection: (0, import_platejs12.bindFirst)(replaceSelectionAIChat, editor)
|
|
783
650
|
}));
|
|
784
651
|
|
|
652
|
+
// src/lib/streaming/utils/escapeInput.ts
|
|
653
|
+
var escapeInput = (data) => {
|
|
654
|
+
let res = data;
|
|
655
|
+
if (data.startsWith("$$") && !data.startsWith("$$\n") && !isCompleteMath(data)) {
|
|
656
|
+
res = data.replace("$$", String.raw`\$\$`);
|
|
657
|
+
}
|
|
658
|
+
return res;
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
// src/lib/streaming/utils/getListNode.ts
|
|
662
|
+
var getListNode = (editor, node) => {
|
|
663
|
+
if (node.listStyleType && node.listStart) {
|
|
664
|
+
const previousNode = editor.api.previous({
|
|
665
|
+
at: editor.selection?.focus
|
|
666
|
+
})?.[0];
|
|
667
|
+
if (previousNode?.listStyleType && previousNode?.listStart) {
|
|
668
|
+
return node;
|
|
669
|
+
} else {
|
|
670
|
+
if (node.listStart === 1) return node;
|
|
671
|
+
return {
|
|
672
|
+
...node,
|
|
673
|
+
listRestartPolite: node.listStart
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
return node;
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
// src/lib/streaming/utils/isSameNode.ts
|
|
681
|
+
var import_platejs13 = require("platejs");
|
|
682
|
+
var LIST_STYLE_TYPE = "listStyleType";
|
|
683
|
+
var isSameNode = (editor, node1, node2) => {
|
|
684
|
+
if (node1.type !== editor.getType(import_platejs13.KEYS.p) || node2.type !== editor.getType(import_platejs13.KEYS.p))
|
|
685
|
+
return node1.type === node2.type;
|
|
686
|
+
if ((0, import_platejs13.isDefined)(node1[LIST_STYLE_TYPE]) || (0, import_platejs13.isDefined)(node2[LIST_STYLE_TYPE])) {
|
|
687
|
+
return node1[LIST_STYLE_TYPE] === node2[LIST_STYLE_TYPE];
|
|
688
|
+
}
|
|
689
|
+
return node1.type === node2.type;
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
// src/lib/streaming/utils/nodesWithProps.ts
|
|
693
|
+
var import_platejs14 = require("platejs");
|
|
694
|
+
var nodesWithProps = (editor, nodes, options) => {
|
|
695
|
+
return nodes.map((node) => {
|
|
696
|
+
if (import_platejs14.ElementApi.isElement(node)) {
|
|
697
|
+
return {
|
|
698
|
+
...getListNode(editor, node),
|
|
699
|
+
...options.elementProps,
|
|
700
|
+
children: nodesWithProps(editor, node.children, options)
|
|
701
|
+
};
|
|
702
|
+
} else {
|
|
703
|
+
return {
|
|
704
|
+
...options.textProps,
|
|
705
|
+
...node,
|
|
706
|
+
text: node.text
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
// src/lib/streaming/utils/utils.ts
|
|
713
|
+
var getChunkTrimmed = (chunk, {
|
|
714
|
+
direction = "right"
|
|
715
|
+
} = {}) => {
|
|
716
|
+
const str = direction === "right" ? chunk.trimEnd() : chunk.trimStart();
|
|
717
|
+
if (direction === "right") {
|
|
718
|
+
return chunk.slice(str.length);
|
|
719
|
+
} else {
|
|
720
|
+
return chunk.slice(0, chunk.length - str.length);
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
function isCompleteCodeBlock(str) {
|
|
724
|
+
const trimmed = str.trim();
|
|
725
|
+
const startsWithCodeBlock = trimmed.startsWith("```");
|
|
726
|
+
const endsWithCodeBlock = trimmed.endsWith("```");
|
|
727
|
+
return startsWithCodeBlock && endsWithCodeBlock;
|
|
728
|
+
}
|
|
729
|
+
function isCompleteMath(str) {
|
|
730
|
+
const trimmed = str.trim();
|
|
731
|
+
const startsWithMath = trimmed.startsWith("$$");
|
|
732
|
+
const endsWithMath = trimmed.endsWith("$$");
|
|
733
|
+
return startsWithMath && endsWithMath;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// src/lib/streaming/streamDeserializeMd.ts
|
|
737
|
+
var statMdxTagRegex = /<([A-Za-z][A-Za-z0-9\-_]*)>/;
|
|
738
|
+
var streamDeserializeMd = (editor, data, options) => {
|
|
739
|
+
const input = escapeInput(data);
|
|
740
|
+
const value = withoutDeserializeInMdx(editor, input);
|
|
741
|
+
if (Array.isArray(value)) return value;
|
|
742
|
+
let blocks = [];
|
|
743
|
+
blocks = editor.getApi(import_markdown3.MarkdownPlugin).markdown.deserialize(input, {
|
|
744
|
+
...options,
|
|
745
|
+
preserveEmptyParagraphs: false
|
|
746
|
+
});
|
|
747
|
+
const trimmedData = getChunkTrimmed(data);
|
|
748
|
+
const lastBlock = blocks.at(-1);
|
|
749
|
+
const addNewLine = trimmedData === "\n\n";
|
|
750
|
+
const unshiftNewLine = getChunkTrimmed(data, { direction: "left" }) === "\n\n";
|
|
751
|
+
const isCodeBlockOrTable = lastBlock?.type === "code_block" || lastBlock?.type === "table";
|
|
752
|
+
let result = blocks;
|
|
753
|
+
if (lastBlock && !isCodeBlockOrTable && trimmedData.length > 0 && !addNewLine) {
|
|
754
|
+
const textNode = [
|
|
755
|
+
{
|
|
756
|
+
text: trimmedData
|
|
757
|
+
}
|
|
758
|
+
];
|
|
759
|
+
const lastChild = lastBlock.children.at(-1);
|
|
760
|
+
if (lastChild && import_platejs15.TextApi.isText(lastChild) && Object.keys(lastChild).length === 1) {
|
|
761
|
+
lastBlock.children.pop();
|
|
762
|
+
const textNode2 = [
|
|
763
|
+
{
|
|
764
|
+
text: lastChild.text + trimmedData
|
|
765
|
+
}
|
|
766
|
+
];
|
|
767
|
+
lastBlock.children.push(...textNode2);
|
|
768
|
+
} else {
|
|
769
|
+
lastBlock.children.push(...textNode);
|
|
770
|
+
}
|
|
771
|
+
result = [...blocks.slice(0, -1), lastBlock];
|
|
772
|
+
}
|
|
773
|
+
if (addNewLine && !isCodeBlockOrTable) {
|
|
774
|
+
result.push({
|
|
775
|
+
children: [{ text: "" }],
|
|
776
|
+
type: import_platejs15.KEYS.p
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
if (unshiftNewLine && !isCodeBlockOrTable) {
|
|
780
|
+
result.unshift({
|
|
781
|
+
children: [{ text: "" }],
|
|
782
|
+
type: import_platejs15.KEYS.p
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
return result;
|
|
786
|
+
};
|
|
787
|
+
var withoutDeserializeInMdx = (editor, input) => {
|
|
788
|
+
const mdxName = editor.getOption(AIChatPlugin, "_mdxName");
|
|
789
|
+
if (mdxName) {
|
|
790
|
+
const isMdxEnd = input.includes(`</${mdxName}>`);
|
|
791
|
+
if (isMdxEnd) {
|
|
792
|
+
editor.setOption(AIChatPlugin, "_mdxName", null);
|
|
793
|
+
return false;
|
|
794
|
+
} else {
|
|
795
|
+
return [
|
|
796
|
+
{
|
|
797
|
+
children: [
|
|
798
|
+
{
|
|
799
|
+
text: input
|
|
800
|
+
}
|
|
801
|
+
],
|
|
802
|
+
type: (0, import_platejs15.getPluginType)(editor, import_platejs15.KEYS.p)
|
|
803
|
+
}
|
|
804
|
+
];
|
|
805
|
+
}
|
|
806
|
+
} else {
|
|
807
|
+
const newMdxName = statMdxTagRegex.exec(input)?.[1];
|
|
808
|
+
if (input.startsWith(`<${newMdxName}`)) {
|
|
809
|
+
editor.setOption(AIChatPlugin, "_mdxName", newMdxName ?? null);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
// src/lib/streaming/streamInsertChunk.ts
|
|
815
|
+
var import_platejs17 = require("platejs");
|
|
816
|
+
|
|
785
817
|
// src/lib/streaming/streamSerializeMd.ts
|
|
786
818
|
var import_markdown4 = require("@platejs/markdown");
|
|
787
|
-
var
|
|
788
|
-
var trimEndHeading = (value) => {
|
|
789
|
-
const headingKeys = /* @__PURE__ */ new Set([
|
|
819
|
+
var import_platejs16 = require("platejs");
|
|
820
|
+
var trimEndHeading = (editor, value) => {
|
|
821
|
+
const headingKeys = /* @__PURE__ */ new Set([
|
|
822
|
+
import_platejs16.KEYS.h1,
|
|
823
|
+
import_platejs16.KEYS.h2,
|
|
824
|
+
import_platejs16.KEYS.h3,
|
|
825
|
+
import_platejs16.KEYS.h4,
|
|
826
|
+
import_platejs16.KEYS.h5,
|
|
827
|
+
import_platejs16.KEYS.h6
|
|
828
|
+
]);
|
|
790
829
|
const lastBlock = value.at(-1);
|
|
791
|
-
if (lastBlock && headingKeys.has(
|
|
830
|
+
if (lastBlock && headingKeys.has(
|
|
831
|
+
(0, import_platejs16.getPluginKey)(editor, lastBlock.type) ?? lastBlock.type
|
|
832
|
+
) && import_platejs16.ElementApi.isElement(lastBlock)) {
|
|
792
833
|
const lastTextNode = lastBlock.children.at(-1);
|
|
793
|
-
if (
|
|
834
|
+
if (import_platejs16.TextApi.isText(lastTextNode)) {
|
|
794
835
|
const trimmedText = getChunkTrimmed(lastTextNode?.text);
|
|
795
836
|
const newChildren = [
|
|
796
837
|
...lastBlock.children.slice(0, -1),
|
|
@@ -810,7 +851,7 @@ var trimEndHeading = (value) => {
|
|
|
810
851
|
};
|
|
811
852
|
var streamSerializeMd = (editor, options, chunk) => {
|
|
812
853
|
const { value: optionsValue, ...restOptions } = options;
|
|
813
|
-
const { value } = trimEndHeading(optionsValue ?? editor.children);
|
|
854
|
+
const { value } = trimEndHeading(editor, optionsValue ?? editor.children);
|
|
814
855
|
let result = "";
|
|
815
856
|
result = editor.getApi(import_markdown4.MarkdownPlugin).markdown.serialize({
|
|
816
857
|
preserveEmptyParagraphs: false,
|
|
@@ -842,12 +883,20 @@ var streamSerializeMd = (editor, options, chunk) => {
|
|
|
842
883
|
};
|
|
843
884
|
|
|
844
885
|
// src/lib/streaming/streamInsertChunk.ts
|
|
886
|
+
var getNextPath = (path, length) => {
|
|
887
|
+
let result = path;
|
|
888
|
+
for (let i = 0; i < length; i++) {
|
|
889
|
+
result = import_platejs17.PathApi.next(result);
|
|
890
|
+
}
|
|
891
|
+
return result;
|
|
892
|
+
};
|
|
845
893
|
function streamInsertChunk(editor, chunk, options = {}) {
|
|
846
894
|
const { _blockChunks, _blockPath } = editor.getOptions(AIChatPlugin);
|
|
847
895
|
if (_blockPath === null) {
|
|
848
896
|
const blocks = streamDeserializeMd(editor, chunk);
|
|
849
897
|
const path = getCurrentBlockPath(editor);
|
|
850
|
-
const
|
|
898
|
+
const startBlock = editor.api.node(path)[0];
|
|
899
|
+
const startInEmptyParagraph = import_platejs17.NodeApi.string(startBlock).length === 0 && startBlock.type === (0, import_platejs17.getPluginType)(editor, import_platejs17.KEYS.p);
|
|
851
900
|
if (startInEmptyParagraph) {
|
|
852
901
|
editor.tf.removeNodes({ at: path });
|
|
853
902
|
}
|
|
@@ -867,7 +916,7 @@ function streamInsertChunk(editor, chunk, options = {}) {
|
|
|
867
916
|
nextBlock: true,
|
|
868
917
|
select: true
|
|
869
918
|
});
|
|
870
|
-
const lastBlock = editor.api.node(
|
|
919
|
+
const lastBlock = editor.api.node(getNextPath(nextPath, nextBlocks.length));
|
|
871
920
|
editor.setOption(AIChatPlugin, "_blockPath", lastBlock[1]);
|
|
872
921
|
const lastBlockChunks = streamSerializeMd(
|
|
873
922
|
editor,
|
|
@@ -903,7 +952,7 @@ function streamInsertChunk(editor, chunk, options = {}) {
|
|
|
903
952
|
},
|
|
904
953
|
tempBlockChunks
|
|
905
954
|
);
|
|
906
|
-
const blockText =
|
|
955
|
+
const blockText = import_platejs17.NodeApi.string(tempBlocks[0]);
|
|
907
956
|
if (serializedBlock === tempBlockChunks && blockText === serializedBlock) {
|
|
908
957
|
editor.setOption(AIChatPlugin, "_blockChunks", tempBlockChunks);
|
|
909
958
|
} else {
|
|
@@ -925,7 +974,7 @@ function streamInsertChunk(editor, chunk, options = {}) {
|
|
|
925
974
|
AIChatPlugin,
|
|
926
975
|
"_blockChunks",
|
|
927
976
|
// one block includes multiple children
|
|
928
|
-
tempBlocks[0].type ===
|
|
977
|
+
tempBlocks[0].type === (0, import_platejs17.getPluginType)(editor, import_platejs17.KEYS.codeBlock) || tempBlocks[0].type === (0, import_platejs17.getPluginType)(editor, import_platejs17.KEYS.table) || tempBlocks[0].type === (0, import_platejs17.getPluginType)(editor, import_platejs17.KEYS.equation) ? tempBlockChunks : serializedBlock2
|
|
929
978
|
);
|
|
930
979
|
}
|
|
931
980
|
} else {
|
|
@@ -951,11 +1000,11 @@ function streamInsertChunk(editor, chunk, options = {}) {
|
|
|
951
1000
|
select: true
|
|
952
1001
|
});
|
|
953
1002
|
if (tempBlocks.length > 1) {
|
|
954
|
-
const newEndBlockPath =
|
|
1003
|
+
const newEndBlockPath = getNextPath(_blockPath, tempBlocks.length - 1);
|
|
955
1004
|
editor.tf.insertNodes(
|
|
956
1005
|
nodesWithProps(editor, tempBlocks.slice(1), options),
|
|
957
1006
|
{
|
|
958
|
-
at:
|
|
1007
|
+
at: import_platejs17.PathApi.next(_blockPath),
|
|
959
1008
|
select: true
|
|
960
1009
|
}
|
|
961
1010
|
);
|
|
@@ -974,11 +1023,21 @@ function streamInsertChunk(editor, chunk, options = {}) {
|
|
|
974
1023
|
}
|
|
975
1024
|
}
|
|
976
1025
|
var getCurrentBlockPath = (editor) => {
|
|
977
|
-
const
|
|
978
|
-
|
|
979
|
-
|
|
1026
|
+
const getAnchorPreviousPath = (editor2) => {
|
|
1027
|
+
const anchorNode = editor2.getApi(AIChatPlugin).aiChat.node({ anchor: true });
|
|
1028
|
+
if (anchorNode) {
|
|
1029
|
+
return import_platejs17.PathApi.previous(anchorNode[1]);
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
const getFocusPath = (editor2) => {
|
|
1033
|
+
return editor2.selection?.focus.path.slice(0, 1);
|
|
1034
|
+
};
|
|
1035
|
+
const path = getAnchorPreviousPath(editor) ?? getFocusPath(editor) ?? [0];
|
|
1036
|
+
const entry = editor.api.node(path);
|
|
1037
|
+
if (entry && (entry[0].type === (0, import_platejs17.getPluginType)(editor, import_platejs17.KEYS.columnGroup) || entry[0].type === (0, import_platejs17.getPluginType)(editor, import_platejs17.KEYS.table))) {
|
|
1038
|
+
return editor.api.above()?.[1] ?? path;
|
|
980
1039
|
}
|
|
981
|
-
return
|
|
1040
|
+
return path;
|
|
982
1041
|
};
|
|
983
1042
|
// Annotate the CommonJS export names for ESM import in node:
|
|
984
1043
|
0 && (module.exports = {
|