fix(core): add synced doc content to edgeless ai context (#7327)
Closes: [BS-633](https://linear.app/affine-design/issue/BS-633/synced-block-%E7%99%BD%E6%9D%BF%E6%94%AF%E6%8C%81%EF%BC%9A%E4%BD%9C%E4%B8%BA%E4%B8%8A%E4%B8%8B%E6%96%87%E6%8F%90%E4%BE%9B%E7%BB%99-ai#comment-f336c6d5) Related PR: https://github.com/toeverything/blocksuite/pull/7417 Read content from synced doc model as AI context in edgeless model.
This commit is contained in:
@@ -8,6 +8,7 @@ import type {
|
|||||||
import {
|
import {
|
||||||
BlocksUtils,
|
BlocksUtils,
|
||||||
EdgelessTextBlockModel,
|
EdgelessTextBlockModel,
|
||||||
|
EmbedSyncedDocModel,
|
||||||
ImageBlockModel,
|
ImageBlockModel,
|
||||||
NoteBlockModel,
|
NoteBlockModel,
|
||||||
ShapeElementModel,
|
ShapeElementModel,
|
||||||
@@ -96,6 +97,14 @@ function actionToRenderer<T extends keyof BlockSuitePresets.AIActions>(
|
|||||||
return createTextRenderer(host, { maxHeight: 320 });
|
return createTextRenderer(host, { maxHeight: 320 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getContentFromEmbedSyncedDocModel(
|
||||||
|
host: EditorHost,
|
||||||
|
models: EmbedSyncedDocModel[]
|
||||||
|
) {
|
||||||
|
const slice = Slice.fromModels(host.doc, models);
|
||||||
|
return (await getContentFromSlice(host, slice)).trim();
|
||||||
|
}
|
||||||
|
|
||||||
async function getContentFromHubBlockModel(
|
async function getContentFromHubBlockModel(
|
||||||
host: EditorHost,
|
host: EditorHost,
|
||||||
models: EdgelessTextBlockModel[] | NoteBlockModel[]
|
models: EdgelessTextBlockModel[] | NoteBlockModel[]
|
||||||
@@ -132,39 +141,55 @@ export async function getContentFromSelected(
|
|||||||
return el.caption !== undefined && el.caption.length !== 0;
|
return el.caption !== undefined && el.caption.length !== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { notes, texts, shapes, images, edgelessTexts } = selected.reduce<{
|
const { notes, texts, shapes, images, edgelessTexts, embedSyncedDocs } =
|
||||||
notes: NoteBlockModel[];
|
selected.reduce<{
|
||||||
texts: TextElementModel[];
|
notes: NoteBlockModel[];
|
||||||
shapes: RemoveUndefinedKey<ShapeElementModel, 'text'>[];
|
texts: TextElementModel[];
|
||||||
images: RemoveUndefinedKey<ImageBlockModel, 'caption'>[];
|
shapes: RemoveUndefinedKey<ShapeElementModel, 'text'>[];
|
||||||
edgelessTexts: EdgelessTextBlockModel[];
|
images: RemoveUndefinedKey<ImageBlockModel, 'caption'>[];
|
||||||
}>(
|
edgelessTexts: EdgelessTextBlockModel[];
|
||||||
(pre, cur) => {
|
embedSyncedDocs: EmbedSyncedDocModel[];
|
||||||
if (cur instanceof NoteBlockModel) {
|
}>(
|
||||||
pre.notes.push(cur);
|
(pre, cur) => {
|
||||||
} else if (cur instanceof TextElementModel) {
|
if (cur instanceof NoteBlockModel) {
|
||||||
pre.texts.push(cur);
|
pre.notes.push(cur);
|
||||||
} else if (cur instanceof ShapeElementModel && isShapeWithText(cur)) {
|
} else if (cur instanceof TextElementModel) {
|
||||||
pre.shapes.push(cur);
|
pre.texts.push(cur);
|
||||||
} else if (cur instanceof ImageBlockModel && isImageWithCaption(cur)) {
|
} else if (cur instanceof ShapeElementModel && isShapeWithText(cur)) {
|
||||||
pre.images.push(cur);
|
pre.shapes.push(cur);
|
||||||
} else if (cur instanceof EdgelessTextBlockModel) {
|
} else if (cur instanceof ImageBlockModel && isImageWithCaption(cur)) {
|
||||||
pre.edgelessTexts.push(cur);
|
pre.images.push(cur);
|
||||||
}
|
} else if (cur instanceof EdgelessTextBlockModel) {
|
||||||
|
pre.edgelessTexts.push(cur);
|
||||||
|
} else if (cur instanceof EmbedSyncedDocModel) {
|
||||||
|
pre.embedSyncedDocs.push(cur);
|
||||||
|
}
|
||||||
|
|
||||||
return pre;
|
return pre;
|
||||||
},
|
},
|
||||||
{ notes: [], texts: [], shapes: [], images: [], edgelessTexts: [] }
|
{
|
||||||
);
|
notes: [],
|
||||||
|
texts: [],
|
||||||
|
shapes: [],
|
||||||
|
images: [],
|
||||||
|
edgelessTexts: [],
|
||||||
|
embedSyncedDocs: [],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const noteContent = await getContentFromHubBlockModel(host, notes);
|
const noteContent = await getContentFromHubBlockModel(host, notes);
|
||||||
const edgelessTextContent = await getContentFromHubBlockModel(
|
const edgelessTextContent = await getContentFromHubBlockModel(
|
||||||
host,
|
host,
|
||||||
edgelessTexts
|
edgelessTexts
|
||||||
);
|
);
|
||||||
|
const syncedDocsContent = await getContentFromEmbedSyncedDocModel(
|
||||||
|
host,
|
||||||
|
embedSyncedDocs
|
||||||
|
);
|
||||||
|
|
||||||
return `${noteContent.join('\n')}
|
return `${noteContent.join('\n')}
|
||||||
${edgelessTextContent.join('\n')}
|
${edgelessTextContent.join('\n')}
|
||||||
|
${syncedDocsContent}
|
||||||
${texts.map(text => text.text.toString()).join('\n')}
|
${texts.map(text => text.text.toString()).join('\n')}
|
||||||
${shapes.map(shape => shape.text.toString()).join('\n')}
|
${shapes.map(shape => shape.text.toString()).join('\n')}
|
||||||
${images.map(image => image.caption.toString()).join('\n')}
|
${images.map(image => image.caption.toString()).join('\n')}
|
||||||
@@ -449,14 +474,15 @@ export function actionToHandler<T extends keyof BlockSuitePresets.AIActions>(
|
|||||||
if (isCreateImageAction || isMakeItRealAction) {
|
if (isCreateImageAction || isMakeItRealAction) {
|
||||||
togglePanel = async () => {
|
togglePanel = async () => {
|
||||||
if (isEmpty) return true;
|
if (isEmpty) return true;
|
||||||
const {
|
const { notes, shapes, images, edgelessTexts, embedSyncedDocs } =
|
||||||
notes,
|
BlocksUtils.splitElements(selectedElements);
|
||||||
shapes,
|
const blocks = [
|
||||||
images,
|
...notes,
|
||||||
edgelessTexts,
|
...shapes,
|
||||||
frames: _,
|
...images,
|
||||||
} = BlocksUtils.splitElements(selectedElements);
|
...edgelessTexts,
|
||||||
const blocks = [...notes, ...shapes, ...images, ...edgelessTexts];
|
...embedSyncedDocs,
|
||||||
|
];
|
||||||
if (blocks.length === 0) return true;
|
if (blocks.length === 0) return true;
|
||||||
const content = await getContentFromSelected(host, blocks);
|
const content = await getContentFromSelected(host, blocks);
|
||||||
ctx.set({
|
ctx.set({
|
||||||
|
|||||||
Reference in New Issue
Block a user