feat(core): add matched context documents to ai prompt (#11148)

Close [BS-2834](https://linear.app/affine-design/issue/BS-2834).

### What Changed?
- Change `reference_index` from chip order to increasing positive integer.
- Add matched context documents to ai prompt.
This commit is contained in:
akumatus
2025-03-26 01:55:54 +00:00
parent ae552c97cf
commit d991149faa
4 changed files with 57 additions and 51 deletions
@@ -36,17 +36,15 @@ export type ChatStatus =
export interface DocContext {
docId: string;
refIndex: number;
markdown: string;
docContent: string;
}
export type FileContext = {
export interface FileContext {
blobId: string;
refIndex: number;
fileName: string;
fileType: string;
chunks: string;
};
fileContent: string;
}
export type ChatContextValue = {
// history messages of the chat
@@ -23,6 +23,7 @@ import type {
ChatContextValue,
ChatMessage,
DocContext,
FileChip,
FileContext,
} from './chat-context';
import { isDocChip, isFileChip } from './components/utils';
@@ -556,43 +557,55 @@ export class ChatPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
private async _getMatchedContexts(userInput: string) {
const contextId = await this.getContextId();
// TODO(@akumatus): adapt workspace docs
const { files: matched = [] } =
(contextId &&
(await AIProvider.context?.matchContext(contextId, userInput))) ||
{};
if (!contextId) {
return { files: [], docs: [] };
}
const contexts = this.chatContextValue.chips.reduce(
(acc, chip, index) => {
if (chip.state !== 'finished') {
return acc;
}
if (isDocChip(chip) && !!chip.markdown?.value) {
acc.docs.push({
docId: chip.docId,
refIndex: index + 1,
markdown: chip.markdown.value,
const docContexts = new Map<string, DocContext>();
const fileContexts = new Map<string, FileContext>();
const { files: matchedFiles = [], docs: matchedDocs = [] } =
(await AIProvider.context?.matchContext(contextId, userInput)) ?? {};
matchedDocs.forEach(doc => {
docContexts.set(doc.docId, {
docId: doc.docId,
docContent: doc.content,
});
});
matchedFiles.forEach(file => {
const context = fileContexts.get(file.fileId);
if (context) {
context.fileContent += `\n${file.content}`;
} else {
const fileChip = this.chatContextValue.chips.find(
chip => isFileChip(chip) && chip.fileId === file.fileId
) as FileChip | undefined;
if (fileChip && fileChip.blobId) {
fileContexts.set(file.fileId, {
blobId: fileChip.blobId,
fileName: fileChip.file.name,
fileType: fileChip.file.type,
fileContent: file.content,
});
}
if (isFileChip(chip) && chip.blobId) {
const matchedChunks = matched
.filter(chunk => chunk.fileId === chip.fileId)
.map(chunk => chunk.content);
if (matchedChunks.length > 0) {
acc.files.push({
blobId: chip.blobId,
refIndex: index + 1,
fileName: chip.file.name,
fileType: chip.file.type,
chunks: matchedChunks.join('\n'),
});
}
}
return acc;
},
{ docs: [], files: [] } as { docs: DocContext[]; files: FileContext[] }
);
return contexts;
}
});
this.chatContextValue.chips.forEach(chip => {
if (isDocChip(chip) && !!chip.markdown?.value) {
docContexts.set(chip.docId, {
docId: chip.docId,
docContent: chip.markdown.value,
});
}
});
return {
docs: Array.from(docContexts.values()),
files: Array.from(fileContexts.values()),
};
}
}