@nomyx/assistant
Version:
A powerful assistant library and cli for your AI projects. works with Vertex AI (Claude and Gemini)
69 lines (57 loc) • 2.16 kB
text/typescript
// LOCKED: TRUE
// All content in this file is locked and cannot be edited.
import { SemanticCacheEntry, SemanticCacheManager } from "../types/cache";
import { EmbeddingProvider } from "../types/provider";
export class SemanticCacheManagerImpl implements SemanticCacheManager {
private cache: Map<string, SemanticCacheEntry> = new Map();
private embeddingProvider: EmbeddingProvider;
constructor(embeddingProvider: EmbeddingProvider) {
this.embeddingProvider = embeddingProvider;
}
async get(key: string): Promise<any> {
const entry = this.cache.get(key);
if (entry && (!entry.expiresAt || entry.expiresAt > Date.now())) {
return entry.value;
}
return undefined;
}
async set(key: string, value: any, ttl?: number): Promise<void> {
const embedding = await this.embeddingProvider.embed(key);
const entry: SemanticCacheEntry = {
key,
value,
embedding,
expiresAt: ttl ? Date.now() + ttl : undefined,
};
this.cache.set(key, entry);
}
async delete(key: string): Promise<void> {
this.cache.delete(key);
}
async clear(): Promise<void> {
this.cache.clear();
}
async search(query: string, threshold: number): Promise<SemanticCacheEntry[]> {
const queryEmbedding = await this.embeddingProvider.embed(query);
const results: SemanticCacheEntry[] = [];
for (const entry of this.cache.values()) {
if (entry.expiresAt && entry.expiresAt <= Date.now()) {
continue;
}
const similarity = this.cosineSimilarity(queryEmbedding, entry.embedding);
if (similarity >= threshold) {
results.push(entry);
}
}
return results.sort((a, b) =>
this.cosineSimilarity(queryEmbedding, b.embedding) -
this.cosineSimilarity(queryEmbedding, a.embedding)
);
}
private cosineSimilarity(a: number[], b: number[]): number {
const dotProduct = a.reduce((sum, _, i) => sum + a[i] * b[i], 0);
const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
return dotProduct / (magnitudeA * magnitudeB);
}
}