97 lines
3.1 KiB
JavaScript
97 lines
3.1 KiB
JavaScript
'use strict';
|
|
// src/semantic-cache.ts
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
exports.SemanticCacheService = void 0;
|
|
const chromadb_1 = require('chromadb');
|
|
const utils_1 = require('./utils');
|
|
class SemanticCacheService {
|
|
constructor(ollamaURL, config) {
|
|
this.collection = null;
|
|
this.ollamaURL = ollamaURL.replace(/\/+$/, '');
|
|
this.config = config;
|
|
// Use configurable ChromaDB URL or default to localhost
|
|
this.chromaURL = config.chromaURL || 'http://localhost:8000';
|
|
this.client = new chromadb_1.ChromaClient({ path: this.chromaURL });
|
|
}
|
|
async initialize() {
|
|
if (!this.config.enabled) return;
|
|
try {
|
|
this.collection = await this.client.getOrCreateCollection({
|
|
name: this.config.collectionName,
|
|
metadata: { 'hnsw:space': 'cosine' },
|
|
});
|
|
utils_1.Logger.info(
|
|
`Semantic cache initialized: ${this.config.collectionName}`,
|
|
'semantic-cache'
|
|
);
|
|
} catch (error) {
|
|
utils_1.Logger.error(
|
|
`Failed to initialize semantic cache: ${error.message}`,
|
|
'semantic-cache'
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
async getCache(query) {
|
|
if (!this.config.enabled || !this.collection) return null;
|
|
try {
|
|
const results = await this.collection.query({
|
|
query_embeddings: await this.generateEmbedding(query),
|
|
n_results: 1,
|
|
where: { source: 'ollama' },
|
|
});
|
|
if (results.ids[0] && results.ids[0].length > 0) {
|
|
const [id] = results.ids[0];
|
|
const [content] = results.documents[0];
|
|
if (results.distances[0] && results.distances[0][0] > this.config.similarityThreshold) {
|
|
return content;
|
|
}
|
|
}
|
|
return null;
|
|
} catch (error) {
|
|
utils_1.Logger.warn(`Cache lookup failed: ${error.message}`, 'semantic-cache');
|
|
return null;
|
|
}
|
|
}
|
|
async setCache(query, response) {
|
|
if (!this.config.enabled || !this.collection) return;
|
|
try {
|
|
await this.collection.add({
|
|
ids: [crypto.randomUUID()],
|
|
documents: [response],
|
|
embeddings: await this.generateEmbedding(query),
|
|
metadatas: [{ source: 'ollama' }],
|
|
});
|
|
} catch (error) {
|
|
utils_1.Logger.warn(`Cache set failed: ${error.message}`, 'semantic-cache');
|
|
}
|
|
}
|
|
async clearCache() {
|
|
if (!this.config.enabled || !this.collection) return;
|
|
try {
|
|
await this.collection.reset();
|
|
utils_1.Logger.info('Semantic cache cleared', 'semantic-cache');
|
|
} catch (error) {
|
|
utils_1.Logger.error(`Failed to clear semantic cache: ${error.message}`, 'semantic-cache');
|
|
}
|
|
}
|
|
async generateEmbedding(text) {
|
|
const response = await fetch(`${this.ollamaURL}/api/embeddings`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
model: this.config.embeddingModel,
|
|
prompt: text,
|
|
}),
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to generate embedding: ${response.status} ${response.statusText}`);
|
|
}
|
|
const data = await response.json();
|
|
return data.embedding;
|
|
}
|
|
}
|
|
exports.SemanticCacheService = SemanticCacheService;
|