@smyslenny/agent-memory 2.2.0 → 4.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +163 -41
- package/README.md +234 -156
- package/dist/bin/agent-memory.js +2423 -784
- package/dist/bin/agent-memory.js.map +1 -1
- package/dist/index.d.ts +535 -215
- package/dist/index.js +2635 -876
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +2330 -928
- package/dist/mcp/server.js.map +1 -1
- package/docs/README-zh.md +23 -0
- package/docs/architecture.md +239 -0
- package/docs/assets/architecture-diagram.jpg +0 -0
- package/docs/assets/banner.jpg +0 -0
- package/docs/assets/icon.jpg +0 -0
- package/docs/assets/npm-badge.jpg +0 -0
- package/docs/assets/social-preview.jpg +0 -0
- package/docs/design/0014-memory-core-dedup.md +722 -0
- package/docs/design/0015-v4-overhaul.md +631 -0
- package/docs/design/TEMPLATE.md +67 -0
- package/docs/integrations/generic.md +293 -0
- package/docs/integrations/openclaw.md +148 -0
- package/docs/migration-v3-v4.md +236 -0
- package/package.json +11 -5
- package/README.zh-CN.md +0 -170
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/db.ts","../../src/core/memory.ts","../../src/search/tokenizer.ts","../../src/core/export.ts","../../src/search/intent.ts","../../src/search/rerank.ts","../../src/search/bm25.ts","../../src/search/embeddings.ts","../../src/search/hybrid.ts","../../src/search/providers.ts","../../src/search/embed.ts","../../src/core/path.ts","../../src/sleep/boot.ts","../../src/sleep/decay.ts","../../src/core/snapshot.ts","../../src/sleep/tidy.ts","../../src/sleep/govern.ts","../../src/core/guard.ts","../../src/sleep/sync.ts","../../src/bin/agent-memory.ts"],"sourcesContent":["// AgentMemory v2 — SQLite database initialization and schema\nimport Database from \"better-sqlite3\";\nimport { randomUUID } from \"crypto\";\n\nexport const SCHEMA_VERSION = 3;\n\nconst SCHEMA_SQL = `\n-- Memory entries\nCREATE TABLE IF NOT EXISTS memories (\n id TEXT PRIMARY KEY,\n content TEXT NOT NULL,\n type TEXT NOT NULL CHECK(type IN ('identity','emotion','knowledge','event')),\n priority INTEGER NOT NULL DEFAULT 2 CHECK(priority BETWEEN 0 AND 3),\n emotion_val REAL NOT NULL DEFAULT 0.0,\n vitality REAL NOT NULL DEFAULT 1.0,\n stability REAL NOT NULL DEFAULT 1.0,\n access_count INTEGER NOT NULL DEFAULT 0,\n last_accessed TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n source TEXT,\n agent_id TEXT NOT NULL DEFAULT 'default',\n hash TEXT,\n UNIQUE(hash, agent_id)\n);\n\n-- URI paths (Content-Path separation, from nocturne)\nCREATE TABLE IF NOT EXISTS paths (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n agent_id TEXT NOT NULL DEFAULT 'default',\n uri TEXT NOT NULL,\n alias TEXT,\n domain TEXT NOT NULL,\n created_at TEXT NOT NULL,\n UNIQUE(agent_id, uri)\n);\n\n-- Association network (knowledge graph)\nCREATE TABLE IF NOT EXISTS links (\n agent_id TEXT NOT NULL DEFAULT 'default',\n source_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n target_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n relation TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1.0,\n created_at TEXT NOT NULL,\n PRIMARY KEY (agent_id, source_id, target_id)\n);\n\n-- Snapshots (version control, from nocturne + Memory Palace)\nCREATE TABLE IF NOT EXISTS snapshots (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n content TEXT NOT NULL,\n changed_by TEXT,\n action TEXT NOT NULL CHECK(action IN ('create','update','delete','merge')),\n created_at TEXT NOT NULL\n);\n\n-- Full-text search index (BM25)\nCREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(\n id UNINDEXED,\n content,\n tokenize='unicode61'\n);\n\n-- Embeddings (optional semantic layer)\nCREATE TABLE IF NOT EXISTS embeddings (\n agent_id TEXT NOT NULL DEFAULT 'default',\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n model TEXT NOT NULL,\n dim INTEGER NOT NULL,\n vector BLOB NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (agent_id, memory_id, model)\n);\n\n-- Schema version tracking\nCREATE TABLE IF NOT EXISTS schema_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n);\n\n-- Indexes for common queries\nCREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);\nCREATE INDEX IF NOT EXISTS idx_memories_priority ON memories(priority);\nCREATE INDEX IF NOT EXISTS idx_memories_agent ON memories(agent_id);\nCREATE INDEX IF NOT EXISTS idx_memories_vitality ON memories(vitality);\nCREATE INDEX IF NOT EXISTS idx_memories_hash ON memories(hash);\nCREATE INDEX IF NOT EXISTS idx_paths_memory ON paths(memory_id);\nCREATE INDEX IF NOT EXISTS idx_paths_domain ON paths(domain);\n`;\n\nexport interface DbOptions {\n path: string;\n walMode?: boolean;\n}\n\n/**\n * Type guard for SQLite count query results.\n * Validates that a row has a numeric 'c' property.\n */\nexport function isCountRow(row: unknown): row is { c: number } {\n return row !== null && typeof row === \"object\" && \"c\" in (row as Record<string, unknown>) && typeof (row as Record<string, unknown>).c === \"number\";\n}\n\nexport function openDatabase(opts: DbOptions): Database.Database {\n const db = new Database(opts.path);\n\n // Enable WAL mode for better concurrent read performance\n if (opts.walMode !== false) {\n db.pragma(\"journal_mode = WAL\");\n }\n db.pragma(\"foreign_keys = ON\");\n db.pragma(\"busy_timeout = 5000\");\n\n // Run schema creation\n db.exec(SCHEMA_SQL);\n\n // Track schema version and migrate forward if needed\n const currentVersion = getSchemaVersion(db);\n if (currentVersion === null) {\n const inferred = inferSchemaVersion(db);\n if (inferred < SCHEMA_VERSION) {\n migrateDatabase(db, inferred, SCHEMA_VERSION);\n }\n db.prepare(\"INSERT OR REPLACE INTO schema_meta (key, value) VALUES ('version', ?)\").run(String(SCHEMA_VERSION));\n } else if (currentVersion < SCHEMA_VERSION) {\n migrateDatabase(db, currentVersion, SCHEMA_VERSION);\n }\n\n ensureIndexes(db);\n\n return db;\n}\n\nexport function now(): string {\n return new Date().toISOString();\n}\n\nexport function newId(): string {\n return randomUUID();\n}\n\nfunction getSchemaVersion(db: Database.Database): number | null {\n try {\n const row = db.prepare(\"SELECT value FROM schema_meta WHERE key = 'version'\").get() as { value: string } | undefined;\n if (!row) return null;\n const n = Number.parseInt(row.value, 10);\n return Number.isFinite(n) ? n : null;\n } catch {\n return null;\n }\n}\n\nfunction tableHasColumn(db: Database.Database, table: string, column: string): boolean {\n try {\n const cols = db.prepare(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>;\n return cols.some((c) => c.name === column);\n } catch {\n return false;\n }\n}\n\nfunction migrateDatabase(db: Database.Database, from: number, to: number): void {\n let v = from;\n while (v < to) {\n if (v === 1) {\n migrateV1ToV2(db);\n v = 2;\n continue;\n }\n if (v === 2) {\n migrateV2ToV3(db);\n v = 3;\n continue;\n }\n throw new Error(`Unsupported schema migration path: v${from} → v${to} (stuck at v${v})`);\n }\n}\n\nfunction migrateV1ToV2(db: Database.Database): void {\n // v2 introduces agent-scoped paths and links.\n // We rebuild both tables to add agent_id and adjust uniqueness/primary keys.\n const pathsMigrated = tableHasColumn(db, \"paths\", \"agent_id\");\n const linksMigrated = tableHasColumn(db, \"links\", \"agent_id\");\n const alreadyMigrated = pathsMigrated && linksMigrated;\n if (alreadyMigrated) {\n db.prepare(\"UPDATE schema_meta SET value = ? WHERE key = 'version'\").run(String(2));\n return;\n }\n\n db.pragma(\"foreign_keys = OFF\");\n try {\n db.exec(\"BEGIN\");\n\n // ---- paths ----\n if (!pathsMigrated) {\n db.exec(`\n CREATE TABLE IF NOT EXISTS paths_v2 (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n agent_id TEXT NOT NULL DEFAULT 'default',\n uri TEXT NOT NULL,\n alias TEXT,\n domain TEXT NOT NULL,\n created_at TEXT NOT NULL,\n UNIQUE(agent_id, uri)\n );\n `);\n\n // Derive agent_id from the referenced memory (fallback to 'default' for orphans).\n db.exec(`\n INSERT INTO paths_v2 (id, memory_id, agent_id, uri, alias, domain, created_at)\n SELECT p.id, p.memory_id, COALESCE(m.agent_id, 'default'), p.uri, p.alias, p.domain, p.created_at\n FROM paths p\n LEFT JOIN memories m ON m.id = p.memory_id;\n `);\n\n db.exec(\"DROP TABLE paths;\");\n db.exec(\"ALTER TABLE paths_v2 RENAME TO paths;\");\n }\n\n // ---- links ----\n if (!linksMigrated) {\n db.exec(`\n CREATE TABLE IF NOT EXISTS links_v2 (\n agent_id TEXT NOT NULL DEFAULT 'default',\n source_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n target_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n relation TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1.0,\n created_at TEXT NOT NULL,\n PRIMARY KEY (agent_id, source_id, target_id)\n );\n `);\n\n // Derive agent_id from source memory; delete links where source/target agent mismatch after migration.\n db.exec(`\n INSERT INTO links_v2 (agent_id, source_id, target_id, relation, weight, created_at)\n SELECT COALESCE(ms.agent_id, 'default'), l.source_id, l.target_id, l.relation, l.weight, l.created_at\n FROM links l\n LEFT JOIN memories ms ON ms.id = l.source_id;\n `);\n\n // Remove cross-agent links (cannot be represented safely in v2 semantics).\n db.exec(`\n DELETE FROM links_v2\n WHERE EXISTS (SELECT 1 FROM memories s WHERE s.id = links_v2.source_id AND s.agent_id != links_v2.agent_id)\n OR EXISTS (SELECT 1 FROM memories t WHERE t.id = links_v2.target_id AND t.agent_id != links_v2.agent_id);\n `);\n\n db.exec(\"DROP TABLE links;\");\n db.exec(\"ALTER TABLE links_v2 RENAME TO links;\");\n }\n\n // Recreate indexes that were dropped with the old tables.\n db.exec(`\n CREATE INDEX IF NOT EXISTS idx_paths_memory ON paths(memory_id);\n CREATE INDEX IF NOT EXISTS idx_paths_domain ON paths(domain);\n `);\n\n db.prepare(\"UPDATE schema_meta SET value = ? WHERE key = 'version'\").run(String(2));\n db.exec(\"COMMIT\");\n } catch (e) {\n try { db.exec(\"ROLLBACK\"); } catch {}\n throw e;\n } finally {\n db.pragma(\"foreign_keys = ON\");\n }\n}\n\nfunction inferSchemaVersion(db: Database.Database): number {\n // Best-effort inference for databases created without schema_meta.\n const hasAgentScopedPaths = tableHasColumn(db, \"paths\", \"agent_id\");\n const hasAgentScopedLinks = tableHasColumn(db, \"links\", \"agent_id\");\n const hasEmbeddings = (() => {\n try {\n const row = db.prepare(\"SELECT name FROM sqlite_master WHERE type='table' AND name='embeddings'\").get() as { name: string } | undefined;\n return Boolean(row);\n } catch {\n return false;\n }\n })();\n if (hasAgentScopedPaths && hasAgentScopedLinks && hasEmbeddings) return 3;\n if (hasAgentScopedPaths && hasAgentScopedLinks) return 2;\n return 1;\n}\n\nfunction ensureIndexes(db: Database.Database): void {\n // Indexes that depend on newer columns must be created conditionally.\n if (tableHasColumn(db, \"paths\", \"agent_id\")) {\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_paths_agent_uri ON paths(agent_id, uri);\");\n }\n if (tableHasColumn(db, \"links\", \"agent_id\")) {\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_links_agent_source ON links(agent_id, source_id);\");\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_links_agent_target ON links(agent_id, target_id);\");\n }\n try {\n const row = db.prepare(\"SELECT name FROM sqlite_master WHERE type='table' AND name='embeddings'\").get() as { name: string } | undefined;\n if (row) {\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_embeddings_agent_model ON embeddings(agent_id, model);\");\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_embeddings_memory ON embeddings(memory_id);\");\n }\n } catch {\n // ignore\n }\n}\n\nfunction migrateV2ToV3(db: Database.Database): void {\n // v3 introduces embeddings table for optional semantic search.\n // Safe additive migration.\n try {\n db.exec(\"BEGIN\");\n db.exec(`\n CREATE TABLE IF NOT EXISTS embeddings (\n agent_id TEXT NOT NULL DEFAULT 'default',\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n model TEXT NOT NULL,\n dim INTEGER NOT NULL,\n vector BLOB NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (agent_id, memory_id, model)\n );\n `);\n db.prepare(\"UPDATE schema_meta SET value = ? WHERE key = 'version'\").run(String(3));\n db.exec(\"COMMIT\");\n } catch (e) {\n try { db.exec(\"ROLLBACK\"); } catch {}\n throw e;\n }\n}\n","// AgentMemory v2 — Memory CRUD operations\nimport { createHash } from \"crypto\";\nimport type Database from \"better-sqlite3\";\nimport { newId, now } from \"./db.js\";\nimport { tokenizeForIndex } from \"../search/tokenizer.js\";\n\nexport type MemoryType = \"identity\" | \"emotion\" | \"knowledge\" | \"event\";\nexport type Priority = 0 | 1 | 2 | 3;\n\nexport interface Memory {\n id: string;\n content: string;\n type: MemoryType;\n priority: Priority;\n emotion_val: number;\n vitality: number;\n stability: number;\n access_count: number;\n last_accessed: string | null;\n created_at: string;\n updated_at: string;\n source: string | null;\n agent_id: string;\n hash: string | null;\n}\n\nexport interface CreateMemoryInput {\n content: string;\n type: MemoryType;\n priority?: Priority;\n emotion_val?: number;\n source?: string;\n agent_id?: string;\n}\n\nexport interface UpdateMemoryInput {\n content?: string;\n type?: MemoryType;\n priority?: Priority;\n emotion_val?: number;\n vitality?: number;\n stability?: number;\n source?: string;\n}\n\nexport function contentHash(content: string): string {\n return createHash(\"sha256\").update(content.trim()).digest(\"hex\").slice(0, 16);\n}\n\n// Priority defaults based on type\nconst TYPE_PRIORITY: Record<MemoryType, Priority> = {\n identity: 0,\n emotion: 1,\n knowledge: 2,\n event: 3,\n};\n\n// Initial stability (Ebbinghaus S parameter) based on priority\nconst PRIORITY_STABILITY: Record<Priority, number> = {\n 0: Infinity, // P0: never decays\n 1: 365, // P1: 365-day half-life\n 2: 90, // P2: 90-day half-life\n 3: 14, // P3: 14-day half-life\n};\n\nexport function createMemory(db: Database.Database, input: CreateMemoryInput): Memory | null {\n const hash = contentHash(input.content);\n const agentId = input.agent_id ?? \"default\";\n const priority = input.priority ?? TYPE_PRIORITY[input.type];\n const stability = PRIORITY_STABILITY[priority];\n\n // Dedup: check if identical content already exists for this agent\n const existing = db\n .prepare(\"SELECT id FROM memories WHERE hash = ? AND agent_id = ?\")\n .get(hash, agentId) as { id: string } | undefined;\n if (existing) {\n return null; // Already exists, skip\n }\n\n const id = newId();\n const timestamp = now();\n\n db.prepare(\n `INSERT INTO memories (id, content, type, priority, emotion_val, vitality, stability,\n access_count, created_at, updated_at, source, agent_id, hash)\n VALUES (?, ?, ?, ?, ?, 1.0, ?, 0, ?, ?, ?, ?, ?)`,\n ).run(\n id,\n input.content,\n input.type,\n priority,\n input.emotion_val ?? 0.0,\n stability === Infinity ? 999999 : stability,\n timestamp,\n timestamp,\n input.source ?? null,\n agentId,\n hash,\n );\n\n // Sync to FTS index (tokenized for CJK support)\n db.prepare(\"INSERT INTO memories_fts (id, content) VALUES (?, ?)\").run(id, tokenizeForIndex(input.content));\n\n return getMemory(db, id)!;\n}\n\nexport function getMemory(db: Database.Database, id: string): Memory | null {\n return (db.prepare(\"SELECT * FROM memories WHERE id = ?\").get(id) as Memory) ?? null;\n}\n\nexport function updateMemory(\n db: Database.Database,\n id: string,\n input: UpdateMemoryInput,\n): Memory | null {\n const existing = getMemory(db, id);\n if (!existing) return null;\n\n const fields: string[] = [];\n const values: unknown[] = [];\n\n if (input.content !== undefined) {\n fields.push(\"content = ?\", \"hash = ?\");\n values.push(input.content, contentHash(input.content));\n }\n if (input.type !== undefined) {\n fields.push(\"type = ?\");\n values.push(input.type);\n }\n if (input.priority !== undefined) {\n fields.push(\"priority = ?\");\n values.push(input.priority);\n }\n if (input.emotion_val !== undefined) {\n fields.push(\"emotion_val = ?\");\n values.push(input.emotion_val);\n }\n if (input.vitality !== undefined) {\n fields.push(\"vitality = ?\");\n values.push(input.vitality);\n }\n if (input.stability !== undefined) {\n fields.push(\"stability = ?\");\n values.push(input.stability);\n }\n if (input.source !== undefined) {\n fields.push(\"source = ?\");\n values.push(input.source);\n }\n\n fields.push(\"updated_at = ?\");\n values.push(now());\n values.push(id);\n\n db.prepare(`UPDATE memories SET ${fields.join(\", \")} WHERE id = ?`).run(...values);\n\n // Update FTS if content changed\n if (input.content !== undefined) {\n db.prepare(\"DELETE FROM memories_fts WHERE id = ?\").run(id);\n db.prepare(\"INSERT INTO memories_fts (id, content) VALUES (?, ?)\").run(id, tokenizeForIndex(input.content));\n }\n\n return getMemory(db, id);\n}\n\nexport function deleteMemory(db: Database.Database, id: string): boolean {\n // FTS cleanup\n db.prepare(\"DELETE FROM memories_fts WHERE id = ?\").run(id);\n const result = db.prepare(\"DELETE FROM memories WHERE id = ?\").run(id);\n return result.changes > 0;\n}\n\nexport function listMemories(\n db: Database.Database,\n opts?: {\n agent_id?: string;\n type?: MemoryType;\n priority?: Priority;\n min_vitality?: number;\n limit?: number;\n offset?: number;\n },\n): Memory[] {\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (opts?.agent_id) {\n conditions.push(\"agent_id = ?\");\n params.push(opts.agent_id);\n }\n if (opts?.type) {\n conditions.push(\"type = ?\");\n params.push(opts.type);\n }\n if (opts?.priority !== undefined) {\n conditions.push(\"priority = ?\");\n params.push(opts.priority);\n }\n if (opts?.min_vitality !== undefined) {\n conditions.push(\"vitality >= ?\");\n params.push(opts.min_vitality);\n }\n\n const where = conditions.length ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n const limit = opts?.limit ?? 100;\n const offset = opts?.offset ?? 0;\n\n return db\n .prepare(`SELECT * FROM memories ${where} ORDER BY priority ASC, updated_at DESC LIMIT ? OFFSET ?`)\n .all(...params, limit, offset) as Memory[];\n}\n\nexport function recordAccess(db: Database.Database, id: string, growthFactor = 1.5): void {\n const mem = getMemory(db, id);\n if (!mem) return;\n\n const newStability = Math.min(999999, mem.stability * growthFactor);\n\n db.prepare(\n `UPDATE memories SET access_count = access_count + 1, last_accessed = ?, stability = ?,\n vitality = MIN(1.0, vitality * 1.2) WHERE id = ?`,\n ).run(now(), newStability, id);\n}\n\nexport function countMemories(\n db: Database.Database,\n agent_id = \"default\",\n): { total: number; by_type: Record<string, number>; by_priority: Record<string, number> } {\n const total = (\n db.prepare(\"SELECT COUNT(*) as c FROM memories WHERE agent_id = ?\").get(agent_id) as {\n c: number;\n }\n ).c;\n\n const byType = db\n .prepare(\"SELECT type, COUNT(*) as c FROM memories WHERE agent_id = ? GROUP BY type\")\n .all(agent_id) as Array<{ type: string; c: number }>;\n\n const byPriority = db\n .prepare(\"SELECT priority, COUNT(*) as c FROM memories WHERE agent_id = ? GROUP BY priority\")\n .all(agent_id) as Array<{ priority: number; c: number }>;\n\n return {\n total,\n by_type: Object.fromEntries(byType.map((r) => [r.type, r.c])),\n by_priority: Object.fromEntries(byPriority.map((r) => [`P${r.priority}`, r.c])),\n };\n}\n","// AgentMemory v2 — Tokenizer with jieba Chinese segmentation\n// Uses @node-rs/jieba for proper Chinese word segmentation,\n// falls back to CJK bigram splitting if jieba unavailable.\n\nimport { readFileSync } from \"fs\";\nimport { createRequire } from \"module\";\n\ninterface JiebaInstance {\n cutForSearch(text: string): string[];\n}\n\nlet _jieba: JiebaInstance | null | undefined; // undefined = not tried yet\n\n/**\n * Lazily initialize jieba with built-in dictionary.\n * Returns null if @node-rs/jieba is not installed.\n */\nfunction getJieba(): JiebaInstance | null {\n if (_jieba !== undefined) return _jieba;\n\n try {\n // Use createRequire to resolve from this package's node_modules\n const req = createRequire(import.meta.url);\n const { Jieba } = req(\"@node-rs/jieba\");\n const dictPath = req.resolve(\"@node-rs/jieba/dict.txt\");\n const dictBuf = readFileSync(dictPath);\n _jieba = Jieba.withDict(dictBuf) as JiebaInstance;\n } catch {\n _jieba = null;\n }\n return _jieba;\n}\n\n// Common Chinese stopwords to filter out\nconst STOPWORDS = new Set([\n \"的\", \"了\", \"在\", \"是\", \"我\", \"有\", \"和\", \"就\", \"不\", \"人\",\n \"都\", \"一\", \"个\", \"上\", \"也\", \"到\", \"他\", \"没\", \"这\", \"要\",\n \"会\", \"对\", \"说\", \"而\", \"去\", \"之\", \"被\", \"她\", \"把\", \"那\",\n]);\n\n/**\n * Tokenize text for FTS5 queries.\n * - Latin/numeric words: split on whitespace, filter len > 1\n * - CJK text: use jieba cutForSearch, fallback to unigram + bigram\n * Returns deduplicated token array, max 30 tokens.\n */\nexport function tokenize(text: string): string[] {\n const cleaned = text.replace(/[^\\w\\u4e00-\\u9fff\\u3040-\\u30ff\\uac00-\\ud7af\\s]/g, \" \");\n const tokens: string[] = [];\n\n // Extract Latin/numeric words\n const latinWords = cleaned\n .replace(/[\\u4e00-\\u9fff\\u3040-\\u30ff\\uac00-\\ud7af]/g, \" \")\n .split(/\\s+/)\n .filter((w) => w.length > 1);\n tokens.push(...latinWords);\n\n // Extract CJK portions\n const cjkChunks = cleaned.match(/[\\u4e00-\\u9fff\\u3040-\\u30ff\\uac00-\\ud7af]+/g);\n if (cjkChunks && cjkChunks.length > 0) {\n const jieba = getJieba();\n for (const chunk of cjkChunks) {\n if (jieba) {\n // Use jieba for proper segmentation\n const words = jieba.cutForSearch(chunk).filter((w: string) => w.length >= 1);\n tokens.push(...words);\n } else {\n // Fallback: unigrams + bigrams\n for (const ch of chunk) {\n tokens.push(ch);\n }\n for (let i = 0; i < chunk.length - 1; i++) {\n tokens.push(chunk[i] + chunk[i + 1]);\n }\n }\n }\n }\n\n // Deduplicate, filter stopwords, limit\n const unique = [...new Set(tokens)]\n .filter((t) => t.length > 0 && !STOPWORDS.has(t))\n .slice(0, 30);\n\n return unique;\n}\n\n/**\n * Tokenize content for FTS5 indexing.\n * Segments CJK text and joins all tokens with spaces so FTS5's unicode61\n * tokenizer can index each word separately.\n * This ensures query-side and index-side tokenization match.\n */\nexport function tokenizeForIndex(text: string): string {\n const tokens = tokenize(text);\n // Also keep the original text so exact substrings still work via LIKE fallback\n return tokens.join(\" \");\n}","// AgentMemory v2 — Export memories to Markdown files\nimport type Database from \"better-sqlite3\";\nimport { listMemories, type Memory } from \"./memory.js\";\nimport { writeFileSync, mkdirSync, existsSync } from \"fs\";\nimport { join } from \"path\";\n\nexport interface ExportResult {\n exported: number;\n files: string[];\n}\n\n/**\n * Export all memories to Markdown files in the given directory.\n * Creates MEMORY.md for identity/emotion/knowledge and daily .md files for events.\n */\nexport function exportMemories(\n db: Database.Database,\n dirPath: string,\n opts?: { agent_id?: string },\n): ExportResult {\n const agentId = opts?.agent_id ?? \"default\";\n if (!existsSync(dirPath)) mkdirSync(dirPath, { recursive: true });\n\n let exported = 0;\n const files: string[] = [];\n\n // Export identity, emotion, knowledge as MEMORY.md\n const identities = listMemories(db, { agent_id: agentId, type: \"identity\" });\n const knowledge = listMemories(db, { agent_id: agentId, type: \"knowledge\" });\n const emotions = listMemories(db, { agent_id: agentId, type: \"emotion\" });\n\n if (identities.length || knowledge.length || emotions.length) {\n const sections: string[] = [\"# Agent Memory Export\\n\"];\n\n if (identities.length) {\n sections.push(\"## Identity\\n\");\n for (const m of identities) {\n sections.push(`- ${m.content}\\n`);\n exported++;\n }\n }\n if (emotions.length) {\n sections.push(\"\\n## Emotions\\n\");\n for (const m of emotions) {\n sections.push(`- ${m.content}\\n`);\n exported++;\n }\n }\n if (knowledge.length) {\n sections.push(\"\\n## Knowledge\\n\");\n for (const m of knowledge) {\n sections.push(`- ${m.content}\\n`);\n exported++;\n }\n }\n\n const memoryPath = join(dirPath, \"MEMORY.md\");\n writeFileSync(memoryPath, sections.join(\"\\n\"));\n files.push(memoryPath);\n }\n\n // Export events as daily journal files\n const events = listMemories(db, { agent_id: agentId, type: \"event\", limit: 10000 });\n const byDate = new Map<string, Memory[]>();\n for (const ev of events) {\n const date = ev.created_at.slice(0, 10);\n if (!byDate.has(date)) byDate.set(date, []);\n byDate.get(date)!.push(ev);\n }\n\n for (const [date, mems] of byDate) {\n const lines = [`# ${date}\\n`];\n for (const m of mems) {\n lines.push(`- ${m.content}\\n`);\n exported++;\n }\n const filePath = join(dirPath, `${date}.md`);\n writeFileSync(filePath, lines.join(\"\\n\"));\n files.push(filePath);\n }\n\n return { exported, files };\n}\n","// AgentMemory v2 — Intent classifier\n// Routes search queries to optimal strategies\n// Enhanced Chinese support with jieba tokenization\n\nimport { tokenize } from \"./tokenizer.js\";\n\nexport type SearchIntent = \"factual\" | \"exploratory\" | \"temporal\" | \"causal\";\n\nexport interface IntentResult {\n intent: SearchIntent;\n confidence: number;\n}\n\n// Keyword patterns for intent detection (EN + CN)\nconst INTENT_PATTERNS: Record<SearchIntent, RegExp[]> = {\n factual: [\n // English\n /^(what|who|where|which|how much|how many)\\b/i,\n /\\b(name|address|number|password|config|setting)\\b/i,\n // Chinese - questions about facts\n /是(什么|谁|哪|啥)/,\n /叫(什么|啥)/,\n /(名字|地址|号码|密码|配置|设置|账号|邮箱|链接|版本)/,\n /(多少|几个|哪个|哪些|哪里)/,\n // Chinese - lookup patterns\n /(查一下|找一下|看看|搜一下)/,\n /(.+)是什么$/,\n ],\n temporal: [\n // English\n /^(when|what time|how long)\\b/i,\n /\\b(yesterday|today|tomorrow|last week|recently|ago|before|after)\\b/i,\n /\\b(first|latest|newest|oldest|previous|next)\\b/i,\n // Chinese - time expressions\n /什么时候/,\n /(昨天|今天|明天|上周|下周|最近|以前|之前|之后|刚才|刚刚)/,\n /(几月|几号|几点|多久|多长时间)/,\n /(上次|下次|第一次|最后一次|那天|那时)/,\n // Date patterns\n /\\d{4}[-/.]\\d{1,2}/,\n /\\d{1,2}月\\d{1,2}[日号]/,\n // Chinese - temporal context\n /(历史|记录|日志|以来|至今|期间)/,\n ],\n causal: [\n // English\n /^(why|how come|what caused)\\b/i,\n /\\b(because|due to|reason|cause|result)\\b/i,\n // Chinese - causal questions\n /为(什么|啥|何)/,\n /(原因|导致|造成|引起|因为|所以|结果)/,\n /(怎么回事|怎么了|咋回事|咋了)/,\n /(为啥|凭啥|凭什么)/,\n // Chinese - problem/diagnosis\n /(出(了|了什么)?问题|报错|失败|出错|bug)/,\n ],\n exploratory: [\n // English\n /^(how|tell me about|explain|describe|show me)\\b/i,\n /^(what do you think|what about|any)\\b/i,\n /\\b(overview|summary|list|compare)\\b/i,\n // Chinese - exploratory\n /(怎么样|怎样|如何)/,\n /(介绍|说说|讲讲|聊聊|谈谈)/,\n /(有哪些|有什么|有没有)/,\n /(关于|对于|至于|关联)/,\n /(总结|概括|梳理|回顾|盘点)/,\n // Chinese - opinion/analysis\n /(看法|想法|意见|建议|评价|感觉|觉得)/,\n /(对比|比较|区别|差异|优缺点)/,\n ],\n};\n\n// Chinese structural markers that boost certain intents\nconst CN_STRUCTURE_BOOSTS: Record<SearchIntent, RegExp[]> = {\n factual: [/^.{1,6}(是什么|叫什么|在哪)/, /^(谁|哪)/],\n temporal: [/^(什么时候|上次|最近)/, /(时间|日期)$/],\n causal: [/^(为什么|为啥)/, /(为什么|怎么回事)$/],\n exploratory: [/^(怎么|如何|说说)/, /(哪些|什么样)$/],\n};\n\n/**\n * Classify the intent of a search query.\n * Uses keyword pattern matching + structural analysis.\n * Enhanced for Chinese with jieba-aware token analysis.\n */\nexport function classifyIntent(query: string): IntentResult {\n const scores: Record<SearchIntent, number> = {\n factual: 0,\n exploratory: 0,\n temporal: 0,\n causal: 0,\n };\n\n // Pattern matching\n for (const [intent, patterns] of Object.entries(INTENT_PATTERNS)) {\n for (const pattern of patterns) {\n if (pattern.test(query)) {\n scores[intent as SearchIntent] += 1;\n }\n }\n }\n\n // Chinese structural boosts (sentence-level patterns worth more)\n for (const [intent, patterns] of Object.entries(CN_STRUCTURE_BOOSTS)) {\n for (const pattern of patterns) {\n if (pattern.test(query)) {\n scores[intent as SearchIntent] += 0.5;\n }\n }\n }\n\n // Token-based analysis: short queries with no pattern match → factual\n const tokens = tokenize(query);\n const totalPatternScore = Object.values(scores).reduce((a, b) => a + b, 0);\n if (totalPatternScore === 0 && tokens.length <= 3) {\n // Short query with no intent signal = likely a factual lookup\n scores.factual += 1;\n }\n\n // Find highest scoring intent\n let maxIntent: SearchIntent = \"factual\";\n let maxScore = 0;\n\n for (const [intent, score] of Object.entries(scores)) {\n if (score > maxScore) {\n maxScore = score;\n maxIntent = intent as SearchIntent;\n }\n }\n\n const totalScore = Object.values(scores).reduce((a, b) => a + b, 0);\n const confidence = totalScore > 0 ? Math.min(0.95, maxScore / totalScore) : 0.5;\n\n return { intent: maxIntent, confidence };\n}\n\n/**\n * Get search strategy based on intent\n */\nexport function getStrategy(intent: SearchIntent): {\n boostRecent: boolean;\n boostPriority: boolean;\n limit: number;\n} {\n switch (intent) {\n case \"factual\":\n return { boostRecent: false, boostPriority: true, limit: 5 };\n case \"temporal\":\n return { boostRecent: true, boostPriority: false, limit: 10 };\n case \"causal\":\n return { boostRecent: false, boostPriority: false, limit: 10 };\n case \"exploratory\":\n return { boostRecent: false, boostPriority: false, limit: 15 };\n }\n}\n","// AgentMemory v2 — Search result reranking + priority weighting\nimport type { SearchResult } from \"./bm25.js\";\nimport type { SearchIntent } from \"./intent.js\";\nimport type { RerankProvider } from \"./rerank-provider.js\";\n\n/**\n * Optionally rerank results using an external semantic reranker provider.\n * Best-effort: on failure, returns original results unchanged.\n */\nexport async function rerankWithProvider(\n results: SearchResult[],\n query: string,\n provider: RerankProvider,\n): Promise<SearchResult[]> {\n if (results.length === 0) return results;\n\n const documents = results.map((r) => r.memory.content);\n\n try {\n const apiResults = await provider.rerank(query, documents);\n const scoreMap = new Map(apiResults.map((r) => [r.index, r.relevance_score]));\n\n return results.map((r, i) => {\n const score = scoreMap.get(i);\n if (score === undefined) return r;\n return {\n ...r,\n score,\n matchReason: `${r.matchReason}+rerank`,\n };\n });\n } catch (err) {\n console.warn(\"[agent-memory] External rerank failed, falling back:\", err);\n return results;\n }\n}\n\n/**\n * Rerank search results based on intent strategy and priority weighting.\n */\nexport function rerank(\n results: SearchResult[],\n opts: {\n intent?: SearchIntent;\n boostRecent: boolean;\n boostPriority: boolean;\n limit: number;\n },\n): SearchResult[] {\n const now = Date.now();\n\n const scored = results.map((r) => {\n let finalScore = r.score;\n\n // Priority boost: P0 > P1 > P2 > P3\n if (opts.boostPriority) {\n const priorityMultiplier = [4.0, 3.0, 2.0, 1.0][r.memory.priority] ?? 1.0;\n finalScore *= priorityMultiplier;\n }\n\n // Recency boost for temporal queries\n if (opts.boostRecent && r.memory.updated_at) {\n const age = now - new Date(r.memory.updated_at).getTime();\n const daysSinceUpdate = age / (1000 * 60 * 60 * 24);\n const recencyBoost = Math.max(0.1, 1.0 / (1.0 + daysSinceUpdate * 0.1));\n finalScore *= recencyBoost;\n }\n\n // Vitality factor — higher vitality memories are more relevant\n finalScore *= Math.max(0.1, r.memory.vitality);\n\n return { ...r, score: finalScore };\n });\n\n // Sort by final score (descending)\n scored.sort((a, b) => b.score - a.score);\n\n return scored.slice(0, opts.limit);\n}\n","// AgentMemory v2 — BM25 full-text search via SQLite FTS5\nimport type Database from \"better-sqlite3\";\nimport type { Memory } from \"../core/memory.js\";\nimport { tokenize } from \"./tokenizer.js\";\n\nexport interface SearchResult {\n memory: Memory;\n score: number;\n matchReason: string;\n}\n\n/**\n * BM25 search using SQLite FTS5.\n * Returns memories ranked by relevance.\n */\nexport function searchBM25(\n db: Database.Database,\n query: string,\n opts?: {\n agent_id?: string;\n limit?: number;\n min_vitality?: number;\n },\n): SearchResult[] {\n const limit = opts?.limit ?? 20;\n const agentId = opts?.agent_id ?? \"default\";\n const minVitality = opts?.min_vitality ?? 0.0;\n\n const ftsQuery = buildFtsQuery(query);\n if (!ftsQuery) return [];\n\n try {\n const rows = db\n .prepare(\n `SELECT m.*, rank AS score\n FROM memories_fts f\n JOIN memories m ON m.id = f.id\n WHERE memories_fts MATCH ?\n AND m.agent_id = ?\n AND m.vitality >= ?\n ORDER BY rank\n LIMIT ?`,\n )\n .all(ftsQuery, agentId, minVitality, limit) as Array<Memory & { score: number }>;\n\n return rows.map((row) => {\n const { score: _score, ...memoryFields } = row;\n return {\n memory: memoryFields as Memory,\n score: Math.abs(row.score), // FTS5 rank is negative (lower = better)\n matchReason: \"bm25\",\n };\n });\n } catch {\n // FTS query syntax error — fall back to simpler query\n return searchSimple(db, query, agentId, minVitality, limit);\n }\n}\n\n/**\n * Simple LIKE search as fallback when FTS fails\n */\nfunction searchSimple(\n db: Database.Database,\n query: string,\n agentId: string,\n minVitality: number,\n limit: number,\n): SearchResult[] {\n const rows = db\n .prepare(\n `SELECT * FROM memories\n WHERE agent_id = ? AND vitality >= ? AND content LIKE ?\n ORDER BY priority ASC, updated_at DESC\n LIMIT ?`,\n )\n .all(agentId, minVitality, `%${query}%`, limit) as Memory[];\n\n return rows.map((m, i) => ({\n memory: m,\n score: 1.0 / (i + 1), // Simple rank by position\n matchReason: \"like\",\n }));\n}\n\n/**\n * Build FTS5 query from natural language.\n * Uses jieba for Chinese word segmentation, falls back to bigram splitting.\n */\nfunction buildFtsQuery(text: string): string | null {\n const tokens = tokenize(text);\n if (tokens.length === 0) return null;\n\n // Use OR for broad matching\n return tokens.map((w) => `\"${w}\"`).join(\" OR \");\n}\n","// AgentMemory v2 — Embedding storage helpers (SQLite BLOB)\nimport type Database from \"better-sqlite3\";\nimport { now } from \"../core/db.js\";\n\nexport interface StoredEmbedding {\n agent_id: string;\n memory_id: string;\n model: string;\n dim: number;\n vector: Float32Array;\n created_at: string;\n updated_at: string;\n}\n\nexport function encodeEmbedding(vector: number[] | Float32Array): Buffer {\n const arr = vector instanceof Float32Array ? vector : Float32Array.from(vector);\n // Node Buffer shares memory with underlying ArrayBuffer view.\n return Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\nexport function decodeEmbedding(buf: Buffer): Float32Array {\n // Copy to detach from sqlite/Buffer lifetime assumptions.\n const copy = Buffer.from(buf);\n return new Float32Array(copy.buffer, copy.byteOffset, Math.floor(copy.byteLength / 4));\n}\n\nexport function upsertEmbedding(\n db: Database.Database,\n input: {\n agent_id: string;\n memory_id: string;\n model: string;\n vector: number[] | Float32Array;\n },\n): void {\n const ts = now();\n const vec = input.vector instanceof Float32Array ? input.vector : Float32Array.from(input.vector);\n const blob = encodeEmbedding(vec);\n db.prepare(\n `INSERT INTO embeddings (agent_id, memory_id, model, dim, vector, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(agent_id, memory_id, model) DO UPDATE SET\n dim = excluded.dim,\n vector = excluded.vector,\n updated_at = excluded.updated_at`,\n ).run(input.agent_id, input.memory_id, input.model, vec.length, blob, ts, ts);\n}\n\nexport function getEmbedding(\n db: Database.Database,\n agent_id: string,\n memory_id: string,\n model: string,\n): StoredEmbedding | null {\n const row = db.prepare(\n \"SELECT agent_id, memory_id, model, dim, vector, created_at, updated_at FROM embeddings WHERE agent_id = ? AND memory_id = ? AND model = ?\",\n ).get(agent_id, memory_id, model) as (Omit<StoredEmbedding, \"vector\"> & { vector: Buffer }) | undefined;\n if (!row) return null;\n return { ...row, vector: decodeEmbedding(row.vector) };\n}\n\nexport function listEmbeddings(\n db: Database.Database,\n agent_id: string,\n model: string,\n): Array<{ memory_id: string; vector: Float32Array }> {\n const rows = db.prepare(\n \"SELECT memory_id, vector FROM embeddings WHERE agent_id = ? AND model = ?\",\n ).all(agent_id, model) as Array<{ memory_id: string; vector: Buffer }>;\n return rows.map((r) => ({ memory_id: r.memory_id, vector: decodeEmbedding(r.vector) }));\n}\n\n","// AgentMemory v2 — Hybrid search (BM25 + Embeddings + RRF)\nimport type Database from \"better-sqlite3\";\nimport type { Memory } from \"../core/memory.js\";\nimport { searchBM25, type SearchResult } from \"./bm25.js\";\nimport { listEmbeddings } from \"./embeddings.js\";\nimport type { EmbeddingProvider } from \"./providers.js\";\n\nexport interface HybridSearchOptions {\n agent_id?: string;\n limit?: number;\n bm25CandidateMultiplier?: number; // default 3\n semanticCandidates?: number; // default 50\n rrfK?: number; // default 60\n embeddingProvider?: EmbeddingProvider | null;\n embeddingModel?: string;\n}\n\nfunction cosine(a: Float32Array, b: Float32Array): number {\n const n = Math.min(a.length, b.length);\n let dot = 0;\n let na = 0;\n let nb = 0;\n for (let i = 0; i < n; i++) {\n const x = a[i]!;\n const y = b[i]!;\n dot += x * y;\n na += x * x;\n nb += y * y;\n }\n if (na === 0 || nb === 0) return 0;\n return dot / (Math.sqrt(na) * Math.sqrt(nb));\n}\n\nfunction rrfScore(rank: number, k: number): number {\n return 1.0 / (k + rank);\n}\n\nfunction fuseRrf(\n lists: Array<{ name: string; items: Array<{ id: string; score: number }> }>,\n k: number,\n): Map<string, { score: number; sources: string[] }> {\n const out = new Map<string, { score: number; sources: string[] }>();\n for (const list of lists) {\n for (let i = 0; i < list.items.length; i++) {\n const it = list.items[i]!;\n const rank = i + 1;\n const add = rrfScore(rank, k);\n const prev = out.get(it.id);\n if (!prev) out.set(it.id, { score: add, sources: [list.name] });\n else {\n prev.score += add;\n if (!prev.sources.includes(list.name)) prev.sources.push(list.name);\n }\n }\n }\n return out;\n}\n\nfunction fetchMemories(db: Database.Database, ids: string[], agentId?: string): Memory[] {\n if (ids.length === 0) return [];\n const placeholders = ids.map(() => \"?\").join(\", \");\n const sql = agentId\n ? `SELECT * FROM memories WHERE id IN (${placeholders}) AND agent_id = ?`\n : `SELECT * FROM memories WHERE id IN (${placeholders})`;\n const rows = db.prepare(sql).all(...(agentId ? [...ids, agentId] : ids)) as Memory[];\n return rows;\n}\n\nexport async function searchHybrid(\n db: Database.Database,\n query: string,\n opts?: HybridSearchOptions,\n): Promise<SearchResult[]> {\n const agentId = opts?.agent_id ?? \"default\";\n const limit = opts?.limit ?? 10;\n const bm25Mult = opts?.bm25CandidateMultiplier ?? 3;\n const semanticCandidates = opts?.semanticCandidates ?? 50;\n const rrfK = opts?.rrfK ?? 60;\n\n const bm25 = searchBM25(db, query, {\n agent_id: agentId,\n limit: limit * bm25Mult,\n });\n\n const provider = opts?.embeddingProvider ?? null;\n const model = opts?.embeddingModel ?? provider?.model;\n if (!provider || !model) {\n return bm25.slice(0, limit);\n }\n\n // Semantic retrieval: brute-force cosine over stored embeddings for the agent.\n const embedFn = provider.embedQuery ?? provider.embed;\n const qVec = Float32Array.from(await embedFn.call(provider, query));\n const embeddings = listEmbeddings(db, agentId, model);\n\n const scored: Array<{ id: string; score: number }> = [];\n for (const e of embeddings) {\n scored.push({ id: e.memory_id, score: cosine(qVec, e.vector) });\n }\n scored.sort((a, b) => b.score - a.score);\n const semanticTop = scored.slice(0, semanticCandidates);\n\n const fused = fuseRrf(\n [\n { name: \"bm25\", items: bm25.map((r) => ({ id: r.memory.id, score: r.score })) },\n { name: \"semantic\", items: semanticTop },\n ],\n rrfK,\n );\n\n const ids = [...fused.keys()];\n const memories = fetchMemories(db, ids, agentId);\n const byId = new Map(memories.map((m) => [m.id, m]));\n\n const out: SearchResult[] = [];\n for (const [id, meta] of fused) {\n const mem = byId.get(id);\n if (!mem) continue;\n out.push({\n memory: mem,\n score: meta.score,\n matchReason: meta.sources.sort().join(\"+\"),\n });\n }\n\n out.sort((a, b) => b.score - a.score);\n return out.slice(0, limit);\n}\n","// AgentMemory v2 — Embedding providers (OpenAI / Qwen / Gemini) via fetch\nexport interface EmbeddingProvider {\n id: string;\n model: string;\n dimension?: number;\n instructionPrefix?: string | null;\n embed(text: string): Promise<number[]>;\n embedQuery?(query: string): Promise<number[]>;\n}\n\nconst QWEN_DEFAULT_INSTRUCTION = \"Given a query, retrieve the most semantically relevant document\";\n\nexport function getDefaultInstruction(model: string): string | null {\n const m = model.toLowerCase();\n if (m.includes(\"qwen\")) return QWEN_DEFAULT_INSTRUCTION;\n if (m.includes(\"gemini\")) return null;\n return null;\n}\n\nfunction resolveInstruction(model: string): string | null {\n const override = process.env.AGENT_MEMORY_EMBEDDINGS_INSTRUCTION;\n if (override !== undefined) {\n const normalized = override.trim();\n if (!normalized) return null;\n const lowered = normalized.toLowerCase();\n if (lowered === \"none\" || lowered === \"off\" || lowered === \"false\" || lowered === \"null\") return null;\n return normalized;\n }\n\n return getDefaultInstruction(model);\n}\n\nfunction buildQueryInput(query: string, instructionPrefix?: string | null): string {\n if (!instructionPrefix) return query;\n return `Instruct: ${instructionPrefix}\\nQuery: ${query}`;\n}\n\nexport function getEmbeddingProviderFromEnv(): EmbeddingProvider | null {\n const provider = (process.env.AGENT_MEMORY_EMBEDDINGS_PROVIDER ?? \"none\").toLowerCase();\n if (provider === \"none\" || provider === \"off\" || provider === \"false\") return null;\n\n if (provider === \"openai\") {\n const apiKey = process.env.OPENAI_API_KEY;\n const model = process.env.AGENT_MEMORY_EMBEDDINGS_MODEL ?? \"text-embedding-3-small\";\n const baseUrl = process.env.OPENAI_BASE_URL ?? \"https://api.openai.com/v1\";\n if (!apiKey) return null;\n const instruction = resolveInstruction(model);\n return createOpenAIProvider({ apiKey, model, baseUrl, instruction });\n }\n\n if (provider === \"gemini\" || provider === \"google\") {\n const apiKey = process.env.GEMINI_API_KEY ?? process.env.OPENAI_API_KEY;\n const model = process.env.AGENT_MEMORY_EMBEDDINGS_MODEL ?? \"gemini-embedding-001\";\n const baseUrl = process.env.GEMINI_BASE_URL ?? process.env.OPENAI_BASE_URL ?? \"https://generativelanguage.googleapis.com/v1beta\";\n if (!apiKey) return null;\n const instruction = resolveInstruction(model);\n return createOpenAIProvider({ id: \"gemini\", apiKey, model, baseUrl, instruction });\n }\n\n if (provider === \"qwen\" || provider === \"dashscope\" || provider === \"tongyi\") {\n const apiKey = process.env.DASHSCOPE_API_KEY;\n const model = process.env.AGENT_MEMORY_EMBEDDINGS_MODEL ?? \"text-embedding-v3\";\n const baseUrl = process.env.DASHSCOPE_BASE_URL ?? \"https://dashscope.aliyuncs.com\";\n if (!apiKey) return null;\n const instruction = resolveInstruction(model);\n return createDashScopeProvider({ apiKey, model, baseUrl, instruction });\n }\n\n return null;\n}\n\nfunction authHeader(apiKey: string): string {\n return apiKey.startsWith(\"Bearer \") ? apiKey : `Bearer ${apiKey}`;\n}\n\nfunction normalizeEmbedding(e: unknown): number[] {\n if (!Array.isArray(e)) throw new Error(\"Invalid embedding: not an array\");\n if (e.length === 0) throw new Error(\"Invalid embedding: empty\");\n return e.map((x) => {\n if (typeof x !== \"number\" || !Number.isFinite(x)) throw new Error(\"Invalid embedding: non-numeric value\");\n return x;\n });\n}\n\nexport function createOpenAIProvider(opts: {\n id?: string;\n apiKey: string;\n model: string;\n baseUrl?: string;\n instruction?: string | null;\n}): EmbeddingProvider {\n const baseUrl = opts.baseUrl ?? \"https://api.openai.com/v1\";\n const instructionPrefix = opts.instruction ?? null;\n\n async function requestEmbedding(input: string): Promise<number[]> {\n const resp = await fetch(`${baseUrl.replace(/\\/$/, \"\")}/embeddings`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: authHeader(opts.apiKey),\n },\n body: JSON.stringify({ model: opts.model, input }),\n });\n if (!resp.ok) {\n const body = await resp.text().catch(() => \"\");\n throw new Error(`OpenAI embeddings failed: ${resp.status} ${resp.statusText} ${body}`.trim());\n }\n const data = await resp.json() as { data?: Array<{ embedding?: unknown }> };\n return normalizeEmbedding(data.data?.[0]?.embedding);\n }\n\n return {\n id: opts.id ?? \"openai\",\n model: opts.model,\n instructionPrefix,\n async embed(text: string) {\n return requestEmbedding(text);\n },\n async embedQuery(query: string) {\n return requestEmbedding(buildQueryInput(query, instructionPrefix));\n },\n };\n}\n\nexport function createDashScopeProvider(opts: {\n apiKey: string;\n model: string;\n baseUrl?: string;\n instruction?: string | null;\n}): EmbeddingProvider {\n const baseUrl = opts.baseUrl ?? \"https://dashscope.aliyuncs.com\";\n const instructionPrefix = opts.instruction ?? null;\n\n async function requestEmbedding(text: string): Promise<number[]> {\n const resp = await fetch(`${baseUrl.replace(/\\/$/, \"\")}/api/v1/services/embeddings/text-embedding/text-embedding`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: authHeader(opts.apiKey),\n },\n body: JSON.stringify({\n model: opts.model,\n input: { texts: [text] },\n }),\n });\n if (!resp.ok) {\n const body = await resp.text().catch(() => \"\");\n throw new Error(`DashScope embeddings failed: ${resp.status} ${resp.statusText} ${body}`.trim());\n }\n const data = await resp.json() as {\n output?: {\n embeddings?: Array<{ embedding?: unknown; vector?: unknown }>;\n embedding?: unknown;\n };\n data?: Array<{ embedding?: unknown }>;\n };\n\n const emb =\n data.output?.embeddings?.[0]?.embedding\n ?? data.output?.embeddings?.[0]?.vector\n ?? data.output?.embedding\n ?? data.data?.[0]?.embedding;\n\n return normalizeEmbedding(emb);\n }\n\n return {\n id: \"dashscope\",\n model: opts.model,\n instructionPrefix,\n async embed(text: string) {\n return requestEmbedding(text);\n },\n async embedQuery(query: string) {\n return requestEmbedding(buildQueryInput(query, instructionPrefix));\n },\n };\n}\n","// AgentMemory v2 — Embedding generation helpers (async)\nimport type Database from \"better-sqlite3\";\nimport type { EmbeddingProvider } from \"./providers.js\";\nimport { upsertEmbedding } from \"./embeddings.js\";\n\nexport async function embedMemory(\n db: Database.Database,\n memoryId: string,\n provider: EmbeddingProvider,\n opts?: { agent_id?: string; model?: string; maxChars?: number },\n): Promise<boolean> {\n const row = db.prepare(\"SELECT id, agent_id, content FROM memories WHERE id = ?\").get(memoryId) as { id: string; agent_id: string; content: string } | undefined;\n if (!row) return false;\n if (opts?.agent_id && row.agent_id !== opts.agent_id) return false;\n\n const model = opts?.model ?? provider.model;\n const maxChars = opts?.maxChars ?? 2000;\n const text = row.content.length > maxChars ? row.content.slice(0, maxChars) : row.content;\n\n const vector = await provider.embed(text);\n upsertEmbedding(db, {\n agent_id: row.agent_id,\n memory_id: row.id,\n model,\n vector,\n });\n return true;\n}\n\nexport async function embedMissingForAgent(\n db: Database.Database,\n provider: EmbeddingProvider,\n opts?: { agent_id?: string; model?: string; limit?: number; maxChars?: number },\n): Promise<{ embedded: number; scanned: number }> {\n const agentId = opts?.agent_id ?? \"default\";\n const model = opts?.model ?? provider.model;\n const limit = opts?.limit ?? 1000;\n\n const rows = db.prepare(\n `SELECT m.id\n FROM memories m\n LEFT JOIN embeddings e\n ON e.memory_id = m.id AND e.agent_id = m.agent_id AND e.model = ?\n WHERE m.agent_id = ? AND e.memory_id IS NULL\n ORDER BY m.updated_at DESC\n LIMIT ?`,\n ).all(model, agentId, limit) as Array<{ id: string }>;\n\n let embedded = 0;\n for (const r of rows) {\n const ok = await embedMemory(db, r.id, provider, { agent_id: agentId, model, maxChars: opts?.maxChars });\n if (ok) embedded++;\n }\n return { embedded, scanned: rows.length };\n}\n\n","// AgentMemory v2 — URI path system (from nocturne's Content-Path separation)\nimport type Database from \"better-sqlite3\";\nimport { newId, now } from \"./db.js\";\n\nexport interface Path {\n id: string;\n memory_id: string;\n agent_id: string;\n uri: string;\n alias: string | null;\n domain: string;\n created_at: string;\n}\n\n// Valid domains (extensible)\nconst DEFAULT_DOMAINS = new Set([\"core\", \"emotion\", \"knowledge\", \"event\", \"system\"]);\n\nexport function parseUri(uri: string): { domain: string; path: string } {\n const match = uri.match(/^([a-z]+):\\/\\/(.+)$/);\n if (!match) throw new Error(`Invalid URI: ${uri}. Expected format: domain://path`);\n return { domain: match[1], path: match[2] };\n}\n\nexport function createPath(\n db: Database.Database,\n memoryId: string,\n uri: string,\n alias?: string,\n validDomains?: Set<string>,\n agent_id?: string,\n): Path {\n const { domain } = parseUri(uri);\n const domains = validDomains ?? DEFAULT_DOMAINS;\n if (!domains.has(domain)) {\n throw new Error(`Invalid domain \"${domain}\". Valid: ${[...domains].join(\", \")}`);\n }\n\n const memoryAgent = (db.prepare(\"SELECT agent_id FROM memories WHERE id = ?\").get(memoryId) as { agent_id: string } | undefined)?.agent_id;\n if (!memoryAgent) throw new Error(`Memory not found: ${memoryId}`);\n if (agent_id && agent_id !== memoryAgent) {\n throw new Error(`Agent mismatch for path: memory agent_id=${memoryAgent}, requested agent_id=${agent_id}`);\n }\n const agentId = agent_id ?? memoryAgent;\n\n // Check URI uniqueness\n const existing = db.prepare(\"SELECT id FROM paths WHERE agent_id = ? AND uri = ?\").get(agentId, uri) as\n | { id: string }\n | undefined;\n if (existing) {\n throw new Error(`URI already exists: ${uri}`);\n }\n\n const id = newId();\n db.prepare(\n \"INSERT INTO paths (id, memory_id, agent_id, uri, alias, domain, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)\",\n ).run(id, memoryId, agentId, uri, alias ?? null, domain, now());\n\n return getPath(db, id)!;\n}\n\nexport function getPath(db: Database.Database, id: string): Path | null {\n return (db.prepare(\"SELECT * FROM paths WHERE id = ?\").get(id) as Path) ?? null;\n}\n\nexport function getPathByUri(db: Database.Database, uri: string, agent_id = \"default\"): Path | null {\n return (db.prepare(\"SELECT * FROM paths WHERE agent_id = ? AND uri = ?\").get(agent_id, uri) as Path) ?? null;\n}\n\nexport function getPathsByMemory(db: Database.Database, memoryId: string): Path[] {\n return db.prepare(\"SELECT * FROM paths WHERE memory_id = ?\").all(memoryId) as Path[];\n}\n\nexport function getPathsByDomain(db: Database.Database, domain: string, agent_id = \"default\"): Path[] {\n return db\n .prepare(\"SELECT * FROM paths WHERE agent_id = ? AND domain = ? ORDER BY uri\")\n .all(agent_id, domain) as Path[];\n}\n\nexport function getPathsByPrefix(db: Database.Database, prefix: string, agent_id = \"default\"): Path[] {\n return db\n .prepare(\"SELECT * FROM paths WHERE agent_id = ? AND uri LIKE ? ORDER BY uri\")\n .all(agent_id, `${prefix}%`) as Path[];\n}\n\nexport function deletePath(db: Database.Database, id: string): boolean {\n const result = db.prepare(\"DELETE FROM paths WHERE id = ?\").run(id);\n return result.changes > 0;\n}\n\nexport function deletePathsByMemory(db: Database.Database, memoryId: string): number {\n const result = db.prepare(\"DELETE FROM paths WHERE memory_id = ?\").run(memoryId);\n return result.changes;\n}\n","// AgentMemory v2 — Boot loader (system://boot identity loading)\n// From nocturne's CORE_MEMORY_URIS concept\nimport type Database from \"better-sqlite3\";\nimport type { Memory } from \"../core/memory.js\";\nimport { getPathByUri } from \"../core/path.js\";\nimport { getMemory, listMemories, recordAccess } from \"../core/memory.js\";\n\nexport interface BootResult {\n identityMemories: Memory[];\n bootPaths: string[];\n}\n\n/**\n * Load core identity memories at startup.\n * Returns all P0 (identity) memories + any memories referenced by system://boot.\n */\nexport function boot(\n db: Database.Database,\n opts?: { agent_id?: string; corePaths?: string[] },\n): BootResult {\n const agentId = opts?.agent_id ?? \"default\";\n const corePaths = opts?.corePaths ?? [\n \"core://agent\",\n \"core://user\",\n \"core://agent/identity\",\n \"core://user/identity\",\n ];\n\n const memories = new Map<string, Memory>();\n\n // 1. Load all P0 identity memories\n const identities = listMemories(db, { agent_id: agentId, priority: 0 });\n for (const mem of identities) {\n memories.set(mem.id, mem);\n recordAccess(db, mem.id, 1.1); // Light access boost on boot\n }\n\n // 2. Load memories at configured core paths\n const bootPaths: string[] = [];\n for (const uri of corePaths) {\n const path = getPathByUri(db, uri, agentId);\n if (path) {\n bootPaths.push(uri);\n if (!memories.has(path.memory_id)) {\n const mem = getMemory(db, path.memory_id);\n if (mem) {\n memories.set(mem.id, mem);\n recordAccess(db, mem.id, 1.1);\n }\n }\n }\n }\n\n // 3. Check system://boot for additional paths\n const bootEntry = getPathByUri(db, \"system://boot\", agentId);\n if (bootEntry) {\n const bootMem = getMemory(db, bootEntry.memory_id);\n if (bootMem) {\n // system://boot content may list additional URIs (one per line)\n const additionalUris = bootMem.content\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l.match(/^[a-z]+:\\/\\//));\n\n for (const uri of additionalUris) {\n const path = getPathByUri(db, uri, agentId);\n if (path && !memories.has(path.memory_id)) {\n const mem = getMemory(db, path.memory_id);\n if (mem) {\n memories.set(mem.id, mem);\n bootPaths.push(uri);\n }\n }\n }\n }\n }\n\n return {\n identityMemories: [...memories.values()],\n bootPaths,\n };\n}\n","// AgentMemory v2 — Ebbinghaus forgetting curve decay engine\n// From PowerMem's cognitive science approach: R = e^(-t/S)\nimport type Database from \"better-sqlite3\";\nimport { now } from \"../core/db.js\";\n\n/**\n * Ebbinghaus forgetting curve: R = e^(-t/S)\n * R = retention (vitality), range [0, 1]\n * t = time elapsed (days)\n * S = stability (increases with each recall)\n *\n * Priority-based minimum vitality:\n * P0 (identity): never decays (min 1.0)\n * P1 (emotion): min 0.3\n * P2 (knowledge): min 0.1\n * P3 (event): min 0.0 (can be cleaned up)\n */\n\nconst MIN_VITALITY: Record<number, number> = {\n 0: 1.0, // P0: identity — never decays\n 1: 0.3, // P1: emotion — slow decay\n 2: 0.1, // P2: knowledge — normal decay\n 3: 0.0, // P3: event — full decay\n};\n\n/**\n * Calculate vitality using Ebbinghaus forgetting curve.\n * @param stability - S parameter (higher = slower decay)\n * @param daysSinceLastAccess - days since last recall (or creation if never accessed)\n * @param priority - memory priority (0-3)\n */\nexport function calculateVitality(\n stability: number,\n daysSinceLastAccess: number,\n priority: number,\n): number {\n // P0 never decays\n if (priority === 0) return 1.0;\n\n // Prevent division by zero\n const S = Math.max(0.01, stability);\n\n // R = e^(-t/S)\n // t is measured from last access (recall), matching Ebbinghaus's insight\n // that forgetting restarts from the most recent retrieval.\n const retention = Math.exp(-daysSinceLastAccess / S);\n\n // Apply minimum vitality based on priority\n const minVit = MIN_VITALITY[priority] ?? 0.0;\n return Math.max(minVit, retention);\n}\n\n/**\n * Run decay on all memories.\n * Updates vitality based on Ebbinghaus curve.\n * Returns count of memories updated.\n */\nexport function runDecay(\n db: Database.Database,\n opts?: { agent_id?: string },\n): {\n updated: number;\n decayed: number;\n belowThreshold: number;\n} {\n const currentTime = now();\n const currentMs = new Date(currentTime).getTime();\n const agentId = opts?.agent_id;\n\n // Get all non-P0 memories, including last_accessed for proper decay timing\n const query = agentId\n ? \"SELECT id, priority, stability, created_at, last_accessed, vitality FROM memories WHERE priority > 0 AND agent_id = ?\"\n : \"SELECT id, priority, stability, created_at, last_accessed, vitality FROM memories WHERE priority > 0\";\n\n const memories = db\n .prepare(query)\n .all(...(agentId ? [agentId] : [])) as Array<{\n id: string;\n priority: number;\n stability: number;\n created_at: string;\n last_accessed: string | null;\n vitality: number;\n }>;\n\n let updated = 0;\n let decayed = 0;\n let belowThreshold = 0;\n\n const updateStmt = db.prepare(\"UPDATE memories SET vitality = ?, updated_at = ? WHERE id = ?\");\n\n const transaction = db.transaction(() => {\n for (const mem of memories) {\n // Use last_accessed if available, otherwise fall back to created_at.\n // This matches Ebbinghaus: forgetting starts from the last recall.\n const referenceTime = mem.last_accessed ?? mem.created_at;\n const referenceMs = new Date(referenceTime).getTime();\n const daysSince = (currentMs - referenceMs) / (1000 * 60 * 60 * 24);\n\n const newVitality = calculateVitality(mem.stability, daysSince, mem.priority);\n\n // Only update if vitality actually changed (>0.001 difference)\n if (Math.abs(newVitality - mem.vitality) > 0.001) {\n updateStmt.run(newVitality, currentTime, mem.id);\n updated++;\n\n if (newVitality < mem.vitality) {\n decayed++;\n }\n\n if (newVitality < 0.05) {\n belowThreshold++;\n }\n }\n }\n });\n\n transaction();\n\n return { updated, decayed, belowThreshold };\n}\n\n/**\n * Get memories that are candidates for cleanup (vitality < threshold).\n * Only P3 (event) memories can be fully cleaned.\n */\nexport function getDecayedMemories(\n db: Database.Database,\n threshold = 0.05,\n opts?: { agent_id?: string },\n): Array<{ id: string; content: string; vitality: number; priority: number }> {\n const agentId = opts?.agent_id;\n return db\n .prepare(\n agentId\n ? `SELECT id, content, vitality, priority FROM memories\n WHERE vitality < ? AND priority >= 3 AND agent_id = ?\n ORDER BY vitality ASC`\n : `SELECT id, content, vitality, priority FROM memories\n WHERE vitality < ? AND priority >= 3\n ORDER BY vitality ASC`,\n )\n .all(...(agentId ? [threshold, agentId] : [threshold])) as Array<{\n id: string;\n content: string;\n vitality: number;\n priority: number;\n }>;\n}\n","// AgentMemory v2 — Snapshot system (version control, from nocturne + Memory Palace)\nimport type Database from \"better-sqlite3\";\nimport { newId, now } from \"./db.js\";\nimport { tokenizeForIndex } from \"../search/tokenizer.js\";\n\nexport type SnapshotAction = \"create\" | \"update\" | \"delete\" | \"merge\";\n\nexport interface Snapshot {\n id: string;\n memory_id: string;\n content: string;\n changed_by: string | null;\n action: SnapshotAction;\n created_at: string;\n}\n\n/**\n * Create a snapshot before modifying a memory.\n * Call this BEFORE any update/delete operation.\n */\nexport function createSnapshot(\n db: Database.Database,\n memoryId: string,\n action: SnapshotAction,\n changedBy?: string,\n): Snapshot {\n const memory = db.prepare(\"SELECT content FROM memories WHERE id = ?\").get(memoryId) as\n | { content: string }\n | undefined;\n\n if (!memory) throw new Error(`Memory not found: ${memoryId}`);\n\n const id = newId();\n db.prepare(\n `INSERT INTO snapshots (id, memory_id, content, changed_by, action, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(id, memoryId, memory.content, changedBy ?? null, action, now());\n\n return { id, memory_id: memoryId, content: memory.content, changed_by: changedBy ?? null, action, created_at: now() };\n}\n\nexport function getSnapshots(db: Database.Database, memoryId: string): Snapshot[] {\n return db\n .prepare(\"SELECT * FROM snapshots WHERE memory_id = ? ORDER BY created_at DESC\")\n .all(memoryId) as Snapshot[];\n}\n\nexport function getSnapshot(db: Database.Database, id: string): Snapshot | null {\n return (db.prepare(\"SELECT * FROM snapshots WHERE id = ?\").get(id) as Snapshot) ?? null;\n}\n\n/**\n * Rollback a memory to a specific snapshot.\n * Creates a new snapshot of the current state before rolling back.\n */\nexport function rollback(db: Database.Database, snapshotId: string): boolean {\n const snapshot = getSnapshot(db, snapshotId);\n if (!snapshot) return false;\n\n // Snapshot current state before rollback\n createSnapshot(db, snapshot.memory_id, \"update\", \"rollback\");\n\n // Restore content\n db.prepare(\"UPDATE memories SET content = ?, updated_at = ? WHERE id = ?\").run(\n snapshot.content,\n now(),\n snapshot.memory_id,\n );\n\n // Update FTS\n db.prepare(\"DELETE FROM memories_fts WHERE id = ?\").run(snapshot.memory_id);\n db.prepare(\"INSERT INTO memories_fts (id, content) VALUES (?, ?)\").run(\n snapshot.memory_id,\n tokenizeForIndex(snapshot.content),\n );\n\n return true;\n}\n\nexport function deleteSnapshots(db: Database.Database, memoryId: string): number {\n const result = db.prepare(\"DELETE FROM snapshots WHERE memory_id = ?\").run(memoryId);\n return result.changes;\n}\n","// AgentMemory v2 — Sleep tidy engine (deep sleep phase)\n// Compresses, distills, archives old memories\nimport type Database from \"better-sqlite3\";\nimport { deleteMemory, listMemories, type Memory } from \"../core/memory.js\";\nimport { createSnapshot } from \"../core/snapshot.js\";\nimport { getDecayedMemories } from \"./decay.js\";\n\nexport interface TidyResult {\n archived: number;\n orphansCleaned: number;\n snapshotsPruned: number;\n}\n\n/**\n * Run the tidy (deep sleep) cycle:\n * 1. Archive decayed P3 memories (vitality < threshold)\n * 2. Clean orphan paths (paths with no memory)\n * 3. Prune old snapshots (keep last N per memory)\n */\nexport function runTidy(\n db: Database.Database,\n opts?: {\n vitalityThreshold?: number;\n maxSnapshotsPerMemory?: number;\n agent_id?: string;\n },\n): TidyResult {\n const threshold = opts?.vitalityThreshold ?? 0.05;\n const maxSnapshots = opts?.maxSnapshotsPerMemory ?? 10;\n const agentId = opts?.agent_id;\n\n let archived = 0;\n let orphansCleaned = 0;\n let snapshotsPruned = 0;\n\n const transaction = db.transaction(() => {\n // 1. Archive decayed memories\n const decayed = getDecayedMemories(db, threshold, agentId ? { agent_id: agentId } : undefined);\n for (const mem of decayed) {\n // Snapshot before delete\n try {\n createSnapshot(db, mem.id, \"delete\", \"tidy\");\n } catch {\n // Memory might already be gone\n }\n deleteMemory(db, mem.id);\n archived++;\n }\n\n // 2. Clean orphan paths (paths pointing to deleted memories)\n const orphans = agentId\n ? db.prepare(\n `DELETE FROM paths\n WHERE agent_id = ?\n AND memory_id NOT IN (SELECT id FROM memories WHERE agent_id = ?)`,\n ).run(agentId, agentId)\n : db.prepare(\n \"DELETE FROM paths WHERE memory_id NOT IN (SELECT id FROM memories)\",\n ).run();\n orphansCleaned = orphans.changes;\n\n // 3. Prune old snapshots (keep only latest N per memory)\n const memoriesWithSnapshots = agentId\n ? db\n .prepare(\n `SELECT s.memory_id, COUNT(*) as cnt\n FROM snapshots s\n JOIN memories m ON m.id = s.memory_id\n WHERE m.agent_id = ?\n GROUP BY s.memory_id HAVING cnt > ?`,\n )\n .all(agentId, maxSnapshots) as Array<{ memory_id: string; cnt: number }>\n : db\n .prepare(\n `SELECT memory_id, COUNT(*) as cnt FROM snapshots\n GROUP BY memory_id HAVING cnt > ?`,\n )\n .all(maxSnapshots) as Array<{ memory_id: string; cnt: number }>;\n\n for (const { memory_id } of memoriesWithSnapshots) {\n const pruned = db\n .prepare(\n `DELETE FROM snapshots WHERE id NOT IN (\n SELECT id FROM snapshots WHERE memory_id = ?\n ORDER BY created_at DESC LIMIT ?\n ) AND memory_id = ?`,\n )\n .run(memory_id, maxSnapshots, memory_id);\n snapshotsPruned += pruned.changes;\n }\n });\n\n transaction();\n\n return { archived, orphansCleaned, snapshotsPruned };\n}\n","// AgentMemory v2 — Governance cycle (memory health maintenance)\nimport type Database from \"better-sqlite3\";\n\nexport interface GovernResult {\n orphanPaths: number;\n orphanLinks: number;\n emptyMemories: number;\n}\n\n/**\n * Run governance checks and cleanup:\n * 1. Remove orphan paths (no parent memory)\n * 2. Remove orphan links (source or target missing)\n * 3. Remove empty memories (blank content)\n */\nexport function runGovern(db: Database.Database, opts?: { agent_id?: string }): GovernResult {\n const agentId = opts?.agent_id;\n let orphanPaths = 0;\n let orphanLinks = 0;\n let emptyMemories = 0;\n\n const transaction = db.transaction(() => {\n // 1. Orphan paths\n const pathResult = agentId\n ? db.prepare(\n `DELETE FROM paths\n WHERE agent_id = ?\n AND memory_id NOT IN (SELECT id FROM memories WHERE agent_id = ?)`,\n ).run(agentId, agentId)\n : db.prepare(\"DELETE FROM paths WHERE memory_id NOT IN (SELECT id FROM memories)\").run();\n orphanPaths = pathResult.changes;\n\n // 2. Orphan links\n const linkResult = agentId\n ? db.prepare(\n `DELETE FROM links WHERE\n agent_id = ? AND (\n source_id NOT IN (SELECT id FROM memories WHERE agent_id = ?) OR\n target_id NOT IN (SELECT id FROM memories WHERE agent_id = ?)\n )`,\n ).run(agentId, agentId, agentId)\n : db.prepare(\n `DELETE FROM links WHERE\n source_id NOT IN (SELECT id FROM memories) OR\n target_id NOT IN (SELECT id FROM memories)`,\n ).run();\n orphanLinks = linkResult.changes;\n\n // 3. Empty memories\n const emptyResult = agentId\n ? db.prepare(\"DELETE FROM memories WHERE agent_id = ? AND TRIM(content) = ''\").run(agentId)\n : db.prepare(\"DELETE FROM memories WHERE TRIM(content) = ''\").run();\n emptyMemories = emptyResult.changes;\n });\n\n transaction();\n\n return { orphanPaths, orphanLinks, emptyMemories };\n}\n","// AgentMemory v2 — Write Guard (dedup + conflict detection + 4-criterion gate)\nimport type Database from \"better-sqlite3\";\nimport { contentHash, type CreateMemoryInput, type Memory } from \"./memory.js\";\nimport { getPathByUri } from \"./path.js\";\nimport { tokenize } from \"../search/tokenizer.js\";\n\nexport type GuardAction = \"add\" | \"update\" | \"skip\" | \"merge\";\n\nexport interface GuardResult {\n action: GuardAction;\n reason: string;\n existingId?: string;\n mergedContent?: string;\n}\n\n/**\n * Write Guard — decides whether to add, update, skip, or merge a memory.\n *\n * Pipeline:\n * 1. Hash dedup (exact content match → skip)\n * 2. URI conflict (URI exists → update path)\n * 3. BM25 similarity (dynamic threshold → merge or update)\n * 4. Four-criterion gate: Specificity, Novelty, Relevance, Coherence\n */\nexport function guard(\n db: Database.Database,\n input: CreateMemoryInput & { uri?: string },\n): GuardResult {\n const hash = contentHash(input.content);\n const agentId = input.agent_id ?? \"default\";\n\n // 1. Hash dedup — exact content match\n const exactMatch = db\n .prepare(\"SELECT id FROM memories WHERE hash = ? AND agent_id = ?\")\n .get(hash, agentId) as { id: string } | undefined;\n\n if (exactMatch) {\n return { action: \"skip\", reason: \"Exact duplicate (hash match)\", existingId: exactMatch.id };\n }\n\n // 2. URI conflict — URI already exists, update instead of add\n if (input.uri) {\n const existingPath = getPathByUri(db, input.uri, agentId);\n if (existingPath) {\n return {\n action: \"update\",\n reason: `URI ${input.uri} already exists, updating`,\n existingId: existingPath.memory_id,\n };\n }\n }\n\n // 3. BM25 similarity with dynamic threshold\n const ftsTokens = tokenize(input.content.slice(0, 200));\n const ftsQuery = ftsTokens.length > 0\n ? ftsTokens.slice(0, 8).map((w) => `\"${w}\"`).join(\" OR \")\n : null;\n\n if (ftsQuery) {\n try {\n const similar = db\n .prepare(\n `SELECT m.id, m.content, m.type, rank\n FROM memories_fts f\n JOIN memories m ON m.id = f.id\n WHERE memories_fts MATCH ? AND m.agent_id = ?\n ORDER BY rank\n LIMIT 3`,\n )\n .all(ftsQuery, agentId) as Array<Memory & { rank: number }>;\n\n if (similar.length > 0) {\n // Dynamic threshold: use relative scoring instead of hardcoded -10\n // FTS5 rank is negative; more negative = better match\n // Compare top result against token count for relative threshold\n const topRank = Math.abs(similar[0].rank);\n const tokenCount = ftsTokens.length;\n // Threshold: at least 1.5 score per query token indicates strong overlap\n const dynamicThreshold = tokenCount * 1.5;\n\n if (topRank > dynamicThreshold) {\n const existing = similar[0];\n if (existing.type === input.type) {\n // Same type + high similarity → merge\n const merged = `${existing.content}\\n\\n[Updated] ${input.content}`;\n return {\n action: \"merge\",\n reason: `Similar content found (score=${topRank.toFixed(1)}, threshold=${dynamicThreshold.toFixed(1)}), merging`,\n existingId: existing.id,\n mergedContent: merged,\n };\n }\n }\n }\n } catch {\n // FTS query error — continue to gate check\n }\n }\n\n // 4. Four-criterion gate\n const gateResult = fourCriterionGate(input);\n if (!gateResult.pass) {\n return { action: \"skip\", reason: `Gate rejected: ${gateResult.failedCriteria.join(\", \")}` };\n }\n\n // All checks passed → add\n return { action: \"add\", reason: \"Passed all guard checks\" };\n}\n\n/**\n * Four-criterion gate for memory quality.\n * Each criterion scores 0-1, all must pass minimum threshold.\n *\n * 1. Specificity — content has enough substance (not too vague/short)\n * 2. Novelty — content contains information (not just filler words)\n * 3. Relevance — content has identifiable topics/entities\n * 4. Coherence — content is well-formed (not garbled/truncated)\n */\ninterface GateResult {\n pass: boolean;\n scores: { specificity: number; novelty: number; relevance: number; coherence: number };\n failedCriteria: string[];\n}\n\nfunction fourCriterionGate(input: CreateMemoryInput): GateResult {\n const content = input.content.trim();\n const failed: string[] = [];\n\n // --- Specificity: content has enough substance ---\n // Minimum length varies by priority: P0/P1 can be shorter\n const priority = input.priority ?? (input.type === \"identity\" ? 0 : input.type === \"emotion\" ? 1 : input.type === \"knowledge\" ? 2 : 3);\n const minLength = priority <= 1 ? 4 : 8;\n const specificity = content.length >= minLength ? Math.min(1, content.length / 50) : 0;\n if (specificity === 0) failed.push(`specificity (too short: ${content.length} < ${minLength} chars)`);\n\n // --- Novelty: content has information, not just stopwords/filler ---\n const tokens = tokenize(content);\n // After stopword removal, we should have meaningful tokens\n const novelty = tokens.length >= 1 ? Math.min(1, tokens.length / 5) : 0;\n if (novelty === 0) failed.push(\"novelty (no meaningful tokens after filtering)\");\n\n // --- Relevance: content has identifiable topics ---\n // Check for nouns/entities: CJK chars, capitalized words, numbers, URIs, meaningful length\n const hasCJK = /[\\u4e00-\\u9fff]/.test(content);\n const hasCapitalized = /[A-Z][a-z]+/.test(content);\n const hasNumbers = /\\d+/.test(content);\n const hasURI = /\\w+:\\/\\//.test(content);\n const hasEntityMarkers = /[@#]/.test(content);\n const hasMeaningfulLength = content.length >= 15; // longer content is self-evidently relevant\n const topicSignals = [hasCJK, hasCapitalized, hasNumbers, hasURI, hasEntityMarkers, hasMeaningfulLength].filter(Boolean).length;\n const relevance = topicSignals >= 1 ? Math.min(1, topicSignals / 3) : 0;\n if (relevance === 0) failed.push(\"relevance (no identifiable topics/entities)\");\n\n // --- Coherence: content is well-formed ---\n // Check: not all caps, not garbled (reasonable char distribution), has word boundaries\n const allCaps = content === content.toUpperCase() && content.length > 20 && /^[A-Z\\s]+$/.test(content);\n const hasWhitespaceOrPunctuation = /[\\s,。!?,.!?;;::]/.test(content) || content.length < 30;\n const excessiveRepetition = /(.)\\1{9,}/.test(content); // same char 10+ times\n let coherence = 1;\n if (allCaps) { coherence -= 0.5; }\n if (!hasWhitespaceOrPunctuation) { coherence -= 0.3; }\n if (excessiveRepetition) { coherence -= 0.5; }\n coherence = Math.max(0, coherence);\n if (coherence < 0.3) failed.push(\"coherence (garbled or malformed content)\");\n\n return {\n pass: failed.length === 0,\n scores: { specificity, novelty, relevance, coherence },\n failedCriteria: failed,\n };\n}\n","// AgentMemory v2 — Sleep sync engine (light sleep phase)\n// Captures new information, deduplicates, writes structured memories\nimport type Database from \"better-sqlite3\";\nimport { createMemory, type CreateMemoryInput, type Memory } from \"../core/memory.js\";\nimport { createPath, getPathByUri } from \"../core/path.js\";\nimport { createSnapshot } from \"../core/snapshot.js\";\nimport { guard } from \"../core/guard.js\";\nimport { updateMemory } from \"../core/memory.js\";\n\nexport interface SyncInput {\n content: string;\n type?: CreateMemoryInput[\"type\"];\n priority?: CreateMemoryInput[\"priority\"];\n emotion_val?: number;\n uri?: string;\n source?: string;\n agent_id?: string;\n}\n\nexport interface SyncResult {\n action: \"added\" | \"updated\" | \"merged\" | \"skipped\";\n memoryId?: string;\n reason: string;\n}\n\n/**\n * Sync a single piece of information into memory.\n * Runs full Write Guard pipeline before writing.\n */\nexport function syncOne(db: Database.Database, input: SyncInput): SyncResult {\n const memInput: CreateMemoryInput & { uri?: string } = {\n content: input.content,\n type: input.type ?? \"event\",\n priority: input.priority,\n emotion_val: input.emotion_val,\n source: input.source,\n agent_id: input.agent_id,\n uri: input.uri,\n };\n\n // Run Write Guard\n const guardResult = guard(db, memInput);\n\n switch (guardResult.action) {\n case \"skip\":\n return { action: \"skipped\", reason: guardResult.reason, memoryId: guardResult.existingId };\n\n case \"add\": {\n const mem = createMemory(db, memInput);\n if (!mem) return { action: \"skipped\", reason: \"createMemory returned null\" };\n\n // Create URI path if provided\n if (input.uri) {\n try {\n createPath(db, mem.id, input.uri);\n } catch {\n // URI might already exist, that's OK\n }\n }\n return { action: \"added\", memoryId: mem.id, reason: guardResult.reason };\n }\n\n case \"update\": {\n if (!guardResult.existingId) return { action: \"skipped\", reason: \"No existing ID for update\" };\n createSnapshot(db, guardResult.existingId, \"update\", \"sync\");\n updateMemory(db, guardResult.existingId, { content: input.content });\n return { action: \"updated\", memoryId: guardResult.existingId, reason: guardResult.reason };\n }\n\n case \"merge\": {\n if (!guardResult.existingId || !guardResult.mergedContent) {\n return { action: \"skipped\", reason: \"Missing merge data\" };\n }\n createSnapshot(db, guardResult.existingId, \"merge\", \"sync\");\n updateMemory(db, guardResult.existingId, { content: guardResult.mergedContent });\n return { action: \"merged\", memoryId: guardResult.existingId, reason: guardResult.reason };\n }\n }\n}\n\n/**\n * Sync multiple items in a batch (within a transaction).\n */\nexport function syncBatch(db: Database.Database, inputs: SyncInput[]): SyncResult[] {\n const results: SyncResult[] = [];\n const transaction = db.transaction(() => {\n for (const input of inputs) {\n results.push(syncOne(db, input));\n }\n });\n transaction();\n return results;\n}\n","#!/usr/bin/env node\n// AgentMemory v2 — CLI\nimport { openDatabase } from \"../core/db.js\";\nimport { createMemory, countMemories, listMemories } from \"../core/memory.js\";\nimport { exportMemories } from \"../core/export.js\";\nimport { createPath } from \"../core/path.js\";\nimport { tokenizeForIndex } from \"../search/tokenizer.js\";\nimport { classifyIntent, getStrategy } from \"../search/intent.js\";\nimport { rerank } from \"../search/rerank.js\";\nimport { searchHybrid } from \"../search/hybrid.js\";\nimport { getEmbeddingProviderFromEnv } from \"../search/providers.js\";\nimport { embedMemory, embedMissingForAgent } from \"../search/embed.js\";\nimport { boot } from \"../sleep/boot.js\";\nimport { runDecay } from \"../sleep/decay.js\";\nimport { runTidy } from \"../sleep/tidy.js\";\nimport { runGovern } from \"../sleep/govern.js\";\nimport { syncOne } from \"../sleep/sync.js\";\nimport { existsSync, readFileSync, readdirSync, mkdirSync, writeFileSync } from \"fs\";\nimport { resolve, basename, join } from \"path\";\nimport type { MemoryType } from \"../core/memory.js\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nfunction getDbPath(): string {\n return process.env.AGENT_MEMORY_DB ?? \"./agent-memory.db\";\n}\n\nfunction getAgentId(): string {\n return process.env.AGENT_MEMORY_AGENT_ID ?? \"default\";\n}\n\nfunction printHelp() {\n console.log(`\n🧠 AgentMemory v2 — Sleep-cycle memory for AI agents\n\nUsage: agent-memory <command> [options]\n\nCommands:\n init Create database\n db:migrate Run schema migrations (no-op if up-to-date)\n embed [--limit N] Embed missing memories (requires provider)\n remember <content> [--uri X] [--type T] Store a memory\n recall <query> [--limit N] Search memories\n boot Load identity memories\n status Show statistics\n reflect [decay|tidy|govern|all] Run sleep cycle\n reindex Rebuild FTS index with jieba tokenizer\n migrate <dir> Import from Markdown files\n export <dir> Export memories to Markdown files\n help Show this help\n\nEnvironment:\n AGENT_MEMORY_DB Database path (default: ./agent-memory.db)\n AGENT_MEMORY_AGENT_ID Agent ID (default: \"default\")\n`);\n}\n\nfunction getFlag(flag: string): string | undefined {\n const idx = args.indexOf(flag);\n if (idx >= 0 && idx + 1 < args.length) return args[idx + 1];\n return undefined;\n}\n\nasync function main() {\n try {\n switch (command) {\n case \"init\": {\n const dbPath = getDbPath();\n openDatabase({ path: dbPath });\n console.log(`✅ Database created at ${dbPath}`);\n break;\n }\n\n case \"db:migrate\": {\n const dbPath = getDbPath();\n const db = openDatabase({ path: dbPath });\n const version = (db.prepare(\"SELECT value FROM schema_meta WHERE key = 'version'\").get() as { value: string } | undefined)?.value;\n console.log(`✅ Schema version: ${version ?? \"unknown\"} (${dbPath})`);\n db.close();\n break;\n }\n\n case \"embed\": {\n const provider = getEmbeddingProviderFromEnv();\n if (!provider) {\n console.error(\"Embedding provider not configured. Set AGENT_MEMORY_EMBEDDINGS_PROVIDER=openai|qwen and the corresponding API key.\");\n process.exit(1);\n }\n const db = openDatabase({ path: getDbPath() });\n const agentId = getAgentId();\n const limit = parseInt(getFlag(\"--limit\") ?? \"200\");\n const r = await embedMissingForAgent(db, provider, { agent_id: agentId, limit });\n console.log(`✅ Embedded: ${r.embedded}/${r.scanned} (agent_id=${agentId}, model=${provider.model})`);\n db.close();\n break;\n }\n\n case \"remember\": {\n const content = args.slice(1).filter((a) => !a.startsWith(\"--\")).join(\" \");\n if (!content) { console.error(\"Usage: agent-memory remember <content>\"); process.exit(1); }\n const db = openDatabase({ path: getDbPath() });\n const uri = getFlag(\"--uri\");\n const type = (getFlag(\"--type\") ?? \"knowledge\") as MemoryType;\n const agentId = getAgentId();\n const provider = getEmbeddingProviderFromEnv();\n const result = syncOne(db, { content, type, uri, agent_id: agentId });\n if (provider && result.memoryId && (result.action === \"added\" || result.action === \"updated\" || result.action === \"merged\")) {\n try {\n await embedMemory(db, result.memoryId, provider, { agent_id: agentId });\n } catch {\n // best-effort\n }\n }\n console.log(`${result.action}: ${result.reason}${result.memoryId ? ` (${result.memoryId.slice(0, 8)})` : \"\"}`);\n db.close();\n break;\n }\n\n case \"recall\": {\n const query = args.slice(1).filter((a) => !a.startsWith(\"--\")).join(\" \");\n if (!query) { console.error(\"Usage: agent-memory recall <query>\"); process.exit(1); }\n const db = openDatabase({ path: getDbPath() });\n const limit = parseInt(getFlag(\"--limit\") ?? \"10\");\n const { intent } = classifyIntent(query);\n const strategy = getStrategy(intent);\n const agentId = getAgentId();\n const provider = getEmbeddingProviderFromEnv();\n const raw = await searchHybrid(db, query, { agent_id: agentId, embeddingProvider: provider, limit: limit * 2 });\n const results = rerank(raw, { ...strategy, limit });\n\n console.log(`🔍 Intent: ${intent} | Results: ${results.length}\\n`);\n for (const r of results) {\n const p = [\"🔴\", \"🟠\", \"🟡\", \"⚪\"][r.memory.priority];\n const v = (r.memory.vitality * 100).toFixed(0);\n console.log(`${p} P${r.memory.priority} [${v}%] ${r.memory.content.slice(0, 80)}`);\n }\n db.close();\n break;\n }\n\n case \"boot\": {\n const db = openDatabase({ path: getDbPath() });\n const result = boot(db, { agent_id: getAgentId() });\n console.log(`🧠 Boot: ${result.identityMemories.length} identity memories loaded\\n`);\n for (const m of result.identityMemories) {\n console.log(` 🔴 ${m.content.slice(0, 100)}`);\n }\n if (result.bootPaths.length) {\n console.log(`\\n📍 Boot paths: ${result.bootPaths.join(\", \")}`);\n }\n db.close();\n break;\n }\n\n case \"status\": {\n const db = openDatabase({ path: getDbPath() });\n const agentId = getAgentId();\n const stats = countMemories(db, agentId);\n const lowVit = (db.prepare(\"SELECT COUNT(*) as c FROM memories WHERE vitality < 0.1 AND agent_id = ?\").get(agentId) as { c: number }).c;\n const paths = (db.prepare(\"SELECT COUNT(*) as c FROM paths WHERE agent_id = ?\").get(agentId) as { c: number }).c;\n const links = (db.prepare(\"SELECT COUNT(*) as c FROM links WHERE agent_id = ?\").get(agentId) as { c: number }).c;\n const snaps = (db.prepare(\n `SELECT COUNT(*) as c FROM snapshots s\n JOIN memories m ON m.id = s.memory_id\n WHERE m.agent_id = ?`,\n ).get(agentId) as { c: number }).c;\n\n console.log(\"🧠 AgentMemory Status\\n\");\n console.log(` Total memories: ${stats.total}`);\n console.log(` By type: ${Object.entries(stats.by_type).map(([k, v]) => `${k}=${v}`).join(\", \")}`);\n console.log(` By priority: ${Object.entries(stats.by_priority).map(([k, v]) => `${k}=${v}`).join(\", \")}`);\n console.log(` Paths: ${paths} | Links: ${links} | Snapshots: ${snaps}`);\n console.log(` Low vitality (<10%): ${lowVit}`);\n db.close();\n break;\n }\n\n case \"reflect\": {\n const phase = args[1] ?? \"all\";\n const db = openDatabase({ path: getDbPath() });\n const agentId = getAgentId();\n console.log(`🌙 Running ${phase} phase...\\n`);\n\n if (phase === \"decay\" || phase === \"all\") {\n const r = runDecay(db, { agent_id: agentId });\n console.log(` Decay: ${r.updated} updated, ${r.decayed} decayed, ${r.belowThreshold} below threshold`);\n }\n if (phase === \"tidy\" || phase === \"all\") {\n const r = runTidy(db, { agent_id: agentId });\n console.log(` Tidy: ${r.archived} archived, ${r.orphansCleaned} orphans, ${r.snapshotsPruned} snapshots pruned`);\n }\n if (phase === \"govern\" || phase === \"all\") {\n const r = runGovern(db, { agent_id: agentId });\n console.log(` Govern: ${r.orphanPaths} paths, ${r.orphanLinks} links, ${r.emptyMemories} empty cleaned`);\n }\n db.close();\n break;\n }\n\n case \"reindex\": {\n const db = openDatabase({ path: getDbPath() });\n const memories = db.prepare(\"SELECT id, content FROM memories\").all() as Array<{ id: string; content: string }>;\n \n // Clear and rebuild FTS index\n db.exec(\"DELETE FROM memories_fts\");\n const insert = db.prepare(\"INSERT INTO memories_fts (id, content) VALUES (?, ?)\");\n \n let count = 0;\n const txn = db.transaction(() => {\n for (const mem of memories) {\n insert.run(mem.id, tokenizeForIndex(mem.content));\n count++;\n }\n });\n txn();\n \n console.log(`🔄 Reindexed ${count} memories with jieba tokenizer`);\n db.close();\n break;\n }\n\n case \"export\": {\n const dir = args[1];\n if (!dir) { console.error(\"Usage: agent-memory export <directory>\"); process.exit(1); }\n const dirPath = resolve(dir);\n\n const db = openDatabase({ path: getDbPath() });\n const agentId = getAgentId();\n const result = exportMemories(db, dirPath, { agent_id: agentId });\n console.log(`✅ Export complete: ${result.exported} items to ${dirPath} (${result.files.length} files)`);\n db.close();\n break;\n }\n\n case \"migrate\": {\n const dir = args[1];\n if (!dir) { console.error(\"Usage: agent-memory migrate <directory>\"); process.exit(1); }\n const dirPath = resolve(dir);\n if (!existsSync(dirPath)) { console.error(`Directory not found: ${dirPath}`); process.exit(1); }\n\n const db = openDatabase({ path: getDbPath() });\n const agentId = getAgentId();\n let imported = 0;\n\n // Check for MEMORY.md / MEMORY.qmd\n const memoryFile = ([\"MEMORY.md\", \"MEMORY.qmd\"].map((f) => resolve(dirPath, f))).find((p) => existsSync(p));\n if (memoryFile) {\n const content = readFileSync(memoryFile, \"utf-8\");\n const sections = content.split(/^## /m).filter((s) => s.trim());\n\n for (const section of sections) {\n const lines = section.split(\"\\n\");\n const title = lines[0]?.trim();\n const body = lines.slice(1).join(\"\\n\").trim();\n if (!body) continue;\n\n const type: MemoryType = title?.toLowerCase().includes(\"关于\") || title?.toLowerCase().includes(\"about\")\n ? \"identity\" : \"knowledge\";\n const uri = `knowledge://memory-md/${title?.replace(/[^a-z0-9\\u4e00-\\u9fff]/gi, \"-\").toLowerCase()}`;\n\n syncOne(db, { content: `## ${title}\\n${body}`, type, uri, source: `migrate:${basename(memoryFile)}`, agent_id: agentId });\n imported++;\n }\n console.log(`📄 ${basename(memoryFile)}: ${sections.length} sections imported`);\n }\n\n // Check for daily journals\n const mdFiles = readdirSync(dirPath).filter((f) => /^\\d{4}-\\d{2}-\\d{2}\\.(md|qmd)$/.test(f)).sort();\n for (const file of mdFiles) {\n const content = readFileSync(resolve(dirPath, file), \"utf-8\");\n const date = file.replace(/\\.(md|qmd)$/i, \"\");\n syncOne(db, {\n content,\n type: \"event\",\n uri: `event://journal/${date}`,\n source: `migrate:${file}`,\n agent_id: agentId,\n });\n imported++;\n }\n if (mdFiles.length) console.log(`📝 Journals: ${mdFiles.length} files imported`);\n\n // Check for weekly summaries\n const weeklyDir = resolve(dirPath, \"weekly\");\n if (existsSync(weeklyDir)) {\n const weeklyFiles = readdirSync(weeklyDir).filter((f) => f.endsWith(\".md\") || f.endsWith(\".qmd\"));\n for (const file of weeklyFiles) {\n const content = readFileSync(resolve(weeklyDir, file), \"utf-8\");\n const week = file.replace(/\\.(md|qmd)$/i, \"\");\n syncOne(db, {\n content,\n type: \"knowledge\",\n uri: `knowledge://weekly/${week}`,\n source: `migrate:weekly/${file}`,\n agent_id: agentId,\n });\n imported++;\n }\n if (weeklyFiles.length) console.log(`📦 Weekly: ${weeklyFiles.length} files imported`);\n }\n\n console.log(`\\n✅ Migration complete: ${imported} items imported`);\n db.close();\n break;\n }\n\n case \"help\":\n case \"--help\":\n case \"-h\":\n case undefined:\n printHelp();\n break;\n\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(\"Error:\", message);\n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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","names":["now","existsSync","readFileSync"]}
|
|
1
|
+
{"version":3,"sources":["../../src/bin/agent-memory.ts","../../src/core/db.ts","../../src/core/memory.ts","../../src/search/tokenizer.ts","../../src/search/embedding.ts","../../src/search/providers.ts","../../src/search/vector.ts","../../src/core/export.ts","../../src/core/path.ts","../../src/sleep/boot.ts","../../src/transports/http.ts","../../src/search/bm25.ts","../../src/search/hybrid.ts","../../src/core/merge.ts","../../src/core/guard.ts","../../src/sleep/sync.ts","../../src/app/remember.ts","../../src/app/recall.ts","../../src/app/feedback.ts","../../src/app/surface.ts","../../src/sleep/decay.ts","../../src/sleep/tidy.ts","../../src/sleep/govern.ts","../../src/sleep/jobs.ts","../../src/sleep/orchestrator.ts","../../src/app/reflect.ts","../../src/app/status.ts","../../src/app/reindex.ts"],"sourcesContent":["#!/usr/bin/env node\n// AgentMemory v4 — CLI\nimport { existsSync, readFileSync, readdirSync } from \"fs\";\nimport { basename, resolve } from \"path\";\nimport { openDatabase } from \"../core/db.js\";\nimport { type MemoryType } from \"../core/memory.js\";\nimport { exportMemories } from \"../core/export.js\";\nimport { boot } from \"../sleep/boot.js\";\nimport { startHttpServer } from \"../transports/http.js\";\nimport { rememberMemory } from \"../app/remember.js\";\nimport { recallMemory } from \"../app/recall.js\";\nimport { getMemoryStatus } from \"../app/status.js\";\nimport { reflectMemories } from \"../app/reflect.js\";\nimport { reindexMemories } from \"../app/reindex.js\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nfunction getDbPath(): string {\n return process.env.AGENT_MEMORY_DB ?? \"./agent-memory.db\";\n}\n\nfunction getAgentId(): string {\n return process.env.AGENT_MEMORY_AGENT_ID ?? \"default\";\n}\n\nfunction printHelp() {\n console.log(`\n🧠 AgentMemory v4 — Sleep-cycle memory for AI agents\n\nUsage: agent-memory <command> [options]\n\nCommands:\n init Create database\n db:migrate Run schema migrations (no-op if up-to-date)\n remember <content> [--uri X] [--type T] Store a memory\n recall <query> [--limit N] Search memories (hybrid retrieval, auto-fallback to BM25)\n boot Load identity memories\n status Show statistics\n reflect [decay|tidy|govern|all] Run sleep cycle\n reindex [--full] [--batch-size N] Rebuild FTS index and embeddings (if configured)\n serve [--host H] [--port N] Start the HTTP/SSE API server\n migrate <dir> Import from Markdown files\n export <dir> Export memories to Markdown files\n help Show this help\n\nEnvironment:\n AGENT_MEMORY_DB Database path (default: ./agent-memory.db)\n AGENT_MEMORY_AGENT_ID Agent ID (default: \"default\")\n`);\n}\n\nfunction getFlag(flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index >= 0 && index + 1 < args.length) return args[index + 1];\n return undefined;\n}\n\nfunction hasFlag(flag: string): boolean {\n return args.includes(flag);\n}\n\nfunction getPositionalArgs(startIndex = 1): string[] {\n const values: string[] = [];\n for (let index = startIndex; index < args.length; index++) {\n const token = args[index];\n if (token.startsWith(\"--\")) {\n const next = args[index + 1];\n if (next !== undefined && !next.startsWith(\"--\")) {\n index += 1;\n }\n continue;\n }\n values.push(token);\n }\n return values;\n}\n\nasync function main() {\n try {\n switch (command) {\n case \"init\": {\n const dbPath = getDbPath();\n openDatabase({ path: dbPath });\n console.log(`✅ Database created at ${dbPath}`);\n break;\n }\n\n case \"db:migrate\": {\n const dbPath = getDbPath();\n const db = openDatabase({ path: dbPath });\n const version = (db.prepare(\"SELECT value FROM schema_meta WHERE key = 'version'\").get() as { value: string } | undefined)?.value;\n console.log(`✅ Schema version: ${version ?? \"unknown\"} (${dbPath})`);\n db.close();\n break;\n }\n\n case \"remember\": {\n const content = getPositionalArgs(1).join(\" \");\n if (!content) {\n console.error(\"Usage: agent-memory remember <content>\");\n process.exit(1);\n }\n const db = openDatabase({ path: getDbPath() });\n const uri = getFlag(\"--uri\");\n const type = (getFlag(\"--type\") ?? \"knowledge\") as MemoryType;\n const result = await rememberMemory(db, {\n content,\n type,\n uri,\n source: \"manual\",\n agent_id: getAgentId(),\n });\n console.log(`${result.action}: ${result.reason}${result.memoryId ? ` (${result.memoryId.slice(0, 8)})` : \"\"}`);\n db.close();\n break;\n }\n\n case \"recall\": {\n const query = getPositionalArgs(1).join(\" \");\n if (!query) {\n console.error(\"Usage: agent-memory recall <query>\");\n process.exit(1);\n }\n const db = openDatabase({ path: getDbPath() });\n const result = await recallMemory(db, {\n query,\n agent_id: getAgentId(),\n limit: Number.parseInt(getFlag(\"--limit\") ?? \"10\", 10),\n });\n\n console.log(`🔍 Results: ${result.results.length} (${result.mode})\\n`);\n for (const row of result.results) {\n const priorityLabel = [\"🔴\", \"🟠\", \"🟡\", \"⚪\"][row.memory.priority];\n const vitality = (row.memory.vitality * 100).toFixed(0);\n const branches = [\n row.bm25_rank ? `bm25#${row.bm25_rank}` : null,\n row.vector_rank ? `vec#${row.vector_rank}` : null,\n ].filter(Boolean).join(\" + \");\n console.log(`${priorityLabel} P${row.memory.priority} [${vitality}%] ${row.memory.content.slice(0, 80)}${branches ? ` (${branches})` : \"\"}`);\n }\n db.close();\n break;\n }\n\n case \"boot\": {\n const db = openDatabase({ path: getDbPath() });\n const result = boot(db, { agent_id: getAgentId() });\n console.log(`🧠 Boot: ${result.identityMemories.length} identity memories loaded\\n`);\n for (const memory of result.identityMemories) {\n console.log(` 🔴 ${memory.content.slice(0, 100)}`);\n }\n if (result.bootPaths.length) {\n console.log(`\\n📍 Boot paths: ${result.bootPaths.join(\", \")}`);\n }\n db.close();\n break;\n }\n\n case \"status\": {\n const db = openDatabase({ path: getDbPath() });\n const status = getMemoryStatus(db, { agent_id: getAgentId() });\n\n console.log(\"🧠 AgentMemory Status\\n\");\n console.log(` Total memories: ${status.total}`);\n console.log(` By type: ${Object.entries(status.by_type).map(([key, value]) => `${key}=${value}`).join(\", \")}`);\n console.log(` By priority: ${Object.entries(status.by_priority).map(([key, value]) => `${key}=${value}`).join(\", \")}`);\n console.log(` Paths: ${status.paths}`);\n console.log(` Low vitality (<10%): ${status.low_vitality}`);\n console.log(` Feedback events: ${status.feedback_events}`);\n db.close();\n break;\n }\n\n case \"reflect\": {\n const phase = (args[1] ?? \"all\") as \"decay\" | \"tidy\" | \"govern\" | \"all\";\n const db = openDatabase({ path: getDbPath() });\n const result = await reflectMemories(db, { phase, agent_id: getAgentId() });\n console.log(`🌙 Reflect job ${result.jobId}${result.resumed ? \" (resume)\" : \"\"}`);\n for (const [name, summary] of Object.entries(result.results)) {\n console.log(` ${name}: ${JSON.stringify(summary)}`);\n }\n db.close();\n break;\n }\n\n case \"reindex\": {\n const db = openDatabase({ path: getDbPath() });\n const result = await reindexMemories(db, {\n agent_id: getAgentId(),\n force: hasFlag(\"--full\"),\n batchSize: Number.parseInt(getFlag(\"--batch-size\") ?? \"16\", 10),\n });\n console.log(`🔄 Reindexed ${result.fts.reindexed} memories in BM25 index`);\n if (result.embeddings.enabled) {\n console.log(`🧬 Embeddings: provider=${result.embeddings.providerId} scanned=${result.embeddings.scanned} embedded=${result.embeddings.embedded} failed=${result.embeddings.failed}`);\n } else {\n console.log(\"🧬 Embeddings: disabled (no provider configured)\");\n }\n db.close();\n break;\n }\n\n case \"serve\": {\n const port = Number.parseInt(getFlag(\"--port\") ?? process.env.AGENT_MEMORY_HTTP_PORT ?? \"3000\", 10);\n const host = getFlag(\"--host\") ?? process.env.AGENT_MEMORY_HTTP_HOST ?? \"127.0.0.1\";\n const service = await startHttpServer({\n dbPath: getDbPath(),\n agentId: getAgentId(),\n port,\n host,\n });\n const address = service.server.address();\n if (address && typeof address !== \"string\") {\n console.log(`🌐 AgentMemory HTTP server listening on http://${address.address}:${address.port}`);\n } else {\n console.log(`🌐 AgentMemory HTTP server listening on http://${host}:${port}`);\n }\n\n const shutdown = async () => {\n try {\n await service.close();\n } finally {\n process.exit(0);\n }\n };\n\n process.once(\"SIGINT\", () => { void shutdown(); });\n process.once(\"SIGTERM\", () => { void shutdown(); });\n break;\n }\n\n case \"export\": {\n const dir = args[1];\n if (!dir) {\n console.error(\"Usage: agent-memory export <directory>\");\n process.exit(1);\n }\n const db = openDatabase({ path: getDbPath() });\n const result = exportMemories(db, resolve(dir), { agent_id: getAgentId() });\n console.log(`✅ Export complete: ${result.exported} items to ${resolve(dir)} (${result.files.length} files)`);\n db.close();\n break;\n }\n\n case \"migrate\": {\n const dir = args[1];\n if (!dir) {\n console.error(\"Usage: agent-memory migrate <directory>\");\n process.exit(1);\n }\n const dirPath = resolve(dir);\n if (!existsSync(dirPath)) {\n console.error(`Directory not found: ${dirPath}`);\n process.exit(1);\n }\n\n const db = openDatabase({ path: getDbPath() });\n const agentId = getAgentId();\n let imported = 0;\n\n const memoryFile = [\"MEMORY.md\", \"MEMORY.qmd\"].map((file) => resolve(dirPath, file)).find((file) => existsSync(file));\n if (memoryFile) {\n const content = readFileSync(memoryFile, \"utf-8\");\n const sections = content.split(/^## /m).filter((section) => section.trim());\n for (const section of sections) {\n const lines = section.split(\"\\n\");\n const title = lines[0]?.trim();\n const body = lines.slice(1).join(\"\\n\").trim();\n if (!body) continue;\n const type: MemoryType = title?.toLowerCase().includes(\"关于\") || title?.toLowerCase().includes(\"about\") ? \"identity\" : \"knowledge\";\n const uri = `knowledge://memory-md/${title?.replace(/[^a-z0-9\\u4e00-\\u9fff]/gi, \"-\").toLowerCase()}`;\n await rememberMemory(db, {\n content: `## ${title}\\n${body}`,\n type,\n uri,\n source: `migrate:${basename(memoryFile)}`,\n agent_id: agentId,\n });\n imported += 1;\n }\n console.log(`📄 ${basename(memoryFile)}: ${sections.length} sections imported`);\n }\n\n const mdFiles = readdirSync(dirPath).filter((file) => /^\\d{4}-\\d{2}-\\d{2}\\.(md|qmd)$/.test(file)).sort();\n for (const file of mdFiles) {\n const content = readFileSync(resolve(dirPath, file), \"utf-8\");\n const date = file.replace(/\\.(md|qmd)$/i, \"\");\n await rememberMemory(db, {\n content,\n type: \"event\",\n uri: `event://journal/${date}`,\n source: `migrate:${file}`,\n agent_id: agentId,\n });\n imported += 1;\n }\n if (mdFiles.length) console.log(`📝 Journals: ${mdFiles.length} files imported`);\n\n const weeklyDir = resolve(dirPath, \"weekly\");\n if (existsSync(weeklyDir)) {\n const weeklyFiles = readdirSync(weeklyDir).filter((file) => file.endsWith(\".md\") || file.endsWith(\".qmd\"));\n for (const file of weeklyFiles) {\n const content = readFileSync(resolve(weeklyDir, file), \"utf-8\");\n const week = file.replace(/\\.(md|qmd)$/i, \"\");\n await rememberMemory(db, {\n content,\n type: \"knowledge\",\n uri: `knowledge://weekly/${week}`,\n source: `migrate:weekly/${file}`,\n agent_id: agentId,\n });\n imported += 1;\n }\n if (weeklyFiles.length) console.log(`📦 Weekly: ${weeklyFiles.length} files imported`);\n }\n\n console.log(`\\n✅ Migration complete: ${imported} items imported`);\n db.close();\n break;\n }\n\n case \"help\":\n case \"--help\":\n case \"-h\":\n case undefined:\n printHelp();\n break;\n\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(\"Error:\", message);\n process.exit(1);\n }\n}\n\nmain();\n","// AgentMemory v4 — SQLite database initialization and schema\nimport Database from \"better-sqlite3\";\nimport { randomUUID } from \"crypto\";\n\nexport const SCHEMA_VERSION = 5;\n\nconst SCHEMA_SQL = `\n-- Memory entries\nCREATE TABLE IF NOT EXISTS memories (\n id TEXT PRIMARY KEY,\n content TEXT NOT NULL,\n type TEXT NOT NULL CHECK(type IN ('identity','emotion','knowledge','event')),\n priority INTEGER NOT NULL DEFAULT 2 CHECK(priority BETWEEN 0 AND 3),\n emotion_val REAL NOT NULL DEFAULT 0.0,\n vitality REAL NOT NULL DEFAULT 1.0,\n stability REAL NOT NULL DEFAULT 1.0,\n access_count INTEGER NOT NULL DEFAULT 0,\n last_accessed TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n source TEXT,\n agent_id TEXT NOT NULL DEFAULT 'default',\n hash TEXT,\n UNIQUE(hash, agent_id)\n);\n\n-- URI paths (Content-Path separation, from nocturne)\nCREATE TABLE IF NOT EXISTS paths (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n agent_id TEXT NOT NULL DEFAULT 'default',\n uri TEXT NOT NULL,\n alias TEXT,\n domain TEXT NOT NULL,\n created_at TEXT NOT NULL,\n UNIQUE(agent_id, uri)\n);\n\n-- Association network (knowledge graph)\nCREATE TABLE IF NOT EXISTS links (\n agent_id TEXT NOT NULL DEFAULT 'default',\n source_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n target_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n relation TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1.0,\n created_at TEXT NOT NULL,\n PRIMARY KEY (agent_id, source_id, target_id)\n);\n\n-- Snapshots (version control, from nocturne + Memory Palace)\nCREATE TABLE IF NOT EXISTS snapshots (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n content TEXT NOT NULL,\n changed_by TEXT,\n action TEXT NOT NULL CHECK(action IN ('create','update','delete','merge')),\n created_at TEXT NOT NULL\n);\n\n-- Full-text search index (BM25)\nCREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(\n id UNINDEXED,\n content,\n tokenize='unicode61'\n);\n\n-- Embeddings (optional semantic layer)\nCREATE TABLE IF NOT EXISTS embeddings (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n provider_id TEXT NOT NULL,\n vector BLOB,\n content_hash TEXT NOT NULL,\n status TEXT NOT NULL CHECK(status IN ('pending','ready','failed')),\n created_at TEXT NOT NULL,\n UNIQUE(memory_id, provider_id)\n);\n\n-- Maintenance jobs (reflect / reindex checkpoints)\nCREATE TABLE IF NOT EXISTS maintenance_jobs (\n job_id TEXT PRIMARY KEY,\n phase TEXT NOT NULL CHECK(phase IN ('decay','tidy','govern','all')),\n status TEXT NOT NULL CHECK(status IN ('running','completed','failed')),\n checkpoint TEXT,\n error TEXT,\n started_at TEXT NOT NULL,\n finished_at TEXT\n);\n\n-- Feedback signals (recall/surface usefulness + governance priors)\nCREATE TABLE IF NOT EXISTS feedback_events (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n source TEXT NOT NULL DEFAULT 'surface',\n useful INTEGER NOT NULL DEFAULT 1,\n agent_id TEXT NOT NULL DEFAULT 'default',\n event_type TEXT NOT NULL DEFAULT 'surface:useful',\n value REAL NOT NULL DEFAULT 1.0,\n created_at TEXT NOT NULL\n);\n\n-- Schema version tracking\nCREATE TABLE IF NOT EXISTS schema_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n);\n\n-- Indexes for common queries\nCREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);\nCREATE INDEX IF NOT EXISTS idx_memories_priority ON memories(priority);\nCREATE INDEX IF NOT EXISTS idx_memories_agent ON memories(agent_id);\nCREATE INDEX IF NOT EXISTS idx_memories_vitality ON memories(vitality);\nCREATE INDEX IF NOT EXISTS idx_memories_hash ON memories(hash);\nCREATE INDEX IF NOT EXISTS idx_paths_memory ON paths(memory_id);\nCREATE INDEX IF NOT EXISTS idx_paths_domain ON paths(domain);\nCREATE INDEX IF NOT EXISTS idx_maintenance_jobs_phase_status ON maintenance_jobs(phase, status, started_at DESC);\nCREATE INDEX IF NOT EXISTS idx_feedback_events_memory ON feedback_events(memory_id, created_at DESC);\n`;\n\nexport interface DbOptions {\n path: string;\n walMode?: boolean;\n}\n\n/**\n * Type guard for SQLite count query results.\n * Validates that a row has a numeric 'c' property.\n */\nexport function isCountRow(row: unknown): row is { c: number } {\n return row !== null && typeof row === \"object\" && \"c\" in (row as Record<string, unknown>) && typeof (row as Record<string, unknown>).c === \"number\";\n}\n\nexport function openDatabase(opts: DbOptions): Database.Database {\n const db = new Database(opts.path);\n\n // Enable WAL mode for better concurrent read performance\n if (opts.walMode !== false) {\n db.pragma(\"journal_mode = WAL\");\n }\n db.pragma(\"foreign_keys = ON\");\n db.pragma(\"busy_timeout = 5000\");\n\n // Run schema creation\n db.exec(SCHEMA_SQL);\n\n // Track schema version and migrate forward if needed\n const currentVersion = getSchemaVersion(db);\n if (currentVersion === null) {\n const inferred = inferSchemaVersion(db);\n if (inferred < SCHEMA_VERSION) {\n migrateDatabase(db, inferred, SCHEMA_VERSION);\n }\n db.prepare(\"INSERT OR REPLACE INTO schema_meta (key, value) VALUES ('version', ?)\").run(String(SCHEMA_VERSION));\n } else if (currentVersion < SCHEMA_VERSION) {\n migrateDatabase(db, currentVersion, SCHEMA_VERSION);\n }\n\n ensureIndexes(db);\n ensureFeedbackEventSchema(db);\n\n return db;\n}\n\nexport function now(): string {\n return new Date().toISOString();\n}\n\nexport function newId(): string {\n return randomUUID();\n}\n\nfunction getSchemaVersion(db: Database.Database): number | null {\n try {\n const row = db.prepare(\"SELECT value FROM schema_meta WHERE key = 'version'\").get() as { value: string } | undefined;\n if (!row) return null;\n const n = Number.parseInt(row.value, 10);\n return Number.isFinite(n) ? n : null;\n } catch {\n return null;\n }\n}\n\nfunction tableExists(db: Database.Database, table: string): boolean {\n try {\n const row = db.prepare(\"SELECT name FROM sqlite_master WHERE type='table' AND name = ?\").get(table) as { name: string } | undefined;\n return Boolean(row?.name);\n } catch {\n return false;\n }\n}\n\nfunction tableHasColumn(db: Database.Database, table: string, column: string): boolean {\n try {\n const cols = db.prepare(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>;\n return cols.some((c) => c.name === column);\n } catch {\n return false;\n }\n}\n\nfunction migrateDatabase(db: Database.Database, from: number, to: number): void {\n let v = from;\n while (v < to) {\n if (v === 1) {\n migrateV1ToV2(db);\n v = 2;\n continue;\n }\n if (v === 2) {\n migrateV2ToV3(db);\n v = 3;\n continue;\n }\n if (v === 3) {\n migrateV3ToV4(db);\n v = 4;\n continue;\n }\n if (v === 4) {\n migrateV4ToV5(db);\n v = 5;\n continue;\n }\n throw new Error(`Unsupported schema migration path: v${from} → v${to} (stuck at v${v})`);\n }\n}\n\nfunction migrateV1ToV2(db: Database.Database): void {\n // v2 introduces agent-scoped paths and links.\n // We rebuild both tables to add agent_id and adjust uniqueness/primary keys.\n const pathsMigrated = tableHasColumn(db, \"paths\", \"agent_id\");\n const linksMigrated = tableHasColumn(db, \"links\", \"agent_id\");\n const alreadyMigrated = pathsMigrated && linksMigrated;\n if (alreadyMigrated) {\n db.prepare(\"UPDATE schema_meta SET value = ? WHERE key = 'version'\").run(String(2));\n return;\n }\n\n db.pragma(\"foreign_keys = OFF\");\n try {\n db.exec(\"BEGIN\");\n\n // ---- paths ----\n if (!pathsMigrated) {\n db.exec(`\n CREATE TABLE IF NOT EXISTS paths_v2 (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n agent_id TEXT NOT NULL DEFAULT 'default',\n uri TEXT NOT NULL,\n alias TEXT,\n domain TEXT NOT NULL,\n created_at TEXT NOT NULL,\n UNIQUE(agent_id, uri)\n );\n `);\n\n // Derive agent_id from the referenced memory (fallback to 'default' for orphans).\n db.exec(`\n INSERT INTO paths_v2 (id, memory_id, agent_id, uri, alias, domain, created_at)\n SELECT p.id, p.memory_id, COALESCE(m.agent_id, 'default'), p.uri, p.alias, p.domain, p.created_at\n FROM paths p\n LEFT JOIN memories m ON m.id = p.memory_id;\n `);\n\n db.exec(\"DROP TABLE paths;\");\n db.exec(\"ALTER TABLE paths_v2 RENAME TO paths;\");\n }\n\n // ---- links ----\n if (!linksMigrated) {\n db.exec(`\n CREATE TABLE IF NOT EXISTS links_v2 (\n agent_id TEXT NOT NULL DEFAULT 'default',\n source_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n target_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n relation TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1.0,\n created_at TEXT NOT NULL,\n PRIMARY KEY (agent_id, source_id, target_id)\n );\n `);\n\n // Derive agent_id from source memory; delete links where source/target agent mismatch after migration.\n db.exec(`\n INSERT INTO links_v2 (agent_id, source_id, target_id, relation, weight, created_at)\n SELECT COALESCE(ms.agent_id, 'default'), l.source_id, l.target_id, l.relation, l.weight, l.created_at\n FROM links l\n LEFT JOIN memories ms ON ms.id = l.source_id;\n `);\n\n // Remove cross-agent links (cannot be represented safely in v2 semantics).\n db.exec(`\n DELETE FROM links_v2\n WHERE EXISTS (SELECT 1 FROM memories s WHERE s.id = links_v2.source_id AND s.agent_id != links_v2.agent_id)\n OR EXISTS (SELECT 1 FROM memories t WHERE t.id = links_v2.target_id AND t.agent_id != links_v2.agent_id);\n `);\n\n db.exec(\"DROP TABLE links;\");\n db.exec(\"ALTER TABLE links_v2 RENAME TO links;\");\n }\n\n // Recreate indexes that were dropped with the old tables.\n db.exec(`\n CREATE INDEX IF NOT EXISTS idx_paths_memory ON paths(memory_id);\n CREATE INDEX IF NOT EXISTS idx_paths_domain ON paths(domain);\n `);\n\n db.prepare(\"UPDATE schema_meta SET value = ? WHERE key = 'version'\").run(String(2));\n db.exec(\"COMMIT\");\n } catch (e) {\n try { db.exec(\"ROLLBACK\"); } catch {}\n throw e;\n } finally {\n db.pragma(\"foreign_keys = ON\");\n }\n}\n\nfunction inferSchemaVersion(db: Database.Database): number {\n // Best-effort inference for databases created without schema_meta.\n const hasAgentScopedPaths = tableHasColumn(db, \"paths\", \"agent_id\");\n const hasAgentScopedLinks = tableHasColumn(db, \"links\", \"agent_id\");\n const hasEmbeddings = tableExists(db, \"embeddings\");\n const hasV4Embeddings = hasEmbeddings\n && tableHasColumn(db, \"embeddings\", \"provider_id\")\n && tableHasColumn(db, \"embeddings\", \"status\")\n && tableHasColumn(db, \"embeddings\", \"content_hash\")\n && tableHasColumn(db, \"embeddings\", \"id\");\n const hasMaintenanceJobs = tableExists(db, \"maintenance_jobs\");\n const hasFeedbackEvents = tableExists(db, \"feedback_events\");\n\n if (hasAgentScopedPaths && hasAgentScopedLinks && hasV4Embeddings && hasMaintenanceJobs && hasFeedbackEvents) return 5;\n if (hasAgentScopedPaths && hasAgentScopedLinks && hasV4Embeddings) return 4;\n if (hasAgentScopedPaths && hasAgentScopedLinks && hasEmbeddings) return 3;\n if (hasAgentScopedPaths && hasAgentScopedLinks) return 2;\n return 1;\n}\n\nfunction ensureIndexes(db: Database.Database): void {\n // Indexes that depend on newer columns must be created conditionally.\n if (tableHasColumn(db, \"paths\", \"agent_id\")) {\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_paths_agent_uri ON paths(agent_id, uri);\");\n }\n if (tableHasColumn(db, \"links\", \"agent_id\")) {\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_links_agent_source ON links(agent_id, source_id);\");\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_links_agent_target ON links(agent_id, target_id);\");\n }\n if (tableExists(db, \"embeddings\")) {\n if (tableHasColumn(db, \"embeddings\", \"provider_id\")) {\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_embeddings_provider_status ON embeddings(provider_id, status);\");\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_embeddings_memory_provider ON embeddings(memory_id, provider_id);\");\n } else {\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_embeddings_agent_model ON embeddings(agent_id, model);\");\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_embeddings_memory ON embeddings(memory_id);\");\n }\n }\n if (tableExists(db, \"maintenance_jobs\")) {\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_maintenance_jobs_phase_status ON maintenance_jobs(phase, status, started_at DESC);\");\n }\n if (tableExists(db, \"feedback_events\")) {\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_feedback_events_memory ON feedback_events(memory_id, created_at DESC);\");\n if (tableHasColumn(db, \"feedback_events\", \"agent_id\") && tableHasColumn(db, \"feedback_events\", \"source\")) {\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_feedback_events_agent_source ON feedback_events(agent_id, source, created_at DESC);\");\n }\n }\n}\n\nfunction ensureFeedbackEventSchema(db: Database.Database): void {\n if (!tableExists(db, \"feedback_events\")) return;\n\n if (!tableHasColumn(db, \"feedback_events\", \"source\")) {\n db.exec(\"ALTER TABLE feedback_events ADD COLUMN source TEXT NOT NULL DEFAULT 'surface';\");\n }\n if (!tableHasColumn(db, \"feedback_events\", \"useful\")) {\n db.exec(\"ALTER TABLE feedback_events ADD COLUMN useful INTEGER NOT NULL DEFAULT 1;\");\n }\n if (!tableHasColumn(db, \"feedback_events\", \"agent_id\")) {\n db.exec(\"ALTER TABLE feedback_events ADD COLUMN agent_id TEXT NOT NULL DEFAULT 'default';\");\n }\n\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_feedback_events_agent_source ON feedback_events(agent_id, source, created_at DESC);\");\n}\n\nfunction migrateV2ToV3(db: Database.Database): void {\n // v3 introduces embeddings table for optional semantic search.\n // Safe additive migration.\n try {\n db.exec(\"BEGIN\");\n db.exec(`\n CREATE TABLE IF NOT EXISTS embeddings (\n agent_id TEXT NOT NULL DEFAULT 'default',\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n model TEXT NOT NULL,\n dim INTEGER NOT NULL,\n vector BLOB NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (agent_id, memory_id, model)\n );\n `);\n db.prepare(\"UPDATE schema_meta SET value = ? WHERE key = 'version'\").run(String(3));\n db.exec(\"COMMIT\");\n } catch (e) {\n try { db.exec(\"ROLLBACK\"); } catch {}\n throw e;\n }\n}\n\nfunction migrateV3ToV4(db: Database.Database): void {\n const alreadyMigrated = tableHasColumn(db, \"embeddings\", \"provider_id\")\n && tableHasColumn(db, \"embeddings\", \"status\")\n && tableHasColumn(db, \"embeddings\", \"content_hash\")\n && tableHasColumn(db, \"embeddings\", \"id\");\n\n if (alreadyMigrated) {\n db.prepare(\"UPDATE schema_meta SET value = ? WHERE key = 'version'\").run(String(4));\n return;\n }\n\n try {\n db.exec(\"BEGIN\");\n\n const legacyRows = tableExists(db, \"embeddings\")\n ? db.prepare(\n `SELECT e.agent_id, e.memory_id, e.model, e.vector, e.created_at, m.hash\n FROM embeddings e\n LEFT JOIN memories m ON m.id = e.memory_id`,\n ).all() as Array<{ agent_id: string; memory_id: string; model: string; vector: Buffer; created_at: string; hash: string | null }>\n : [];\n\n db.exec(`\n CREATE TABLE IF NOT EXISTS embeddings_v4 (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n provider_id TEXT NOT NULL,\n vector BLOB,\n content_hash TEXT NOT NULL,\n status TEXT NOT NULL CHECK(status IN ('pending','ready','failed')),\n created_at TEXT NOT NULL,\n UNIQUE(memory_id, provider_id)\n );\n `);\n\n const insert = db.prepare(\n `INSERT INTO embeddings_v4 (id, memory_id, provider_id, vector, content_hash, status, created_at)\n VALUES (?, ?, ?, ?, ?, 'ready', ?)`,\n );\n\n for (const row of legacyRows) {\n insert.run(newId(), row.memory_id, `legacy:${row.agent_id}:${row.model}`, row.vector, row.hash ?? \"\", row.created_at);\n }\n\n if (tableExists(db, \"embeddings\")) {\n db.exec(\"DROP TABLE embeddings;\");\n }\n db.exec(\"ALTER TABLE embeddings_v4 RENAME TO embeddings;\");\n\n db.prepare(\"UPDATE schema_meta SET value = ? WHERE key = 'version'\").run(String(4));\n db.exec(\"COMMIT\");\n } catch (e) {\n try { db.exec(\"ROLLBACK\"); } catch {}\n throw e;\n }\n}\n\nfunction migrateV4ToV5(db: Database.Database): void {\n const hasMaintenanceJobs = tableExists(db, \"maintenance_jobs\");\n const hasFeedbackEvents = tableExists(db, \"feedback_events\");\n\n if (hasMaintenanceJobs && hasFeedbackEvents) {\n db.prepare(\"UPDATE schema_meta SET value = ? WHERE key = 'version'\").run(String(5));\n return;\n }\n\n try {\n db.exec(\"BEGIN\");\n db.exec(`\n CREATE TABLE IF NOT EXISTS maintenance_jobs (\n job_id TEXT PRIMARY KEY,\n phase TEXT NOT NULL CHECK(phase IN ('decay','tidy','govern','all')),\n status TEXT NOT NULL CHECK(status IN ('running','completed','failed')),\n checkpoint TEXT,\n error TEXT,\n started_at TEXT NOT NULL,\n finished_at TEXT\n );\n `);\n db.exec(`\n CREATE TABLE IF NOT EXISTS feedback_events (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n source TEXT NOT NULL DEFAULT 'surface',\n useful INTEGER NOT NULL DEFAULT 1,\n agent_id TEXT NOT NULL DEFAULT 'default',\n event_type TEXT NOT NULL DEFAULT 'surface:useful',\n value REAL NOT NULL DEFAULT 1.0,\n created_at TEXT NOT NULL\n );\n `);\n db.prepare(\"UPDATE schema_meta SET value = ? WHERE key = 'version'\").run(String(5));\n db.exec(\"COMMIT\");\n } catch (e) {\n try { db.exec(\"ROLLBACK\"); } catch {}\n throw e;\n }\n}\n","// AgentMemory v4 — Memory CRUD operations\nimport { createHash } from \"crypto\";\nimport type Database from \"better-sqlite3\";\nimport { newId, now } from \"./db.js\";\nimport { tokenizeForIndex } from \"../search/tokenizer.js\";\nimport { getConfiguredEmbeddingProviderId } from \"../search/providers.js\";\nimport { markAllEmbeddingsPending, markMemoryEmbeddingPending } from \"../search/vector.js\";\n\nexport type MemoryType = \"identity\" | \"emotion\" | \"knowledge\" | \"event\";\nexport type Priority = 0 | 1 | 2 | 3;\n\nexport interface Memory {\n id: string;\n content: string;\n type: MemoryType;\n priority: Priority;\n emotion_val: number;\n vitality: number;\n stability: number;\n access_count: number;\n last_accessed: string | null;\n created_at: string;\n updated_at: string;\n source: string | null;\n agent_id: string;\n hash: string | null;\n}\n\nexport interface CreateMemoryInput {\n content: string;\n type: MemoryType;\n priority?: Priority;\n emotion_val?: number;\n source?: string;\n agent_id?: string;\n embedding_provider_id?: string | null;\n}\n\nexport interface UpdateMemoryInput {\n content?: string;\n type?: MemoryType;\n priority?: Priority;\n emotion_val?: number;\n vitality?: number;\n stability?: number;\n source?: string;\n embedding_provider_id?: string | null;\n}\n\nexport function contentHash(content: string): string {\n return createHash(\"sha256\").update(content.trim()).digest(\"hex\").slice(0, 16);\n}\n\n// Priority defaults based on type\nconst TYPE_PRIORITY: Record<MemoryType, Priority> = {\n identity: 0,\n emotion: 1,\n knowledge: 2,\n event: 3,\n};\n\n// Initial stability (Ebbinghaus S parameter) based on priority\nconst PRIORITY_STABILITY: Record<Priority, number> = {\n 0: Infinity, // P0: never decays\n 1: 365, // P1: 365-day half-life\n 2: 90, // P2: 90-day half-life\n 3: 14, // P3: 14-day half-life\n};\n\nfunction resolveEmbeddingProviderId(explicitProviderId?: string | null): string | null {\n if (explicitProviderId !== undefined) {\n return explicitProviderId;\n }\n return getConfiguredEmbeddingProviderId();\n}\n\nfunction markEmbeddingDirtyIfNeeded(\n db: Database.Database,\n memoryId: string,\n hash: string,\n providerId?: string | null,\n): void {\n if (!providerId) return;\n try {\n markMemoryEmbeddingPending(db, memoryId, providerId, hash);\n } catch {\n // Older schemas (for migration tests) may not have the embeddings table yet.\n }\n}\n\nexport function createMemory(db: Database.Database, input: CreateMemoryInput): Memory | null {\n const hash = contentHash(input.content);\n const agentId = input.agent_id ?? \"default\";\n const priority = input.priority ?? TYPE_PRIORITY[input.type];\n const stability = PRIORITY_STABILITY[priority];\n\n // Dedup: check if identical content already exists for this agent\n const existing = db\n .prepare(\"SELECT id FROM memories WHERE hash = ? AND agent_id = ?\")\n .get(hash, agentId) as { id: string } | undefined;\n if (existing) {\n return null; // Already exists, skip\n }\n\n const id = newId();\n const timestamp = now();\n\n db.prepare(\n `INSERT INTO memories (id, content, type, priority, emotion_val, vitality, stability,\n access_count, created_at, updated_at, source, agent_id, hash)\n VALUES (?, ?, ?, ?, ?, 1.0, ?, 0, ?, ?, ?, ?, ?)`,\n ).run(\n id,\n input.content,\n input.type,\n priority,\n input.emotion_val ?? 0.0,\n stability === Infinity ? 999999 : stability,\n timestamp,\n timestamp,\n input.source ?? null,\n agentId,\n hash,\n );\n\n // Sync to FTS index (tokenized for CJK support)\n db.prepare(\"INSERT INTO memories_fts (id, content) VALUES (?, ?)\").run(id, tokenizeForIndex(input.content));\n\n markEmbeddingDirtyIfNeeded(db, id, hash, resolveEmbeddingProviderId(input.embedding_provider_id));\n\n return getMemory(db, id)!;\n}\n\nexport function getMemory(db: Database.Database, id: string): Memory | null {\n return (db.prepare(\"SELECT * FROM memories WHERE id = ?\").get(id) as Memory) ?? null;\n}\n\nexport function updateMemory(\n db: Database.Database,\n id: string,\n input: UpdateMemoryInput,\n): Memory | null {\n const existing = getMemory(db, id);\n if (!existing) return null;\n\n const fields: string[] = [];\n const values: unknown[] = [];\n let nextHash: string | null = null;\n\n if (input.content !== undefined) {\n nextHash = contentHash(input.content);\n fields.push(\"content = ?\", \"hash = ?\");\n values.push(input.content, nextHash);\n }\n if (input.type !== undefined) {\n fields.push(\"type = ?\");\n values.push(input.type);\n }\n if (input.priority !== undefined) {\n fields.push(\"priority = ?\");\n values.push(input.priority);\n }\n if (input.emotion_val !== undefined) {\n fields.push(\"emotion_val = ?\");\n values.push(input.emotion_val);\n }\n if (input.vitality !== undefined) {\n fields.push(\"vitality = ?\");\n values.push(input.vitality);\n }\n if (input.stability !== undefined) {\n fields.push(\"stability = ?\");\n values.push(input.stability);\n }\n if (input.source !== undefined) {\n fields.push(\"source = ?\");\n values.push(input.source);\n }\n\n fields.push(\"updated_at = ?\");\n values.push(now());\n values.push(id);\n\n db.prepare(`UPDATE memories SET ${fields.join(\", \")} WHERE id = ?`).run(...values);\n\n // Update FTS if content changed\n if (input.content !== undefined) {\n db.prepare(\"DELETE FROM memories_fts WHERE id = ?\").run(id);\n db.prepare(\"INSERT INTO memories_fts (id, content) VALUES (?, ?)\").run(id, tokenizeForIndex(input.content));\n\n if (nextHash) {\n try {\n markAllEmbeddingsPending(db, id, nextHash);\n } catch {\n // Older schemas (for migration tests) may not have the embeddings table yet.\n }\n markEmbeddingDirtyIfNeeded(db, id, nextHash, resolveEmbeddingProviderId(input.embedding_provider_id));\n }\n }\n\n return getMemory(db, id);\n}\n\nexport function deleteMemory(db: Database.Database, id: string): boolean {\n // FTS cleanup\n db.prepare(\"DELETE FROM memories_fts WHERE id = ?\").run(id);\n const result = db.prepare(\"DELETE FROM memories WHERE id = ?\").run(id);\n return result.changes > 0;\n}\n\nexport function listMemories(\n db: Database.Database,\n opts?: {\n agent_id?: string;\n type?: MemoryType;\n priority?: Priority;\n min_vitality?: number;\n limit?: number;\n offset?: number;\n },\n): Memory[] {\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (opts?.agent_id) {\n conditions.push(\"agent_id = ?\");\n params.push(opts.agent_id);\n }\n if (opts?.type) {\n conditions.push(\"type = ?\");\n params.push(opts.type);\n }\n if (opts?.priority !== undefined) {\n conditions.push(\"priority = ?\");\n params.push(opts.priority);\n }\n if (opts?.min_vitality !== undefined) {\n conditions.push(\"vitality >= ?\");\n params.push(opts.min_vitality);\n }\n\n const where = conditions.length ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n const limit = opts?.limit ?? 100;\n const offset = opts?.offset ?? 0;\n\n return db\n .prepare(`SELECT * FROM memories ${where} ORDER BY priority ASC, updated_at DESC LIMIT ? OFFSET ?`)\n .all(...params, limit, offset) as Memory[];\n}\n\nexport function recordAccess(db: Database.Database, id: string, growthFactor = 1.5): void {\n const mem = getMemory(db, id);\n if (!mem) return;\n\n const newStability = Math.min(999999, mem.stability * growthFactor);\n\n db.prepare(\n `UPDATE memories SET access_count = access_count + 1, last_accessed = ?, stability = ?,\n vitality = MIN(1.0, vitality * 1.2) WHERE id = ?`,\n ).run(now(), newStability, id);\n}\n\nexport function countMemories(\n db: Database.Database,\n agent_id = \"default\",\n): { total: number; by_type: Record<string, number>; by_priority: Record<string, number> } {\n const total = (\n db.prepare(\"SELECT COUNT(*) as c FROM memories WHERE agent_id = ?\").get(agent_id) as {\n c: number;\n }\n ).c;\n\n const byType = db\n .prepare(\"SELECT type, COUNT(*) as c FROM memories WHERE agent_id = ? GROUP BY type\")\n .all(agent_id) as Array<{ type: string; c: number }>;\n\n const byPriority = db\n .prepare(\"SELECT priority, COUNT(*) as c FROM memories WHERE agent_id = ? GROUP BY priority\")\n .all(agent_id) as Array<{ priority: number; c: number }>;\n\n return {\n total,\n by_type: Object.fromEntries(byType.map((r) => [r.type, r.c])),\n by_priority: Object.fromEntries(byPriority.map((r) => [`P${r.priority}`, r.c])),\n };\n}\n","// AgentMemory v2 — Tokenizer with jieba Chinese segmentation\n// Uses @node-rs/jieba for proper Chinese word segmentation,\n// falls back to CJK bigram splitting if jieba unavailable.\n\nimport { readFileSync } from \"fs\";\nimport { createRequire } from \"module\";\n\ninterface JiebaInstance {\n cutForSearch(text: string): string[];\n}\n\nlet _jieba: JiebaInstance | null | undefined; // undefined = not tried yet\n\n/**\n * Lazily initialize jieba with built-in dictionary.\n * Returns null if @node-rs/jieba is not installed.\n */\nfunction getJieba(): JiebaInstance | null {\n if (_jieba !== undefined) return _jieba;\n\n try {\n // Use createRequire to resolve from this package's node_modules\n const req = createRequire(import.meta.url);\n const { Jieba } = req(\"@node-rs/jieba\");\n const dictPath = req.resolve(\"@node-rs/jieba/dict.txt\");\n const dictBuf = readFileSync(dictPath);\n _jieba = Jieba.withDict(dictBuf) as JiebaInstance;\n } catch {\n _jieba = null;\n }\n return _jieba;\n}\n\n// Common Chinese stopwords to filter out\nconst STOPWORDS = new Set([\n \"的\", \"了\", \"在\", \"是\", \"我\", \"有\", \"和\", \"就\", \"不\", \"人\",\n \"都\", \"一\", \"个\", \"上\", \"也\", \"到\", \"他\", \"没\", \"这\", \"要\",\n \"会\", \"对\", \"说\", \"而\", \"去\", \"之\", \"被\", \"她\", \"把\", \"那\",\n]);\n\n/**\n * Tokenize text for FTS5 queries.\n * - Latin/numeric words: split on whitespace, filter len > 1\n * - CJK text: use jieba cutForSearch, fallback to unigram + bigram\n * Returns deduplicated token array, max 30 tokens.\n */\nexport function tokenize(text: string): string[] {\n const cleaned = text.replace(/[^\\w\\u4e00-\\u9fff\\u3040-\\u30ff\\uac00-\\ud7af\\s]/g, \" \");\n const tokens: string[] = [];\n\n // Extract Latin/numeric words\n const latinWords = cleaned\n .replace(/[\\u4e00-\\u9fff\\u3040-\\u30ff\\uac00-\\ud7af]/g, \" \")\n .split(/\\s+/)\n .filter((w) => w.length > 1);\n tokens.push(...latinWords);\n\n // Extract CJK portions\n const cjkChunks = cleaned.match(/[\\u4e00-\\u9fff\\u3040-\\u30ff\\uac00-\\ud7af]+/g);\n if (cjkChunks && cjkChunks.length > 0) {\n const jieba = getJieba();\n for (const chunk of cjkChunks) {\n if (jieba) {\n // Use jieba for proper segmentation\n const words = jieba.cutForSearch(chunk).filter((w: string) => w.length >= 1);\n tokens.push(...words);\n } else {\n // Fallback: unigrams + bigrams\n for (const ch of chunk) {\n tokens.push(ch);\n }\n for (let i = 0; i < chunk.length - 1; i++) {\n tokens.push(chunk[i] + chunk[i + 1]);\n }\n }\n }\n }\n\n // Deduplicate, filter stopwords, limit\n const unique = [...new Set(tokens)]\n .filter((t) => t.length > 0 && !STOPWORDS.has(t))\n .slice(0, 30);\n\n return unique;\n}\n\n/**\n * Tokenize content for FTS5 indexing.\n * Segments CJK text and joins all tokens with spaces so FTS5's unicode61\n * tokenizer can index each word separately.\n * This ensures query-side and index-side tokenization match.\n */\nexport function tokenizeForIndex(text: string): string {\n const tokens = tokenize(text);\n // Also keep the original text so exact substrings still work via LIKE fallback\n return tokens.join(\" \");\n}","import { createHash } from \"crypto\";\n\nexport interface EmbeddingProvider {\n id: string;\n model: string;\n dimension: number;\n embed(texts: string[]): Promise<number[][]>;\n healthcheck?(): Promise<void>;\n}\n\nexport interface EmbeddingProviderOptions {\n baseUrl: string;\n model: string;\n dimension: number;\n apiKey?: string;\n endpoint?: string;\n headers?: Record<string, string>;\n fetchImpl?: typeof fetch;\n}\n\ninterface EmbeddingResponseItem {\n embedding: number[];\n}\n\nfunction trimTrailingSlashes(value: string): string {\n return value.replace(/\\/+$/, \"\");\n}\n\nfunction resolveEndpoint(baseUrl: string, endpoint = \"/embeddings\"): string {\n const trimmed = trimTrailingSlashes(baseUrl);\n if (trimmed.endsWith(\"/embeddings\")) {\n return trimmed;\n }\n const normalizedEndpoint = endpoint.startsWith(\"/\") ? endpoint : `/${endpoint}`;\n return `${trimmed}${normalizedEndpoint}`;\n}\n\nfunction stableProviderId(prefix: string, input: string): string {\n const digest = createHash(\"sha256\").update(input).digest(\"hex\").slice(0, 12);\n return `${prefix}:${digest}`;\n}\n\nfunction getFetch(fetchImpl?: typeof fetch): typeof fetch {\n const candidate = fetchImpl ?? globalThis.fetch;\n if (!candidate) {\n throw new Error(\"Global fetch is not available in this runtime\");\n }\n return candidate;\n}\n\nfunction assertEmbeddingVector(vector: unknown, dimension: number, context: string): number[] {\n if (!Array.isArray(vector) || !vector.every((value) => typeof value === \"number\" && Number.isFinite(value))) {\n throw new Error(`${context} returned an invalid embedding vector`);\n }\n if (vector.length !== dimension) {\n throw new Error(`${context} returned dimension ${vector.length}, expected ${dimension}`);\n }\n return vector as number[];\n}\n\nfunction parseOpenAIResponse(json: unknown, dimension: number, context: string): number[][] {\n const rows = (json as { data?: EmbeddingResponseItem[] })?.data;\n if (!Array.isArray(rows)) {\n throw new Error(`${context} returned an invalid embeddings payload`);\n }\n return rows.map((row, index) => assertEmbeddingVector(row?.embedding, dimension, `${context} item ${index}`));\n}\n\nfunction parseLocalHttpResponse(json: unknown, dimension: number, context: string): number[][] {\n if (Array.isArray((json as { embeddings?: unknown }).embeddings)) {\n const embeddings = (json as { embeddings: unknown[] }).embeddings;\n return embeddings.map((row, index) => assertEmbeddingVector(row, dimension, `${context} item ${index}`));\n }\n return parseOpenAIResponse(json, dimension, context);\n}\n\nasync function runEmbeddingRequest(input: {\n context: string;\n url: string;\n body: unknown;\n headers?: Record<string, string>;\n parser: (json: unknown, dimension: number, context: string) => number[][];\n dimension: number;\n fetchImpl?: typeof fetch;\n}): Promise<number[][]> {\n const fetchFn = getFetch(input.fetchImpl);\n const response = await fetchFn(input.url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...input.headers,\n },\n body: JSON.stringify(input.body),\n });\n\n if (!response.ok) {\n const detail = await response.text().catch(() => \"\");\n throw new Error(`${input.context} request failed: ${response.status} ${response.statusText}${detail ? ` — ${detail}` : \"\"}`);\n }\n\n const json = await response.json();\n return input.parser(json, input.dimension, input.context);\n}\n\nexport function createOpenAICompatibleEmbeddingProvider(opts: EmbeddingProviderOptions): EmbeddingProvider {\n const url = resolveEndpoint(opts.baseUrl, opts.endpoint);\n const providerDescriptor = `${trimTrailingSlashes(opts.baseUrl)}|${opts.model}|${opts.dimension}`;\n const id = stableProviderId(`openai-compatible:${opts.model}`, providerDescriptor);\n\n return {\n id,\n model: opts.model,\n dimension: opts.dimension,\n async embed(texts: string[]): Promise<number[][]> {\n if (texts.length === 0) return [];\n return runEmbeddingRequest({\n context: \"openai-compatible embedding provider\",\n url,\n dimension: opts.dimension,\n fetchImpl: opts.fetchImpl,\n headers: {\n ...(opts.apiKey ? { authorization: `Bearer ${opts.apiKey}` } : {}),\n ...opts.headers,\n },\n body: {\n model: opts.model,\n input: texts,\n },\n parser: parseOpenAIResponse,\n });\n },\n async healthcheck(): Promise<void> {\n await this.embed([\"healthcheck\"]);\n },\n };\n}\n\nexport function createLocalHttpEmbeddingProvider(opts: EmbeddingProviderOptions): EmbeddingProvider {\n const url = resolveEndpoint(opts.baseUrl, opts.endpoint);\n const providerDescriptor = `${trimTrailingSlashes(opts.baseUrl)}|${opts.model}|${opts.dimension}`;\n const id = stableProviderId(`local-http:${opts.model}`, providerDescriptor);\n\n return {\n id,\n model: opts.model,\n dimension: opts.dimension,\n async embed(texts: string[]): Promise<number[][]> {\n if (texts.length === 0) return [];\n return runEmbeddingRequest({\n context: \"local-http embedding provider\",\n url,\n dimension: opts.dimension,\n fetchImpl: opts.fetchImpl,\n headers: opts.headers,\n body: {\n model: opts.model,\n input: texts,\n },\n parser: parseLocalHttpResponse,\n });\n },\n async healthcheck(): Promise<void> {\n await this.embed([\"healthcheck\"]);\n },\n };\n}\n\nexport function normalizeEmbeddingBaseUrl(baseUrl: string): string {\n return trimTrailingSlashes(baseUrl);\n}\n","import {\n createLocalHttpEmbeddingProvider,\n createOpenAICompatibleEmbeddingProvider,\n normalizeEmbeddingBaseUrl,\n type EmbeddingProvider,\n} from \"./embedding.js\";\n\nexport type EmbeddingProviderKind = \"openai-compatible\" | \"local-http\";\n\nexport interface EmbeddingProviderConfig {\n provider: EmbeddingProviderKind;\n baseUrl: string;\n model: string;\n dimension: number;\n apiKey?: string;\n}\n\nexport interface EmbeddingProviderFactoryOptions {\n config?: Partial<EmbeddingProviderConfig>;\n env?: NodeJS.ProcessEnv;\n fetchImpl?: typeof fetch;\n}\n\nfunction parseDimension(raw: string | undefined): number | undefined {\n if (!raw) return undefined;\n const value = Number.parseInt(raw, 10);\n return Number.isFinite(value) && value > 0 ? value : undefined;\n}\n\nfunction parseProvider(raw: string | undefined): EmbeddingProviderKind | null {\n if (!raw) return null;\n if (raw === \"openai-compatible\" || raw === \"local-http\") {\n return raw;\n }\n throw new Error(`Unsupported embedding provider: ${raw}`);\n}\n\nexport function getEmbeddingProviderConfigFromEnv(env: NodeJS.ProcessEnv = process.env): EmbeddingProviderConfig | null {\n const provider = parseProvider(env.AGENT_MEMORY_EMBEDDING_PROVIDER);\n if (!provider) return null;\n\n const baseUrl = env.AGENT_MEMORY_EMBEDDING_BASE_URL;\n const model = env.AGENT_MEMORY_EMBEDDING_MODEL;\n const dimension = parseDimension(env.AGENT_MEMORY_EMBEDDING_DIMENSION);\n\n if (!baseUrl) {\n throw new Error(\"AGENT_MEMORY_EMBEDDING_BASE_URL is required when embeddings are enabled\");\n }\n if (!model) {\n throw new Error(\"AGENT_MEMORY_EMBEDDING_MODEL is required when embeddings are enabled\");\n }\n if (!dimension) {\n throw new Error(\"AGENT_MEMORY_EMBEDDING_DIMENSION is required when embeddings are enabled\");\n }\n if (provider === \"openai-compatible\" && !env.AGENT_MEMORY_EMBEDDING_API_KEY) {\n throw new Error(\"AGENT_MEMORY_EMBEDDING_API_KEY is required for openai-compatible providers\");\n }\n\n return {\n provider,\n baseUrl,\n model,\n dimension,\n apiKey: env.AGENT_MEMORY_EMBEDDING_API_KEY,\n };\n}\n\nexport function createEmbeddingProvider(\n input: EmbeddingProviderConfig,\n opts?: { fetchImpl?: typeof fetch },\n): EmbeddingProvider {\n const normalized = {\n ...input,\n baseUrl: normalizeEmbeddingBaseUrl(input.baseUrl),\n };\n\n if (normalized.provider === \"openai-compatible\") {\n return createOpenAICompatibleEmbeddingProvider({\n baseUrl: normalized.baseUrl,\n model: normalized.model,\n dimension: normalized.dimension,\n apiKey: normalized.apiKey,\n fetchImpl: opts?.fetchImpl,\n });\n }\n\n return createLocalHttpEmbeddingProvider({\n baseUrl: normalized.baseUrl,\n model: normalized.model,\n dimension: normalized.dimension,\n fetchImpl: opts?.fetchImpl,\n });\n}\n\nexport function resolveEmbeddingProviderConfig(opts?: { config?: Partial<EmbeddingProviderConfig>; env?: NodeJS.ProcessEnv }): EmbeddingProviderConfig | null {\n const envConfig = getEmbeddingProviderConfigFromEnv(opts?.env);\n if (!envConfig && !opts?.config?.provider) {\n return null;\n }\n\n const provider = opts?.config?.provider ?? envConfig?.provider;\n const baseUrl = opts?.config?.baseUrl ?? envConfig?.baseUrl;\n const model = opts?.config?.model ?? envConfig?.model;\n const dimension = opts?.config?.dimension ?? envConfig?.dimension;\n const apiKey = opts?.config?.apiKey ?? envConfig?.apiKey;\n\n if (!provider || !baseUrl || !model || !dimension) {\n throw new Error(\"Incomplete embedding provider configuration\");\n }\n if (provider === \"openai-compatible\" && !apiKey) {\n throw new Error(\"OpenAI-compatible embedding providers require an API key\");\n }\n\n return { provider, baseUrl, model, dimension, apiKey };\n}\n\nexport function getEmbeddingProvider(opts?: EmbeddingProviderFactoryOptions): EmbeddingProvider | null {\n const config = resolveEmbeddingProviderConfig({ config: opts?.config, env: opts?.env });\n if (!config) return null;\n return createEmbeddingProvider(config, { fetchImpl: opts?.fetchImpl });\n}\n\nexport function getEmbeddingProviderFromEnv(env: NodeJS.ProcessEnv = process.env): EmbeddingProvider | null {\n try {\n return getEmbeddingProvider({ env });\n } catch {\n return null;\n }\n}\n\nexport function getConfiguredEmbeddingProviderId(opts?: { config?: Partial<EmbeddingProviderConfig>; env?: NodeJS.ProcessEnv }): string | null {\n try {\n const provider = getEmbeddingProvider({ config: opts?.config, env: opts?.env });\n return provider?.id ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function healthcheckEmbeddingProvider(provider: EmbeddingProvider | null): Promise<{ enabled: boolean; providerId?: string }> {\n if (!provider) {\n return { enabled: false };\n }\n if (provider.healthcheck) {\n await provider.healthcheck();\n } else {\n await provider.embed([\"healthcheck\"]);\n }\n return { enabled: true, providerId: provider.id };\n}\n","import type Database from \"better-sqlite3\";\nimport { newId, now } from \"../core/db.js\";\nimport type { Memory } from \"../core/memory.js\";\n\nexport type EmbeddingStatus = \"pending\" | \"ready\" | \"failed\";\n\nexport interface StoredEmbedding {\n id: string;\n memory_id: string;\n provider_id: string;\n vector: Buffer | null;\n content_hash: string;\n status: EmbeddingStatus;\n created_at: string;\n}\n\nexport interface VectorSearchResult {\n memory: Memory;\n similarity: number;\n rank: number;\n provider_id: string;\n}\n\nexport interface PendingEmbeddingRecord {\n embeddingId: string;\n memoryId: string;\n content: string;\n contentHash: string;\n providerId: string;\n status: EmbeddingStatus;\n}\n\nexport function encodeVector(vector: ArrayLike<number>): Buffer {\n const float32 = vector instanceof Float32Array ? vector : Float32Array.from(vector);\n return Buffer.from(float32.buffer.slice(float32.byteOffset, float32.byteOffset + float32.byteLength));\n}\n\nexport function decodeVector(blob: Uint8Array | ArrayBuffer): number[] {\n const buffer = blob instanceof Uint8Array ? blob : new Uint8Array(blob);\n const aligned = buffer.byteOffset === 0 && buffer.byteLength === buffer.buffer.byteLength\n ? buffer.buffer\n : buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);\n return Array.from(new Float32Array(aligned));\n}\n\nexport function cosineSimilarity(a: ArrayLike<number>, b: ArrayLike<number>): number {\n const length = Math.min(a.length, b.length);\n if (length === 0 || a.length !== b.length) return 0;\n\n let dot = 0;\n let normA = 0;\n let normB = 0;\n\n for (let index = 0; index < length; index++) {\n const left = Number(a[index] ?? 0);\n const right = Number(b[index] ?? 0);\n dot += left * right;\n normA += left * left;\n normB += right * right;\n }\n\n if (normA === 0 || normB === 0) return 0;\n return dot / (Math.sqrt(normA) * Math.sqrt(normB));\n}\n\nexport function getEmbedding(db: Database.Database, memoryId: string, providerId: string): StoredEmbedding | null {\n return (db.prepare(\"SELECT * FROM embeddings WHERE memory_id = ? AND provider_id = ?\").get(memoryId, providerId) as StoredEmbedding) ?? null;\n}\n\nexport function markMemoryEmbeddingPending(\n db: Database.Database,\n memoryId: string,\n providerId: string,\n contentHash: string,\n): void {\n db.prepare(\n `INSERT INTO embeddings (id, memory_id, provider_id, vector, content_hash, status, created_at)\n VALUES (?, ?, ?, NULL, ?, 'pending', ?)\n ON CONFLICT(memory_id, provider_id) DO UPDATE SET\n vector = NULL,\n content_hash = excluded.content_hash,\n status = 'pending'`,\n ).run(newId(), memoryId, providerId, contentHash, now());\n}\n\nexport function markAllEmbeddingsPending(db: Database.Database, memoryId: string, contentHash: string): number {\n const result = db.prepare(\n `UPDATE embeddings\n SET vector = NULL,\n content_hash = ?,\n status = 'pending'\n WHERE memory_id = ?`,\n ).run(contentHash, memoryId);\n return result.changes;\n}\n\nexport function upsertReadyEmbedding(input: {\n db: Database.Database;\n memoryId: string;\n providerId: string;\n vector: ArrayLike<number>;\n contentHash: string;\n}): void {\n input.db.prepare(\n `INSERT INTO embeddings (id, memory_id, provider_id, vector, content_hash, status, created_at)\n VALUES (?, ?, ?, ?, ?, 'ready', ?)\n ON CONFLICT(memory_id, provider_id) DO UPDATE SET\n vector = excluded.vector,\n content_hash = excluded.content_hash,\n status = 'ready'`,\n ).run(newId(), input.memoryId, input.providerId, encodeVector(input.vector), input.contentHash, now());\n}\n\nexport function markEmbeddingFailed(\n db: Database.Database,\n memoryId: string,\n providerId: string,\n contentHash: string,\n): void {\n db.prepare(\n `INSERT INTO embeddings (id, memory_id, provider_id, vector, content_hash, status, created_at)\n VALUES (?, ?, ?, NULL, ?, 'failed', ?)\n ON CONFLICT(memory_id, provider_id) DO UPDATE SET\n vector = NULL,\n content_hash = excluded.content_hash,\n status = 'failed'`,\n ).run(newId(), memoryId, providerId, contentHash, now());\n}\n\nexport function listPendingEmbeddings(\n db: Database.Database,\n opts: {\n providerId: string;\n agent_id?: string;\n limit?: number;\n includeFailed?: boolean;\n },\n): PendingEmbeddingRecord[] {\n const statuses = opts.includeFailed ? [\"pending\", \"failed\"] : [\"pending\"];\n const placeholders = statuses.map(() => \"?\").join(\", \");\n const limit = opts.limit ?? 100;\n const agentId = opts.agent_id ?? \"default\";\n\n return db.prepare(\n `SELECT e.id as embeddingId,\n e.memory_id as memoryId,\n m.content as content,\n e.content_hash as contentHash,\n e.provider_id as providerId,\n e.status as status\n FROM embeddings e\n JOIN memories m ON m.id = e.memory_id\n WHERE e.provider_id = ?\n AND m.agent_id = ?\n AND e.status IN (${placeholders})\n ORDER BY e.created_at ASC\n LIMIT ?`,\n ).all(opts.providerId, agentId, ...statuses, limit) as PendingEmbeddingRecord[];\n}\n\nexport function searchByVector(\n db: Database.Database,\n queryVector: ArrayLike<number>,\n opts: {\n providerId: string;\n agent_id?: string;\n limit?: number;\n min_vitality?: number;\n },\n): VectorSearchResult[] {\n const limit = opts.limit ?? 20;\n const agentId = opts.agent_id ?? \"default\";\n const minVitality = opts.min_vitality ?? 0;\n\n const rows = db.prepare(\n `SELECT e.provider_id, e.vector, e.content_hash,\n m.id, m.content, m.type, m.priority, m.emotion_val, m.vitality,\n m.stability, m.access_count, m.last_accessed, m.created_at,\n m.updated_at, m.source, m.agent_id, m.hash\n FROM embeddings e\n JOIN memories m ON m.id = e.memory_id\n WHERE e.provider_id = ?\n AND e.status = 'ready'\n AND e.vector IS NOT NULL\n AND e.content_hash = m.hash\n AND m.agent_id = ?\n AND m.vitality >= ?`,\n ).all(opts.providerId, agentId, minVitality) as Array<{ provider_id: string; vector: Buffer; content_hash: string } & Memory>;\n\n const scored = rows\n .map((row) => ({\n provider_id: row.provider_id,\n memory: {\n id: row.id,\n content: row.content,\n type: row.type,\n priority: row.priority,\n emotion_val: row.emotion_val,\n vitality: row.vitality,\n stability: row.stability,\n access_count: row.access_count,\n last_accessed: row.last_accessed,\n created_at: row.created_at,\n updated_at: row.updated_at,\n source: row.source,\n agent_id: row.agent_id,\n hash: row.hash,\n } as Memory,\n similarity: cosineSimilarity(queryVector, decodeVector(row.vector)),\n }))\n .filter((row) => Number.isFinite(row.similarity) && row.similarity > 0)\n .sort((left, right) => right.similarity - left.similarity)\n .slice(0, limit);\n\n return scored.map((row, index) => ({\n memory: row.memory,\n similarity: row.similarity,\n rank: index + 1,\n provider_id: row.provider_id,\n }));\n}\n","// AgentMemory v2 — Export memories to Markdown files\nimport type Database from \"better-sqlite3\";\nimport { listMemories, type Memory } from \"./memory.js\";\nimport { writeFileSync, mkdirSync, existsSync } from \"fs\";\nimport { join } from \"path\";\n\nexport interface ExportResult {\n exported: number;\n files: string[];\n}\n\n/**\n * Export all memories to Markdown files in the given directory.\n * Creates MEMORY.md for identity/emotion/knowledge and daily .md files for events.\n */\nexport function exportMemories(\n db: Database.Database,\n dirPath: string,\n opts?: { agent_id?: string },\n): ExportResult {\n const agentId = opts?.agent_id ?? \"default\";\n if (!existsSync(dirPath)) mkdirSync(dirPath, { recursive: true });\n\n let exported = 0;\n const files: string[] = [];\n\n // Export identity, emotion, knowledge as MEMORY.md\n const identities = listMemories(db, { agent_id: agentId, type: \"identity\" });\n const knowledge = listMemories(db, { agent_id: agentId, type: \"knowledge\" });\n const emotions = listMemories(db, { agent_id: agentId, type: \"emotion\" });\n\n if (identities.length || knowledge.length || emotions.length) {\n const sections: string[] = [\"# Agent Memory Export\\n\"];\n\n if (identities.length) {\n sections.push(\"## Identity\\n\");\n for (const m of identities) {\n sections.push(`- ${m.content}\\n`);\n exported++;\n }\n }\n if (emotions.length) {\n sections.push(\"\\n## Emotions\\n\");\n for (const m of emotions) {\n sections.push(`- ${m.content}\\n`);\n exported++;\n }\n }\n if (knowledge.length) {\n sections.push(\"\\n## Knowledge\\n\");\n for (const m of knowledge) {\n sections.push(`- ${m.content}\\n`);\n exported++;\n }\n }\n\n const memoryPath = join(dirPath, \"MEMORY.md\");\n writeFileSync(memoryPath, sections.join(\"\\n\"));\n files.push(memoryPath);\n }\n\n // Export events as daily journal files\n const events = listMemories(db, { agent_id: agentId, type: \"event\", limit: 10000 });\n const byDate = new Map<string, Memory[]>();\n for (const ev of events) {\n const date = ev.created_at.slice(0, 10);\n if (!byDate.has(date)) byDate.set(date, []);\n byDate.get(date)!.push(ev);\n }\n\n for (const [date, mems] of byDate) {\n const lines = [`# ${date}\\n`];\n for (const m of mems) {\n lines.push(`- ${m.content}\\n`);\n exported++;\n }\n const filePath = join(dirPath, `${date}.md`);\n writeFileSync(filePath, lines.join(\"\\n\"));\n files.push(filePath);\n }\n\n return { exported, files };\n}\n","// AgentMemory v2 — URI path system (from nocturne's Content-Path separation)\nimport type Database from \"better-sqlite3\";\nimport { newId, now } from \"./db.js\";\n\nexport interface Path {\n id: string;\n memory_id: string;\n agent_id: string;\n uri: string;\n alias: string | null;\n domain: string;\n created_at: string;\n}\n\n// Valid domains (extensible)\nconst DEFAULT_DOMAINS = new Set([\"core\", \"emotion\", \"knowledge\", \"event\", \"system\"]);\n\nexport function parseUri(uri: string): { domain: string; path: string } {\n const match = uri.match(/^([a-z]+):\\/\\/(.+)$/);\n if (!match) throw new Error(`Invalid URI: ${uri}. Expected format: domain://path`);\n return { domain: match[1], path: match[2] };\n}\n\nexport function createPath(\n db: Database.Database,\n memoryId: string,\n uri: string,\n alias?: string,\n validDomains?: Set<string>,\n agent_id?: string,\n): Path {\n const { domain } = parseUri(uri);\n const domains = validDomains ?? DEFAULT_DOMAINS;\n if (!domains.has(domain)) {\n throw new Error(`Invalid domain \"${domain}\". Valid: ${[...domains].join(\", \")}`);\n }\n\n const memoryAgent = (db.prepare(\"SELECT agent_id FROM memories WHERE id = ?\").get(memoryId) as { agent_id: string } | undefined)?.agent_id;\n if (!memoryAgent) throw new Error(`Memory not found: ${memoryId}`);\n if (agent_id && agent_id !== memoryAgent) {\n throw new Error(`Agent mismatch for path: memory agent_id=${memoryAgent}, requested agent_id=${agent_id}`);\n }\n const agentId = agent_id ?? memoryAgent;\n\n // Check URI uniqueness\n const existing = db.prepare(\"SELECT id FROM paths WHERE agent_id = ? AND uri = ?\").get(agentId, uri) as\n | { id: string }\n | undefined;\n if (existing) {\n throw new Error(`URI already exists: ${uri}`);\n }\n\n const id = newId();\n db.prepare(\n \"INSERT INTO paths (id, memory_id, agent_id, uri, alias, domain, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)\",\n ).run(id, memoryId, agentId, uri, alias ?? null, domain, now());\n\n return getPath(db, id)!;\n}\n\nexport function getPath(db: Database.Database, id: string): Path | null {\n return (db.prepare(\"SELECT * FROM paths WHERE id = ?\").get(id) as Path) ?? null;\n}\n\nexport function getPathByUri(db: Database.Database, uri: string, agent_id = \"default\"): Path | null {\n return (db.prepare(\"SELECT * FROM paths WHERE agent_id = ? AND uri = ?\").get(agent_id, uri) as Path) ?? null;\n}\n\nexport function getPathsByMemory(db: Database.Database, memoryId: string): Path[] {\n return db.prepare(\"SELECT * FROM paths WHERE memory_id = ?\").all(memoryId) as Path[];\n}\n\nexport function getPathsByDomain(db: Database.Database, domain: string, agent_id = \"default\"): Path[] {\n return db\n .prepare(\"SELECT * FROM paths WHERE agent_id = ? AND domain = ? ORDER BY uri\")\n .all(agent_id, domain) as Path[];\n}\n\nexport function getPathsByPrefix(db: Database.Database, prefix: string, agent_id = \"default\"): Path[] {\n return db\n .prepare(\"SELECT * FROM paths WHERE agent_id = ? AND uri LIKE ? ORDER BY uri\")\n .all(agent_id, `${prefix}%`) as Path[];\n}\n\nexport function deletePath(db: Database.Database, id: string): boolean {\n const result = db.prepare(\"DELETE FROM paths WHERE id = ?\").run(id);\n return result.changes > 0;\n}\n\nexport function deletePathsByMemory(db: Database.Database, memoryId: string): number {\n const result = db.prepare(\"DELETE FROM paths WHERE memory_id = ?\").run(memoryId);\n return result.changes;\n}\n","// AgentMemory v2 — Boot loader (system://boot identity loading)\n// From nocturne's CORE_MEMORY_URIS concept\nimport type Database from \"better-sqlite3\";\nimport type { Memory } from \"../core/memory.js\";\nimport { getPathByUri } from \"../core/path.js\";\nimport { getMemory, listMemories, recordAccess } from \"../core/memory.js\";\n\nexport interface BootResult {\n identityMemories: Memory[];\n bootPaths: string[];\n}\n\n/**\n * Load core identity memories at startup.\n * Returns all P0 (identity) memories + any memories referenced by system://boot.\n */\nexport function boot(\n db: Database.Database,\n opts?: { agent_id?: string; corePaths?: string[] },\n): BootResult {\n const agentId = opts?.agent_id ?? \"default\";\n const corePaths = opts?.corePaths ?? [\n \"core://agent\",\n \"core://user\",\n \"core://agent/identity\",\n \"core://user/identity\",\n ];\n\n const memories = new Map<string, Memory>();\n\n // 1. Load all P0 identity memories\n const identities = listMemories(db, { agent_id: agentId, priority: 0 });\n for (const mem of identities) {\n memories.set(mem.id, mem);\n recordAccess(db, mem.id, 1.1); // Light access boost on boot\n }\n\n // 2. Load memories at configured core paths\n const bootPaths: string[] = [];\n for (const uri of corePaths) {\n const path = getPathByUri(db, uri, agentId);\n if (path) {\n bootPaths.push(uri);\n if (!memories.has(path.memory_id)) {\n const mem = getMemory(db, path.memory_id);\n if (mem) {\n memories.set(mem.id, mem);\n recordAccess(db, mem.id, 1.1);\n }\n }\n }\n }\n\n // 3. Check system://boot for additional paths\n const bootEntry = getPathByUri(db, \"system://boot\", agentId);\n if (bootEntry) {\n const bootMem = getMemory(db, bootEntry.memory_id);\n if (bootMem) {\n // system://boot content may list additional URIs (one per line)\n const additionalUris = bootMem.content\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l.match(/^[a-z]+:\\/\\//));\n\n for (const uri of additionalUris) {\n const path = getPathByUri(db, uri, agentId);\n if (path && !memories.has(path.memory_id)) {\n const mem = getMemory(db, path.memory_id);\n if (mem) {\n memories.set(mem.id, mem);\n bootPaths.push(uri);\n }\n }\n }\n }\n }\n\n return {\n identityMemories: [...memories.values()],\n bootPaths,\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport http, { type IncomingMessage, type ServerResponse } from \"node:http\";\nimport type Database from \"better-sqlite3\";\nimport type { EmbeddingProvider } from \"../search/embedding.js\";\nimport { openDatabase } from \"../core/db.js\";\nimport { rememberMemory } from \"../app/remember.js\";\nimport { recallMemory } from \"../app/recall.js\";\nimport { surfaceMemories } from \"../app/surface.js\";\nimport { reflectMemories } from \"../app/reflect.js\";\nimport { getMemoryStatus } from \"../app/status.js\";\nimport { recordFeedbackEvent } from \"../app/feedback.js\";\nimport { reindexMemories } from \"../app/reindex.js\";\nimport type { MemoryType } from \"../core/memory.js\";\nimport type { MaintenancePhase } from \"../sleep/jobs.js\";\nimport { getMaintenanceJob } from \"../sleep/jobs.js\";\nimport type { ReflectRunners } from \"../sleep/orchestrator.js\";\n\nexport interface HttpJobStatus {\n id: string;\n kind: \"reflect\" | \"reindex\";\n status: \"running\" | \"completed\" | \"failed\";\n stage: string;\n progress: number;\n agent_id: string;\n started_at: string;\n finished_at: string | null;\n backend_job_id?: string;\n error?: string;\n result?: unknown;\n}\n\nexport interface HttpServerOptions {\n db?: Database.Database;\n dbPath?: string;\n agentId?: string;\n provider?: EmbeddingProvider | null;\n reflectRunners?: Partial<ReflectRunners>;\n}\n\nexport interface AgentMemoryHttpServer {\n server: http.Server;\n db: Database.Database;\n jobs: Map<string, HttpJobStatus>;\n listen: (port?: number, host?: string) => Promise<{ port: number; host: string }>;\n close: () => Promise<void>;\n}\n\nconst VALID_MEMORY_TYPES = new Set<MemoryType>([\"identity\", \"emotion\", \"knowledge\", \"event\"]);\nconst VALID_PHASES = new Set<MaintenancePhase>([\"decay\", \"tidy\", \"govern\", \"all\"]);\nconst VALID_INTENTS = new Set([\"factual\", \"preference\", \"temporal\", \"planning\", \"design\"]);\n\nfunction json<T>(value: T): string {\n return JSON.stringify(value);\n}\n\nfunction now(): string {\n return new Date().toISOString();\n}\n\nfunction sendJson(res: ServerResponse, statusCode: number, payload: unknown): void {\n res.writeHead(statusCode, {\n \"content-type\": \"application/json; charset=utf-8\",\n \"cache-control\": \"no-store\",\n });\n res.end(json(payload));\n}\n\nfunction sendError(res: ServerResponse, statusCode: number, error: string, details?: unknown): void {\n sendJson(res, statusCode, { error, details });\n}\n\nfunction openSse(res: ServerResponse): void {\n res.writeHead(200, {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-cache, no-transform\",\n connection: \"keep-alive\",\n });\n res.write(\": connected\\n\\n\");\n}\n\nfunction sendSse(res: ServerResponse, event: string, payload: unknown): void {\n if (res.writableEnded) return;\n res.write(`event: ${event}\\n`);\n res.write(`data: ${json(payload)}\\n\\n`);\n}\n\nasync function readJsonBody(req: IncomingMessage): Promise<Record<string, unknown>> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n const raw = Buffer.concat(chunks).toString(\"utf8\").trim();\n if (!raw) return {};\n\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"Request body must be a JSON object\");\n }\n return parsed as Record<string, unknown>;\n } catch (error) {\n throw new Error(error instanceof Error ? error.message : \"Invalid JSON body\");\n }\n}\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction asBoolean(value: unknown): boolean | undefined {\n return typeof value === \"boolean\" ? value : undefined;\n}\n\nfunction asNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction asStringArray(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const result = value.filter((item): item is string => typeof item === \"string\").map((item) => item.trim()).filter(Boolean);\n return result.length > 0 ? result : [];\n}\n\nfunction wantsSse(req: IncomingMessage, body: Record<string, unknown>): boolean {\n const accept = req.headers.accept ?? \"\";\n return accept.includes(\"text/event-stream\") || body.stream === true;\n}\n\nfunction formatRecallResponse(result: Awaited<ReturnType<typeof recallMemory>>) {\n return {\n mode: result.mode,\n provider_id: result.providerId,\n used_vector_search: result.usedVectorSearch,\n count: result.results.length,\n memories: result.results.map((row) => ({\n id: row.memory.id,\n content: row.memory.content,\n type: row.memory.type,\n priority: row.memory.priority,\n vitality: row.memory.vitality,\n score: row.score,\n bm25_rank: row.bm25_rank,\n vector_rank: row.vector_rank,\n bm25_score: row.bm25_score,\n vector_score: row.vector_score,\n updated_at: row.memory.updated_at,\n })),\n };\n}\n\nfunction formatSurfaceResponse(result: Awaited<ReturnType<typeof surfaceMemories>>) {\n return {\n count: result.count,\n query: result.query,\n task: result.task,\n intent: result.intent,\n results: result.results.map((row) => ({\n id: row.memory.id,\n content: row.memory.content,\n type: row.memory.type,\n priority: row.memory.priority,\n vitality: row.memory.vitality,\n score: row.score,\n semantic_score: row.semantic_score,\n lexical_score: row.lexical_score,\n task_match: row.task_match,\n priority_prior: row.priority_prior,\n feedback_score: row.feedback_score,\n feedback_summary: row.feedback_summary,\n reason_codes: row.reason_codes,\n updated_at: row.memory.updated_at,\n })),\n };\n}\n\nfunction createJob(jobs: Map<string, HttpJobStatus>, kind: HttpJobStatus[\"kind\"], agentId: string): HttpJobStatus {\n const job: HttpJobStatus = {\n id: randomUUID(),\n kind,\n status: \"running\",\n stage: \"queued\",\n progress: 0,\n agent_id: agentId,\n started_at: now(),\n finished_at: null,\n };\n jobs.set(job.id, job);\n return job;\n}\n\nfunction updateJob(job: HttpJobStatus, patch: Partial<HttpJobStatus>): HttpJobStatus {\n Object.assign(job, patch);\n return job;\n}\n\nexport function createHttpServer(options?: HttpServerOptions): AgentMemoryHttpServer {\n const ownsDb = !options?.db;\n const db = options?.db ?? openDatabase({ path: options?.dbPath ?? process.env.AGENT_MEMORY_DB ?? \"./agent-memory.db\" });\n const defaultAgentId = options?.agentId ?? process.env.AGENT_MEMORY_AGENT_ID ?? \"default\";\n const jobs = new Map<string, HttpJobStatus>();\n\n const executeReflectJob = async (\n job: HttpJobStatus,\n body: Record<string, unknown>,\n stream?: ServerResponse,\n ) => {\n const phase = (asString(body.phase) ?? \"all\") as MaintenancePhase;\n if (!VALID_PHASES.has(phase)) {\n throw new Error(`Invalid phase: ${String(body.phase)}`);\n }\n\n updateJob(job, { stage: phase, progress: 0.01 });\n\n try {\n const result = await reflectMemories(db, {\n phase,\n agent_id: asString(body.agent_id) ?? defaultAgentId,\n runners: options?.reflectRunners,\n onProgress: (event) => {\n updateJob(job, {\n stage: String(event.phase),\n progress: event.progress,\n backend_job_id: event.jobId ?? job.backend_job_id,\n });\n if (stream) {\n sendSse(stream, \"progress\", {\n job,\n event,\n });\n }\n },\n });\n\n updateJob(job, {\n status: \"completed\",\n stage: \"done\",\n progress: 1,\n backend_job_id: result.jobId,\n finished_at: now(),\n result,\n });\n\n return { job, result };\n } catch (error) {\n updateJob(job, {\n status: \"failed\",\n stage: \"failed\",\n progress: 1,\n finished_at: now(),\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n };\n\n const executeReindexJob = async (\n job: HttpJobStatus,\n body: Record<string, unknown>,\n stream?: ServerResponse,\n ) => {\n updateJob(job, { stage: \"fts\", progress: 0.01 });\n\n try {\n const result = await reindexMemories(db, {\n agent_id: asString(body.agent_id) ?? defaultAgentId,\n provider: options?.provider,\n force: asBoolean(body.full) ?? false,\n batchSize: asNumber(body.batch_size) ?? 16,\n onProgress: (event) => {\n updateJob(job, {\n stage: event.stage,\n progress: event.progress,\n });\n if (stream) {\n sendSse(stream, \"progress\", {\n job,\n event,\n });\n }\n },\n });\n\n updateJob(job, {\n status: \"completed\",\n stage: \"done\",\n progress: 1,\n finished_at: now(),\n result,\n });\n return { job, result };\n } catch (error) {\n updateJob(job, {\n status: \"failed\",\n stage: \"failed\",\n progress: 1,\n finished_at: now(),\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n };\n\n const server = http.createServer(async (req, res) => {\n try {\n const method = req.method ?? \"GET\";\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n const pathname = url.pathname;\n\n if (method === \"GET\" && pathname === \"/health\") {\n sendJson(res, 200, {\n ok: true,\n service: \"agent-memory\",\n time: now(),\n });\n return;\n }\n\n if (method === \"GET\" && pathname === \"/v1/status\") {\n const agentId = url.searchParams.get(\"agent_id\") ?? defaultAgentId;\n sendJson(res, 200, getMemoryStatus(db, { agent_id: agentId }));\n return;\n }\n\n if (method === \"GET\" && pathname.startsWith(\"/v1/jobs/\")) {\n const id = decodeURIComponent(pathname.slice(\"/v1/jobs/\".length));\n const job = jobs.get(id);\n if (job) {\n sendJson(res, 200, job);\n return;\n }\n\n const maintenanceJob = getMaintenanceJob(db, id);\n if (maintenanceJob) {\n sendJson(res, 200, maintenanceJob);\n return;\n }\n\n sendError(res, 404, `Job not found: ${id}`);\n return;\n }\n\n if (method !== \"POST\") {\n sendError(res, 404, `Route not found: ${method} ${pathname}`);\n return;\n }\n\n const body = await readJsonBody(req);\n\n if (pathname === \"/v1/memories\") {\n const content = asString(body.content)?.trim();\n if (!content) {\n sendError(res, 400, \"content is required\");\n return;\n }\n\n const type = (asString(body.type) ?? \"knowledge\") as MemoryType;\n if (!VALID_MEMORY_TYPES.has(type)) {\n sendError(res, 400, `Invalid memory type: ${String(body.type)}`);\n return;\n }\n\n const result = await rememberMemory(db, {\n content,\n type,\n uri: asString(body.uri),\n source: asString(body.source),\n emotion_val: asNumber(body.emotion_val),\n agent_id: asString(body.agent_id) ?? defaultAgentId,\n conservative: asBoolean(body.conservative),\n provider: options?.provider,\n });\n\n sendJson(res, 200, result);\n return;\n }\n\n if (pathname === \"/v1/recall\") {\n const query = asString(body.query)?.trim();\n if (!query) {\n sendError(res, 400, \"query is required\");\n return;\n }\n\n const result = await recallMemory(db, {\n query,\n limit: asNumber(body.limit),\n agent_id: asString(body.agent_id) ?? defaultAgentId,\n provider: options?.provider,\n });\n\n sendJson(res, 200, formatRecallResponse(result));\n return;\n }\n\n if (pathname === \"/v1/surface\") {\n const types = asStringArray(body.types)?.filter((type): type is MemoryType => VALID_MEMORY_TYPES.has(type as MemoryType));\n const intent = asString(body.intent);\n if (intent !== undefined && !VALID_INTENTS.has(intent)) {\n sendError(res, 400, `Invalid intent: ${intent}`);\n return;\n }\n\n const result = await surfaceMemories(db, {\n query: asString(body.query),\n task: asString(body.task),\n recent_turns: asStringArray(body.recent_turns),\n intent: intent as Parameters<typeof surfaceMemories>[1][\"intent\"],\n types,\n limit: asNumber(body.limit),\n agent_id: asString(body.agent_id) ?? defaultAgentId,\n provider: options?.provider,\n });\n\n sendJson(res, 200, formatSurfaceResponse(result));\n return;\n }\n\n if (pathname === \"/v1/feedback\") {\n const memoryId = asString(body.memory_id)?.trim();\n const source = asString(body.source);\n const useful = asBoolean(body.useful);\n if (!memoryId) {\n sendError(res, 400, \"memory_id is required\");\n return;\n }\n if (source !== \"recall\" && source !== \"surface\") {\n sendError(res, 400, \"source must be 'recall' or 'surface'\");\n return;\n }\n if (useful === undefined) {\n sendError(res, 400, \"useful must be boolean\");\n return;\n }\n\n const result = recordFeedbackEvent(db, {\n memory_id: memoryId,\n source,\n useful,\n agent_id: asString(body.agent_id) ?? defaultAgentId,\n });\n\n sendJson(res, 200, result);\n return;\n }\n\n if (pathname === \"/v1/reflect\") {\n const agentId = asString(body.agent_id) ?? defaultAgentId;\n const job = createJob(jobs, \"reflect\", agentId);\n\n if (wantsSse(req, body)) {\n openSse(res);\n sendSse(res, \"job\", job);\n void executeReflectJob(job, body, res)\n .then(({ job: currentJob, result }) => {\n sendSse(res, \"done\", { job: currentJob, result });\n })\n .catch((error) => {\n sendSse(res, \"error\", {\n job,\n error: error instanceof Error ? error.message : String(error),\n });\n })\n .finally(() => {\n if (!res.writableEnded) res.end();\n });\n return;\n }\n\n const result = await executeReflectJob(job, body);\n sendJson(res, 200, result);\n return;\n }\n\n if (pathname === \"/v1/reindex\") {\n const agentId = asString(body.agent_id) ?? defaultAgentId;\n const job = createJob(jobs, \"reindex\", agentId);\n\n if (wantsSse(req, body)) {\n openSse(res);\n sendSse(res, \"job\", job);\n void executeReindexJob(job, body, res)\n .then(({ job: currentJob, result }) => {\n sendSse(res, \"done\", { job: currentJob, result });\n })\n .catch((error) => {\n sendSse(res, \"error\", {\n job,\n error: error instanceof Error ? error.message : String(error),\n });\n })\n .finally(() => {\n if (!res.writableEnded) res.end();\n });\n return;\n }\n\n const result = await executeReindexJob(job, body);\n sendJson(res, 200, result);\n return;\n }\n\n sendError(res, 404, `Route not found: ${method} ${pathname}`);\n } catch (error) {\n sendError(res, 500, error instanceof Error ? error.message : String(error));\n }\n });\n\n return {\n server,\n db,\n jobs,\n listen(port = 3000, host = \"127.0.0.1\") {\n return new Promise((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port, host, () => {\n server.off(\"error\", reject);\n const address = server.address();\n if (!address || typeof address === \"string\") {\n resolve({ port, host });\n return;\n }\n resolve({ port: address.port, host: address.address });\n });\n });\n },\n close() {\n return new Promise((resolve, reject) => {\n server.close((error) => {\n if (ownsDb) {\n try { db.close(); } catch {}\n }\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n },\n };\n}\n\nexport async function startHttpServer(options?: HttpServerOptions & { port?: number; host?: string }): Promise<AgentMemoryHttpServer> {\n const service = createHttpServer(options);\n await service.listen(options?.port, options?.host);\n return service;\n}\n","// AgentMemory v2 — BM25 full-text search via SQLite FTS5\nimport type Database from \"better-sqlite3\";\nimport type { Memory } from \"../core/memory.js\";\nimport { tokenize, tokenizeForIndex } from \"./tokenizer.js\";\n\nexport interface SearchResult {\n memory: Memory;\n score: number;\n rank: number;\n matchReason: string;\n}\n\n/**\n * BM25 search using SQLite FTS5.\n * Returns memories ranked by relevance.\n */\nexport function searchBM25(\n db: Database.Database,\n query: string,\n opts?: {\n agent_id?: string;\n limit?: number;\n min_vitality?: number;\n },\n): SearchResult[] {\n const limit = opts?.limit ?? 20;\n const agentId = opts?.agent_id ?? \"default\";\n const minVitality = opts?.min_vitality ?? 0.0;\n\n const ftsQuery = buildFtsQuery(query);\n if (!ftsQuery) return [];\n\n try {\n const rows = db\n .prepare(\n `SELECT m.*, rank AS score\n FROM memories_fts f\n JOIN memories m ON m.id = f.id\n WHERE memories_fts MATCH ?\n AND m.agent_id = ?\n AND m.vitality >= ?\n ORDER BY rank\n LIMIT ?`,\n )\n .all(ftsQuery, agentId, minVitality, limit) as Array<Memory & { score: number }>;\n\n return rows.map((row, index) => {\n const { score: _score, ...memoryFields } = row;\n return {\n memory: memoryFields as Memory,\n score: Math.abs(row.score), // FTS5 rank is negative (lower = better)\n rank: index + 1,\n matchReason: \"bm25\",\n };\n });\n } catch {\n // FTS query syntax error — fall back to simpler query\n return searchSimple(db, query, agentId, minVitality, limit);\n }\n}\n\n/**\n * Simple LIKE search as fallback when FTS fails\n */\nfunction searchSimple(\n db: Database.Database,\n query: string,\n agentId: string,\n minVitality: number,\n limit: number,\n): SearchResult[] {\n const rows = db\n .prepare(\n `SELECT * FROM memories\n WHERE agent_id = ? AND vitality >= ? AND content LIKE ?\n ORDER BY priority ASC, updated_at DESC\n LIMIT ?`,\n )\n .all(agentId, minVitality, `%${query}%`, limit) as Memory[];\n\n return rows.map((memory, index) => ({\n memory,\n score: 1.0 / (index + 1),\n rank: index + 1,\n matchReason: \"like\",\n }));\n}\n\n/**\n * Build FTS5 query from natural language.\n * Uses jieba for Chinese word segmentation, falls back to bigram splitting.\n */\nexport function buildFtsQuery(text: string): string | null {\n const tokens = tokenize(text);\n if (tokens.length === 0) return null;\n\n // Use OR for broad matching\n return tokens.map((w) => `\"${w}\"`).join(\" OR \");\n}\n\nexport function rebuildBm25Index(\n db: Database.Database,\n opts?: { agent_id?: string },\n): { reindexed: number } {\n const memories = opts?.agent_id\n ? db.prepare(\"SELECT id, content FROM memories WHERE agent_id = ?\").all(opts.agent_id) as Array<{ id: string; content: string }>\n : db.prepare(\"SELECT id, content FROM memories\").all() as Array<{ id: string; content: string }>;\n\n const insert = db.prepare(\"INSERT INTO memories_fts (id, content) VALUES (?, ?)\");\n const deleteOne = db.prepare(\"DELETE FROM memories_fts WHERE id = ?\");\n\n const transaction = db.transaction(() => {\n if (!opts?.agent_id) {\n db.exec(\"DELETE FROM memories_fts\");\n }\n\n for (const memory of memories) {\n if (opts?.agent_id) {\n deleteOne.run(memory.id);\n }\n insert.run(memory.id, tokenizeForIndex(memory.content));\n }\n });\n\n transaction();\n return { reindexed: memories.length };\n}\n","import type Database from \"better-sqlite3\";\nimport type { Memory } from \"../core/memory.js\";\nimport { recordAccess } from \"../core/memory.js\";\nimport { searchBM25, rebuildBm25Index, type SearchResult } from \"./bm25.js\";\nimport type { EmbeddingProvider } from \"./embedding.js\";\nimport { getEmbeddingProviderFromEnv } from \"./providers.js\";\nimport {\n markEmbeddingFailed,\n markMemoryEmbeddingPending,\n searchByVector,\n type VectorSearchResult,\n upsertReadyEmbedding,\n} from \"./vector.js\";\n\nexport interface HybridRecallResult {\n memory: Memory;\n score: number;\n bm25_rank?: number;\n vector_rank?: number;\n bm25_score?: number;\n vector_score?: number;\n}\n\nexport interface HybridRecallResponse {\n mode: \"bm25-only\" | \"vector-only\" | \"dual-path\";\n providerId: string | null;\n usedVectorSearch: boolean;\n results: HybridRecallResult[];\n}\n\nexport interface RecallOptions {\n agent_id?: string;\n limit?: number;\n min_vitality?: number;\n lexicalLimit?: number;\n vectorLimit?: number;\n provider?: EmbeddingProvider | null;\n recordAccess?: boolean;\n}\n\nexport interface ReindexOptions {\n agent_id?: string;\n provider?: EmbeddingProvider | null;\n force?: boolean;\n batchSize?: number;\n}\n\nexport interface ReindexEmbeddingsResult {\n enabled: boolean;\n providerId: string | null;\n scanned: number;\n pending: number;\n embedded: number;\n failed: number;\n}\n\nexport interface ReindexSearchResult {\n fts: { reindexed: number };\n embeddings: ReindexEmbeddingsResult;\n}\n\nconst PRIORITY_WEIGHT: Record<number, number> = {\n 0: 4.0,\n 1: 3.0,\n 2: 2.0,\n 3: 1.0,\n};\n\nconst PRIORITY_PRIOR: Record<number, number> = {\n 0: 1.0,\n 1: 0.75,\n 2: 0.5,\n 3: 0.25,\n};\n\nfunction scoreBm25Only(results: SearchResult[], limit: number): HybridRecallResult[] {\n return results\n .map((row) => {\n const weight = PRIORITY_WEIGHT[row.memory.priority] ?? 1.0;\n const vitality = Math.max(0.1, row.memory.vitality);\n return {\n memory: row.memory,\n score: row.score * weight * vitality,\n bm25_rank: row.rank,\n bm25_score: row.score,\n };\n })\n .sort((left, right) => right.score - left.score)\n .slice(0, limit);\n}\n\nexport function priorityPrior(priority: number): number {\n return PRIORITY_PRIOR[priority] ?? 0.25;\n}\n\nexport function fusionScore(input: {\n memory: Memory;\n bm25Rank?: number;\n vectorRank?: number;\n}): number {\n const lexical = input.bm25Rank ? 0.45 / (60 + input.bm25Rank) : 0;\n const semantic = input.vectorRank ? 0.45 / (60 + input.vectorRank) : 0;\n return lexical + semantic + 0.05 * priorityPrior(input.memory.priority) + 0.05 * input.memory.vitality;\n}\n\nexport function fuseHybridResults(\n lexical: SearchResult[],\n vector: VectorSearchResult[],\n limit: number,\n): HybridRecallResult[] {\n const candidates = new Map<string, HybridRecallResult>();\n\n for (const row of lexical) {\n candidates.set(row.memory.id, {\n memory: row.memory,\n score: 0,\n bm25_rank: row.rank,\n bm25_score: row.score,\n });\n }\n\n for (const row of vector) {\n const existing = candidates.get(row.memory.id);\n if (existing) {\n existing.vector_rank = row.rank;\n existing.vector_score = row.similarity;\n } else {\n candidates.set(row.memory.id, {\n memory: row.memory,\n score: 0,\n vector_rank: row.rank,\n vector_score: row.similarity,\n });\n }\n }\n\n return [...candidates.values()]\n .map((row) => ({\n ...row,\n score: fusionScore({ memory: row.memory, bm25Rank: row.bm25_rank, vectorRank: row.vector_rank }),\n }))\n .sort((left, right) => {\n if (right.score !== left.score) return right.score - left.score;\n return right.memory.updated_at.localeCompare(left.memory.updated_at);\n })\n .slice(0, limit);\n}\n\nasync function searchVectorBranch(\n db: Database.Database,\n query: string,\n opts: {\n provider: EmbeddingProvider;\n agent_id: string;\n limit: number;\n min_vitality: number;\n },\n): Promise<VectorSearchResult[]> {\n const [queryVector] = await opts.provider.embed([query]);\n if (!queryVector) return [];\n return searchByVector(db, queryVector, {\n providerId: opts.provider.id,\n agent_id: opts.agent_id,\n limit: opts.limit,\n min_vitality: opts.min_vitality,\n });\n}\n\nexport async function recallMemories(\n db: Database.Database,\n query: string,\n opts?: RecallOptions,\n): Promise<HybridRecallResponse> {\n const limit = opts?.limit ?? 10;\n const agentId = opts?.agent_id ?? \"default\";\n const minVitality = opts?.min_vitality ?? 0;\n const lexicalLimit = opts?.lexicalLimit ?? Math.max(limit * 2, limit);\n const vectorLimit = opts?.vectorLimit ?? Math.max(limit * 2, limit);\n const provider = opts?.provider === undefined ? getEmbeddingProviderFromEnv() : opts.provider;\n\n const lexical = searchBM25(db, query, {\n agent_id: agentId,\n limit: lexicalLimit,\n min_vitality: minVitality,\n });\n\n let vector: VectorSearchResult[] = [];\n if (provider) {\n try {\n vector = await searchVectorBranch(db, query, {\n provider,\n agent_id: agentId,\n limit: vectorLimit,\n min_vitality: minVitality,\n });\n } catch {\n vector = [];\n }\n }\n\n const mode = vector.length > 0 && lexical.length > 0\n ? \"dual-path\"\n : vector.length > 0\n ? \"vector-only\"\n : \"bm25-only\";\n\n const results = mode === \"bm25-only\"\n ? scoreBm25Only(lexical, limit)\n : fuseHybridResults(lexical, vector, limit);\n\n if (opts?.recordAccess !== false) {\n for (const row of results) {\n recordAccess(db, row.memory.id);\n }\n }\n\n return {\n mode,\n providerId: provider?.id ?? null,\n usedVectorSearch: vector.length > 0,\n results,\n };\n}\n\ninterface ReindexCandidate {\n memoryId: string;\n content: string;\n contentHash: string;\n}\n\nfunction listReindexCandidates(\n db: Database.Database,\n providerId: string,\n agentId: string,\n force: boolean,\n): ReindexCandidate[] {\n const rows = db.prepare(\n `SELECT m.id as memoryId,\n m.content as content,\n m.hash as contentHash,\n e.status as embeddingStatus,\n e.content_hash as embeddingHash\n FROM memories m\n LEFT JOIN embeddings e\n ON e.memory_id = m.id\n AND e.provider_id = ?\n WHERE m.agent_id = ?\n AND m.hash IS NOT NULL`,\n ).all(providerId, agentId) as Array<{\n memoryId: string;\n content: string;\n contentHash: string;\n embeddingStatus?: string | null;\n embeddingHash?: string | null;\n }>;\n\n return rows\n .filter((row) => {\n if (force) return true;\n if (!row.embeddingStatus) return true;\n if (row.embeddingStatus !== \"ready\") return true;\n return row.embeddingHash !== row.contentHash;\n })\n .map((row) => ({\n memoryId: row.memoryId,\n content: row.content,\n contentHash: row.contentHash,\n }));\n}\n\nexport async function reindexEmbeddings(\n db: Database.Database,\n opts?: ReindexOptions,\n): Promise<ReindexEmbeddingsResult> {\n const provider = opts?.provider === undefined ? getEmbeddingProviderFromEnv() : opts.provider;\n if (!provider) {\n return {\n enabled: false,\n providerId: null,\n scanned: 0,\n pending: 0,\n embedded: 0,\n failed: 0,\n };\n }\n\n const agentId = opts?.agent_id ?? \"default\";\n const force = opts?.force ?? false;\n const batchSize = Math.max(1, opts?.batchSize ?? 16);\n const candidates = listReindexCandidates(db, provider.id, agentId, force);\n\n for (const candidate of candidates) {\n markMemoryEmbeddingPending(db, candidate.memoryId, provider.id, candidate.contentHash);\n }\n\n let embedded = 0;\n let failed = 0;\n\n for (let index = 0; index < candidates.length; index += batchSize) {\n const batch = candidates.slice(index, index + batchSize);\n try {\n const vectors = await provider.embed(batch.map((row) => row.content));\n if (vectors.length !== batch.length) {\n throw new Error(`Expected ${batch.length} embeddings, received ${vectors.length}`);\n }\n for (let offset = 0; offset < batch.length; offset++) {\n upsertReadyEmbedding({\n db,\n memoryId: batch[offset].memoryId,\n providerId: provider.id,\n vector: vectors[offset],\n contentHash: batch[offset].contentHash,\n });\n embedded += 1;\n }\n } catch {\n for (const candidate of batch) {\n markEmbeddingFailed(db, candidate.memoryId, provider.id, candidate.contentHash);\n failed += 1;\n }\n }\n }\n\n return {\n enabled: true,\n providerId: provider.id,\n scanned: candidates.length,\n pending: candidates.length,\n embedded,\n failed,\n };\n}\n\nexport async function reindexMemorySearch(\n db: Database.Database,\n opts?: ReindexOptions,\n): Promise<ReindexSearchResult> {\n const fts = rebuildBm25Index(db, { agent_id: opts?.agent_id });\n const embeddings = await reindexEmbeddings(db, opts);\n return { fts, embeddings };\n}\n","import type { CreateMemoryInput, Memory, MemoryType } from \"./memory.js\";\n\nexport interface MergePlan {\n strategy: \"replace\" | \"append_evidence\" | \"synthesize\" | \"compact_timeline\";\n content: string;\n aliases?: string[];\n notes?: string[];\n}\n\nexport interface MergeContext {\n existing: Memory;\n incoming: Pick<CreateMemoryInput, \"content\" | \"type\" | \"source\"> & { observed_at?: string | null };\n}\n\nfunction uniqueNonEmpty(values: Array<string | null | undefined>): string[] {\n return [...new Set(values.map((value) => value?.trim()).filter((value): value is string => Boolean(value)))];\n}\n\nfunction splitClauses(content: string): string[] {\n return content\n .split(/[\\n;;。.!?!?]+/)\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction mergeAliases(existing: string, incoming: string, content: string): string[] | undefined {\n const aliases = uniqueNonEmpty([\n existing !== content ? existing : undefined,\n incoming !== content ? incoming : undefined,\n ]);\n return aliases.length > 0 ? aliases : undefined;\n}\n\nfunction replaceIdentity(context: MergeContext): MergePlan {\n const content = context.incoming.content.trim();\n return {\n strategy: \"replace\",\n content,\n aliases: mergeAliases(context.existing.content, context.incoming.content, content),\n notes: [\"identity canonicalized to the newest authoritative phrasing\"],\n };\n}\n\nfunction appendEmotionEvidence(context: MergeContext): MergePlan {\n const lines = uniqueNonEmpty([\n ...context.existing.content.split(/\\n+/),\n context.incoming.content,\n ]);\n\n const content = lines.length <= 1\n ? lines[0] ?? context.incoming.content.trim()\n : [lines[0], \"\", ...lines.slice(1).map((line) => `- ${line.replace(/^-\\s*/, \"\")}`)].join(\"\\n\");\n\n return {\n strategy: \"append_evidence\",\n content,\n aliases: mergeAliases(context.existing.content, context.incoming.content, content),\n notes: [\"emotion evidence appended to preserve timeline without duplicating identical lines\"],\n };\n}\n\nfunction synthesizeKnowledge(context: MergeContext): MergePlan {\n const clauses = uniqueNonEmpty([\n ...splitClauses(context.existing.content),\n ...splitClauses(context.incoming.content),\n ]);\n\n const content = clauses.length <= 1 ? clauses[0] ?? context.incoming.content.trim() : clauses.join(\";\");\n\n return {\n strategy: \"synthesize\",\n content,\n aliases: mergeAliases(context.existing.content, context.incoming.content, content),\n notes: [\"knowledge statements synthesized into a canonical summary\"],\n };\n}\n\nfunction compactEventTimeline(context: MergeContext): MergePlan {\n const points = uniqueNonEmpty([\n ...context.existing.content.split(/\\n+/),\n context.incoming.content,\n ]).map((line) => line.replace(/^-\\s*/, \"\"));\n\n const content = points.length <= 1\n ? points[0] ?? context.incoming.content.trim()\n : [\"Timeline:\", ...points.map((line) => `- ${line}`)].join(\"\\n\");\n\n return {\n strategy: \"compact_timeline\",\n content,\n aliases: mergeAliases(context.existing.content, context.incoming.content, content),\n notes: [\"event observations compacted into a single timeline window\"],\n };\n}\n\nexport function buildMergePlan(context: MergeContext): MergePlan {\n const type = (context.incoming.type ?? context.existing.type) as MemoryType;\n\n switch (type) {\n case \"identity\":\n return replaceIdentity(context);\n case \"emotion\":\n return appendEmotionEvidence(context);\n case \"knowledge\":\n return synthesizeKnowledge(context);\n case \"event\":\n return compactEventTimeline(context);\n }\n}\n","// AgentMemory v4 — semantic Write Guard (dedup + merge selection + four-criterion gate)\nimport type Database from \"better-sqlite3\";\nimport { recallMemories, type HybridRecallResult } from \"../search/hybrid.js\";\nimport type { EmbeddingProvider } from \"../search/embedding.js\";\nimport { getEmbeddingProviderFromEnv } from \"../search/providers.js\";\nimport { tokenize } from \"../search/tokenizer.js\";\nimport { parseUri, getPathByUri } from \"./path.js\";\nimport { buildMergePlan, type MergePlan } from \"./merge.js\";\nimport { contentHash, type CreateMemoryInput, type Memory } from \"./memory.js\";\n\nexport type GuardAction = \"add\" | \"update\" | \"skip\" | \"merge\";\n\nexport interface DedupScoreBreakdown {\n semantic_similarity: number;\n lexical_overlap: number;\n uri_scope_match: number;\n entity_overlap: number;\n time_proximity: number;\n dedup_score: number;\n}\n\nexport interface GuardResult {\n action: GuardAction;\n reason: string;\n existingId?: string;\n updatedContent?: string;\n mergedContent?: string;\n mergePlan?: MergePlan;\n score?: DedupScoreBreakdown;\n}\n\nexport interface GuardInput extends CreateMemoryInput {\n uri?: string;\n provider?: EmbeddingProvider | null;\n candidateLimit?: number;\n conservative?: boolean;\n now?: string;\n}\n\ninterface GuardCandidate {\n result: HybridRecallResult;\n uri: string | null;\n domain: string | null;\n score: DedupScoreBreakdown;\n}\n\nconst NEAR_EXACT_THRESHOLD = 0.93;\nconst MERGE_THRESHOLD = 0.82;\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0;\n return Math.max(0, Math.min(1, value));\n}\n\nfunction uniqueTokenSet(text: string): Set<string> {\n return new Set(tokenize(text));\n}\n\nfunction overlapScore(left: Iterable<string>, right: Iterable<string>): number {\n const a = new Set(left);\n const b = new Set(right);\n if (a.size === 0 || b.size === 0) return 0;\n\n let shared = 0;\n for (const token of a) {\n if (b.has(token)) shared += 1;\n }\n\n return shared / Math.max(a.size, b.size);\n}\n\nfunction extractEntities(text: string): Set<string> {\n const matches = text.match(/[A-Z][A-Za-z0-9_-]+|\\d+(?:[-/:]\\d+)*|[#@][\\w-]+|[\\u4e00-\\u9fff]{2,}|\\w+:\\/\\/[^\\s]+/g) ?? [];\n return new Set(matches.map((value) => value.trim()).filter(Boolean));\n}\n\nfunction safeDomain(uri?: string | null): string | null {\n if (!uri) return null;\n try {\n return parseUri(uri).domain;\n } catch {\n return null;\n }\n}\n\nfunction getPrimaryUri(db: Database.Database, memoryId: string, agentId: string): string | null {\n const row = db\n .prepare(\"SELECT uri FROM paths WHERE memory_id = ? AND agent_id = ? ORDER BY created_at DESC LIMIT 1\")\n .get(memoryId, agentId) as { uri: string } | undefined;\n return row?.uri ?? null;\n}\n\nfunction uriScopeMatch(inputUri?: string, candidateUri?: string | null): number {\n if (inputUri && candidateUri) {\n if (inputUri === candidateUri) return 1;\n const inputDomain = safeDomain(inputUri);\n const candidateDomain = safeDomain(candidateUri);\n if (inputDomain && candidateDomain && inputDomain === candidateDomain) return 0.85;\n return 0;\n }\n\n if (!inputUri && !candidateUri) {\n return 0.65;\n }\n\n const inputDomain = safeDomain(inputUri ?? null);\n const candidateDomain = safeDomain(candidateUri ?? null);\n if (inputDomain && candidateDomain && inputDomain === candidateDomain) {\n return 0.75;\n }\n return 0.2;\n}\n\nfunction extractObservedAt(parts: Array<string | null | undefined>, fallback?: string | null): Date | null {\n for (const part of parts) {\n if (!part) continue;\n const match = part.match(/(20\\d{2}-\\d{2}-\\d{2})(?:[ T](\\d{2}:\\d{2}(?::\\d{2})?))?/);\n if (!match) continue;\n const iso = match[2] ? `${match[1]}T${match[2]}Z` : `${match[1]}T00:00:00Z`;\n const parsed = new Date(iso);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed;\n }\n }\n\n if (fallback) {\n const parsed = new Date(fallback);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed;\n }\n }\n\n return null;\n}\n\nfunction timeProximity(input: GuardInput, memory: Memory, candidateUri?: string | null): number {\n if (input.type !== \"event\") {\n return 1;\n }\n\n const inputTime = extractObservedAt([input.uri, input.source, input.content], input.now ?? null);\n const existingTime = extractObservedAt([candidateUri, memory.source, memory.content], memory.created_at);\n if (!inputTime || !existingTime) {\n return 0.5;\n }\n\n const diffDays = Math.abs(inputTime.getTime() - existingTime.getTime()) / (1000 * 60 * 60 * 24);\n return clamp01(1 - diffDays / 7);\n}\n\nfunction scoreCandidate(input: GuardInput, candidate: HybridRecallResult, candidateUri?: string | null): DedupScoreBreakdown {\n const lexicalOverlap = overlapScore(uniqueTokenSet(input.content), uniqueTokenSet(candidate.memory.content));\n const entityOverlap = Math.max(\n overlapScore(extractEntities(input.content), extractEntities(candidate.memory.content)),\n lexicalOverlap * 0.75,\n );\n const uriMatch = uriScopeMatch(input.uri, candidateUri);\n const temporal = timeProximity(input, candidate.memory, candidateUri);\n const semantic = clamp01(candidate.vector_score ?? lexicalOverlap);\n const dedupScore = clamp01(\n 0.50 * semantic\n + 0.20 * lexicalOverlap\n + 0.15 * uriMatch\n + 0.10 * entityOverlap\n + 0.05 * temporal,\n );\n\n return {\n semantic_similarity: semantic,\n lexical_overlap: lexicalOverlap,\n uri_scope_match: uriMatch,\n entity_overlap: entityOverlap,\n time_proximity: temporal,\n dedup_score: dedupScore,\n };\n}\n\nasync function recallCandidates(db: Database.Database, input: GuardInput, agentId: string): Promise<GuardCandidate[]> {\n const provider = input.provider === undefined ? getEmbeddingProviderFromEnv() : input.provider;\n const response = await recallMemories(db, input.content, {\n agent_id: agentId,\n limit: Math.max(6, input.candidateLimit ?? 8),\n lexicalLimit: Math.max(8, input.candidateLimit ?? 8),\n vectorLimit: Math.max(8, input.candidateLimit ?? 8),\n provider,\n recordAccess: false,\n });\n\n return response.results\n .filter((row) => row.memory.type === input.type)\n .map((row) => {\n const uri = getPrimaryUri(db, row.memory.id, agentId);\n return {\n result: row,\n uri,\n domain: safeDomain(uri),\n score: scoreCandidate(input, row, uri),\n };\n })\n .sort((left, right) => right.score.dedup_score - left.score.dedup_score);\n}\n\n/**\n * Four-criterion gate for memory quality.\n * Each criterion scores 0-1, all must pass minimum threshold.\n */\ninterface GateResult {\n pass: boolean;\n scores: { specificity: number; novelty: number; relevance: number; coherence: number };\n failedCriteria: string[];\n}\n\nfunction fourCriterionGate(input: CreateMemoryInput): GateResult {\n const content = input.content.trim();\n const failed: string[] = [];\n\n // --- Specificity: content has enough substance ---\n // Minimum length varies by priority: P0/P1 can be shorter\n const priority = input.priority ?? (input.type === \"identity\" ? 0 : input.type === \"emotion\" ? 1 : input.type === \"knowledge\" ? 2 : 3);\n const minLength = priority <= 1 ? 4 : 8;\n const specificity = content.length >= minLength ? Math.min(1, content.length / 50) : 0;\n if (specificity === 0) failed.push(`specificity (too short: ${content.length} < ${minLength} chars)`);\n\n // --- Novelty: content has information, not just stopwords/filler ---\n const tokens = tokenize(content);\n const novelty = tokens.length >= 1 ? Math.min(1, tokens.length / 5) : 0;\n if (novelty === 0) failed.push(\"novelty (no meaningful tokens after filtering)\");\n\n // --- Relevance: content has identifiable topics ---\n const hasCJK = /[\\u4e00-\\u9fff]/.test(content);\n const hasCapitalized = /[A-Z][a-z]+/.test(content);\n const hasNumbers = /\\d+/.test(content);\n const hasURI = /\\w+:\\/\\//.test(content);\n const hasEntityMarkers = /[@#]/.test(content);\n const hasMeaningfulLength = content.length >= 15;\n const topicSignals = [hasCJK, hasCapitalized, hasNumbers, hasURI, hasEntityMarkers, hasMeaningfulLength].filter(Boolean).length;\n const relevance = topicSignals >= 1 ? Math.min(1, topicSignals / 3) : 0;\n if (relevance === 0) failed.push(\"relevance (no identifiable topics/entities)\");\n\n // --- Coherence: content is well-formed ---\n const allCaps = content === content.toUpperCase() && content.length > 20 && /^[A-Z\\s]+$/.test(content);\n const hasWhitespaceOrPunctuation = /[\\s,。!?,.!?;;::]/.test(content) || content.length < 30;\n const excessiveRepetition = /(.)\\1{9,}/.test(content);\n let coherence = 1;\n if (allCaps) coherence -= 0.5;\n if (!hasWhitespaceOrPunctuation) coherence -= 0.3;\n if (excessiveRepetition) coherence -= 0.5;\n coherence = Math.max(0, coherence);\n if (coherence < 0.3) failed.push(\"coherence (garbled or malformed content)\");\n\n return {\n pass: failed.length === 0,\n scores: { specificity, novelty, relevance, coherence },\n failedCriteria: failed,\n };\n}\n\nexport async function guard(\n db: Database.Database,\n input: GuardInput,\n): Promise<GuardResult> {\n const hash = contentHash(input.content);\n const agentId = input.agent_id ?? \"default\";\n\n // 1. exact hash dedup\n const exactMatch = db\n .prepare(\"SELECT id FROM memories WHERE hash = ? AND agent_id = ?\")\n .get(hash, agentId) as { id: string } | undefined;\n\n if (exactMatch) {\n return { action: \"skip\", reason: \"Exact duplicate (hash match)\", existingId: exactMatch.id };\n }\n\n // 2. URI conflict check\n if (input.uri) {\n const existingPath = getPathByUri(db, input.uri, agentId);\n if (existingPath) {\n return {\n action: \"update\",\n reason: `URI ${input.uri} already exists, updating canonical content`,\n existingId: existingPath.memory_id,\n updatedContent: input.content,\n };\n }\n }\n\n const gateResult = fourCriterionGate(input);\n if (!gateResult.pass) {\n return { action: \"skip\", reason: `Gate rejected: ${gateResult.failedCriteria.join(\", \")}` };\n }\n\n if (input.conservative) {\n return { action: \"add\", reason: \"Conservative mode enabled; semantic dedup disabled\" };\n }\n\n // 3~5. hybrid candidate recall + semantic scoring + merge policy selection\n const candidates = await recallCandidates(db, input, agentId);\n const best = candidates[0];\n\n if (!best) {\n return { action: \"add\", reason: \"No relevant semantic candidates found\" };\n }\n\n const score = best.score;\n if (score.dedup_score >= NEAR_EXACT_THRESHOLD) {\n const shouldUpdateMetadata = Boolean(input.uri && !getPathByUri(db, input.uri, agentId));\n return {\n action: shouldUpdateMetadata ? \"update\" : \"skip\",\n reason: shouldUpdateMetadata\n ? `Near-exact duplicate detected (score=${score.dedup_score.toFixed(3)}), updating metadata`\n : `Near-exact duplicate detected (score=${score.dedup_score.toFixed(3)})`,\n existingId: best.result.memory.id,\n score,\n };\n }\n\n if (score.dedup_score >= MERGE_THRESHOLD) {\n const mergePlan = buildMergePlan({\n existing: best.result.memory,\n incoming: {\n content: input.content,\n type: input.type,\n source: input.source,\n },\n });\n\n return {\n action: \"merge\",\n reason: `Semantic near-duplicate detected (score=${score.dedup_score.toFixed(3)}), applying ${mergePlan.strategy}`,\n existingId: best.result.memory.id,\n mergedContent: mergePlan.content,\n mergePlan,\n score,\n };\n }\n\n return {\n action: \"add\",\n reason: `Semantic score below merge threshold (score=${score.dedup_score.toFixed(3)})`,\n score,\n };\n}\n","// AgentMemory v3 — Sleep sync engine (light sleep phase)\n// Captures new information, deduplicates, writes structured memories\nimport type Database from \"better-sqlite3\";\nimport { createMemory, type CreateMemoryInput, updateMemory } from \"../core/memory.js\";\nimport { createPath, getPathByUri } from \"../core/path.js\";\nimport { guard } from \"../core/guard.js\";\nimport type { EmbeddingProvider } from \"../search/embedding.js\";\n\nexport interface SyncInput {\n content: string;\n type?: CreateMemoryInput[\"type\"];\n priority?: CreateMemoryInput[\"priority\"];\n emotion_val?: number;\n uri?: string;\n source?: string;\n agent_id?: string;\n provider?: EmbeddingProvider | null;\n conservative?: boolean;\n}\n\nexport interface SyncResult {\n action: \"added\" | \"updated\" | \"merged\" | \"skipped\";\n memoryId?: string;\n reason: string;\n}\n\nfunction ensureUriPath(db: Database.Database, memoryId: string, uri?: string, agentId?: string): void {\n if (!uri) return;\n if (getPathByUri(db, uri, agentId ?? \"default\")) return;\n try {\n createPath(db, memoryId, uri, undefined, undefined, agentId);\n } catch {\n // URI might already exist or belong to a conflicting path; guard already decided best effort.\n }\n}\n\n/**\n * Sync a single piece of information into memory.\n * Runs full Write Guard pipeline before writing.\n */\nexport async function syncOne(db: Database.Database, input: SyncInput): Promise<SyncResult> {\n const memInput: CreateMemoryInput & {\n uri?: string;\n provider?: EmbeddingProvider | null;\n conservative?: boolean;\n } = {\n content: input.content,\n type: input.type ?? \"event\",\n priority: input.priority,\n emotion_val: input.emotion_val,\n source: input.source,\n agent_id: input.agent_id,\n uri: input.uri,\n provider: input.provider,\n conservative: input.conservative,\n };\n\n const guardResult = await guard(db, memInput);\n\n switch (guardResult.action) {\n case \"skip\":\n return { action: \"skipped\", reason: guardResult.reason, memoryId: guardResult.existingId };\n\n case \"add\": {\n const mem = createMemory(db, memInput);\n if (!mem) return { action: \"skipped\", reason: \"createMemory returned null\" };\n ensureUriPath(db, mem.id, input.uri, input.agent_id);\n return { action: \"added\", memoryId: mem.id, reason: guardResult.reason };\n }\n\n case \"update\": {\n if (!guardResult.existingId) return { action: \"skipped\", reason: \"No existing ID for update\" };\n if (guardResult.updatedContent !== undefined) {\n updateMemory(db, guardResult.existingId, { content: guardResult.updatedContent });\n }\n ensureUriPath(db, guardResult.existingId, input.uri, input.agent_id);\n return { action: \"updated\", memoryId: guardResult.existingId, reason: guardResult.reason };\n }\n\n case \"merge\": {\n if (!guardResult.existingId || !guardResult.mergedContent) {\n return { action: \"skipped\", reason: \"Missing merge data\" };\n }\n updateMemory(db, guardResult.existingId, { content: guardResult.mergedContent });\n ensureUriPath(db, guardResult.existingId, input.uri, input.agent_id);\n return { action: \"merged\", memoryId: guardResult.existingId, reason: guardResult.reason };\n }\n }\n}\n\n/**\n * Sync multiple items in a batch.\n * Semantic guard may require async provider calls, so batch writes are serialized.\n */\nexport async function syncBatch(db: Database.Database, inputs: SyncInput[]): Promise<SyncResult[]> {\n const results: SyncResult[] = [];\n for (const input of inputs) {\n results.push(await syncOne(db, input));\n }\n return results;\n}\n","import type Database from \"better-sqlite3\";\nimport type { EmbeddingProvider } from \"../search/embedding.js\";\nimport { syncOne, type SyncResult } from \"../sleep/sync.js\";\nimport type { MemoryType, Priority } from \"../core/memory.js\";\n\nexport interface RememberInput {\n content: string;\n type?: MemoryType;\n priority?: Priority;\n emotion_val?: number;\n uri?: string;\n source?: string;\n agent_id?: string;\n provider?: EmbeddingProvider | null;\n conservative?: boolean;\n}\n\nexport async function rememberMemory(\n db: Database.Database,\n input: RememberInput,\n): Promise<SyncResult> {\n return syncOne(db, {\n content: input.content,\n type: input.type,\n priority: input.priority,\n emotion_val: input.emotion_val,\n uri: input.uri,\n source: input.source,\n agent_id: input.agent_id,\n provider: input.provider,\n conservative: input.conservative,\n });\n}\n","import type Database from \"better-sqlite3\";\nimport type { EmbeddingProvider } from \"../search/embedding.js\";\nimport { recallMemories, type HybridRecallResponse } from \"../search/hybrid.js\";\n\nexport interface RecallInput {\n query: string;\n limit?: number;\n agent_id?: string;\n min_vitality?: number;\n lexicalLimit?: number;\n vectorLimit?: number;\n provider?: EmbeddingProvider | null;\n recordAccess?: boolean;\n}\n\nexport async function recallMemory(\n db: Database.Database,\n input: RecallInput,\n): Promise<HybridRecallResponse> {\n return recallMemories(db, input.query, {\n agent_id: input.agent_id,\n limit: input.limit,\n min_vitality: input.min_vitality,\n lexicalLimit: input.lexicalLimit,\n vectorLimit: input.vectorLimit,\n provider: input.provider,\n recordAccess: input.recordAccess,\n });\n}\n","import type Database from \"better-sqlite3\";\nimport { newId, now } from \"../core/db.js\";\n\nexport type FeedbackSource = \"recall\" | \"surface\";\n\nexport interface FeedbackEventInput {\n memory_id: string;\n source: FeedbackSource;\n useful: boolean;\n agent_id?: string;\n}\n\nexport interface FeedbackEventRecord extends FeedbackEventInput {\n id: string;\n created_at: string;\n value: number;\n}\n\nexport interface FeedbackSummary {\n total: number;\n useful: number;\n not_useful: number;\n score: number;\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0;\n return Math.max(0, Math.min(1, value));\n}\n\nexport function recordFeedbackEvent(\n db: Database.Database,\n input: FeedbackEventInput,\n): FeedbackEventRecord {\n const id = newId();\n const created_at = now();\n const agentId = input.agent_id ?? \"default\";\n const useful = input.useful ? 1 : 0;\n const value = input.useful ? 1 : 0;\n const eventType = `${input.source}:${input.useful ? \"useful\" : \"not_useful\"}`;\n\n const exists = db.prepare(\"SELECT id FROM memories WHERE id = ?\").get(input.memory_id) as { id: string } | undefined;\n if (!exists) {\n throw new Error(`Memory not found: ${input.memory_id}`);\n }\n\n try {\n db.prepare(\n `INSERT INTO feedback_events (id, memory_id, source, useful, agent_id, event_type, value, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(id, input.memory_id, input.source, useful, agentId, eventType, value, created_at);\n } catch {\n db.prepare(\n `INSERT INTO feedback_events (id, memory_id, event_type, value, created_at)\n VALUES (?, ?, ?, ?, ?)`,\n ).run(id, input.memory_id, eventType, value, created_at);\n }\n\n return {\n id,\n memory_id: input.memory_id,\n source: input.source,\n useful: input.useful,\n agent_id: agentId,\n created_at,\n value,\n };\n}\n\nexport function getFeedbackSummary(\n db: Database.Database,\n memoryId: string,\n agentId?: string,\n): FeedbackSummary {\n try {\n const row = db.prepare(\n `SELECT COUNT(*) as total,\n COALESCE(SUM(CASE WHEN useful = 1 THEN 1 ELSE 0 END), 0) as useful,\n COALESCE(SUM(CASE WHEN useful = 0 THEN 1 ELSE 0 END), 0) as not_useful\n FROM feedback_events\n WHERE memory_id = ?\n AND (? IS NULL OR agent_id = ?)`,\n ).get(memoryId, agentId ?? null, agentId ?? null) as {\n total: number;\n useful: number;\n not_useful: number;\n };\n\n if (!row || row.total === 0) {\n return { total: 0, useful: 0, not_useful: 0, score: 0.5 };\n }\n\n return {\n total: row.total,\n useful: row.useful,\n not_useful: row.not_useful,\n score: clamp01(row.useful / row.total),\n };\n } catch {\n const row = db.prepare(\n `SELECT COUNT(*) as total,\n COALESCE(SUM(CASE WHEN value >= 0.5 THEN 1 ELSE 0 END), 0) as useful,\n COALESCE(SUM(CASE WHEN value < 0.5 THEN 1 ELSE 0 END), 0) as not_useful,\n COALESCE(AVG(value), 0.5) as avg_value\n FROM feedback_events\n WHERE memory_id = ?`,\n ).get(memoryId) as {\n total: number;\n useful: number;\n not_useful: number;\n avg_value: number;\n };\n\n if (!row || row.total === 0) {\n return { total: 0, useful: 0, not_useful: 0, score: 0.5 };\n }\n\n return {\n total: row.total,\n useful: row.useful,\n not_useful: row.not_useful,\n score: clamp01(row.avg_value),\n };\n }\n}\n\nexport function getFeedbackScore(\n db: Database.Database,\n memoryId: string,\n agentId?: string,\n): number {\n return getFeedbackSummary(db, memoryId, agentId).score;\n}\n","import type Database from \"better-sqlite3\";\nimport { listMemories, type Memory, type MemoryType } from \"../core/memory.js\";\nimport type { EmbeddingProvider } from \"../search/embedding.js\";\nimport { priorityPrior } from \"../search/hybrid.js\";\nimport { getEmbeddingProviderFromEnv } from \"../search/providers.js\";\nimport { searchBM25 } from \"../search/bm25.js\";\nimport { tokenize } from \"../search/tokenizer.js\";\nimport { searchByVector } from \"../search/vector.js\";\nimport { getFeedbackSummary, type FeedbackSummary } from \"./feedback.js\";\n\nexport type SurfaceIntent = \"factual\" | \"preference\" | \"temporal\" | \"planning\" | \"design\";\n\nexport interface SurfaceInput {\n query?: string;\n task?: string;\n recent_turns?: string[];\n intent?: SurfaceIntent;\n types?: MemoryType[];\n limit?: number;\n agent_id?: string;\n provider?: EmbeddingProvider | null;\n min_vitality?: number;\n}\n\nexport interface SurfaceResult {\n memory: Memory;\n score: number;\n semantic_score: number;\n lexical_score: number;\n task_match: number;\n vitality: number;\n priority_prior: number;\n feedback_score: number;\n feedback_summary: FeedbackSummary;\n reason_codes: string[];\n lexical_rank?: number;\n semantic_rank?: number;\n semantic_similarity?: number;\n}\n\nexport interface SurfaceResponse {\n count: number;\n query?: string;\n task?: string;\n intent?: SurfaceIntent;\n results: SurfaceResult[];\n}\n\ninterface CandidateSignal {\n memory: Memory;\n queryRank?: number;\n taskRank?: number;\n recentRank?: number;\n semanticRank?: number;\n semanticSimilarity?: number;\n}\n\nconst INTENT_PRIORS: Record<SurfaceIntent, Record<MemoryType, number>> = {\n factual: {\n identity: 0.25,\n emotion: 0.15,\n knowledge: 1.0,\n event: 0.8,\n },\n preference: {\n identity: 1.0,\n emotion: 0.85,\n knowledge: 0.55,\n event: 0.25,\n },\n temporal: {\n identity: 0.15,\n emotion: 0.35,\n knowledge: 0.5,\n event: 1.0,\n },\n planning: {\n identity: 0.65,\n emotion: 0.2,\n knowledge: 1.0,\n event: 0.6,\n },\n design: {\n identity: 0.8,\n emotion: 0.35,\n knowledge: 1.0,\n event: 0.25,\n },\n};\n\nconst DESIGN_HINT_RE = /\\b(ui|ux|design|style|component|layout|brand|palette|theme)\\b|风格|界面|设计|配色|低饱和|玻璃拟态|渐变/i;\nconst PLANNING_HINT_RE = /\\b(plan|planning|todo|next|ship|build|implement|roadmap|task|milestone)\\b|计划|下一步|待办|实现|重构/i;\nconst FACTUAL_HINT_RE = /\\b(what|fact|constraint|rule|docs|document|api|status)\\b|规则|约束|文档|接口|事实/i;\nconst TEMPORAL_HINT_RE = /\\b(today|yesterday|tomorrow|recent|before|after|when|timeline)\\b|今天|昨天|明天|最近|时间线|何时/i;\nconst PREFERENCE_HINT_RE = /\\b(prefer|preference|like|dislike|avoid|favorite)\\b|喜欢|偏好|不喜欢|避免|讨厌/i;\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0;\n return Math.max(0, Math.min(1, value));\n}\n\nfunction uniqueTokenSet(values: Array<string | undefined>): Set<string> {\n return new Set(\n values\n .flatMap((value) => tokenize(value ?? \"\"))\n .map((token) => token.trim())\n .filter(Boolean),\n );\n}\n\nfunction overlapScore(left: Set<string>, right: Set<string>): number {\n if (left.size === 0 || right.size === 0) return 0;\n\n let shared = 0;\n for (const token of left) {\n if (right.has(token)) shared += 1;\n }\n\n return clamp01(shared / Math.max(left.size, right.size));\n}\n\nfunction rankScore(rank: number | undefined, window: number): number {\n if (!rank) return 0;\n return clamp01(1 - (rank - 1) / Math.max(window, 1));\n}\n\nfunction topicLabel(...parts: Array<string | undefined>): string {\n const token = parts\n .flatMap((part) => tokenize(part ?? \"\"))\n .find((value) => value.trim().length > 1);\n\n const label = (token ?? \"context\")\n .replace(/[^\\p{L}\\p{N}_-]+/gu, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 32);\n\n return label || \"context\";\n}\n\nfunction intentKeywordBoost(memory: Memory, intent: SurfaceIntent): number {\n const content = memory.content;\n switch (intent) {\n case \"design\":\n return DESIGN_HINT_RE.test(content) ? 1 : 0.65;\n case \"planning\":\n return PLANNING_HINT_RE.test(content) ? 1 : 0.7;\n case \"factual\":\n return FACTUAL_HINT_RE.test(content) ? 1 : 0.75;\n case \"temporal\":\n return TEMPORAL_HINT_RE.test(content) ? 1 : 0.75;\n case \"preference\":\n return PREFERENCE_HINT_RE.test(content) ? 1 : 0.8;\n }\n}\n\nfunction intentMatch(memory: Memory, intent?: SurfaceIntent): number {\n if (!intent) return 0;\n const prior = INTENT_PRIORS[intent][memory.type] ?? 0;\n return clamp01(prior * intentKeywordBoost(memory, intent));\n}\n\nfunction buildReasonCodes(input: {\n memory: Memory;\n query?: string;\n task?: string;\n intent?: SurfaceIntent;\n semanticScore: number;\n lexicalScore: number;\n taskMatch: number;\n feedbackScore: number;\n}): string[] {\n const reasons = new Set<string>();\n reasons.add(`type:${input.memory.type}`);\n\n if (input.semanticScore > 0.2) {\n reasons.add(`semantic:${topicLabel(input.query, input.task)}`);\n }\n if (input.lexicalScore > 0.2 && input.query) {\n reasons.add(`lexical:${topicLabel(input.query)}`);\n }\n if (input.taskMatch > 0.2) {\n reasons.add(`task:${topicLabel(input.task, input.intent)}`);\n }\n if (input.intent) {\n reasons.add(`intent:${input.intent}`);\n }\n if (input.feedbackScore >= 0.67) {\n reasons.add(\"feedback:reinforced\");\n } else if (input.feedbackScore <= 0.33) {\n reasons.add(\"feedback:negative\");\n }\n\n return [...reasons];\n}\n\nfunction collectBranch(\n signals: Map<string, CandidateSignal>,\n rows: Array<{ memory: Memory; rank: number }>,\n key: \"queryRank\" | \"taskRank\" | \"recentRank\" | \"semanticRank\",\n similarity?: Map<string, number>,\n): void {\n for (const row of rows) {\n const existing = signals.get(row.memory.id) ?? { memory: row.memory };\n const currentRank = existing[key];\n if (currentRank === undefined || row.rank < currentRank) {\n existing[key] = row.rank;\n }\n if (similarity) {\n const currentSimilarity = similarity.get(row.memory.id);\n if (currentSimilarity !== undefined) {\n existing.semanticSimilarity = Math.max(existing.semanticSimilarity ?? 0, currentSimilarity);\n }\n }\n signals.set(row.memory.id, existing);\n }\n}\n\nexport async function surfaceMemories(\n db: Database.Database,\n input: SurfaceInput,\n): Promise<SurfaceResponse> {\n const agentId = input.agent_id ?? \"default\";\n const limit = Math.max(1, Math.min(input.limit ?? 5, 20));\n const lexicalWindow = Math.max(24, limit * 6);\n const minVitality = input.min_vitality ?? 0.05;\n const provider = input.provider === undefined ? getEmbeddingProviderFromEnv() : input.provider;\n const signals = new Map<string, CandidateSignal>();\n\n const trimmedQuery = input.query?.trim();\n const trimmedTask = input.task?.trim();\n const recentTurns = (input.recent_turns ?? []).map((turn) => turn.trim()).filter(Boolean).slice(-4);\n const queryTokens = uniqueTokenSet([trimmedQuery, ...recentTurns]);\n const taskTokens = uniqueTokenSet([trimmedTask]);\n\n if (trimmedQuery) {\n collectBranch(\n signals,\n searchBM25(db, trimmedQuery, {\n agent_id: agentId,\n limit: lexicalWindow,\n min_vitality: minVitality,\n }),\n \"queryRank\",\n );\n }\n\n if (trimmedTask) {\n collectBranch(\n signals,\n searchBM25(db, trimmedTask, {\n agent_id: agentId,\n limit: lexicalWindow,\n min_vitality: minVitality,\n }),\n \"taskRank\",\n );\n }\n\n if (recentTurns.length > 0) {\n collectBranch(\n signals,\n searchBM25(db, recentTurns.join(\" \"), {\n agent_id: agentId,\n limit: lexicalWindow,\n min_vitality: minVitality,\n }),\n \"recentRank\",\n );\n }\n\n const semanticQuery = [trimmedQuery, trimmedTask, ...recentTurns].filter(Boolean).join(\"\\n\").trim();\n if (provider && semanticQuery) {\n try {\n const [queryVector] = await provider.embed([semanticQuery]);\n if (queryVector) {\n const vectorRows = searchByVector(db, queryVector, {\n providerId: provider.id,\n agent_id: agentId,\n limit: lexicalWindow,\n min_vitality: minVitality,\n });\n const similarity = new Map(vectorRows.map((row) => [row.memory.id, row.similarity]));\n collectBranch(signals, vectorRows, \"semanticRank\", similarity);\n }\n } catch {\n // Surface should still work in lexical-only mode.\n }\n }\n\n const fallbackMemories = listMemories(db, {\n agent_id: agentId,\n min_vitality: minVitality,\n limit: Math.max(48, lexicalWindow),\n });\n\n for (const memory of fallbackMemories) {\n if (!signals.has(memory.id)) {\n signals.set(memory.id, { memory });\n }\n }\n\n const results = [...signals.values()]\n .map((signal) => signal.memory)\n .filter((memory) => memory.vitality >= minVitality)\n .filter((memory) => (input.types?.length ? input.types.includes(memory.type) : true))\n .map((memory) => {\n const signal = signals.get(memory.id) ?? { memory };\n const memoryTokens = new Set(tokenize(memory.content));\n const lexicalOverlap = overlapScore(memoryTokens, queryTokens);\n const taskOverlap = overlapScore(memoryTokens, taskTokens);\n const lexicalScore = clamp01(\n 0.45 * rankScore(signal.queryRank, lexicalWindow)\n + 0.15 * rankScore(signal.recentRank, lexicalWindow)\n + 0.15 * rankScore(signal.taskRank, lexicalWindow)\n + 0.25 * lexicalOverlap,\n );\n const semanticScore = signal.semanticSimilarity !== undefined\n ? clamp01(Math.max(signal.semanticSimilarity, lexicalOverlap * 0.7))\n : (trimmedQuery || recentTurns.length > 0)\n ? clamp01(lexicalOverlap * 0.7)\n : 0;\n const intentScore = intentMatch(memory, input.intent);\n const taskMatch = trimmedTask\n ? clamp01(0.7 * taskOverlap + 0.3 * intentScore)\n : intentScore;\n const priorityScore = priorityPrior(memory.priority);\n const feedbackSummary = getFeedbackSummary(db, memory.id, agentId);\n const feedbackScore = feedbackSummary.score;\n const score = clamp01(\n 0.35 * semanticScore\n + 0.20 * lexicalScore\n + 0.15 * taskMatch\n + 0.10 * memory.vitality\n + 0.10 * priorityScore\n + 0.10 * feedbackScore,\n );\n\n return {\n memory,\n score,\n semantic_score: semanticScore,\n lexical_score: lexicalScore,\n task_match: taskMatch,\n vitality: memory.vitality,\n priority_prior: priorityScore,\n feedback_score: feedbackScore,\n feedback_summary: feedbackSummary,\n reason_codes: buildReasonCodes({\n memory,\n query: semanticQuery || trimmedQuery,\n task: trimmedTask,\n intent: input.intent,\n semanticScore,\n lexicalScore,\n taskMatch,\n feedbackScore,\n }),\n lexical_rank: signal.queryRank ?? signal.recentRank ?? signal.taskRank,\n semantic_rank: signal.semanticRank,\n semantic_similarity: signal.semanticSimilarity,\n } satisfies SurfaceResult;\n })\n .sort((left, right) => {\n if (right.score !== left.score) return right.score - left.score;\n if (right.semantic_score !== left.semantic_score) return right.semantic_score - left.semantic_score;\n if (right.lexical_score !== left.lexical_score) return right.lexical_score - left.lexical_score;\n if (left.memory.priority !== right.memory.priority) return left.memory.priority - right.memory.priority;\n return right.memory.updated_at.localeCompare(left.memory.updated_at);\n })\n .slice(0, limit);\n\n return {\n count: results.length,\n query: trimmedQuery,\n task: trimmedTask,\n intent: input.intent,\n results,\n };\n}\n","// AgentMemory v2 — Ebbinghaus forgetting curve decay engine\n// From PowerMem's cognitive science approach: R = e^(-t/S)\nimport type Database from \"better-sqlite3\";\nimport { now } from \"../core/db.js\";\n\n/**\n * Ebbinghaus forgetting curve: R = e^(-t/S)\n * R = retention (vitality), range [0, 1]\n * t = time elapsed (days)\n * S = stability (increases with each recall)\n *\n * Priority-based minimum vitality:\n * P0 (identity): never decays (min 1.0)\n * P1 (emotion): min 0.3\n * P2 (knowledge): min 0.1\n * P3 (event): min 0.0 (can be cleaned up)\n */\n\nconst MIN_VITALITY: Record<number, number> = {\n 0: 1.0, // P0: identity — never decays\n 1: 0.3, // P1: emotion — slow decay\n 2: 0.1, // P2: knowledge — normal decay\n 3: 0.0, // P3: event — full decay\n};\n\n/**\n * Calculate vitality using Ebbinghaus forgetting curve.\n * @param stability - S parameter (higher = slower decay)\n * @param daysSinceLastAccess - days since last recall (or creation if never accessed)\n * @param priority - memory priority (0-3)\n */\nexport function calculateVitality(\n stability: number,\n daysSinceLastAccess: number,\n priority: number,\n): number {\n // P0 never decays\n if (priority === 0) return 1.0;\n\n // Prevent division by zero\n const S = Math.max(0.01, stability);\n\n // R = e^(-t/S)\n // t is measured from last access (recall), matching Ebbinghaus's insight\n // that forgetting restarts from the most recent retrieval.\n const retention = Math.exp(-daysSinceLastAccess / S);\n\n // Apply minimum vitality based on priority\n const minVit = MIN_VITALITY[priority] ?? 0.0;\n return Math.max(minVit, retention);\n}\n\n/**\n * Run decay on all memories.\n * Updates vitality based on Ebbinghaus curve.\n * Returns count of memories updated.\n */\nexport function runDecay(\n db: Database.Database,\n opts?: { agent_id?: string },\n): {\n updated: number;\n decayed: number;\n belowThreshold: number;\n} {\n const currentTime = now();\n const currentMs = new Date(currentTime).getTime();\n const agentId = opts?.agent_id;\n\n // Get all non-P0 memories, including last_accessed for proper decay timing\n const query = agentId\n ? \"SELECT id, priority, stability, created_at, last_accessed, vitality FROM memories WHERE priority > 0 AND agent_id = ?\"\n : \"SELECT id, priority, stability, created_at, last_accessed, vitality FROM memories WHERE priority > 0\";\n\n const memories = db\n .prepare(query)\n .all(...(agentId ? [agentId] : [])) as Array<{\n id: string;\n priority: number;\n stability: number;\n created_at: string;\n last_accessed: string | null;\n vitality: number;\n }>;\n\n let updated = 0;\n let decayed = 0;\n let belowThreshold = 0;\n\n const updateStmt = db.prepare(\"UPDATE memories SET vitality = ?, updated_at = ? WHERE id = ?\");\n\n const transaction = db.transaction(() => {\n for (const mem of memories) {\n // Use last_accessed if available, otherwise fall back to created_at.\n // This matches Ebbinghaus: forgetting starts from the last recall.\n const referenceTime = mem.last_accessed ?? mem.created_at;\n const referenceMs = new Date(referenceTime).getTime();\n const daysSince = (currentMs - referenceMs) / (1000 * 60 * 60 * 24);\n\n const newVitality = calculateVitality(mem.stability, daysSince, mem.priority);\n\n // Only update if vitality actually changed (>0.001 difference)\n if (Math.abs(newVitality - mem.vitality) > 0.001) {\n updateStmt.run(newVitality, currentTime, mem.id);\n updated++;\n\n if (newVitality < mem.vitality) {\n decayed++;\n }\n\n if (newVitality < 0.05) {\n belowThreshold++;\n }\n }\n }\n });\n\n transaction();\n\n return { updated, decayed, belowThreshold };\n}\n\n/**\n * Get memories that are candidates for cleanup (vitality < threshold).\n * Only P3 (event) memories can be fully cleaned.\n */\nexport function getDecayedMemories(\n db: Database.Database,\n threshold = 0.05,\n opts?: { agent_id?: string },\n): Array<{ id: string; content: string; vitality: number; priority: number }> {\n const agentId = opts?.agent_id;\n return db\n .prepare(\n agentId\n ? `SELECT id, content, vitality, priority FROM memories\n WHERE vitality < ? AND priority >= 3 AND agent_id = ?\n ORDER BY vitality ASC`\n : `SELECT id, content, vitality, priority FROM memories\n WHERE vitality < ? AND priority >= 3\n ORDER BY vitality ASC`,\n )\n .all(...(agentId ? [threshold, agentId] : [threshold])) as Array<{\n id: string;\n content: string;\n vitality: number;\n priority: number;\n }>;\n}\n","// AgentMemory v4 — Sleep tidy engine (deep sleep phase)\n// Compression / merge / archive only. Governance belongs in govern.ts.\nimport type Database from \"better-sqlite3\";\nimport { deleteMemory } from \"../core/memory.js\";\nimport { getDecayedMemories } from \"./decay.js\";\n\nexport interface TidyResult {\n archived: number;\n orphansCleaned: number;\n}\n\n/**\n * Run the tidy (deep sleep) cycle:\n * 1. Archive decayed P3 memories (vitality < threshold)\n *\n * Path/orphan cleanup moved to govern.ts in Phase 2.\n */\nexport function runTidy(\n db: Database.Database,\n opts?: {\n vitalityThreshold?: number;\n agent_id?: string;\n },\n): TidyResult {\n const threshold = opts?.vitalityThreshold ?? 0.05;\n const agentId = opts?.agent_id;\n\n let archived = 0;\n\n const transaction = db.transaction(() => {\n const decayed = getDecayedMemories(db, threshold, agentId ? { agent_id: agentId } : undefined);\n for (const mem of decayed) {\n deleteMemory(db, mem.id);\n archived += 1;\n }\n });\n\n transaction();\n\n return { archived, orphansCleaned: 0 };\n}\n","// AgentMemory v4 — Governance cycle (memory health maintenance)\nimport type Database from \"better-sqlite3\";\nimport { deleteMemory, type Memory } from \"../core/memory.js\";\nimport { tokenize } from \"../search/tokenizer.js\";\n\nexport interface GovernResult {\n orphanPaths: number;\n emptyMemories: number;\n evicted: number;\n}\n\nexport interface EvictionCandidate {\n memory: Memory;\n redundancy_score: number;\n age_score: number;\n low_feedback_penalty: number;\n low_priority_penalty: number;\n eviction_score: number;\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0;\n return Math.max(0, Math.min(1, value));\n}\n\nfunction overlapScore(left: Set<string>, right: Set<string>): number {\n if (left.size === 0 || right.size === 0) return 0;\n let shared = 0;\n for (const token of left) {\n if (right.has(token)) shared += 1;\n }\n return shared / Math.max(left.size, right.size);\n}\n\nfunction feedbackPenalty(db: Database.Database, memoryId: string): number {\n try {\n const row = db.prepare(\n `SELECT COUNT(*) as count, COALESCE(AVG(value), 0) as avgValue\n FROM feedback_events\n WHERE memory_id = ?`,\n ).get(memoryId) as { count: number; avgValue: number };\n\n if (!row || row.count === 0) return 1;\n return clamp01(1 - row.avgValue);\n } catch {\n return 1;\n }\n}\n\nfunction ageScore(memory: Memory, referenceMs = Date.now()): number {\n const createdAt = new Date(memory.created_at).getTime();\n if (Number.isNaN(createdAt)) return 0;\n const ageDays = Math.max(0, (referenceMs - createdAt) / (1000 * 60 * 60 * 24));\n return clamp01(ageDays / 180);\n}\n\nexport function computeEvictionScore(input: {\n vitality: number;\n redundancy_score: number;\n age_score: number;\n low_feedback_penalty: number;\n low_priority_penalty: number;\n}): number {\n return clamp01(\n 0.40 * (1 - clamp01(input.vitality))\n + 0.20 * clamp01(input.redundancy_score)\n + 0.20 * clamp01(input.age_score)\n + 0.10 * clamp01(input.low_feedback_penalty)\n + 0.10 * clamp01(input.low_priority_penalty),\n );\n}\n\nexport function rankEvictionCandidates(\n db: Database.Database,\n opts?: { agent_id?: string },\n): EvictionCandidate[] {\n const agentId = opts?.agent_id;\n const rows = db.prepare(\n agentId\n ? `SELECT * FROM memories WHERE agent_id = ? AND priority > 0 AND TRIM(content) != ''`\n : `SELECT * FROM memories WHERE priority > 0 AND TRIM(content) != ''`,\n ).all(...(agentId ? [agentId] : [])) as Memory[];\n\n const tokenSets = new Map(rows.map((memory) => [memory.id, new Set(tokenize(memory.content))]));\n\n return rows\n .map((memory) => {\n const ownTokens = tokenSets.get(memory.id) ?? new Set<string>();\n const redundancy = rows\n .filter((candidate) => candidate.id !== memory.id && candidate.type === memory.type)\n .reduce((maxOverlap, candidate) => {\n const candidateTokens = tokenSets.get(candidate.id) ?? new Set<string>();\n return Math.max(maxOverlap, overlapScore(ownTokens, candidateTokens));\n }, 0);\n\n const candidate: EvictionCandidate = {\n memory,\n redundancy_score: redundancy,\n age_score: ageScore(memory),\n low_feedback_penalty: feedbackPenalty(db, memory.id),\n low_priority_penalty: clamp01(memory.priority / 3),\n eviction_score: 0,\n };\n\n candidate.eviction_score = computeEvictionScore({\n vitality: memory.vitality,\n redundancy_score: candidate.redundancy_score,\n age_score: candidate.age_score,\n low_feedback_penalty: candidate.low_feedback_penalty,\n low_priority_penalty: candidate.low_priority_penalty,\n });\n\n return candidate;\n })\n .sort((left, right) => {\n if (right.eviction_score !== left.eviction_score) {\n return right.eviction_score - left.eviction_score;\n }\n return left.memory.priority - right.memory.priority;\n });\n}\n\n/**\n * Run governance checks and cleanup:\n * 1. Remove orphan paths (no parent memory)\n * 2. Remove empty memories (blank content)\n * 3. Evict low-value memories when over capacity using eviction_score\n */\nexport function runGovern(\n db: Database.Database,\n opts?: { agent_id?: string; maxMemories?: number },\n): GovernResult {\n const agentId = opts?.agent_id;\n const maxMemories = opts?.maxMemories ?? 200;\n let orphanPaths = 0;\n let emptyMemories = 0;\n let evicted = 0;\n\n const transaction = db.transaction(() => {\n const pathResult = agentId\n ? db.prepare(\n `DELETE FROM paths\n WHERE agent_id = ?\n AND memory_id NOT IN (SELECT id FROM memories WHERE agent_id = ?)`,\n ).run(agentId, agentId)\n : db.prepare(\"DELETE FROM paths WHERE memory_id NOT IN (SELECT id FROM memories)\").run();\n orphanPaths = pathResult.changes;\n\n const emptyResult = agentId\n ? db.prepare(\"DELETE FROM memories WHERE agent_id = ? AND TRIM(content) = ''\").run(agentId)\n : db.prepare(\"DELETE FROM memories WHERE TRIM(content) = ''\").run();\n emptyMemories = emptyResult.changes;\n\n const total = (\n db.prepare(agentId ? \"SELECT COUNT(*) as c FROM memories WHERE agent_id = ?\" : \"SELECT COUNT(*) as c FROM memories\").get(...(agentId ? [agentId] : [])) as { c: number }\n ).c;\n\n const excess = Math.max(0, total - maxMemories);\n if (excess <= 0) return;\n\n const candidates = rankEvictionCandidates(db, { agent_id: agentId }).slice(0, excess);\n for (const candidate of candidates) {\n deleteMemory(db, candidate.memory.id);\n evicted += 1;\n }\n });\n\n transaction();\n\n return { orphanPaths, emptyMemories, evicted };\n}\n","import type Database from \"better-sqlite3\";\nimport { newId, now } from \"../core/db.js\";\n\nexport type MaintenancePhase = \"decay\" | \"tidy\" | \"govern\" | \"all\";\nexport type MaintenanceStatus = \"running\" | \"completed\" | \"failed\";\nexport type ReflectStep = Exclude<MaintenancePhase, \"all\">;\n\nexport interface ReflectCheckpoint {\n requestedPhase: MaintenancePhase;\n nextPhase: ReflectStep | null;\n completedPhases: ReflectStep[];\n phaseResults: Partial<Record<ReflectStep, unknown>>;\n}\n\nexport interface MaintenanceJob {\n job_id: string;\n phase: MaintenancePhase;\n status: MaintenanceStatus;\n checkpoint: ReflectCheckpoint | null;\n error: string | null;\n started_at: string;\n finished_at: string | null;\n}\n\ninterface RawMaintenanceJob {\n job_id: string;\n phase: MaintenancePhase;\n status: MaintenanceStatus;\n checkpoint: string | null;\n error: string | null;\n started_at: string;\n finished_at: string | null;\n}\n\nfunction parseCheckpoint(raw: string | null): ReflectCheckpoint | null {\n if (!raw) return null;\n try {\n return JSON.parse(raw) as ReflectCheckpoint;\n } catch {\n return null;\n }\n}\n\nfunction serializeCheckpoint(checkpoint: ReflectCheckpoint | null | undefined): string | null {\n if (!checkpoint) return null;\n return JSON.stringify(checkpoint);\n}\n\nfunction toJob(row: RawMaintenanceJob | undefined): MaintenanceJob | null {\n if (!row) return null;\n return {\n ...row,\n checkpoint: parseCheckpoint(row.checkpoint),\n };\n}\n\nexport function createInitialCheckpoint(phase: MaintenancePhase): ReflectCheckpoint {\n return {\n requestedPhase: phase,\n nextPhase: phase === \"all\" ? \"decay\" : phase,\n completedPhases: [],\n phaseResults: {},\n };\n}\n\nexport function createMaintenanceJob(\n db: Database.Database,\n phase: MaintenancePhase,\n checkpoint = createInitialCheckpoint(phase),\n): MaintenanceJob {\n const jobId = newId();\n const startedAt = now();\n\n db.prepare(\n `INSERT INTO maintenance_jobs (job_id, phase, status, checkpoint, error, started_at, finished_at)\n VALUES (?, ?, 'running', ?, NULL, ?, NULL)`,\n ).run(jobId, phase, serializeCheckpoint(checkpoint), startedAt);\n\n return getMaintenanceJob(db, jobId)!;\n}\n\nexport function getMaintenanceJob(db: Database.Database, jobId: string): MaintenanceJob | null {\n const row = db.prepare(\"SELECT * FROM maintenance_jobs WHERE job_id = ?\").get(jobId) as RawMaintenanceJob | undefined;\n return toJob(row);\n}\n\nexport function findResumableMaintenanceJob(db: Database.Database, phase: MaintenancePhase): MaintenanceJob | null {\n const row = db.prepare(\n `SELECT *\n FROM maintenance_jobs\n WHERE phase = ?\n AND status IN ('running', 'failed')\n ORDER BY started_at DESC\n LIMIT 1`,\n ).get(phase) as RawMaintenanceJob | undefined;\n\n return toJob(row);\n}\n\nexport function updateMaintenanceCheckpoint(\n db: Database.Database,\n jobId: string,\n checkpoint: ReflectCheckpoint,\n): MaintenanceJob | null {\n db.prepare(\n `UPDATE maintenance_jobs\n SET checkpoint = ?,\n error = NULL,\n finished_at = NULL,\n status = 'running'\n WHERE job_id = ?`,\n ).run(serializeCheckpoint(checkpoint), jobId);\n\n return getMaintenanceJob(db, jobId);\n}\n\nexport function failMaintenanceJob(db: Database.Database, jobId: string, error: string, checkpoint?: ReflectCheckpoint | null): MaintenanceJob | null {\n db.prepare(\n `UPDATE maintenance_jobs\n SET status = 'failed',\n checkpoint = COALESCE(?, checkpoint),\n error = ?,\n finished_at = ?\n WHERE job_id = ?`,\n ).run(serializeCheckpoint(checkpoint), error, now(), jobId);\n\n return getMaintenanceJob(db, jobId);\n}\n\nexport function completeMaintenanceJob(db: Database.Database, jobId: string, checkpoint?: ReflectCheckpoint | null): MaintenanceJob | null {\n db.prepare(\n `UPDATE maintenance_jobs\n SET status = 'completed',\n checkpoint = COALESCE(?, checkpoint),\n error = NULL,\n finished_at = ?\n WHERE job_id = ?`,\n ).run(serializeCheckpoint(checkpoint), now(), jobId);\n\n return getMaintenanceJob(db, jobId);\n}\n","import type Database from \"better-sqlite3\";\nimport { runDecay } from \"./decay.js\";\nimport { runTidy } from \"./tidy.js\";\nimport { runGovern } from \"./govern.js\";\nimport {\n completeMaintenanceJob,\n createInitialCheckpoint,\n createMaintenanceJob,\n failMaintenanceJob,\n findResumableMaintenanceJob,\n getMaintenanceJob,\n type MaintenancePhase,\n type MaintenanceJob,\n type ReflectCheckpoint,\n type ReflectStep,\n updateMaintenanceCheckpoint,\n} from \"./jobs.js\";\n\nexport interface ReflectStats {\n total: number;\n avgVitality: number;\n}\n\nexport interface ReflectRunners {\n decay: (db: Database.Database, opts?: { agent_id?: string }) => unknown | Promise<unknown>;\n tidy: (db: Database.Database, opts?: { agent_id?: string }) => unknown | Promise<unknown>;\n govern: (db: Database.Database, opts?: { agent_id?: string }) => unknown | Promise<unknown>;\n}\n\nexport interface ReflectProgressEvent {\n status: \"started\" | \"phase-completed\" | \"completed\" | \"failed\";\n phase: MaintenancePhase | ReflectStep;\n progress: number;\n jobId?: string;\n detail?: unknown;\n}\n\nexport interface ReflectOptions {\n phase: MaintenancePhase;\n agent_id?: string;\n jobId?: string;\n resume?: boolean;\n runners?: Partial<ReflectRunners>;\n onProgress?: (event: ReflectProgressEvent) => void;\n}\n\nexport interface ReflectRunResult {\n job: MaintenanceJob;\n jobId: string;\n phase: MaintenancePhase;\n resumed: boolean;\n checkpoint: ReflectCheckpoint;\n results: Partial<Record<ReflectStep, unknown>>;\n before: ReflectStats;\n after: ReflectStats;\n}\n\nconst DEFAULT_RUNNERS: ReflectRunners = {\n decay: (db, opts) => runDecay(db, opts),\n tidy: (db, opts) => runTidy(db, opts),\n govern: (db, opts) => runGovern(db, opts),\n};\n\nconst PHASE_SEQUENCE: ReflectStep[] = [\"decay\", \"tidy\", \"govern\"];\n\nfunction getSummaryStats(db: Database.Database, agentId?: string): ReflectStats {\n const row = agentId\n ? db.prepare(\"SELECT COUNT(*) as total, COALESCE(AVG(vitality), 0) as avg FROM memories WHERE agent_id = ?\").get(agentId) as { total: number; avg: number }\n : db.prepare(\"SELECT COUNT(*) as total, COALESCE(AVG(vitality), 0) as avg FROM memories\").get() as { total: number; avg: number };\n\n return {\n total: row.total,\n avgVitality: row.avg,\n };\n}\n\nfunction getPhaseSequence(phase: MaintenancePhase): ReflectStep[] {\n return phase === \"all\" ? [...PHASE_SEQUENCE] : [phase];\n}\n\nfunction resolveJob(db: Database.Database, opts: ReflectOptions): { job: MaintenanceJob; resumed: boolean } {\n if (opts.jobId) {\n const job = getMaintenanceJob(db, opts.jobId);\n if (!job) {\n throw new Error(`Maintenance job not found: ${opts.jobId}`);\n }\n if (job.phase !== opts.phase) {\n throw new Error(`Maintenance job ${opts.jobId} phase mismatch: expected ${opts.phase}, got ${job.phase}`);\n }\n return { job, resumed: true };\n }\n\n if (opts.resume !== false) {\n const resumable = findResumableMaintenanceJob(db, opts.phase);\n if (resumable) {\n return { job: resumable, resumed: true };\n }\n }\n\n return {\n job: createMaintenanceJob(db, opts.phase),\n resumed: false,\n };\n}\n\nfunction nextPhase(current: ReflectStep, requested: MaintenancePhase): ReflectStep | null {\n if (requested !== \"all\") return null;\n const index = PHASE_SEQUENCE.indexOf(current);\n return PHASE_SEQUENCE[index + 1] ?? null;\n}\n\nexport async function runReflectOrchestrator(\n db: Database.Database,\n opts: ReflectOptions,\n): Promise<ReflectRunResult> {\n const runners: ReflectRunners = {\n ...DEFAULT_RUNNERS,\n ...opts.runners,\n };\n\n const before = getSummaryStats(db, opts.agent_id);\n const { job: baseJob, resumed } = resolveJob(db, opts);\n let checkpoint = baseJob.checkpoint ?? createInitialCheckpoint(opts.phase);\n const jobId = baseJob.job_id;\n\n const orderedPhases = getPhaseSequence(opts.phase);\n const startPhase = checkpoint.nextPhase ?? orderedPhases[orderedPhases.length - 1] ?? \"decay\";\n const startIndex = Math.max(0, orderedPhases.indexOf(startPhase));\n const phasesToRun = checkpoint.nextPhase === null ? [] : orderedPhases.slice(startIndex);\n const totalPhases = Math.max(orderedPhases.length, 1);\n\n opts.onProgress?.({\n status: \"started\",\n phase: opts.phase,\n progress: checkpoint.completedPhases.length / totalPhases,\n jobId,\n detail: {\n resumed,\n nextPhase: checkpoint.nextPhase,\n },\n });\n\n try {\n for (const phase of phasesToRun) {\n const result = await Promise.resolve(runners[phase](db, { agent_id: opts.agent_id }));\n checkpoint = {\n ...checkpoint,\n completedPhases: [...new Set([...checkpoint.completedPhases, phase])],\n phaseResults: {\n ...checkpoint.phaseResults,\n [phase]: result,\n },\n nextPhase: nextPhase(phase, opts.phase),\n };\n updateMaintenanceCheckpoint(db, jobId, checkpoint);\n opts.onProgress?.({\n status: \"phase-completed\",\n phase,\n progress: checkpoint.completedPhases.length / totalPhases,\n jobId,\n detail: result,\n });\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const failed = failMaintenanceJob(db, jobId, message, checkpoint) ?? baseJob;\n opts.onProgress?.({\n status: \"failed\",\n phase: checkpoint.nextPhase ?? opts.phase,\n progress: checkpoint.completedPhases.length / totalPhases,\n jobId,\n detail: { error: message },\n });\n throw Object.assign(new Error(message), { job: failed, checkpoint });\n }\n\n const completedCheckpoint: ReflectCheckpoint = {\n ...checkpoint,\n nextPhase: null,\n };\n const job = completeMaintenanceJob(db, jobId, completedCheckpoint) ?? baseJob;\n const after = getSummaryStats(db, opts.agent_id);\n\n opts.onProgress?.({\n status: \"completed\",\n phase: opts.phase,\n progress: 1,\n jobId,\n detail: completedCheckpoint.phaseResults,\n });\n\n return {\n job,\n jobId,\n phase: opts.phase,\n resumed,\n checkpoint: completedCheckpoint,\n results: completedCheckpoint.phaseResults,\n before,\n after,\n };\n}\n","import type Database from \"better-sqlite3\";\nimport {\n runReflectOrchestrator,\n type ReflectOptions,\n type ReflectRunResult,\n type ReflectRunners,\n} from \"../sleep/orchestrator.js\";\nimport type { MaintenancePhase, ReflectStep } from \"../sleep/jobs.js\";\n\nexport interface ReflectProgressEvent {\n status: \"started\" | \"phase-completed\" | \"completed\" | \"failed\";\n phase: MaintenancePhase | ReflectStep;\n progress: number;\n jobId?: string;\n detail?: unknown;\n}\n\nexport interface ReflectInput {\n phase: MaintenancePhase;\n agent_id?: string;\n jobId?: string;\n resume?: boolean;\n runners?: Partial<ReflectRunners>;\n onProgress?: (event: ReflectProgressEvent) => void;\n}\n\nexport async function reflectMemories(\n db: Database.Database,\n input: ReflectInput,\n): Promise<ReflectRunResult> {\n const options: ReflectOptions = {\n phase: input.phase,\n agent_id: input.agent_id,\n jobId: input.jobId,\n resume: input.resume,\n runners: input.runners,\n onProgress: input.onProgress,\n };\n\n return runReflectOrchestrator(db, options);\n}\n","import type Database from \"better-sqlite3\";\nimport { countMemories } from \"../core/memory.js\";\n\nexport interface StatusResult {\n total: number;\n by_type: Record<string, number>;\n by_priority: Record<string, number>;\n paths: number;\n low_vitality: number;\n feedback_events: number;\n agent_id: string;\n}\n\nexport function getMemoryStatus(\n db: Database.Database,\n input?: { agent_id?: string },\n): StatusResult {\n const agentId = input?.agent_id ?? \"default\";\n const stats = countMemories(db, agentId);\n const lowVitality = db.prepare(\n \"SELECT COUNT(*) as c FROM memories WHERE vitality < 0.1 AND agent_id = ?\",\n ).get(agentId) as { c: number };\n const totalPaths = db.prepare(\n \"SELECT COUNT(*) as c FROM paths WHERE agent_id = ?\",\n ).get(agentId) as { c: number };\n const feedbackEvents = db.prepare(\n \"SELECT COUNT(*) as c FROM feedback_events WHERE agent_id = ?\",\n ).get(agentId) as { c: number };\n\n return {\n ...stats,\n paths: totalPaths.c,\n low_vitality: lowVitality.c,\n feedback_events: feedbackEvents.c,\n agent_id: agentId,\n };\n}\n","import type Database from \"better-sqlite3\";\nimport type { EmbeddingProvider } from \"../search/embedding.js\";\nimport { rebuildBm25Index } from \"../search/bm25.js\";\nimport {\n reindexEmbeddings,\n type ReindexEmbeddingsResult,\n type ReindexSearchResult,\n} from \"../search/hybrid.js\";\n\nexport interface ReindexProgressEvent {\n status: \"started\" | \"stage-completed\" | \"completed\" | \"failed\";\n stage: \"fts\" | \"embeddings\" | \"done\";\n progress: number;\n detail?: unknown;\n}\n\nexport interface ReindexInput {\n agent_id?: string;\n provider?: EmbeddingProvider | null;\n force?: boolean;\n batchSize?: number;\n onProgress?: (event: ReindexProgressEvent) => void;\n}\n\nexport async function reindexMemories(\n db: Database.Database,\n input?: ReindexInput,\n): Promise<ReindexSearchResult> {\n input?.onProgress?.({ status: \"started\", stage: \"fts\", progress: 0 });\n\n try {\n const fts = rebuildBm25Index(db, { agent_id: input?.agent_id });\n input?.onProgress?.({\n status: \"stage-completed\",\n stage: \"fts\",\n progress: 0.5,\n detail: fts,\n });\n\n const embeddings: ReindexEmbeddingsResult = await reindexEmbeddings(db, {\n agent_id: input?.agent_id,\n provider: input?.provider,\n force: input?.force,\n batchSize: input?.batchSize,\n });\n\n input?.onProgress?.({\n status: \"stage-completed\",\n stage: \"embeddings\",\n progress: 0.9,\n detail: embeddings,\n });\n\n const result = { fts, embeddings };\n input?.onProgress?.({\n status: \"completed\",\n stage: \"done\",\n progress: 1,\n detail: result,\n });\n return result;\n } catch (error) {\n input?.onProgress?.({\n status: \"failed\",\n stage: \"done\",\n progress: 1,\n detail: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n}\n"],"mappings":"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","names":["existsSync","readFileSync","createHash","json","contentHash","createHash","randomUUID","inputDomain","candidateDomain","clamp01","clamp01","uniqueTokenSet","overlapScore","clamp01","overlapScore","candidate","now","randomUUID","result","resolve","existsSync","readFileSync"]}
|