UNPKG

autosnippet

Version:

Extract code patterns into a knowledge base for AI coding assistants

172 lines (171 loc) 8.38 kB
/** * PersistentMemory — 持久化语义记忆 (Tier 3) — Facade * * 统一的项目级永久记忆存储,使用 SQLite 提供: * - 重要性评分 (importance 1.0-10.0) * - 综合检索 (recency × importance × relevance) * - Extract-Update 模式固化 (ADD / UPDATE / MERGE / NOOP) * - Mem0 风格冲突解决 (矛盾检测 + 自动替换) * - TTL 自动过期 + 访问计数 * - 向量嵌入预留接口 * - 预算感知 toPromptSection * * 内部委托: * - MemoryStore — CRUD + SQL 基础设施 * - MemoryRetriever — 三维打分检索 + Prompt 生成 * - MemoryConsolidator — 智能固化 + 冲突解决 * * 记忆类型: fact / insight / preference * 来源: bootstrap / user / system * * @module PersistentMemory */ import { unwrapRawDb } from '../../repository/search/SearchRepoAdapter.js'; import { MemoryConsolidator } from './MemoryConsolidator.js'; import { MemoryRetriever } from './MemoryRetriever.js'; import { MemoryStore } from './MemoryStore.js'; export class PersistentMemory { #store; #retriever; #consolidator; #logger; /** @param db better-sqlite3 实例 */ constructor(db, opts = {}) { const { logger, embeddingFn, embeddingStore } = typeof opts === 'object' && opts !== null ? opts : {}; if (!db) { throw new Error('PersistentMemory requires a database instance'); } const rawDb = unwrapRawDb(db); this.#logger = logger || null; // 组装子模块 this.#store = new MemoryStore(rawDb); this.#retriever = new MemoryRetriever(this.#store, { embeddingFn, embeddingStore }); this.#consolidator = new MemoryConsolidator(this.#store, { logger: this.#logger }); } // ═══════════════════════════════════════════════════════════ // 基本 CRUD — 委托 MemoryStore // ═══════════════════════════════════════════════════════════ /** 添加一条记忆 */ add(memory) { return this.#store.add(memory); } /** 更新已有记忆 */ update(id, updates) { return this.#store.update(id, updates); } /** 删除一条记忆 */ delete(id) { return this.#store.delete(id); } /** 按 ID 获取 */ get(id) { return this.#store.get(id); } // ═══════════════════════════════════════════════════════════ // 智能固化 — 委托 MemoryConsolidator // ═══════════════════════════════════════════════════════════ /** 智能固化 (ADD / UPDATE / MERGE / NOOP + 冲突解决) */ consolidate(candidateMemories, opts) { return this.#consolidator.consolidate(candidateMemories, opts); } // ═══════════════════════════════════════════════════════════ // 综合检索 — 委托 MemoryRetriever // ═══════════════════════════════════════════════════════════ /** 三维打分综合检索 (含向量相关性) */ async retrieve(query, opts) { return this.#retriever.retrieve(query, opts); } /** 简单文本搜索 */ search(content, opts) { return this.#retriever.search(content, opts); } // ═══════════════════════════════════════════════════════════ // Prompt 生成 + 兼容层 — 委托 MemoryRetriever // ═══════════════════════════════════════════════════════════ /** 预算感知 Prompt section */ async toPromptSection(opts) { return this.#retriever.toPromptSection(opts); } /** 兼容 Memory.load() */ load(limit, opts) { return this.#retriever.load(limit, opts); } /** 兼容 Memory.append() */ append(entry) { return this.#retriever.append(entry); } // ═══════════════════════════════════════════════════════════ // 维护 + 统计 — 委托 MemoryStore // ═══════════════════════════════════════════════════════════ /** 记忆总数 */ size(opts) { return this.#store.size(opts); } /** 维护: 过期清理 + 容量控制 */ compact() { const stats = this.#store.compact(); this.#log(`Compact: ${stats.expired} expired, ${stats.forgotten} forgotten, ${stats.archived} archived, ${stats.remaining} remaining`); return stats; } /** 获取统计信息 */ getStats() { return this.#store.getStats(); } /** 清除所有 bootstrap 来源的记忆 */ clearBootstrapMemories() { const changes = this.#store.clearBootstrapMemories(); this.#log(`Cleared ${changes} bootstrap memories`); return changes; } // ═══════════════════════════════════════════════════════════ // Legacy Migration — 委托 MemoryConsolidator // ═══════════════════════════════════════════════════════════ /** 从旧版 Memory.js JSONL 文件迁移 */ async migrateFromLegacy(projectRoot) { return this.#consolidator.migrateFromLegacy(projectRoot); } // ═══════════════════════════════════════════════════════════ // 向量嵌入接口 — 委托 MemoryRetriever // ═══════════════════════════════════════════════════════════ /** 设置向量嵌入函数 */ setEmbeddingFunction(fn) { this.#retriever.setEmbeddingFunction(fn); } /** 获取当前嵌入函数 */ getEmbeddingFunction() { return this.#retriever.getEmbeddingFunction(); } /** * 为所有缺少 embedding 的记忆批量生成向量嵌入 * @param batchSize 每批数量 * @returns 成功嵌入的记忆数 */ async embedAllMemories(batchSize = 20) { const count = await this.#retriever.embedAllMemories(batchSize); if (count > 0) { this.#log(`Embedded ${count} memories`); } return count; } /** * 计算语义相关性 (异步,使用向量余弦相似度) * @param query 查询文本 * @param content 记忆内容 * @returns 相似度分数 或 null */ async computeEmbeddingRelevance(query, content) { return this.#retriever.computeEmbeddingRelevance(query, content); } // ═══════════════════════════════════════════════════════════ // Private // ═══════════════════════════════════════════════════════════ #log(msg) { const formatted = `[PersistentMemory] ${msg}`; if (this.#logger?.info) { this.#logger.info(formatted); } } } // ── 向后兼容 ── export { PersistentMemory as ProjectSemanticMemory }; export default PersistentMemory;