fix(core): filter embedding results to return only user-selected tags and documents (#11770)

Close [AI-73](https://linear.app/affine-design/issue/AI-73)
This commit is contained in:
akumatus
2025-04-18 03:25:29 +00:00
parent d71cbd5fd3
commit 203e931e30
4 changed files with 53 additions and 6 deletions

View File

@@ -448,11 +448,10 @@ export class ChatPanelChips extends SignalWatcher(
if (!contextId || !AIProvider.context) { if (!contextId || !AIProvider.context) {
throw new Error('Context not found'); throw new Error('Context not found');
} }
const collection = this._collections.value.find(
collection => collection.id === chip.collectionId
);
// TODO: server side docIds calculation // TODO: server side docIds calculation
const docIds = collection?.allowList ?? []; const docIds = this.docDisplayConfig.getCollectionPageIds(
chip.collectionId
);
await AIProvider.context.addContextCollection({ await AIProvider.context.addContextCollection({
contextId, contextId,
collectionId: chip.collectionId, collectionId: chip.collectionId,

View File

@@ -74,6 +74,7 @@ export interface DocDisplayConfig {
signal: Signal<Collection[]>; signal: Signal<Collection[]>;
cleanup: () => void; cleanup: () => void;
}; };
getCollectionPageIds: (collectionId: string) => string[];
} }
export interface SearchMenuConfig { export interface SearchMenuConfig {

View File

@@ -23,7 +23,12 @@ import type {
DocDisplayConfig, DocDisplayConfig,
FileChip, FileChip,
} from '../ai-chat-chips/type'; } from '../ai-chat-chips/type';
import { isDocChip, isFileChip } from '../ai-chat-chips/utils'; import {
isCollectionChip,
isDocChip,
isFileChip,
isTagChip,
} from '../ai-chat-chips/utils';
import type { ChatMessage } from '../ai-chat-messages'; import type { ChatMessage } from '../ai-chat-messages';
import type { AIChatInputContext, AINetworkSearchConfig } from './type'; import type { AIChatInputContext, AINetworkSearchConfig } from './type';
@@ -521,7 +526,8 @@ export class AIChatInput extends SignalWatcher(WithDisposable(LitElement)) {
await this._preUpdateMessages(userInput, attachments); await this._preUpdateMessages(userInput, attachments);
const sessionId = await this.createSessionId(); const sessionId = await this.createSessionId();
const contexts = await this._getMatchedContexts(userInput); let contexts = await this._getMatchedContexts(userInput);
contexts = this._filterContexts(contexts);
if (abortController.signal.aborted) { if (abortController.signal.aborted) {
return; return;
} }
@@ -684,6 +690,42 @@ export class AIChatInput extends SignalWatcher(WithDisposable(LitElement)) {
files: Array.from(fileContexts.values()), files: Array.from(fileContexts.values()),
}; };
} }
// TODO: remove this function after workspace embedding is ready
private _filterContexts(contexts: {
docs: BlockSuitePresets.AIDocContextOption[];
files: BlockSuitePresets.AIFileContextOption[];
}) {
const docIds = this.chips.reduce((acc, chip) => {
if (isDocChip(chip)) {
acc.push(chip.docId);
}
if (isTagChip(chip)) {
const docIds = this.docDisplayConfig.getTagPageIds(chip.tagId);
acc.push(...docIds);
}
if (isCollectionChip(chip)) {
const docIds = this.docDisplayConfig.getCollectionPageIds(
chip.collectionId
);
acc.push(...docIds);
}
return acc;
}, [] as string[]);
const fileIds = this.chips.reduce((acc, chip) => {
if (isFileChip(chip) && chip.blobId) {
acc.push(chip.blobId);
}
return acc;
}, [] as string[]);
const { docs, files } = contexts;
return {
docs: docs.filter(doc => docIds.includes(doc.docId)),
files: files.filter(file => fileIds.includes(file.blobId)),
};
}
} }
declare global { declare global {

View File

@@ -77,6 +77,11 @@ export function useAIChatConfig() {
const collections$ = collectionService.collections$; const collections$ = collectionService.collections$;
return createSignalFromObservable(collections$, []); return createSignalFromObservable(collections$, []);
}, },
getCollectionPageIds: (collectionId: string) => {
const collection$ = collectionService.collection$(collectionId);
// TODO: lack of documents that meet the collection rules
return collection$?.value?.allowList ?? [];
},
}; };
const searchMenuConfig = { const searchMenuConfig = {