Files
obsidian_ollama/src/semantic-cache.js
T

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;