feat: add isolated memory spaces
This commit is contained in:
@@ -120,6 +120,53 @@ describe('IdentityDB semantic search', () => {
|
||||
expect(matches[0]?.statement).toBe('Bun runs TypeScript tooling quickly.');
|
||||
expect(matches[0]!.score).toBeGreaterThan(matches[1]!.score);
|
||||
});
|
||||
|
||||
it('keeps semantic search isolated per space', async () => {
|
||||
const isolatedDb = await IdentityDB.connect({ client: 'sqlite', filename: ':memory:' });
|
||||
try {
|
||||
await isolatedDb.initialize();
|
||||
|
||||
await isolatedDb.addFact({
|
||||
statement: 'Bun runs TypeScript tooling quickly.',
|
||||
spaceName: 'A',
|
||||
topics: [
|
||||
{ name: 'Bun', category: 'entity', granularity: 'concrete' },
|
||||
{ name: 'TypeScript', category: 'entity', granularity: 'concrete' },
|
||||
],
|
||||
});
|
||||
|
||||
await isolatedDb.addFact({
|
||||
statement: 'TypeScript runtime tooling belongs to another tenant.',
|
||||
spaceName: 'B',
|
||||
topics: [
|
||||
{ name: 'TypeScript', category: 'entity', granularity: 'concrete' },
|
||||
],
|
||||
});
|
||||
|
||||
await isolatedDb.indexFactEmbeddings({ provider, spaceName: 'A' });
|
||||
await isolatedDb.indexFactEmbeddings({ provider, spaceName: 'B' });
|
||||
|
||||
const alphaMatches = await isolatedDb.searchFacts({
|
||||
query: 'TypeScript runtime tooling',
|
||||
provider,
|
||||
spaceName: 'A',
|
||||
});
|
||||
const betaMatches = await isolatedDb.searchFacts({
|
||||
query: 'TypeScript runtime tooling',
|
||||
provider,
|
||||
spaceName: 'B',
|
||||
});
|
||||
|
||||
expect(alphaMatches.map((match) => match.statement)).toEqual([
|
||||
'Bun runs TypeScript tooling quickly.',
|
||||
]);
|
||||
expect(betaMatches.map((match) => match.statement)).toEqual([
|
||||
'TypeScript runtime tooling belongs to another tenant.',
|
||||
]);
|
||||
} finally {
|
||||
await isolatedDb.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('IdentityDB dedup-aware ingestion', () => {
|
||||
@@ -167,4 +214,26 @@ describe('IdentityDB dedup-aware ingestion', () => {
|
||||
expect(facts).toHaveLength(1);
|
||||
expect(facts[0]?.statement).toBe('Bun runs TypeScript tooling quickly.');
|
||||
});
|
||||
|
||||
it('does not reuse a semantic duplicate from another space', async () => {
|
||||
const first = await db.ingestStatement('Bun runs TypeScript tooling quickly.', {
|
||||
extractor,
|
||||
embeddingProvider: provider,
|
||||
spaceName: 'A',
|
||||
});
|
||||
|
||||
const second = await db.ingestStatement('Bun makes TypeScript tooling fast.', {
|
||||
extractor,
|
||||
embeddingProvider: provider,
|
||||
duplicateThreshold: 0.95,
|
||||
spaceName: 'B',
|
||||
});
|
||||
|
||||
const alphaFacts = await db.getTopicFacts('TypeScript', { spaceName: 'A' });
|
||||
const betaFacts = await db.getTopicFacts('TypeScript', { spaceName: 'B' });
|
||||
|
||||
expect(second.id).not.toBe(first.id);
|
||||
expect(alphaFacts).toHaveLength(1);
|
||||
expect(betaFacts).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user