Skip to content

Commit 70aa52b

Browse files
authored
fix: AI empty document handling (#1810)
1 parent 0ac9b4a commit 70aa52b

File tree

7 files changed

+27
-13
lines changed

7 files changed

+27
-13
lines changed

packages/xl-ai/src/api/LLMRequest.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { LLMResponse } from "./LLMResponse.js";
99
import type { PromptBuilder } from "./formats/PromptBuilder.js";
1010
import { htmlBlockLLMFormat } from "./formats/html-blocks/htmlBlocks.js";
1111
import { LLMFormat } from "./index.js";
12+
import { trimEmptyBlocks } from "./promptHelpers/trimEmptyBlocks.js";
1213

1314
export type LLMRequestOptions = {
1415
/**
@@ -155,7 +156,7 @@ export async function doLLMRequest(
155156
cursorBlock &&
156157
deleteEmptyCursorBlock &&
157158
isEmptyParagraph(cursorBlock) &&
158-
editor.document.length > 1
159+
trimEmptyBlocks(editor.document).length > 0
159160
? cursorBlock.id
160161
: undefined;
161162

packages/xl-ai/src/api/formats/html-blocks/defaultHTMLPromptBuilder.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { CoreMessage } from "ai";
2+
import { trimEmptyBlocks } from "../../promptHelpers/trimEmptyBlocks.js";
23
import type { PromptBuilder } from "../PromptBuilder.js";
34
import {
45
getDataForPromptNoSelection,
@@ -99,6 +100,8 @@ function promptManipulateDocumentUseHTMLBlocks(opts: {
99100
}
100101

101102
export const defaultHTMLPromptBuilder: PromptBuilder = async (editor, opts) => {
103+
const isEmptyDocument = trimEmptyBlocks(editor.document).length === 0;
104+
102105
if (opts.selectedBlocks) {
103106
const data = await getDataForPromptWithSelection(editor, {
104107
selectedBlocks: opts.selectedBlocks,
@@ -141,7 +144,7 @@ export const defaultHTMLPromptBuilder: PromptBuilder = async (editor, opts) => {
141144
return promptManipulateSelectionHTMLBlocks({
142145
...data,
143146
userPrompt: opts.userPrompt,
144-
isEmptyDocument: editor.isEmpty,
147+
isEmptyDocument,
145148
});
146149
} else {
147150
const data = await getDataForPromptNoSelection(editor, opts);
@@ -174,7 +177,7 @@ export const defaultHTMLPromptBuilder: PromptBuilder = async (editor, opts) => {
174177
return promptManipulateDocumentUseHTMLBlocks({
175178
...data,
176179
userPrompt: opts.userPrompt,
177-
isEmptyDocument: editor.isEmpty,
180+
isEmptyDocument,
178181
});
179182
}
180183
};

packages/xl-ai/src/api/formats/html-blocks/htmlPromptData.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ export async function getDataForPromptNoSelection(
1111
excludeBlockIds?: string[];
1212
},
1313
) {
14-
const input = trimEmptyBlocks(editor.document);
14+
const cursorBlockId = editor.getTextCursorPosition().block.id;
15+
const input = trimEmptyBlocks(editor.document, {
16+
cursorBlockId,
17+
});
1518
const blockArray = await convertBlocks(
1619
flattenBlocks(input),
1720
async (block) => {

packages/xl-ai/src/api/formats/json/defaultJSONPromptBuilder.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { CoreMessage } from "ai";
2+
import { trimEmptyBlocks } from "../../promptHelpers/trimEmptyBlocks.js";
23
import { PromptBuilder } from "../PromptBuilder.js";
34
import {
45
getDataForPromptNoSelection,
@@ -122,21 +123,24 @@ function promptManipulateDocumentUseJSONBlocks(opts: {
122123
}
123124

124125
export const defaultJSONPromptBuilder: PromptBuilder = async (editor, opts) => {
126+
const isEmptyDocument = trimEmptyBlocks(editor.document).length === 0;
127+
125128
if (opts.selectedBlocks) {
126129
const data = await getDataForPromptWithSelection(editor, {
127130
selectedBlocks: opts.selectedBlocks,
128131
});
132+
129133
return promptManipulateSelectionJSONBlocks({
130134
...data,
131135
userPrompt: opts.userPrompt,
132-
isEmptyDocument: editor.isEmpty,
136+
isEmptyDocument,
133137
});
134138
} else {
135139
const data = await getDataForPromptNoSelection(editor, opts);
136140
return promptManipulateDocumentUseJSONBlocks({
137141
...data,
138142
userPrompt: opts.userPrompt,
139-
isEmptyDocument: editor.isEmpty,
143+
isEmptyDocument,
140144
});
141145
}
142146
};

packages/xl-ai/src/api/formats/json/jsonPromptData.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ export async function getDataForPromptNoSelection(
1111
excludeBlockIds?: string[];
1212
},
1313
) {
14-
const input = trimEmptyBlocks(editor.document);
14+
const cursorBlockId = editor.getTextCursorPosition().block.id;
15+
const input = trimEmptyBlocks(editor.document, {
16+
cursorBlockId,
17+
});
1518
const blockArray = await convertBlocks(
1619
flattenBlocks(input),
1720
async (block) => {

packages/xl-ai/src/api/formats/markdown-blocks/markdownPromptData.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ export async function getDataForPromptNoSelection(
1111
excludeBlockIds?: string[];
1212
},
1313
) {
14-
const input = trimEmptyBlocks(editor.document);
14+
const cursorBlockId = editor.getTextCursorPosition().block.id;
15+
const input = trimEmptyBlocks(editor.document, {
16+
cursorBlockId,
17+
});
1518
const blockArray = await convertBlocks(
1619
flattenBlocks(input),
1720
async (block) => {

packages/xl-ai/src/api/promptHelpers/trimEmptyBlocks.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,16 @@ export function trimEmptyBlocks(
77
opts?: {
88
trimStart?: boolean;
99
trimEnd?: boolean;
10+
cursorBlockId?: string;
1011
},
1112
) {
12-
if (source.length === 1) {
13-
// don't trim empty blocks from a single block document
14-
return source;
15-
}
1613
// trim empty trailing blocks that don't have the cursor
1714
// if we don't do this, commands like "add some paragraphs"
1815
// would add paragraphs after the trailing blocks
1916
const trimmedSource = trimArray(
2017
source,
2118
(block) => {
22-
return isEmptyParagraph(block);
19+
return isEmptyParagraph(block) && opts?.cursorBlockId !== block.id;
2320
},
2421
opts?.trimStart ?? false,
2522
opts?.trimEnd ?? true,

0 commit comments

Comments
 (0)