mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-19 23:37:15 +08:00
feat(server): workspace doc update event from indexer (#12186)
fix AI-108 fix AI-109 fix AI-13
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
# Snapshot report for `src/__tests__/models/copilot-context.spec.ts`
|
||||||
|
|
||||||
|
The actual snapshot is saved in `copilot-context.spec.ts.snap`.
|
||||||
|
|
||||||
|
Generated by [AVA](https://avajs.dev).
|
||||||
|
|
||||||
|
## should insert embedding by doc id
|
||||||
|
|
||||||
|
> should return empty array when embedding deleted
|
||||||
|
|
||||||
|
[]
|
||||||
Binary file not shown.
@@ -116,7 +116,7 @@ test('should insert embedding by doc id', async t => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
await t.context.copilotContext.deleteEmbedding(contextId, 'file-id');
|
await t.context.copilotContext.deleteFileEmbedding(contextId, 'file-id');
|
||||||
const ret = await t.context.copilotContext.matchFileEmbedding(
|
const ret = await t.context.copilotContext.matchFileEmbedding(
|
||||||
Array.from({ length: 1024 }, () => 0.9),
|
Array.from({ length: 1024 }, () => 0.9),
|
||||||
contextId,
|
contextId,
|
||||||
@@ -169,6 +169,20 @@ test('should insert embedding by doc id', async t => {
|
|||||||
t.is(ret.length, 1);
|
t.is(ret.length, 1);
|
||||||
t.is(ret[0].content, 'content');
|
t.is(ret[0].content, 'content');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
await t.context.copilotContext.deleteWorkspaceEmbedding(
|
||||||
|
workspace.id,
|
||||||
|
docId
|
||||||
|
);
|
||||||
|
const ret = await t.context.copilotContext.matchWorkspaceEmbedding(
|
||||||
|
Array.from({ length: 1024 }, () => 0.9),
|
||||||
|
workspace.id,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
t.snapshot(ret, 'should return empty array when embedding deleted');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -168,6 +168,12 @@ export class CopilotContextModel extends BaseModel {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteFileEmbedding(contextId: string, fileId: string) {
|
||||||
|
await this.db.aiContextEmbedding.deleteMany({
|
||||||
|
where: { contextId, fileId },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async matchFileEmbedding(
|
async matchFileEmbedding(
|
||||||
embedding: number[],
|
embedding: number[],
|
||||||
contextId: string,
|
contextId: string,
|
||||||
@@ -205,6 +211,12 @@ export class CopilotContextModel extends BaseModel {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteWorkspaceEmbedding(workspaceId: string, docId: string) {
|
||||||
|
await this.db.aiWorkspaceEmbedding.deleteMany({
|
||||||
|
where: { workspaceId, docId },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async matchWorkspaceEmbedding(
|
async matchWorkspaceEmbedding(
|
||||||
embedding: number[],
|
embedding: number[],
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
@@ -222,10 +234,4 @@ export class CopilotContextModel extends BaseModel {
|
|||||||
`;
|
`;
|
||||||
return similarityChunks.filter(c => Number(c.distance) <= threshold);
|
return similarityChunks.filter(c => Number(c.distance) <= threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteEmbedding(contextId: string, fileId: string) {
|
|
||||||
await this.db.aiContextEmbedding.deleteMany({
|
|
||||||
where: { contextId, fileId },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,30 @@ export class CopilotContextDocJob {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @OnEvent('doc.indexer.updated')
|
||||||
|
async addDocEmbeddingQueueFromEvent(
|
||||||
|
// TODO(@darkskygit): replace this with real event type
|
||||||
|
doc: { workspaceId: string; docId: string } //Events['doc.indexer.updated'],
|
||||||
|
) {
|
||||||
|
if (!this.supportEmbedding) return;
|
||||||
|
|
||||||
|
await this.queue.add('copilot.embedding.docs', {
|
||||||
|
workspaceId: doc.workspaceId,
|
||||||
|
docId: doc.workspaceId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// @OnEvent('doc.indexer.deleted')
|
||||||
|
async deleteDocEmbeddingQueueFromEvent(
|
||||||
|
// TODO(@darkskygit): replace this with real event type
|
||||||
|
doc: { workspaceId: string; docId: string } //Events['doc.indexer.deleted'],
|
||||||
|
) {
|
||||||
|
await this.models.copilotContext.deleteWorkspaceEmbedding(
|
||||||
|
doc.workspaceId,
|
||||||
|
doc.docId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async readCopilotBlob(
|
async readCopilotBlob(
|
||||||
userId: string,
|
userId: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
|
|||||||
@@ -164,7 +164,10 @@ export class ContextSession implements AsyncDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async removeFile(fileId: string): Promise<boolean> {
|
async removeFile(fileId: string): Promise<boolean> {
|
||||||
await this.models.copilotContext.deleteEmbedding(this.contextId, fileId);
|
await this.models.copilotContext.deleteFileEmbedding(
|
||||||
|
this.contextId,
|
||||||
|
fileId
|
||||||
|
);
|
||||||
this.config.files = this.config.files.filter(f => f.id !== fileId);
|
this.config.files = this.config.files.filter(f => f.id !== fileId);
|
||||||
await this.save();
|
await this.save();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user