feat(core): extract selected docs (#13426)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Added support for handling and extracting embedded document references within selected content in AI chat features. * Documents associated with selected context chips are now properly managed alongside attachments, improving context handling in AI chat interactions. * **Bug Fixes** * Ensured that the state of context chips accurately reflects the presence of attachments and documents. * **Documentation** * Updated type definitions to include support for document references in relevant AI chat contexts. <!-- end of auto-generated comment: release notes by coderabbit.ai --> > CLOSE AF-2783
This commit is contained in:
@@ -39,6 +39,7 @@ export interface CollectionChip extends BaseChip {
|
|||||||
export interface SelectedContextChip extends BaseChip {
|
export interface SelectedContextChip extends BaseChip {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
attachments: { sourceId: string; name: string }[];
|
attachments: { sourceId: string; name: string }[];
|
||||||
|
docs: string[];
|
||||||
snapshot: string | null;
|
snapshot: string | null;
|
||||||
combinedElementsMarkdown: string | null;
|
combinedElementsMarkdown: string | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -412,15 +412,16 @@ export class AIChatComposer extends SignalWatcher(
|
|||||||
};
|
};
|
||||||
|
|
||||||
private readonly addSelectedContextChip = async () => {
|
private readonly addSelectedContextChip = async () => {
|
||||||
const { attachments, snapshot, combinedElementsMarkdown } =
|
const { attachments, snapshot, combinedElementsMarkdown, docs } =
|
||||||
this.chatContextValue;
|
this.chatContextValue;
|
||||||
await this.removeSelectedContextChip();
|
await this.removeSelectedContextChip();
|
||||||
const chip: SelectedContextChip = {
|
const chip: SelectedContextChip = {
|
||||||
uuid: uuidv4(),
|
uuid: uuidv4(),
|
||||||
attachments,
|
attachments,
|
||||||
|
docs,
|
||||||
snapshot,
|
snapshot,
|
||||||
combinedElementsMarkdown,
|
combinedElementsMarkdown,
|
||||||
state: 'processing',
|
state: attachments.length > 0 ? 'processing' : 'finished',
|
||||||
};
|
};
|
||||||
await this.addChip(chip, true);
|
await this.addChip(chip, true);
|
||||||
};
|
};
|
||||||
@@ -545,7 +546,7 @@ export class AIChatComposer extends SignalWatcher(
|
|||||||
private readonly addSelectedContextChipToContext = async (
|
private readonly addSelectedContextChipToContext = async (
|
||||||
chip: SelectedContextChip
|
chip: SelectedContextChip
|
||||||
) => {
|
) => {
|
||||||
const { attachments } = chip;
|
const { attachments, docs } = chip;
|
||||||
const contextId = await this.createContextId();
|
const contextId = await this.createContextId();
|
||||||
if (!contextId || !AIProvider.context) {
|
if (!contextId || !AIProvider.context) {
|
||||||
throw new Error('Context not found');
|
throw new Error('Context not found');
|
||||||
@@ -554,6 +555,14 @@ export class AIChatComposer extends SignalWatcher(
|
|||||||
blobIds: attachments.map(attachment => attachment.sourceId),
|
blobIds: attachments.map(attachment => attachment.sourceId),
|
||||||
contextId,
|
contextId,
|
||||||
});
|
});
|
||||||
|
await Promise.all(
|
||||||
|
docs.map(docId =>
|
||||||
|
AIProvider.context?.addContextDoc({
|
||||||
|
contextId,
|
||||||
|
docId,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly removeFromContext = async (
|
private readonly removeFromContext = async (
|
||||||
@@ -589,11 +598,19 @@ export class AIChatComposer extends SignalWatcher(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (isSelectedContextChip(chip)) {
|
if (isSelectedContextChip(chip)) {
|
||||||
const { attachments } = chip;
|
const { attachments, docs } = chip;
|
||||||
return await AIProvider.context.removeContextBlobs({
|
await AIProvider.context.removeContextBlobs({
|
||||||
contextId,
|
contextId,
|
||||||
blobIds: attachments.map(attachment => attachment.sourceId),
|
blobIds: attachments.map(attachment => attachment.sourceId),
|
||||||
});
|
});
|
||||||
|
await Promise.all(
|
||||||
|
docs.map(docId =>
|
||||||
|
AIProvider.context?.removeContextDoc({
|
||||||
|
contextId,
|
||||||
|
docId,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ const DEFAULT_CHAT_CONTEXT_VALUE: ChatContextValue = {
|
|||||||
snapshot: null,
|
snapshot: null,
|
||||||
attachments: [],
|
attachments: [],
|
||||||
combinedElementsMarkdown: null,
|
combinedElementsMarkdown: null,
|
||||||
|
docs: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export class AIChatContent extends SignalWatcher(
|
export class AIChatContent extends SignalWatcher(
|
||||||
|
|||||||
@@ -18,5 +18,7 @@ export type ChatContextValue = {
|
|||||||
attachments: { sourceId: string; name: string }[];
|
attachments: { sourceId: string; name: string }[];
|
||||||
// combined markdown of the selected elements
|
// combined markdown of the selected elements
|
||||||
combinedElementsMarkdown: string | null;
|
combinedElementsMarkdown: string | null;
|
||||||
|
// docs of the selected content
|
||||||
|
docs: string[];
|
||||||
abortController: AbortController | null;
|
abortController: AbortController | null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,5 +30,5 @@ export type AIChatInputContext = {
|
|||||||
abortController: AbortController | null;
|
abortController: AbortController | null;
|
||||||
} & Pick<
|
} & Pick<
|
||||||
ChatContextValue,
|
ChatContextValue,
|
||||||
'snapshot' | 'combinedElementsMarkdown' | 'attachments'
|
'snapshot' | 'combinedElementsMarkdown' | 'attachments' | 'docs'
|
||||||
>;
|
>;
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ const DEFAULT_CHAT_CONTEXT_VALUE: ChatContextValue = {
|
|||||||
snapshot: null,
|
snapshot: null,
|
||||||
attachments: [],
|
attachments: [],
|
||||||
combinedElementsMarkdown: null,
|
combinedElementsMarkdown: null,
|
||||||
|
docs: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export class PlaygroundChat extends SignalWatcher(
|
export class PlaygroundChat extends SignalWatcher(
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { WorkspaceImpl } from '@affine/core/modules/workspace/impls/workspace';
|
|||||||
import { getSurfaceBlock } from '@blocksuite/affine/blocks/surface';
|
import { getSurfaceBlock } from '@blocksuite/affine/blocks/surface';
|
||||||
import {
|
import {
|
||||||
DatabaseBlockModel,
|
DatabaseBlockModel,
|
||||||
|
EmbedLinkedDocModel,
|
||||||
|
EmbedSyncedDocModel,
|
||||||
ImageBlockModel,
|
ImageBlockModel,
|
||||||
NoteBlockModel,
|
NoteBlockModel,
|
||||||
NoteDisplayMode,
|
NoteDisplayMode,
|
||||||
@@ -65,6 +67,7 @@ async function extractEdgelessSelected(
|
|||||||
let markdown = '';
|
let markdown = '';
|
||||||
const attachments: ChatContextValue['attachments'] = [];
|
const attachments: ChatContextValue['attachments'] = [];
|
||||||
const images: File[] = [];
|
const images: File[] = [];
|
||||||
|
const docs: ChatContextValue['docs'] = [];
|
||||||
|
|
||||||
if (selectedElements.length) {
|
if (selectedElements.length) {
|
||||||
const transformer = host.store.getTransformer();
|
const transformer = host.store.getTransformer();
|
||||||
@@ -117,6 +120,12 @@ async function extractEdgelessSelected(
|
|||||||
needSnapshot = true;
|
needSnapshot = true;
|
||||||
const props = getElementProps(element, new Map());
|
const props = getElementProps(element, new Map());
|
||||||
surface.addElement(props);
|
surface.addElement(props);
|
||||||
|
} else if (
|
||||||
|
element instanceof EmbedSyncedDocModel ||
|
||||||
|
element instanceof EmbedLinkedDocModel
|
||||||
|
) {
|
||||||
|
const docId = element.props.pageId;
|
||||||
|
docs.push(docId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +153,7 @@ async function extractEdgelessSelected(
|
|||||||
snapshot: snapshot ? JSON.stringify(snapshot) : null,
|
snapshot: snapshot ? JSON.stringify(snapshot) : null,
|
||||||
combinedElementsMarkdown: markdown.length ? markdown : null,
|
combinedElementsMarkdown: markdown.length ? markdown : null,
|
||||||
attachments,
|
attachments,
|
||||||
|
docs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user