fix: remove pgvector dependency from AI knowledge retrieval

This commit is contained in:
2026-07-06 10:36:21 -07:00
parent 0d5093ac6c
commit f74b7f3ca0
9 changed files with 78 additions and 30 deletions

View File

@@ -130,7 +130,7 @@ type RetrievedChunkRow = {
title: string;
category: string;
content: string;
distance: number;
embedding: number[];
};
type KnowledgeDatabaseFake = {
@@ -325,7 +325,7 @@ class SelectBuilder implements PromiseLike<SelectRow[]> {
title: chunk.sourceTitle,
category: chunk.sourceCategory,
content: chunk.content,
distance: 0.1 + rows.length * 0.1,
embedding: chunk.embedding,
});
}
}
@@ -407,6 +407,31 @@ describe("AI knowledge service", () => {
expect(embeddingMocks.embedDocuments).toHaveBeenCalledWith(["night fall risk"]);
});
it("orders retrieved chunks by cosine similarity after scope filtering", async () => {
const weakEntry = createEntry({ id: "entry-weak", title: "Weak guidance" });
const strongEntry = createEntry({ id: "entry-strong", title: "Strong guidance" });
useDatabase(createDatabaseFake({
entries: [weakEntry, strongEntry],
chunks: [
createChunk(weakEntry, { embedding: [0, 1, 0] }),
createChunk(strongEntry, { embedding: [1, 0, 0] }),
],
}));
embeddingMocks.embedDocuments.mockResolvedValueOnce([[1, 0, 0]]);
const result = await retrieveKnowledge("org-1", "night fall risk", { limit: 2 });
expect(result).toEqual({
success: true,
data: {
results: [
expect.objectContaining({ entryId: "entry-strong", score: 1 }),
expect.objectContaining({ entryId: "entry-weak", score: 0 }),
],
},
});
});
it("requires platform management permission before mutating platform knowledge", async () => {
const existingPlatformEntry = createEntry({ id: "entry-platform", scope: "platform", organizationId: null });
useDatabase(createDatabaseFake({ entries: [existingPlatformEntry] }));