UNPKG

claude-conversation-manager

Version:

A CLI tool for managing Claude Code conversation history with parsing and i18n support

71 lines 3.09 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MemoryRetrieval = void 0; class MemoryRetrieval { search(items, keyword, limit = 10) { const needle = keyword.trim().toLowerCase(); if (!needle || limit <= 0) return []; return items .filter(item => item.text.toLowerCase().includes(needle) || item.type.toLowerCase().includes(needle)) .map(item => ({ item, score: this.searchScore(item, needle) })) .sort((a, b) => b.score - a.score) .slice(0, limit); } recall(items, query, limit = 5) { const documents = items.map(item => this.tokens(item.text)); const queryTokens = this.tokens(query); if (queryTokens.length === 0 || limit <= 0) return []; const vocabulary = new Set([...queryTokens, ...documents.flat()]); const idf = new Map(); for (const token of vocabulary) { const containingDocuments = documents.filter(document => document.includes(token)).length; idf.set(token, Math.log((items.length + 1) / (containingDocuments + 1)) + 1); } const queryVector = this.vector(queryTokens, vocabulary, idf); return items .map((item, index) => { const similarity = this.cosine(queryVector, this.vector(documents[index], vocabulary, idf)); const score = similarity > 0 ? similarity + this.recencyBoost(item) * 0.05 : 0; return { item, score }; }) .filter(result => result.score > 0) .sort((a, b) => b.score - a.score) .slice(0, limit); } tokens(text) { return text .toLowerCase() .split(/[^a-z0-9_\-/.\\]+/i) .map(token => token.trim()) .filter(token => token.length > 1); } vector(tokens, vocabulary, idf) { return [...vocabulary].map(token => { const termFrequency = tokens.filter(current => current === token).length / Math.max(tokens.length, 1); return termFrequency * (idf.get(token) || 1); }); } cosine(a, b) { const dot = a.reduce((sum, value, index) => sum + value * b[index], 0); const normA = Math.sqrt(a.reduce((sum, value) => sum + value * value, 0)); const normB = Math.sqrt(b.reduce((sum, value) => sum + value * value, 0)); if (normA === 0 || normB === 0) return 0; return dot / (normA * normB); } recencyBoost(item) { const timestamp = new Date(item.timestamp).getTime(); return Number.isFinite(timestamp) ? timestamp / 10000000000000 : 0; } searchScore(item, keyword) { const text = item.text.toLowerCase(); const type = item.type.toLowerCase(); const textMatches = text.split(keyword).length - 1; const typeMatches = type.includes(keyword) ? 1 : 0; return textMatches + typeMatches + this.recencyBoost(item) * 0.05; } } exports.MemoryRetrieval = MemoryRetrieval; //# sourceMappingURL=retrieval.js.map