@yhc3577/memory-new 0.1.13 → 0.1.14

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/dist/index.js CHANGED
@@ -1423,7 +1423,7 @@ Memory layers: L0 (raw) \u2192 L1 (atomic) \u2192 L2 (scene) \u2192 L3 (persona)
1423
1423
  return void 0;
1424
1424
  }
1425
1425
  });
1426
- api.on("after_prompt_build", async (event, ctx) => {
1426
+ api.on("session_end", async (event, ctx) => {
1427
1427
  if (!config.enabled || !config.layersEnabled.L0) return;
1428
1428
  const sessionKey = ctx.sessionKey ?? "default";
1429
1429
  try {
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../index.ts", "../src/store/storage.ts", "../src/vector/vector-store.ts", "../src/pipeline/distillation.ts"],
4
- "sourcesContent": ["/**\n * Memory New - OpenClaw Memory Plugin\n *\n * Complete implementation with storage and distillation pipeline integration.\n * - L0\u2192L1\u2192L2\u2192L3 distillation (TDB model)\n * - Persistent storage (JSONL + Markdown)\n * - Recall engine for prompt injection\n * - Team memory with visibility ACL\n * - Decay mechanisms\n */\n\nimport { definePluginEntry, type OpenClawPluginApi } from \"openclaw/plugin-sdk/plugin-entry\";\nimport { MemoryStore, StorageAdapter, RecallEngine, type L0Message } from \"./src/store/storage.js\";\nimport { DistillationPipeline, DEFAULT_DISTILLATION_CONFIG } from \"./src/pipeline/distillation.js\";\nimport { VectorStore } from \"./src/vector/vector-store.js\";\nimport type { EmbeddingProvider } from \"openclaw/plugin-sdk/embedding-providers\";\n\n// ============================================================================\n// Types & Interfaces\n// ============================================================================\n\n// 4 orthogonal axes (from Co-Engram research)\nexport type EngramKind = \"observation\" | \"fact\" | \"pattern\" | \"procedure\" | \"hypothesis\";\nexport type EngramStatus = \"draft\" | \"active\" | \"frozen\" | \"forgotten\";\nexport type EngramVisibility = \"public\" | \"team\" | \"private\" | \"restricted\";\nexport type VerificationStatus = \"unverified\" | \"plausible\" | \"probable\" | \"verified\" | \"refuted\";\n\n// Disclosure tiers for progressive reveal\nexport type DisclosureTier = \"catalog\" | \"digest\" | \"content\" | \"meta\" | \"synapses\";\n\n// Memory layer (from TDB research: L0 raw \u2192 L1 atomic \u2192 L2 scene \u2192 L3 persona)\nexport type MemoryLayer = \"L0\" | \"L1\" | \"L2\" | \"L3\";\n\n// Core engram interface\nexport interface Engram {\n id: string;\n kind: EngramKind;\n status: EngramStatus;\n visibility: EngramVisibility;\n verification: VerificationStatus;\n\n // Content\n content: string;\n summary?: string;\n title?: string;\n\n // Importance & dynamics\n importance: number;\n lastEffectiveAt: number;\n\n // Metadata\n metadata: Record<string, unknown>;\n tags: string[];\n contextTags: string[];\n\n // Provenance\n source: string;\n createdAt: number;\n updatedAt: number;\n createdBy: string;\n trustLevel: TrustLevel;\n\n // Relations\n synapses: Synapse[];\n}\n\nexport type TrustLevel = \"direct\" | \"external\" | \"automated\" | \"proposal\";\n\n// Synapse: relationship between engrams\nexport interface Synapse {\n targetId: string;\n strength: number;\n type: \"supports\" | \"contradicts\" | \"references\" | \"refines\";\n}\n\n// Search result\nexport interface SearchResult {\n engram: Engram;\n score: number;\n tier: DisclosureTier;\n matchedOn: string[];\n fromAgentId?: string;\n}\n\n// Configuration\nexport interface MemoryNewConfig {\n enabled: boolean;\n\n // Memory layers\n layersEnabled: {\n L0: boolean;\n L1: boolean;\n L2: boolean;\n L3: boolean;\n };\n\n // Decay mechanisms\n decay: {\n ttl: {\n enabled: boolean;\n retentionDays: number;\n safetyThreshold: number;\n minRetainL0: number;\n minRetainL1: number;\n };\n importance: {\n enabled: boolean;\n baseHalflifeDays: number;\n };\n accessFrequency: {\n enabled: boolean;\n };\n stateMachine: {\n enabled: boolean;\n };\n };\n\n // Team memory\n teamMemory: {\n enabled: boolean;\n maxImportedAgents: number;\n visibilityGate: boolean;\n };\n\n // Retrieval\n retrieval: {\n hybridSearch: boolean;\n semanticWeight: number;\n bm25Weight: number;\n entityBoostWeight: number;\n topK: number;\n overFetch: number;\n };\n\n // Storage\n storage: {\n backend: \"sqlite\" | \"memory\";\n dataDir: string;\n };\n\n // LLM for extraction\n llm?: {\n enabled: boolean;\n model?: string;\n };\n}\n\n// Default config\nconst DEFAULT_CONFIG: MemoryNewConfig = {\n enabled: true,\n layersEnabled: { L0: true, L1: true, L2: true, L3: false },\n decay: {\n ttl: { enabled: true, retentionDays: 30, safetyThreshold: 0.8, minRetainL0: 50, minRetainL1: 20 },\n importance: { enabled: true, baseHalflifeDays: 50 },\n accessFrequency: { enabled: true },\n stateMachine: { enabled: true },\n },\n teamMemory: {\n enabled: true,\n maxImportedAgents: 2,\n visibilityGate: true,\n },\n retrieval: {\n hybridSearch: true,\n semanticWeight: 0.5,\n bm25Weight: 0.25,\n entityBoostWeight: 0.25,\n topK: 10,\n overFetch: 4,\n },\n storage: {\n backend: \"memory\",\n dataDir: \"~/.openclaw/memory-new\",\n },\n llm: {\n enabled: false, // Disabled by default, use fallback extraction\n model: \"default\",\n },\n};\n\n// ============================================================================\n// Core Functions\n// ============================================================================\n\n// Freshness derivation (Ebbinghaus curve, from Co-Engram research)\nfunction deriveFreshness(engram: Engram, config: MemoryNewConfig): \"fresh\" | \"aging\" | \"stale\" | \"forgotten\" {\n if (!config.decay.importance.enabled) return \"fresh\";\n\n const ageDays = (Date.now() - engram.lastEffectiveAt) / (1000 * 60 * 60 * 24);\n const halflife = config.decay.importance.baseHalflifeDays * Math.pow(engram.importance + 0.1, 1.5);\n\n if (ageDays <= halflife) return \"fresh\";\n if (ageDays <= halflife * 2) return \"aging\";\n if (ageDays <= halflife * 4) return \"stale\";\n return \"forgotten\";\n}\n\n// Hotness derivation (from Co-Engram research)\nfunction deriveHotness(retrievalCount: number, ageDays: number): number {\n return 1 / (1 + Math.exp(-Math.log(1 + retrievalCount))) * Math.exp(-Math.LN2 * ageDays / 7);\n}\n\n// 5-factor scoring\nfunction calculateScore(\n relevance: number,\n recency: number,\n importance: number,\n strength: number,\n hotness: number,\n weights = { relevance: 0.50, recency: 0.15, importance: 0.25, strength: 0.05, hotness: 0.05 }\n): number {\n return (\n weights.relevance * relevance +\n weights.recency * recency +\n weights.importance * importance +\n weights.strength * strength +\n weights.hotness * hotness\n );\n}\n\n// Visibility gate (from Co-Engram research)\nfunction validateVisibilityTransition(\n from: EngramVisibility,\n to: EngramVisibility,\n config: MemoryNewConfig\n): boolean {\n if (!config.teamMemory.visibilityGate) return true;\n if (from === to) return true;\n if (to === \"private\" && from !== \"private\") return false;\n if (from === \"private\") return true;\n return true;\n}\n\n// Generate unique ID\nfunction genId(): string {\n return `engram_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\n// ============================================================================\n// Memory Plugin\n// ============================================================================\n\nexport default definePluginEntry({\n id: \"memory_new\",\n name: \"Memory New\",\n description: \"Multi-layered memory system with L0\u2192L1\u2192L2\u2192L3 distillation, persistent storage, and recall\",\n\n register(api: OpenClawPluginApi) {\n const config = (api.pluginConfig ?? DEFAULT_CONFIG) as MemoryNewConfig;\n\n // Ensure storage config exists\n const storageConfig = config.storage ?? { backend: \"memory\", dataDir: \"~/.openclaw/memory-new\" };\n\n // Initialize storage\n const storage = new StorageAdapter(storageConfig.dataDir);\n const store = new MemoryStore(storageConfig.dataDir);\n const recall = new RecallEngine(storage);\n\n // Initialize vector store for semantic search\n const vectorStore = new VectorStore();\n\n // Initialize distillation pipeline\n const pipeline = new DistillationPipeline(DEFAULT_DISTILLATION_CONFIG, store, vectorStore);\n\n // Wire up vector store to memory store\n store.setVectorStore(vectorStore);\n\n // Register embedding provider for vector search (if LLM enabled)\n if (config.llm?.enabled) {\n // Register our built-in embedding provider adapter\n api.registerEmbeddingProvider({\n id: \"memory-new-embedder\",\n defaultModel: config.llm.model ?? \"default\",\n transport: \"local\",\n create: async (options) => {\n // Create a simple hash-based embedder when no real provider is available\n const provider: EmbeddingProvider = {\n id: \"memory-new-embedder\",\n model: options.model,\n dimensions: 384,\n maxInputTokens: 8192,\n embed: async (input) => {\n const text = typeof input === \"string\" ? input : input.text;\n return vectorStore.generatePseudoEmbedding(text);\n },\n embedBatch: async (inputs) => {\n return inputs.map(input => {\n const text = typeof input === \"string\" ? input : input.text;\n return vectorStore.generatePseudoEmbedding(text);\n });\n },\n };\n return { provider, runtime: { id: \"memory-new-embedder\" } };\n },\n });\n\n // Set up subagent runner for LLM extraction\n pipeline.setSubagentRunner(async (prompt: string) => {\n try {\n const result = await api.runtime.subagent.run({\n sessionKey: `memory-${Date.now()}`,\n message: prompt,\n model: config.llm?.model,\n disableTools: true,\n });\n // Wait for completion\n const waitResult = await api.runtime.subagent.waitForRun({ runId: result.runId, timeoutMs: 30000 });\n // Get session messages to extract response\n const messages = await api.runtime.subagent.getSessionMessages({ sessionKey: result.sessionKey! });\n // Find assistant response\n const assistantMsg = messages.messages.find((m: any) => m.role === \"assistant\");\n return assistantMsg?.content?.[0]?.text ?? \"\";\n } catch (error) {\n api.logger.debug?.(`Subagent extraction failed: ${error}`);\n throw error;\n }\n });\n }\n\n // Track session messages for L0\n const sessionMessages = new Map<string, any[]>();\n\n // =========================================================================\n // Commands\n // =========================================================================\n\n api.registerCommand({\n name: \"mem\",\n description: \"Interact with memory system (L0\u2192L1\u2192L2\u2192L3)\",\n acceptsArgs: true,\n exposeSenderIsOwner: true,\n handler: async (ctx) => {\n const args = ctx.args ?? \"\";\n const [action, ...rest] = args.trim().split(/\\s+/);\n\n switch (action) {\n case \"add\": {\n const content = rest.join(\" \");\n if (!content) return { text: \"Usage: mem add <content>\" };\n\n // Store directly to L1\n const now = new Date().toISOString();\n await store.storeL1({\n content,\n type: \"episodic\",\n priority: 50,\n sceneName: \"User Added\",\n sourceMessageIds: [],\n metadata: { source: \"command\" },\n timestamps: [now],\n sessionKey: ctx.sessionKey ?? \"default\",\n sessionId: ctx.sessionKey ?? \"default\",\n userId: ctx.senderIsOwner ? \"owner\" : \"user\",\n agentId: \"self\",\n });\n\n return { text: `Added: ${content.slice(0, 50)}...` };\n }\n\n case \"search\": {\n const query = rest.join(\" \");\n if (!query) return { text: \"Usage: memory search <query>\" };\n\n // Use recall engine for search\n const result = await recall.recall({\n query,\n sessionKey: ctx.sessionKey ?? \"default\",\n userId: ctx.senderIsOwner ? \"owner\" : \"user\",\n agentId: \"self\",\n topK: config.retrieval.topK,\n });\n\n if (!result.prependContext && !result.appendSystemContext) {\n return { text: \"No relevant memories found.\" };\n }\n\n return {\n text: `Found memories:\\n\\n${result.prependContext ?? \"\"}\\n\\n${result.appendSystemContext ?? \"\"}`,\n };\n }\n\n case \"list\": {\n // Get recent L1 records\n const records = await store.searchL1(\"\", 20);\n\n if (records.length === 0) return { text: \"No memories stored.\" };\n\n const lines = records.map(r =>\n `[${r.type}] ${r.content.slice(0, 60)}${r.content.length > 60 ? \"...\" : \"\"}`\n );\n return { text: `Recent ${records.length} memories:\\n\\n${lines.join(\"\\n\")}` };\n }\n\n case \"reinforce\": {\n // Not applicable with new storage model\n return { text: \"Reinforce is not yet supported with persistent storage.\" };\n }\n\n case \"decay\": {\n // Apply decay - placeholder\n return { text: \"Decay is not yet fully implemented.\" };\n }\n\n case \"stats\": {\n const stats = await pipeline.getStats();\n return {\n text: `Memory Stats:\n L0 (buffered): ${stats.l0Count}\n L1 (stored): ${stats.l1Count}\n L2 (scenes): ${stats.l2Count}\n L3 (persona): ${stats.l3Count}`,\n };\n }\n\n case \"config\": {\n return { text: JSON.stringify(config, null, 2) };\n }\n\n default:\n return {\n text: `Memory New commands:\n mem add <content> - Add a memory\n mem search <query> - Search memories\n mem list - List recent memories\n mem stats - Show memory statistics\n mem config - Show configuration\n\nMemory layers: L0 (raw) \u2192 L1 (atomic) \u2192 L2 (scene) \u2192 L3 (persona)`,\n };\n }\n },\n });\n\n // Team memory command\n api.registerCommand({\n name: \"team-mem\",\n description: \"Team memory operations\",\n acceptsArgs: true,\n exposeSenderIsOwner: true,\n handler: async (ctx) => {\n if (!config.teamMemory.enabled) {\n return { text: \"Team memory is disabled.\" };\n }\n\n const args = ctx.args ?? \"\";\n const [action, ...rest] = args.trim().split(/\\s+/);\n\n switch (action) {\n case \"share\": {\n return { text: \"Share is not yet implemented.\" };\n }\n\n case \"import\": {\n return { text: \"Import is not yet implemented.\" };\n }\n\n case \"status\": {\n const stats = await pipeline.getStats();\n return {\n text: `Team memory status:\n Enabled: ${config.teamMemory.enabled}\n Max imported agents: ${config.teamMemory.maxImportedAgents}\n Visibility gate: ${config.teamMemory.visibilityGate}\n Total L1 memories: ${stats.l1Count}\n Total L2 scenes: ${stats.l2Count}`,\n };\n }\n\n default:\n return {\n text: `Team memory commands:\n team-memory status - Show team memory status`,\n };\n }\n },\n });\n\n // =========================================================================\n // Lifecycle Hooks\n // =========================================================================\n\n // before_prompt_build: inject relevant memories\n api.on(\"before_prompt_build\", async (event, ctx) => {\n if (!config.enabled) return undefined;\n\n const sessionKey = ctx.sessionKey ?? \"default\";\n const userId = \"user\"; // Default user\n\n try {\n // Recall relevant memories\n const query = event.prompt?.slice(0, 200) ?? \"\";\n const recallResult = await recall.recall({\n query,\n sessionKey,\n userId,\n agentId: \"self\",\n topK: config.retrieval.topK,\n vectorStore: config.retrieval.hybridSearch ? vectorStore : undefined,\n });\n\n // If no memories, skip\n if (!recallResult.prependContext && !recallResult.appendSystemContext) {\n return undefined;\n }\n\n return {\n prependContext: recallResult.prependContext,\n appendContext: recallResult.appendSystemContext,\n };\n } catch (error) {\n api.logger.debug?.(`Memory recall failed: ${error}`);\n return undefined;\n }\n });\n\n // after_prompt_build: capture messages to L0\n api.on(\"after_prompt_build\", async (event, ctx) => {\n if (!config.enabled || !config.layersEnabled.L0) return;\n\n const sessionKey = ctx.sessionKey ?? \"default\";\n\n try {\n // Get messages from event (if available)\n const messages = (event as any).messages ?? [];\n\n if (messages.length > 0) {\n // Ingest messages into L0\n for (const msg of messages) {\n const l0Msg: Omit<L0Message, \"id\" | \"recordedAt\"> = {\n role: msg.role === \"user\" ? \"user\" : \"assistant\",\n content: msg.content?.slice(0, 10000) ?? \"\", // Limit length\n timestamp: msg.timestamp ?? Date.now(),\n sessionKey,\n sessionId: sessionKey,\n userId: \"user\",\n agentId: \"self\",\n };\n\n await store.ingestMessage(l0Msg);\n }\n\n // Trigger L1 extraction if threshold met\n if (config.layersEnabled.L1 && config.llm?.enabled) {\n await pipeline.distill(\"L1\");\n }\n }\n } catch (error) {\n api.logger.debug?.(`Memory capture failed: ${error}`);\n }\n });\n\n // agent_end: process remaining messages\n api.on(\"agent_end\", (event, ctx) => {\n if (!config.enabled) return;\n\n const runId = event.runId ?? ctx.runId;\n api.logger.debug?.(`Memory: agent ended for run ${runId}`);\n });\n\n // session_end: cleanup and final processing\n api.on(\"session_end\", async (event, ctx) => {\n if (!config.enabled) return;\n\n const sessionKey = ctx.sessionKey ?? \"default\";\n\n try {\n // Trigger L2/L3 distillation if enabled\n if (config.layersEnabled.L2) {\n await pipeline.distill(\"L2\");\n }\n if (config.layersEnabled.L3) {\n await pipeline.distill(\"L3\");\n }\n\n // Clear session message buffer\n sessionMessages.delete(sessionKey);\n\n api.logger.debug?.(`Memory: session ended for ${sessionKey}`);\n } catch (error) {\n api.logger.debug?.(`Memory session cleanup failed: ${error}`);\n }\n });\n\n // =========================================================================\n // Tools\n // =========================================================================\n\n api.registerTool({\n name: \"mem_new_search\",\n description: \"Search memory store using hybrid retrieval\",\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query\" },\n limit: { type: \"number\", description: \"Max results\", default: 10 },\n visibility: {\n type: \"string\",\n enum: [\"all\", \"public\", \"team\", \"private\"],\n default: \"all\",\n },\n },\n required: [\"query\"],\n },\n execute: async (params, ctx) => {\n const result = await recall.recall({\n query: params.query,\n sessionKey: ctx.sessionKey ?? \"default\",\n userId: \"user\",\n agentId: \"self\",\n topK: params.limit ?? 10,\n });\n\n return {\n memories: result.recalledL1Memories ?? [],\n prependContext: result.prependContext,\n appendContext: result.appendSystemContext,\n };\n },\n });\n\n api.registerTool({\n name: \"mem_new_store\",\n description: \"Store a new memory engram\",\n parameters: {\n type: \"object\",\n properties: {\n content: { type: \"string\", description: \"Memory content\" },\n type: {\n type: \"string\",\n enum: [\"persona\", \"episodic\", \"instruction\"],\n default: \"episodic\",\n description: \"Memory type\",\n },\n priority: {\n type: \"number\",\n default: 50,\n description: \"Priority 0-100\",\n },\n sceneName: {\n type: \"string\",\n default: \"General\",\n description: \"Scene name\",\n },\n },\n required: [\"content\"],\n },\n execute: async (params, ctx) => {\n const record = await store.storeL1({\n content: params.content,\n type: params.type as \"persona\" | \"episodic\" | \"instruction\" ?? \"episodic\",\n priority: params.priority ?? 50,\n sceneName: params.sceneName ?? \"General\",\n sourceMessageIds: [],\n metadata: { source: \"tool\" },\n timestamps: [new Date().toISOString()],\n sessionKey: ctx.sessionKey ?? \"default\",\n sessionId: ctx.sessionKey ?? \"default\",\n userId: \"user\",\n agentId: \"self\",\n });\n\n return { engramId: record.id, stored: true };\n },\n });\n\n api.registerTool({\n name: \"mem_new_get\",\n description: \"Get a specific memory by ID\",\n parameters: {\n type: \"object\",\n properties: {\n layer: {\n type: \"string\",\n enum: [\"L0\", \"L1\", \"L2\", \"L3\"],\n default: \"L1\",\n description: \"Memory layer\",\n },\n id: { type: \"string\", description: \"Memory ID (for L2/L3)\" },\n },\n required: [],\n },\n execute: async (params, ctx) => {\n if (params.layer === \"L2\" && params.id) {\n const scene = await store.getScene(params.id);\n return scene ?? { error: \"Scene not found\" };\n }\n\n if (params.layer === \"L3\") {\n const persona = await store.getPersona();\n return persona ?? { error: \"Persona not found\" };\n }\n\n // L1 search\n const records = await store.searchL1(\"\", 10);\n return { records };\n },\n });\n\n api.registerTool({\n name: \"mem_new_distill\",\n description: \"Trigger memory distillation manually\",\n parameters: {\n type: \"object\",\n properties: {\n layer: {\n type: \"string\",\n enum: [\"L1\", \"L2\", \"L3\"],\n default: \"L1\",\n description: \"Layer to distill\",\n },\n },\n required: [\"layer\"],\n },\n execute: async (params, ctx) => {\n const layer = params.layer as MemoryLayer;\n const result = await pipeline.distill(layer);\n\n return {\n layer: result.stage,\n produced: result.produced,\n errors: result.errors,\n };\n },\n });\n\n // =========================================================================\n // HTTP Routes (team memory sync - reserved interface)\n // =========================================================================\n\n api.registerHttpRoute({\n method: \"GET\",\n path: \"/memory/team/status\",\n auth: \"none\",\n handler: async (req, ctx) => {\n if (!config.teamMemory.enabled) {\n return { status: 403, body: { error: \"Team memory disabled\" } };\n }\n\n const stats = await pipeline.getStats();\n return {\n status: 200,\n body: {\n enabled: true,\n maxImportedAgents: config.teamMemory.maxImportedAgents,\n l1Count: stats.l1Count,\n l2Count: stats.l2Count,\n },\n };\n },\n });\n\n api.registerHttpRoute({\n method: \"POST\",\n path: \"/memory/team/share\",\n auth: \"none\",\n handler: async (req, ctx) => {\n if (!config.teamMemory.enabled) {\n return { status: 403, body: { error: \"Team memory disabled\" } };\n }\n return { status: 501, body: { error: \"Not implemented\" } };\n },\n });\n\n api.registerHttpRoute({\n method: \"POST\",\n path: \"/memory/team/import\",\n auth: \"none\",\n handler: async (req, ctx) => {\n if (!config.teamMemory.enabled) {\n return { status: 403, body: { error: \"Team memory disabled\" } };\n }\n return { status: 501, body: { error: \"Not implemented\" } };\n },\n });\n\n api.logger.info?.(\"Memory New plugin registered with storage and pipeline\");\n\n // Auto-configure plugin settings when installed\n api.registerConfigMigration?.({\n id: \"memory-new-default-config\",\n migrate: (existingConfig) => {\n const current = existingConfig?.memory_new;\n if (!current) {\n // First install - set defaults\n return {\n memory_new: {\n enabled: true,\n layersEnabled: { L0: true, L1: true, L2: true, L3: false },\n llm: { enabled: false, model: \"default\" },\n retrieval: {\n hybridSearch: true,\n semanticWeight: 0.5,\n bm25Weight: 0.25,\n entityBoostWeight: 0.25,\n topK: 10,\n overFetch: 4,\n },\n storage: { backend: \"memory\", dataDir: \"~/.openclaw/memory-new\" },\n decay: {\n ttl: { enabled: true, retentionDays: 30, safetyThreshold: 0.8, minRetainL0: 50, minRetainL1: 20 },\n importance: { enabled: true, baseHalflifeDays: 50 },\n accessFrequency: { enabled: true },\n stateMachine: { enabled: true },\n },\n teamMemory: { enabled: true, maxImportedAgents: 2, visibilityGate: true },\n },\n };\n }\n return {}; // No migration needed\n },\n });\n\n // Auto-enable probe - allows OpenClaw to auto-enable this plugin\n api.registerAutoEnableProbe?.({\n id: \"memory-new\",\n check: async (config) => {\n // Check if memory_new config exists or if any memory-related files are present\n const hasConfig = config?.plugins?.memory_new?.enabled === true;\n const hasStorageDir = false; // Could check for ~/.openclaw/memory-new\n return hasConfig || hasStorageDir;\n },\n });\n },\n});\n\n// ============================================================================\n// Exports for testing\n// ============================================================================\n\nexport const testing = {\n deriveFreshness,\n deriveHotness,\n calculateScore,\n validateVisibilityTransition,\n};\n", "/**\n * Memory Storage - Complete L0/L1/L2/L3 Implementation\n *\n * Reference: TDB (TencentDB-Agent-Memory) storage architecture\n *\n * Storage model:\n * - L0: SQLite (messages) + FTS5 (search)\n * - L1: SQLite (atomic memories) + VectorStore (embeddings)\n * - L2: File system (Markdown scene blocks)\n * - L3: File system (persona.md)\n */\n\nimport { mkdirSync, writeFileSync, readFileSync, existsSync, appendFileSync, readdirSync } from \"fs\";\nimport { join, dirname } from \"path\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface L0Message {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n timestamp: number; // epoch ms\n sessionKey: string;\n sessionId: string;\n teamId?: string;\n userId: string;\n agentId: string;\n taskId?: string;\n recordedAt: string; // ISO timestamp\n}\n\nexport interface L1Record {\n id: string;\n content: string;\n type: \"persona\" | \"episodic\" | \"instruction\";\n priority: number; // 0-100\n sceneName: string;\n sourceMessageIds: string[];\n metadata: Record<string, unknown>;\n timestamps: string[];\n createdAt: string;\n updatedAt: string;\n version: number;\n sessionKey: string;\n sessionId: string;\n teamId?: string;\n userId: string;\n agentId: string;\n // Vector embedding stored separately\n}\n\nexport interface L2Scene {\n id: string;\n title: string;\n content: string; // Markdown\n summary: string;\n tags: string[];\n metadata: {\n layer: \"L2\";\n heat: number; // Number of related L1s\n sourceRecords: string[];\n };\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface L3Persona {\n id: string;\n content: string; // Markdown\n summary: string;\n metadata: {\n layer: \"L3\";\n sourceScenes: string[];\n };\n createdAt: string;\n updatedAt: string;\n}\n\n// ============================================================================\n// Storage Paths\n// ============================================================================\n\nexport const STORAGE_PATHS = {\n l0: \"memory/l0/\",\n l1: \"memory/l1/\",\n l2: \"memory/scenes/\",\n l3: \"persona.md\",\n index: {\n l2: \"memory/scenes/index.json\",\n l3: \"persona.md.meta\",\n },\n};\n\n// ============================================================================\n// Storage Adapter (TDB's StorageAdapter pattern)\n// ============================================================================\n\nexport class StorageAdapter {\n private baseDir: string;\n\n constructor(baseDir: string = \"~/.openclaw/memory-new\") {\n this.baseDir = baseDir.replace(\"~\", process.env.HOME || \"/root\");\n mkdirSync(this.baseDir, { recursive: true });\n }\n\n private resolve(path: string): string {\n return join(this.baseDir, path);\n }\n\n // ========== File Operations ==========\n\n async readFile(key: string): Promise<string | null> {\n const filePath = this.resolve(key);\n if (!existsSync(filePath)) return null;\n return readFileSync(filePath, \"utf-8\");\n }\n\n async writeFile(key: string, content: string): Promise<void> {\n const filePath = this.resolve(key);\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, content, \"utf-8\");\n }\n\n async appendFile(key: string, content: string): Promise<void> {\n const filePath = this.resolve(key);\n mkdirSync(dirname(filePath), { recursive: true });\n appendFileSync(filePath, content, \"utf-8\");\n }\n\n async exists(key: string): Promise<boolean> {\n return existsSync(this.resolve(key));\n }\n\n // ========== L0 Operations (JSONL per session) ==========\n\n /**\n * L0: Append message to session's JSONL file (TDB pattern: append-only)\n */\n async appendL0(record: L0Message): Promise<void> {\n const sessionFile = `${STORAGE_PATHS.l0}${record.sessionKey}.jsonl`;\n const line = JSON.stringify(record) + \"\\n\";\n await this.appendFile(sessionFile, line);\n }\n\n /**\n * L0: Batch read messages from session\n */\n async readL0(sessionKey: string, limit: number = 100): Promise<L0Message[]> {\n const sessionFile = `${STORAGE_PATHS.l0}${sessionKey}.jsonl`;\n const content = await this.readFile(sessionFile);\n if (!content) return [];\n\n const lines = content.split(\"\\n\").filter(l => l.trim());\n const messages = lines.slice(-limit).map(line => JSON.parse(line) as L0Message);\n return messages;\n }\n\n // ========== L1 Operations (JSONL) ==========\n\n /**\n * L1: Append atomic memory to session's JSONL file\n */\n async appendL1(record: L1Record): Promise<void> {\n const sessionFile = `${STORAGE_PATHS.l1}${record.sessionKey}.jsonl`;\n const line = JSON.stringify(record) + \"\\n\";\n await this.appendFile(sessionFile, line);\n }\n\n /**\n * L1: Search memories by content (simple full-text scan)\n */\n async searchL1(query: string, limit: number = 10): Promise<L1Record[]> {\n const l1Dir = this.resolve(STORAGE_PATHS.l1);\n\n console.log(`[DEBUG searchL1] l1Dir: ${l1Dir}`);\n\n // Check if directory exists\n if (!existsSync(l1Dir)) {\n console.log(`[DEBUG searchL1] Directory does not exist: ${l1Dir}`);\n return [];\n }\n\n // Read all JSONL files in the directory\n let allRecords: L1Record[] = [];\n try {\n const files = readdirSync(l1Dir).filter(f => f.endsWith('.jsonl'));\n console.log(`[DEBUG searchL1] Found files: ${files}`);\n\n for (const file of files) {\n const filePath = `${STORAGE_PATHS.l1}${file}`;\n console.log(`[DEBUG searchL1] Reading file: ${filePath}`);\n const content = await this.readFile(filePath);\n if (content) {\n const lines = content.split(\"\\n\").filter(l => l.trim());\n const records = lines.map(line => {\n try {\n return JSON.parse(line) as L1Record;\n } catch {\n return null;\n }\n }).filter((r): r is L1Record => r !== null);\n allRecords = allRecords.concat(records);\n }\n }\n console.log(`[DEBUG searchL1] Total records found: ${allRecords.length}`);\n } catch (e) {\n console.log(`[DEBUG searchL1] Error: ${e}`);\n // Directory might not exist\n return [];\n }\n\n // Filter by query if provided\n if (query) {\n const queryLower = query.toLowerCase();\n allRecords = allRecords.filter(r => r.content.toLowerCase().includes(queryLower));\n }\n\n // Sort by createdAt descending (newest first)\n allRecords.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n\n return allRecords.slice(0, limit);\n }\n\n // ========== L2 Operations (Markdown files) ==========\n\n /**\n * L2: Write scene block as Markdown file\n */\n async writeScene(scene: L2Scene): Promise<void> {\n const sceneFile = `${STORAGE_PATHS.l2}${scene.id}.md`;\n const frontmatter = `---\nid: ${scene.id}\ntitle: ${scene.title}\nsummary: ${scene.summary}\ntags: ${JSON.stringify(scene.tags)}\ncreated_at: ${scene.createdAt}\nupdated_at: ${scene.updatedAt}\n---\n\n`;\n await this.writeFile(sceneFile, frontmatter + scene.content);\n await this.updateSceneIndex(scene);\n }\n\n /**\n * L2: Read scene block\n */\n async readScene(sceneId: string): Promise<L2Scene | null> {\n const content = await this.readFile(`${STORAGE_PATHS.l2}${sceneId}.md`);\n if (!content) return null;\n\n // Parse frontmatter (simplified)\n const lines = content.split(\"\\n\");\n const frontmatterEnd = lines.findIndex(l => l === \"---\", 1);\n if (frontmatterEnd <= 1) return null;\n\n const frontmatter: Record<string, string> = {};\n for (let i = 1; i < frontmatterEnd; i++) {\n const [key, ...valueParts] = lines[i].split(\":\");\n if (key && valueParts.length > 0) {\n frontmatter[key.trim()] = valueParts.join(\":\").trim();\n }\n }\n\n return {\n id: scene.id,\n title: frontmatter.title || \"\",\n content: lines.slice(frontmatterEnd + 1).join(\"\\n\"),\n summary: frontmatter.summary || \"\",\n tags: JSON.parse(frontmatter.tags || \"[]\"),\n metadata: { layer: \"L2\", heat: 0, sourceRecords: [] },\n createdAt: frontmatter.created_at || \"\",\n updatedAt: frontmatter.updated_at || \"\",\n };\n }\n\n /**\n * L2: Maintain scene index for navigation\n */\n private async updateSceneIndex(scene: L2Scene): Promise<void> {\n const indexFile = STORAGE_PATHS.index.l2;\n let index: Record<string, { id: string; title: string; summary: string; tags: string[] }> = {};\n\n const existing = await this.readFile(indexFile);\n if (existing) {\n try {\n index = JSON.parse(existing);\n } catch { /* ignore */ }\n }\n\n index[scene.id] = {\n id: scene.id,\n title: scene.title,\n summary: scene.summary,\n tags: scene.tags,\n };\n\n await this.writeFile(indexFile, JSON.stringify(index, null, 2));\n }\n\n /**\n * L2: Read scene index for navigation\n */\n async readSceneIndex(): Promise<Array<{ id: string; title: string; summary: string }>> {\n const indexFile = STORAGE_PATHS.index.l2;\n const content = await this.readFile(indexFile);\n if (!content) return [];\n\n try {\n const index = JSON.parse(content);\n return Object.values(index);\n } catch {\n return [];\n }\n }\n\n // ========== L3 Operations (persona.md) ==========\n\n /**\n * L3: Write persona file\n */\n async writePersona(persona: L3Persona): Promise<void> {\n const frontmatter = `---\nid: ${persona.id}\ncreated_at: ${persona.createdAt}\nupdated_at: ${persona.updatedAt}\n---\n\n`;\n await this.writeFile(STORAGE_PATHS.l3, frontmatter + persona.content);\n }\n\n /**\n * L3: Read persona file\n */\n async readPersona(): Promise<L3Persona | null> {\n const content = await this.readFile(STORAGE_PATHS.l3);\n if (!content) return null;\n\n const lines = content.split(\"\\n\");\n const frontmatterEnd = lines.findIndex(l => l === \"---\", 1);\n if (frontmatterEnd <= 1) return null;\n\n const frontmatter: Record<string, string> = {};\n for (let i = 1; i < frontmatterEnd; i++) {\n const [key, ...valueParts] = lines[i].split(\":\");\n if (key && valueParts.length > 0) {\n frontmatter[key.trim()] = valueParts.join(\":\").trim();\n }\n }\n\n return {\n id: frontmatter.id || \"\",\n content: lines.slice(frontmatterEnd + 1).join(\"\\n\"),\n summary: \"\",\n metadata: { layer: \"L3\", sourceScenes: [] },\n createdAt: frontmatter.created_at || \"\",\n updatedAt: frontmatter.updated_at || \"\",\n };\n }\n}\n\n// ============================================================================\n// Recall Result (TDB's RecallResult pattern)\n// ============================================================================\n\nexport interface RecallResult {\n /** L1 relevant memories \u2014 prepended to user prompt (dynamic, per-turn) */\n prependContext?: string;\n /** Stable recall context appended to system prompt (L2/L3, cacheable) */\n appendSystemContext?: string;\n /** L1 memories with scores (for metrics) */\n recalledL1Memories?: Array<{ content: string; score: number; type: string }>;\n /** L3 persona raw content */\n recalledL3Persona?: string | null;\n /** Search strategy used */\n recallStrategy?: string;\n}\n\nconst RECALL_LINE_SEPARATOR = \"\\n\";\n\n/**\n * Memory tools usage guide (TDB's MEMORY_TOOLS_GUIDE)\n */\nconst MEMORY_TOOLS_GUIDE = `<memory-tools-guide>\n## \u8BB0\u5FC6\u5DE5\u5177\u8C03\u7528\u6307\u5357\n\n\u5F53\u4E0A\u65B9\u6CE8\u5165\u7684\u8BB0\u5FC6\u7247\u6BB5\u4E0D\u8DB3\u4EE5\u56DE\u7B54\u7528\u6237\u95EE\u9898\u65F6\uFF0C\u53EF\u4E3B\u52A8\u8C03\u7528\u4EE5\u4E0B\u5DE5\u5177\u83B7\u53D6\u66F4\u591A\u4FE1\u606F\uFF1A\n\n- **memory_search**\uFF1A\u641C\u7D22\u7ED3\u6784\u5316\u8BB0\u5FC6\uFF08L1\uFF09\uFF0C\u9002\u7528\u4E8E\u56DE\u5FC6\u7528\u6237\u504F\u597D\u3001\u5386\u53F2\u4E8B\u4EF6\u8282\u70B9\u3001\u89C4\u5219\u7B49\u5173\u952E\u4FE1\u606F\u3002\n- **memory_get**\uFF1A\u83B7\u53D6\u7279\u5B9A\u8BB0\u5FC6\u8BE6\u60C5\u3002\n\n### \u8C03\u7528\u6B21\u6570\u9650\u5236\n\u6BCF\u8F6E\u5BF9\u8BDD\u4E2D\uFF0C\u8BB0\u5FC6\u641C\u7D22\u5DE5\u5177**\u5408\u8BA1\u6700\u591A\u8C03\u7528 3 \u6B21**\u3002\n</memory-tools-guide>`;\n\n/**\n * Scene navigation template (TDB's generateSceneNavigation)\n */\nfunction generateSceneNavigation(scenes: Array<{ id: string; title: string; summary: string }>): string {\n if (scenes.length === 0) return \"\";\n\n const lines = scenes.map(s =>\n `- [${s.title}](memory://scene/${s.id}): ${s.summary}`\n );\n\n return `## \u60C5\u5883\u5BFC\u822A\\n${lines.join(RECALL_LINE_SEPARATOR)}`;\n}\n\n// ============================================================================\n// Recall Engine (TDB's performAutoRecall pattern)\n// ============================================================================\n\nexport interface RecallEngineOptions {\n hybridSearch?: boolean;\n semanticWeight?: number;\n bm25Weight?: number;\n entityBoostWeight?: number;\n}\n\nexport class RecallEngine {\n private storage: StorageAdapter;\n private options: RecallEngineOptions;\n\n constructor(storage: StorageAdapter, options: RecallEngineOptions = {}) {\n this.storage = storage;\n this.options = {\n hybridSearch: options.hybridSearch ?? true,\n semanticWeight: options.semanticWeight ?? 0.5,\n bm25Weight: options.bm25Weight ?? 0.25,\n entityBoostWeight: options.entityBoostWeight ?? 0.25,\n };\n }\n\n /**\n * Perform recall: search L1 + read L2 + read L3\n * (Reference: TDB's performAutoRecallCore)\n *\n * Uses hybrid search when vector store is available via hybridSearch option.\n */\n async recall(params: {\n query: string;\n sessionKey: string;\n userId: string;\n agentId: string;\n topK?: number;\n vectorStore?: import(\"../vector/vector-store.js\").VectorStore;\n }): Promise<RecallResult> {\n const { query, sessionKey, topK = 10, vectorStore } = params;\n\n let memories: L1Record[] = [];\n let recallStrategy = \"text\";\n\n // 1. Search L1 memories - use hybrid or text search\n if (vectorStore && this.options.hybridSearch) {\n // Hybrid semantic search using vector store\n const searchResults = await vectorStore.hybridSearch({\n query,\n topK,\n semanticWeight: this.options.semanticWeight!,\n bm25Weight: this.options.bm25Weight!,\n entityBoostWeight: this.options.entityBoostWeight!,\n });\n\n // Get full records from storage for matched IDs\n const matchedRecords: L1Record[] = [];\n for (const result of searchResults) {\n const records = await this.storage.searchL1(\"\", 100);\n const record = records.find(r => r.id === result.id);\n if (record) {\n matchedRecords.push(record);\n }\n }\n memories = matchedRecords;\n recallStrategy = \"hybrid\";\n } else {\n // Text search fallback\n memories = await this.storage.searchL1(query, topK);\n recallStrategy = \"text\";\n }\n\n // 2. Read L2 scene navigation\n const sceneIndex = await this.storage.readSceneIndex();\n\n // 3. Read L3 persona\n const persona = await this.storage.readPersona();\n\n // Build prependContext (L1 - dynamic, per-turn)\n let prependContext: string | undefined;\n if (memories.length > 0) {\n const memoryLines = memories.map(m =>\n `- [${m.type}] ${m.content}`\n );\n prependContext = `<relevant-memories>\n\u4EE5\u4E0B\u662F\u4E0E\u5F53\u524D\u5BF9\u8BDD\u76F8\u5173\u7684\u8BB0\u5FC6\uFF1A\n\n${memoryLines.join(RECALL_LINE_SEPARATOR)}\n</relevant-memories>`;\n }\n\n // Build appendSystemContext (L2/L3 + tools guide - stable, cacheable)\n const stableParts: string[] = [];\n\n if (persona) {\n stableParts.push(`<user-persona>\n${persona.content}\n</user-persona>`);\n }\n\n if (sceneIndex.length > 0) {\n stableParts.push(`<scene-navigation>\n${generateSceneNavigation(sceneIndex)}\n</scene-navigation>`);\n }\n\n if (stableParts.length > 0 || prependContext) {\n stableParts.push(MEMORY_TOOLS_GUIDE);\n }\n\n const appendSystemContext = stableParts.length > 0\n ? stableParts.join(\"\\n\\n\")\n : undefined;\n\n return {\n prependContext,\n appendSystemContext,\n recalledL1Memories: memories.map(m => ({\n content: m.content,\n score: 0.5, // TODO: calculate real score\n type: m.type,\n })),\n recalledL3Persona: persona?.content ?? null,\n recallStrategy,\n };\n }\n}\n\n// ============================================================================\n// Memory Store (combining all layers)\n// ============================================================================\n\nexport class MemoryStore {\n private storage: StorageAdapter;\n private recall: RecallEngine;\n private _vectorStore?: import(\"../vector/vector-store.js\").VectorStore;\n\n constructor(baseDir: string = \"~/.openclaw/memory-new\") {\n this.storage = new StorageAdapter(baseDir);\n this.recall = new RecallEngine(this.storage);\n }\n\n // ========== Vector Store (for semantic search) ==========\n\n get vectorStore(): import(\"../vector/vector-store.js\").VectorStore | undefined {\n return this._vectorStore;\n }\n\n setVectorStore(store: import(\"../vector/vector-store.js\").VectorStore): void {\n this._vectorStore = store;\n }\n\n // ========== L0 Operations ==========\n\n async ingestMessage(message: Omit<L0Message, \"id\" | \"recordedAt\">): Promise<L0Message> {\n const record: L0Message = {\n ...message,\n id: `l0_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n recordedAt: new Date().toISOString(),\n };\n await this.storage.appendL0(record);\n return record;\n }\n\n async getMessages(sessionKey: string, limit: number = 100): Promise<L0Message[]> {\n return this.storage.readL0(sessionKey, limit);\n }\n\n // ========== L1 Operations ==========\n\n async storeL1(record: Omit<L1Record, \"id\" | \"createdAt\" | \"updatedAt\" | \"version\">): Promise<L1Record> {\n const now = new Date().toISOString();\n const fullRecord: L1Record = {\n ...record,\n id: `l1_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n createdAt: now,\n updatedAt: now,\n version: 1,\n };\n await this.storage.appendL1(fullRecord);\n return fullRecord;\n }\n\n async searchL1(query: string, limit: number = 10): Promise<L1Record[]> {\n return this.storage.searchL1(query, limit);\n }\n\n // ========== L2 Operations ==========\n\n async storeL2(scene: Omit<L2Scene, \"id\" | \"createdAt\" | \"updatedAt\">): Promise<L2Scene> {\n const now = new Date().toISOString();\n const fullScene: L2Scene = {\n ...scene,\n id: `scene_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n createdAt: now,\n updatedAt: now,\n };\n await this.storage.writeScene(fullScene);\n return fullScene;\n }\n\n async getScene(sceneId: string): Promise<L2Scene | null> {\n return this.storage.readScene(sceneId);\n }\n\n async getSceneIndex(): Promise<Array<{ id: string; title: string; summary: string }>> {\n return this.storage.readSceneIndex();\n }\n\n // ========== L3 Operations ==========\n\n async storeL3(persona: Omit<L3Persona, \"id\" | \"createdAt\" | \"updatedAt\">): Promise<L3Persona> {\n const now = new Date().toISOString();\n const fullPersona: L3Persona = {\n ...persona,\n id: `persona_${Date.now()}`,\n createdAt: now,\n updatedAt: now,\n };\n await this.storage.writePersona(fullPersona);\n return fullPersona;\n }\n\n async getPersona(): Promise<L3Persona | null> {\n return this.storage.readPersona();\n }\n\n // ========== Recall ==========\n\n async recallMemories(query: string, sessionKey: string, userId: string, agentId: string, topK?: number): Promise<RecallResult> {\n return this.recall.recall({ query, sessionKey, userId, agentId, topK });\n }\n}\n", "/**\n * Vector Store - Embedding-based semantic search\n *\n * Uses OpenClaw's embedding provider for L1 semantic search.\n * Supports hybrid search: vector + BM25 + entity boost.\n */\n\nimport type { EmbeddingProvider } from \"openclaw/plugin-sdk/embedding-providers\";\n\nexport interface VectorRecord {\n id: string;\n content: string;\n embedding: number[];\n metadata: Record<string, unknown>;\n createdAt: number;\n}\n\nexport interface SearchResult {\n id: string;\n content: string;\n score: number;\n metadata: Record<string, unknown>;\n}\n\nexport interface HybridSearchOptions {\n query: string;\n queryEmbedding?: number[];\n topK: number;\n semanticWeight: number;\n bm25Weight: number;\n entityBoostWeight: number;\n minScore?: number;\n}\n\n// ============================================================================\n// Simple in-memory vector store (production would use SQLite FTS5)\n// ============================================================================\n\nexport class VectorStore {\n private records: Map<string, VectorRecord> = new Map();\n private embeddingProvider: EmbeddingProvider | null = null;\n private dimension: number = 384;\n\n constructor(dimension: number = 384) {\n this.dimension = dimension;\n }\n\n setEmbeddingProvider(provider: EmbeddingProvider): void {\n this.embeddingProvider = provider;\n }\n\n // ========== Record Operations ==========\n\n async add(record: Omit<VectorRecord, \"createdAt\">): Promise<VectorRecord> {\n const fullRecord: VectorRecord = {\n ...record,\n createdAt: Date.now(),\n };\n this.records.set(record.id, fullRecord);\n return fullRecord;\n }\n\n async get(id: string): Promise<VectorRecord | null> {\n return this.records.get(id) ?? null;\n }\n\n async delete(id: string): Promise<boolean> {\n return this.records.delete(id);\n }\n\n async update(id: string, updates: Partial<VectorRecord>): Promise<VectorRecord | null> {\n const existing = this.records.get(id);\n if (!existing) return null;\n\n const updated = { ...existing, ...updates };\n this.records.set(id, updated);\n return updated;\n }\n\n // ========== Embedding Operations ==========\n\n async embedContent(content: string): Promise<number[]> {\n if (!this.embeddingProvider) {\n // Fallback: generate simple hash-based pseudo-embedding\n return this.fallbackEmbed(content);\n }\n\n try {\n const embedding = await this.embeddingProvider.embed(content, { inputType: \"query\" });\n return embedding;\n } catch (error) {\n console.error(\"Embedding failed, using fallback:\", error);\n return this.fallbackEmbed(content);\n }\n }\n\n async embedBatch(contents: string[]): Promise<number[][]> {\n if (!this.embeddingProvider) {\n return contents.map(c => this.fallbackEmbed(c));\n }\n\n try {\n return await this.embeddingProvider.embedBatch(contents, { inputType: \"document\" });\n } catch (error) {\n console.error(\"Batch embedding failed, using fallback:\", error);\n return contents.map(c => this.fallbackEmbed(c));\n }\n }\n\n // Fallback pseudo-embedding using hash (for testing without API)\n private fallbackEmbed(content: string): number[] {\n return this.generatePseudoEmbedding(content);\n }\n\n /**\n * Generate pseudo-embedding from text content.\n * Used as fallback when no embedding provider is available.\n */\n generatePseudoEmbedding(content: string): number[] {\n const embedding = new Array(this.dimension).fill(0);\n let hash = 0;\n for (let i = 0; i < content.length; i++) {\n hash = ((hash << 5) - hash) + content.charCodeAt(i);\n hash = hash & hash;\n }\n\n // Seed random with hash for reproducibility\n const seed = Math.abs(hash);\n for (let i = 0; i < this.dimension; i++) {\n // Simple pseudo-random based on content\n const charCode = content.charCodeAt(i % content.length) || 1;\n embedding[i] = Math.sin(seed * (i + 1) * charCode) * 0.5 + 0.5;\n }\n\n // Normalize\n const magnitude = Math.sqrt(embedding.reduce((sum, v) => sum + v * v, 0));\n if (magnitude > 0) {\n for (let i = 0; i < embedding.length; i++) {\n embedding[i] /= magnitude;\n }\n }\n\n return embedding;\n }\n\n // ========== Vector Search ==========\n\n async searchByVector(\n queryEmbedding: number[],\n topK: number,\n minScore: number = 0.0\n ): Promise<SearchResult[]> {\n const results: SearchResult[] = [];\n\n for (const record of this.records.values()) {\n if (record.embedding.length !== queryEmbedding.length) continue;\n\n const score = this.cosineSimilarity(queryEmbedding, record.embedding);\n if (score >= minScore) {\n results.push({\n id: record.id,\n content: record.content,\n score,\n metadata: record.metadata,\n });\n }\n }\n\n // Sort by score descending\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, topK);\n }\n\n // ========== Hybrid Search ==========\n\n async hybridSearch(\n options: HybridSearchOptions,\n getTextScore: (content: string, query: string) => number = bm25Score\n ): Promise<SearchResult[]> {\n const { query, topK, semanticWeight, bm25Weight, entityBoostWeight, minScore = 0.1 } = options;\n\n // Get query embedding if not provided\n let queryEmbedding = options.queryEmbedding;\n if (!queryEmbedding) {\n queryEmbedding = await this.embedContent(query);\n }\n\n // Semantic search\n const semanticResults = await this.searchByVector(queryEmbedding, topK * 2, 0.0);\n\n // BM25 search (simple in-memory version)\n const bm25Results = this.bm25Search(query, topK * 2);\n\n // Entity boost (extract entities and boost matches)\n const entities = this.extractEntities(query);\n const entityBoostResults = this.entityBoostSearch(entities, topK * 2);\n\n // Merge scores\n const scoreMap = new Map<string, SearchResult>();\n\n for (const result of semanticResults) {\n const semanticScore = result.score * semanticWeight;\n scoreMap.set(result.id, {\n id: result.id,\n content: result.content,\n score: semanticScore,\n metadata: result.metadata,\n });\n }\n\n for (const result of bm25Results) {\n const existing = scoreMap.get(result.id);\n const bm25Contribution = result.score * bm25Weight;\n if (existing) {\n existing.score += bm25Contribution;\n } else {\n scoreMap.set(result.id, {\n id: result.id,\n content: result.content,\n score: bm25Contribution,\n metadata: result.metadata,\n });\n }\n }\n\n for (const result of entityBoostResults) {\n const existing = scoreMap.get(result.id);\n const boostContribution = result.score * entityBoostWeight;\n if (existing) {\n existing.score += boostContribution;\n } else {\n scoreMap.set(result.id, {\n id: result.id,\n content: result.content,\n score: boostContribution,\n metadata: result.metadata,\n });\n }\n }\n\n // Filter and sort\n const finalResults = Array.from(scoreMap.values())\n .filter(r => r.score >= minScore)\n .sort((a, b) => b.score - a.score)\n .slice(0, topK);\n\n return finalResults;\n }\n\n // ========== BM25 (in-memory simplified) ==========\n\n private bm25Search(query: string, topK: number): SearchResult[] {\n const queryTerms = query.toLowerCase().split(/\\s+/);\n const results: SearchResult[] = [];\n const avgDocLen = this.getAverageDocLength();\n const k1 = 1.5;\n const b = 0.75;\n\n for (const record of this.records.values()) {\n const terms = record.content.toLowerCase().split(/\\s+/);\n let score = 0;\n\n for (const term of queryTerms) {\n const tf = terms.filter(t => t === term).length;\n if (tf > 0) {\n // Simplified IDF (in production, calculate from corpus)\n const idf = Math.log((this.records.size + 1) / 2);\n const docLen = terms.length;\n const numerator = tf * (k1 + 1);\n const denominator = tf + k1 * (1 - b + b * (docLen / avgDocLen));\n score += idf * (numerator / denominator);\n }\n }\n\n if (score > 0) {\n results.push({\n id: record.id,\n content: record.content,\n score,\n metadata: record.metadata,\n });\n }\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, topK);\n }\n\n private getAverageDocLength(): number {\n if (this.records.size === 0) return 1;\n let total = 0;\n for (const record of this.records.values()) {\n total += record.content.split(/\\s+/).length;\n }\n return total / this.records.size;\n }\n\n // ========== Entity Extraction & Boost ==========\n\n private extractEntities(query: string): string[] {\n // Simple entity extraction (in production use NER)\n const entities: string[] = [];\n\n // Capitalized words (potential entities)\n const capitalizedPattern = /[A-Z][a-z]+/g;\n let match;\n while ((match = capitalizedPattern.exec(query)) !== null) {\n entities.push(match[0].toLowerCase());\n }\n\n // Quoted strings\n const quotedPattern = /\"([^\"]+)\"|'([^']+)'/g;\n while ((match = quotedPattern.exec(query)) !== null) {\n const entity = match[1] || match[2];\n entities.push(entity.toLowerCase());\n }\n\n return [...new Set(entities)];\n }\n\n private entityBoostSearch(entities: string[], topK: number): SearchResult[] {\n if (entities.length === 0) return [];\n\n const results: SearchResult[] = [];\n\n for (const record of this.records.values()) {\n const content = record.content.toLowerCase();\n let matchCount = 0;\n\n for (const entity of entities) {\n if (content.includes(entity)) {\n matchCount++;\n }\n }\n\n if (matchCount > 0) {\n // Score based on how many entities matched\n const score = matchCount / entities.length;\n results.push({\n id: record.id,\n content: record.content,\n score,\n metadata: record.metadata,\n });\n }\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, topK);\n }\n\n // ========== Utilities ==========\n\n private cosineSimilarity(a: number[], b: number[]): number {\n if (a.length !== b.length) return 0;\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n const denominator = Math.sqrt(normA) * Math.sqrt(normB);\n if (denominator === 0) return 0;\n\n return dotProduct / denominator;\n }\n\n async getAll(): Promise<VectorRecord[]> {\n return Array.from(this.records.values());\n }\n\n async count(): Promise<number> {\n return this.records.size;\n }\n\n async clear(): Promise<void> {\n this.records.clear();\n }\n}\n\n// BM25 score helper (exposed for external use)\nexport function bm25Score(content: string, query: string): number {\n const queryTerms = query.toLowerCase().split(/\\s+/);\n const terms = content.toLowerCase().split(/\\s+/);\n let score = 0;\n\n for (const term of queryTerms) {\n const tf = terms.filter(t => t === term).length;\n if (tf > 0) {\n // Simplified BM25\n score += 1 + Math.log(1 + tf);\n }\n }\n\n return score;\n}\n", "/**\n * Memory Distillation Pipeline with Storage Integration\n *\n * Reference: TDB (TencentDB-Agent-Memory) L0\u2192L1\u2192L2\u2192L3 distillation model\n *\n * This version integrates with:\n * - OpenClaw LLM runtime for L1 extraction via subagent\n * - Vector store for semantic search\n */\n\nimport type { Engram, EngramKind, MemoryLayer } from \"../index.js\";\nimport { StorageAdapter, MemoryStore, type L0Message, type L1Record, type L2Scene, type L3Persona } from \"../store/storage.js\";\nimport { VectorStore } from \"../vector/vector-store.js\";\n\nexport interface DistillationConfig {\n l1: {\n messageThreshold: number; // Extract after N messages (default: 5)\n idleSeconds: number; // Or after N seconds of idle (default: 60)\n batchSize: number; // Max messages per extraction (default: 10)\n enableDedup: boolean;\n maxMemoriesPerSession: number;\n };\n l2: {\n minIntervalMs: number;\n maxIntervalMs: number;\n topicThreshold: number;\n delayAfterL1Seconds: number;\n };\n l3: {\n conditions: Array<\"explicit_request\" | \"cold_start\" | \"restore\" | \"first_scene\" | \"threshold\">;\n importanceThreshold: number;\n };\n // LLM extraction config\n llm?: {\n provider?: string;\n model?: string;\n };\n}\n\nexport const DEFAULT_DISTILLATION_CONFIG: DistillationConfig = {\n l1: {\n messageThreshold: 5,\n idleSeconds: 60,\n batchSize: 10,\n enableDedup: true,\n maxMemoriesPerSession: 50,\n },\n l2: {\n minIntervalMs: 15 * 60 * 1000,\n maxIntervalMs: 60 * 60 * 1000,\n topicThreshold: 3,\n delayAfterL1Seconds: 90,\n },\n l3: {\n conditions: [\"explicit_request\", \"cold_start\", \"restore\", \"first_scene\", \"threshold\"],\n importanceThreshold: 0.6,\n },\n};\n\n// ============================================================================\n// LLM Prompt Templates (from TDB)\n// ============================================================================\n\nconst L1_EXTRACTION_SYSTEM_PROMPT = `\u4F60\u662F\u4E13\u4E1A\u7684\"\u5DE5\u4F5C\u60C5\u5883\u5207\u5206\u4E0E\u56E2\u961F\u5171\u4EAB\u8BB0\u5FC6\u63D0\u53D6\u4E13\u5BB6\"\u3002\n\u4F60\u7684\u4EFB\u52A1\u662F\u5206\u6790\u5DE5\u4F5C\u6D88\u606F\uFF0C\u5224\u65AD\u5DE5\u4F5C\u60C5\u5883\u5207\u6362\uFF0C\u5E76\u4ECE\u4E2D\u63D0\u53D6\u53EF\u5728\u56E2\u961F\u5185\u5171\u4EAB\u7684\u7ED3\u6784\u5316\u5DE5\u4F5C\u8BB0\u5FC6\u3002\n\n## \u8F93\u51FA\u8981\u6C42\n\n\u4E25\u683C\u6309\u4EE5\u4E0BJSON\u6570\u7EC4\u683C\u5F0F\u8F93\u51FA\uFF0C\u4E0D\u8981\u8F93\u51FA\u4EFB\u4F55\u989D\u5916\u7684 Markdown \u4EE3\u7801\u5757\u4FEE\u9970\u7B26\uFF08\u5982 \\`\\`\\`json\uFF09\u6216\u89E3\u91CA\u6587\u672C\uFF1A\n\n[\n {\n \"scene_name\": \"\u60C5\u5883\u540D\u79F0\uFF08\u7B80\u6D01\uFF0C1-10\u4E2A\u5B57\uFF09\",\n \"memories\": [\n {\n \"content\": \"\u8BB0\u5FC6\u5185\u5BB9\uFF08\u5B8C\u6574\u53E5\u5B50\uFF0C20-200\u5B57\uFF09\",\n \"type\": \"persona | episodic | instruction\",\n \"priority\": \u4F18\u5148\u7EA7(0-100, \u8D8A\u9AD8\u8D8A\u91CD\u8981),\n \"source_message_ids\": [\"\u76F8\u5173\u6D88\u606FID\"],\n \"metadata\": {}\n }\n ]\n }\n]\n\n## Memory Type \u5B9A\u4E49\n\n- **persona**: \u5173\u4E8E\u7528\u6237\u504F\u597D\u3001\u4E60\u60EF\u3001\u5DE5\u4F5C\u65B9\u5F0F\u7684\u8BB0\u5FC6\uFF08\u5982\"\u7528\u6237\u559C\u6B22\u5728\u4E0A\u5348\u5904\u7406\u590D\u6742\u4EFB\u52A1\"\uFF09\n- **episodic**: \u5177\u4F53\u7684\u9879\u76EE\u4E8B\u4EF6\u3001\u51B3\u7B56\u3001\u8BA8\u8BBA\u8981\u70B9\uFF08\u5982\"\u9879\u76EEX\u51B3\u5B9A\u4F7F\u7528\u5FAE\u670D\u52A1\u67B6\u6784\"\uFF09\n- **instruction**: \u7528\u6237\u7684\u660E\u786E\u6307\u4EE4\u6216\u9700\u6C42\uFF08\u5982\"\u7528\u6237\u8981\u6C42\u6BCF\u5468\u4E94\u540C\u6B65\u8FDB\u5EA6\"\uFF09\n\n## \u573A\u666F\u5207\u6362\u5224\u65AD\n\n\u5F53\u51FA\u73B0\u4EE5\u4E0B\u60C5\u51B5\u65F6\uFF0C\u5E94\u8BE5\u5207\u6362\u5230\u65B0\u573A\u666F\uFF1A\n1. \u8BDD\u9898\u53D1\u751F\u5B9E\u8D28\u6027\u53D8\u5316\n2. \u53C2\u4E0E\u4EBA\u5458\u53D1\u751F\u660E\u663E\u53D8\u5316\n3. \u4EFB\u52A1\u76EE\u6807\u53D1\u751F\u5207\u6362\n4. \u65F6\u95F4\u95F4\u9694\u8D85\u8FC730\u5206\u949F`;\n\nfunction formatExtractionPrompt(\n newMessages: L0Message[],\n backgroundMessages: L0Message[],\n previousSceneName: string\n): { systemPrompt: string; userPrompt: string } {\n const bgText = backgroundMessages.length > 0\n ? backgroundMessages\n .map(m => `[${m.id}] [${m.role}] [${new Date(m.timestamp).toISOString()}]: ${m.content}`)\n .join(\"\\n\\n\")\n : \"\u65E0\";\n\n const newText = newMessages\n .map(m => `[${m.id}] [${m.role}] [${new Date(m.timestamp).toISOString()}]: ${m.content}`)\n .join(\"\\n\\n\");\n\n const userPrompt = `**\u8F93\u51FA\u8BED\u8A00**\uFF1A\u6839\u636E\u4E0B\u65B9\"\u5F85\u63D0\u53D6\u7684\u65B0\u6D88\u606F\"\u4E2D user \u53D1\u8A00\u7684\u4E3B\u5BFC\u8BED\u8A00\u4E66\u5199 \\`scene_name\\` \u548C memory \\`content\\`\u3002\n\n\u3010\u4E0A\u4E00\u4E2A\u60C5\u5883\u3011\uFF1A${previousSceneName || \"\u65E0\"}\n\n\u3010\u80CC\u666F\u5BF9\u8BDD\u3011\uFF08\u4EC5\u4F9B\u7406\u89E3\u4E0A\u4E0B\u6587\u63A8\u65AD\u5173\u7CFB/\u65F6\u95F4\uFF0C\u4E25\u7981\u4ECE\u4E2D\u63D0\u53D6\u8BB0\u5FC6\uFF09\uFF1A\n${bgText}\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n\u3010\u5F85\u63D0\u53D6\u7684\u65B0\u6D88\u606F\u3011\uFF08\u52A1\u5FC5\u7ED3\u5408 timestamp \u63A8\u7B97\u65F6\u95F4\uFF0C\u53EA\u4ECE\u8FD9\u91CC\u63D0\u53D6\u8BB0\u5FC6\uFF01\uFF09\uFF1A\n${newText}`;\n\n return {\n systemPrompt: L1_EXTRACTION_SYSTEM_PROMPT,\n userPrompt,\n };\n}\n\n// ============================================================================\n// Pipeline with Storage Integration\n// ============================================================================\n\nexport class DistillationPipeline {\n private config: DistillationConfig;\n private store: MemoryStore;\n private vectorStore: VectorStore;\n private llmRunner?: (systemPrompt: string, userPrompt: string) => Promise<string>;\n private subagentRunner?: (message: string) => Promise<string>;\n\n private lastL1At: number | null = null;\n private lastL2At: number | null = null;\n private lastL3At: number | null = null;\n\n private pendingL1Extraction: ReturnType<typeof setTimeout> | null = null;\n\n // In-memory buffers (TDB uses VectorStore + JSONL)\n private messageBuffer: L0Message[] = [];\n\n constructor(\n config: DistillationConfig = DEFAULT_DISTILLATION_CONFIG,\n store?: MemoryStore,\n vectorStore?: VectorStore,\n llmRunner?: (systemPrompt: string, userPrompt: string) => Promise<string>\n ) {\n this.config = config;\n this.store = store || new MemoryStore();\n this.vectorStore = vectorStore || new VectorStore();\n this.llmRunner = llmRunner;\n }\n\n /**\n * Set LLM runner for simple prompt-completion style extraction\n */\n setLLMRunner(runner: (systemPrompt: string, userPrompt: string) => Promise<string>): void {\n this.llmRunner = runner;\n }\n\n /**\n * Set subagent runner for L1 extraction via OpenClaw subagent runtime\n */\n setSubagentRunner(runner: (message: string) => Promise<string>): void {\n this.subagentRunner = runner;\n }\n\n /**\n * Set vector store for embedding-based search\n */\n setVectorStore(store: VectorStore): void {\n this.vectorStore = store;\n }\n\n // ============================================================================\n // Ingestion (L0)\n // ============================================================================\n\n /**\n * Ingest messages into L0 layer (TDB's captureAtomic pattern)\n */\n async ingest(messages: Array<Omit<L0Message, \"id\" | \"recordedAt\">>): Promise<L0Message[]> {\n const records: L0Message[] = [];\n\n for (const msg of messages) {\n // Quality gate\n if (!shouldExtractL1(msg.content)) continue;\n\n const record = await this.store.ingestMessage(msg);\n records.push(record);\n this.messageBuffer.push(record);\n }\n\n // Check L1 trigger\n if (this.messageBuffer.length >= this.config.l1.messageThreshold) {\n await this.triggerL1Extraction();\n } else {\n this.scheduleL1Extraction();\n }\n\n return records;\n }\n\n private scheduleL1Extraction(): void {\n if (this.pendingL1Extraction) return;\n\n this.pendingL1Extraction = setTimeout(async () => {\n this.pendingL1Extraction = null;\n if (this.messageBuffer.length > 0) {\n await this.distill(\"L1\");\n }\n }, this.config.l1.idleSeconds * 1000);\n }\n\n private async triggerL1Extraction(): Promise<void> {\n if (this.pendingL1Extraction) {\n clearTimeout(this.pendingL1Extraction);\n this.pendingL1Extraction = null;\n }\n\n await this.distill(\"L1\");\n }\n\n // ============================================================================\n // Distillation\n // ============================================================================\n\n async distill(stage: MemoryLayer): Promise<{ stage: MemoryLayer; produced: number; errors: string[] }> {\n switch (stage) {\n case \"L1\":\n return this.runL1Distillation();\n case \"L2\":\n return this.runL2Distillation();\n case \"L3\":\n return this.runL3Distillation();\n default:\n return { stage, produced: 0, errors: [\"Unknown stage\"] };\n }\n }\n\n /**\n * L1 Distillation: Extract atomic memories from L0 messages\n * (Reference: TDB's extractL1Memories)\n */\n private async runL1Distillation(): Promise<{ stage: MemoryLayer; produced: number; errors: string[] }> {\n const errors: string[] = [];\n let produced = 0;\n\n try {\n // Get batch of messages\n const messages = this.messageBuffer.slice(-this.config.l1.batchSize);\n if (messages.length === 0) {\n return { stage: \"L1\", produced: 0, errors: [] };\n }\n\n // Get previous scene name for continuity\n const lastScene = await this.getLastSceneName();\n\n // Split into new + background\n const maxNew = 5;\n const newMessages = messages.slice(-maxNew);\n const backgroundMessages = messages.slice(0, -maxNew);\n\n // Format prompt\n const { systemPrompt, userPrompt } = formatExtractionPrompt(\n newMessages,\n backgroundMessages,\n lastScene\n );\n\n // Call LLM via subagent runner, llmRunner, or use fallback\n let extractionOutput = \"\";\n if (this.subagentRunner) {\n // Use OpenClaw subagent runtime for LLM extraction\n const fullPrompt = `${systemPrompt}\\n\\n${userPrompt}`;\n extractionOutput = await this.subagentRunner(fullPrompt);\n } else if (this.llmRunner) {\n extractionOutput = await this.llmRunner(systemPrompt, userPrompt);\n } else {\n extractionOutput = this.fallbackExtract(messages, lastScene);\n }\n\n // Parse output\n const extractedMemories = parseExtractionOutput(extractionOutput);\n\n // Store L1 records\n for (const mem of extractedMemories) {\n await this.store.storeL1({\n content: mem.content,\n type: mem.type,\n priority: mem.priority,\n sceneName: mem.scene_name,\n sourceMessageIds: mem.source_message_ids,\n metadata: mem.metadata,\n timestamps: messages.map(m => new Date(m.timestamp).toISOString()),\n sessionKey: messages[0]?.sessionKey || \"default\",\n sessionId: messages[0]?.sessionId || \"\",\n teamId: messages[0]?.teamId,\n userId: messages[0]?.userId || \"\",\n agentId: messages[0]?.agentId || \"\",\n });\n produced++;\n }\n\n // Clear processed messages\n this.messageBuffer = this.messageBuffer.slice(0, Math.max(0, this.messageBuffer.length - messages.length));\n\n this.lastL1At = Date.now();\n\n // Schedule L2 after L1 completes (TDB's delayAfterL1Seconds)\n setTimeout(() => this.distill(\"L2\"), this.config.l2.delayAfterL1Seconds * 1000);\n\n } catch (e) {\n errors.push(String(e));\n }\n\n return { stage: \"L1\", produced, errors };\n }\n\n private async getLastSceneName(): Promise<string> {\n // Try to get from L1 records\n const recent = await this.store.searchL1(\"\", 1);\n return recent[0]?.sceneName || \"\u65E0\";\n }\n\n /**\n * L2 Distillation: Cluster L1 memories into scene blocks\n * (Reference: TDB's SceneExtractor)\n */\n private async runL2Distillation(): Promise<{ stage: MemoryLayer; produced: number; errors: string[] }> {\n const errors: string[] = [];\n let produced = 0;\n\n try {\n // Check time constraints\n const now = Date.now();\n if (this.lastL2At && now - this.lastL2At < this.config.l2.minIntervalMs) {\n return { stage: \"L2\", produced: 0, errors: [\"Too soon since last L2\"] };\n }\n\n // Search all L1 records\n const l1Records = await this.store.searchL1(\"\", 100);\n if (l1Records.length < this.config.l2.topicThreshold) {\n return { stage: \"L2\", produced: 0, errors: [\"Not enough L1 records\"] };\n }\n\n // Group by scene name\n const sceneGroups = new Map<string, typeof l1Records>();\n for (const record of l1Records) {\n if (!sceneGroups.has(record.sceneName)) {\n sceneGroups.set(record.sceneName, []);\n }\n sceneGroups.get(record.sceneName)!.push(record);\n }\n\n // Create scene blocks\n for (const [sceneName, records] of sceneGroups) {\n if (records.length < this.config.l2.topicThreshold) continue;\n\n const avgPriority = records.reduce((sum, r) => sum + r.priority, 0) / records.length;\n const content = this.buildSceneContent(sceneName, records);\n\n await this.store.storeL2({\n title: sceneName,\n content,\n summary: `\u5E73\u5747\u4F18\u5148\u7EA7: ${avgPriority.toFixed(0)}`,\n tags: [sceneName],\n metadata: {\n layer: \"L2\" as const,\n heat: records.length,\n sourceRecords: records.map(r => r.id),\n },\n });\n produced++;\n }\n\n this.lastL2At = now;\n\n // Schedule L3 after L2\n setTimeout(() => this.distill(\"L3\"), 5000);\n\n } catch (e) {\n errors.push(String(e));\n }\n\n return { stage: \"L2\", produced, errors };\n }\n\n private buildSceneContent(sceneName: string, records: L1Record[]): string {\n const points = records.map(r => `- [${r.type}] ${r.content}`).join(\"\\n\");\n const avgPriority = records.reduce((sum, r) => sum + r.priority, 0) / records.length;\n\n return `# ${sceneName}\n\n## Key Points\n${points}\n\n## Summary\n\u5E73\u5747\u4F18\u5148\u7EA7: ${avgPriority.toFixed(0)}\n\u5171 ${records.length} \u6761\u76F8\u5173\u8BB0\u5FC6\n\n---\nGenerated: ${new Date().toISOString()}\n`;\n }\n\n /**\n * L3 Distillation: Build persona from high-value scenes\n * (Reference: TDB's PersonaExtractor)\n */\n private async runL3Distillation(): Promise<{ stage: MemoryLayer; produced: number; errors: string[] }> {\n const errors: string[] = [];\n let produced = 0;\n\n try {\n // Check if threshold met\n const l1Records = await this.store.searchL1(\"\", 100);\n if (l1Records.length === 0) {\n return { stage: \"L3\", produced: 0, errors: [\"No L1 records\"] };\n }\n\n const avgImportance = l1Records.reduce((sum, r) => sum + r.priority, 0) / l1Records.length / 100;\n if (avgImportance < this.config.l3.importanceThreshold) {\n return { stage: \"L3\", produced: 0, errors: [\"Avg importance below threshold\"] };\n }\n\n // Get high-value scenes\n const sceneIndex = await this.store.getSceneIndex();\n const highValueScenes = sceneIndex.filter(s => {\n const avg = l1Records\n .filter(r => r.sceneName === s.title)\n .reduce((sum, r) => sum + r.priority, 0) / Math.max(1, l1Records.filter(r => r.sceneName === s.title).length);\n return avg >= this.config.l3.importanceThreshold * 100;\n });\n\n if (highValueScenes.length === 0) {\n return { stage: \"L3\", produced: 0, errors: [\"No high-value scenes\"] };\n }\n\n // Build persona\n const personaContent = this.buildPersona(highValueScenes, l1Records);\n\n await this.store.storeL3({\n content: personaContent,\n summary: \"Agent Self-Model\",\n metadata: {\n layer: \"L3\" as const,\n sourceScenes: highValueScenes.map(s => s.id),\n },\n });\n\n produced = 1;\n this.lastL3At = Date.now();\n\n } catch (e) {\n errors.push(String(e));\n }\n\n return { stage: \"L3\", produced, errors };\n }\n\n private buildPersona(\n scenes: Array<{ id: string; title: string; summary: string }>,\n l1Records: L1Record[]\n ): string {\n const sceneContents = scenes.map(scene => {\n const relatedMemories = l1Records.filter(r => r.sceneName === scene.title);\n return `### ${scene.title}\\n${relatedMemories.map(m => `- ${m.content}`).join(\"\\n\")}`;\n }).join(\"\\n\\n\");\n\n const avgImportance = l1Records.reduce((sum, r) => sum + r.priority, 0) / l1Records.length / 100;\n\n return `# Agent Self-Model\n\n## Core Knowledge\n${sceneContents}\n\n## Behavioral Patterns\n- \u5171 ${scenes.length} \u4E2A\u9AD8\u4EF7\u503C\u573A\u666F\n- \u5E73\u5747\u91CD\u8981\u6027: ${avgImportance.toFixed(2)}\n\n## Preferences\n(\u4ECE persona \u7C7B\u578B\u8BB0\u5FC6\u4E2D\u63D0\u53D6)\n\n## Communication Style\n(\u4ECE\u4EA4\u4E92\u6A21\u5F0F\u4E2D\u5B66\u4E60)\n\n---\nGenerated: ${new Date().toISOString()}\n`;\n }\n\n // ============================================================================\n // Utilities\n // ============================================================================\n\n private fallbackExtract(messages: L0Message[], previousSceneName: string): string {\n const contents = messages.map(m => m.content).join(\"\\n\");\n const facts: string[] = [];\n\n // Simple patterns\n const patterns = [\n /(?:decided|\u51B3\u5B9A)(.+)/gi,\n /(?:learned|\u5B66\u4E60)(.+)/gi,\n /(?:remember|\u8BB0\u4F4F)(.+)/gi,\n ];\n\n for (const pattern of patterns) {\n let match;\n while ((match = pattern.exec(contents)) !== null) {\n facts.push(match[1].trim());\n }\n }\n\n if (facts.length === 0 && messages[0]) {\n const content = messages[0].content;\n if (content.length > 20) {\n facts.push(content.slice(0, 100));\n }\n }\n\n const sceneName = previousSceneName || \"General\";\n\n return JSON.stringify([{\n scene_name: sceneName,\n memories: facts.slice(0, 3).map((content, i) => ({\n content,\n type: \"episodic\",\n priority: 50 + i * 10,\n source_message_ids: [messages[0]?.id || \"unknown\"],\n metadata: {},\n })),\n }]);\n }\n\n checkTriggers(): { l1: boolean; l2: boolean; l3: boolean } {\n const now = Date.now();\n\n return {\n l1: this.messageBuffer.length >= this.config.l1.messageThreshold,\n l2: this.lastL2At ? now - this.lastL2At >= this.config.l2.minIntervalMs : this.messageBuffer.length >= this.config.l2.topicThreshold,\n l3: this.lastL3At === null,\n };\n }\n\n async getStats(): Promise<{\n l0Count: number;\n l1Count: number;\n l2Count: number;\n l3Count: number;\n }> {\n const l1Records = await this.store.searchL1(\"\", 1000);\n const l2Scenes = await this.store.getSceneIndex();\n const persona = await this.store.getPersona();\n\n return {\n l0Count: this.messageBuffer.length,\n l1Count: l1Records.length,\n l2Count: l2Scenes.length,\n l3Count: persona ? 1 : 0,\n };\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction shouldExtractL1(content: string): boolean {\n if (content.length < 10) return false;\n if (content.length > 10000) return false;\n return true;\n}\n\ninterface ExtractedMemory {\n content: string;\n type: \"persona\" | \"episodic\" | \"instruction\";\n priority: number;\n source_message_ids: string[];\n metadata: Record<string, unknown>;\n scene_name: string;\n}\n\nfunction parseExtractionOutput(output: string): ExtractedMemory[] {\n try {\n const jsonMatch = output.match(/\\[[\\s\\S]*\\]/);\n if (!jsonMatch) {\n const objMatch = output.match(/\\{[\\s\\S]*\\}/);\n if (objMatch) {\n return JSON.parse(objMatch[0]);\n }\n return [];\n }\n\n const parsed = JSON.parse(jsonMatch[0]);\n\n if (parsed.scene_name) {\n return (parsed.memories || []).map((m: any) => ({\n content: m.content,\n type: normalizeMemoryType(m.type),\n priority: Math.min(100, Math.max(0, Number(m.priority) || 50)),\n source_message_ids: Array.isArray(m.source_message_ids) ? m.source_message_ids : [],\n metadata: m.metadata || {},\n scene_name: parsed.scene_name,\n }));\n }\n\n const memories: ExtractedMemory[] = [];\n for (const scene of parsed) {\n for (const m of scene.memories || []) {\n memories.push({\n content: m.content,\n type: normalizeMemoryType(m.type),\n priority: Math.min(100, Math.max(0, Number(m.priority) || 50)),\n source_message_ids: Array.isArray(m.source_message_ids) ? m.source_message_ids : [],\n metadata: m.metadata || {},\n scene_name: scene.scene_name,\n });\n }\n }\n return memories;\n } catch (e) {\n console.error(\"Failed to parse LLM output:\", e);\n return [];\n }\n}\n\nfunction normalizeMemoryType(type: string): \"persona\" | \"episodic\" | \"instruction\" {\n const t = type?.toLowerCase();\n if (t === \"persona\" || t === \"episodic\" || t === \"instruction\") {\n return t as \"persona\" | \"episodic\" | \"instruction\";\n }\n return \"episodic\";\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Memory New - OpenClaw Memory Plugin\n *\n * Complete implementation with storage and distillation pipeline integration.\n * - L0\u2192L1\u2192L2\u2192L3 distillation (TDB model)\n * - Persistent storage (JSONL + Markdown)\n * - Recall engine for prompt injection\n * - Team memory with visibility ACL\n * - Decay mechanisms\n */\n\nimport { definePluginEntry, type OpenClawPluginApi } from \"openclaw/plugin-sdk/plugin-entry\";\nimport { MemoryStore, StorageAdapter, RecallEngine, type L0Message } from \"./src/store/storage.js\";\nimport { DistillationPipeline, DEFAULT_DISTILLATION_CONFIG } from \"./src/pipeline/distillation.js\";\nimport { VectorStore } from \"./src/vector/vector-store.js\";\nimport type { EmbeddingProvider } from \"openclaw/plugin-sdk/embedding-providers\";\n\n// ============================================================================\n// Types & Interfaces\n// ============================================================================\n\n// 4 orthogonal axes (from Co-Engram research)\nexport type EngramKind = \"observation\" | \"fact\" | \"pattern\" | \"procedure\" | \"hypothesis\";\nexport type EngramStatus = \"draft\" | \"active\" | \"frozen\" | \"forgotten\";\nexport type EngramVisibility = \"public\" | \"team\" | \"private\" | \"restricted\";\nexport type VerificationStatus = \"unverified\" | \"plausible\" | \"probable\" | \"verified\" | \"refuted\";\n\n// Disclosure tiers for progressive reveal\nexport type DisclosureTier = \"catalog\" | \"digest\" | \"content\" | \"meta\" | \"synapses\";\n\n// Memory layer (from TDB research: L0 raw \u2192 L1 atomic \u2192 L2 scene \u2192 L3 persona)\nexport type MemoryLayer = \"L0\" | \"L1\" | \"L2\" | \"L3\";\n\n// Core engram interface\nexport interface Engram {\n id: string;\n kind: EngramKind;\n status: EngramStatus;\n visibility: EngramVisibility;\n verification: VerificationStatus;\n\n // Content\n content: string;\n summary?: string;\n title?: string;\n\n // Importance & dynamics\n importance: number;\n lastEffectiveAt: number;\n\n // Metadata\n metadata: Record<string, unknown>;\n tags: string[];\n contextTags: string[];\n\n // Provenance\n source: string;\n createdAt: number;\n updatedAt: number;\n createdBy: string;\n trustLevel: TrustLevel;\n\n // Relations\n synapses: Synapse[];\n}\n\nexport type TrustLevel = \"direct\" | \"external\" | \"automated\" | \"proposal\";\n\n// Synapse: relationship between engrams\nexport interface Synapse {\n targetId: string;\n strength: number;\n type: \"supports\" | \"contradicts\" | \"references\" | \"refines\";\n}\n\n// Search result\nexport interface SearchResult {\n engram: Engram;\n score: number;\n tier: DisclosureTier;\n matchedOn: string[];\n fromAgentId?: string;\n}\n\n// Configuration\nexport interface MemoryNewConfig {\n enabled: boolean;\n\n // Memory layers\n layersEnabled: {\n L0: boolean;\n L1: boolean;\n L2: boolean;\n L3: boolean;\n };\n\n // Decay mechanisms\n decay: {\n ttl: {\n enabled: boolean;\n retentionDays: number;\n safetyThreshold: number;\n minRetainL0: number;\n minRetainL1: number;\n };\n importance: {\n enabled: boolean;\n baseHalflifeDays: number;\n };\n accessFrequency: {\n enabled: boolean;\n };\n stateMachine: {\n enabled: boolean;\n };\n };\n\n // Team memory\n teamMemory: {\n enabled: boolean;\n maxImportedAgents: number;\n visibilityGate: boolean;\n };\n\n // Retrieval\n retrieval: {\n hybridSearch: boolean;\n semanticWeight: number;\n bm25Weight: number;\n entityBoostWeight: number;\n topK: number;\n overFetch: number;\n };\n\n // Storage\n storage: {\n backend: \"sqlite\" | \"memory\";\n dataDir: string;\n };\n\n // LLM for extraction\n llm?: {\n enabled: boolean;\n model?: string;\n };\n}\n\n// Default config\nconst DEFAULT_CONFIG: MemoryNewConfig = {\n enabled: true,\n layersEnabled: { L0: true, L1: true, L2: true, L3: false },\n decay: {\n ttl: { enabled: true, retentionDays: 30, safetyThreshold: 0.8, minRetainL0: 50, minRetainL1: 20 },\n importance: { enabled: true, baseHalflifeDays: 50 },\n accessFrequency: { enabled: true },\n stateMachine: { enabled: true },\n },\n teamMemory: {\n enabled: true,\n maxImportedAgents: 2,\n visibilityGate: true,\n },\n retrieval: {\n hybridSearch: true,\n semanticWeight: 0.5,\n bm25Weight: 0.25,\n entityBoostWeight: 0.25,\n topK: 10,\n overFetch: 4,\n },\n storage: {\n backend: \"memory\",\n dataDir: \"~/.openclaw/memory-new\",\n },\n llm: {\n enabled: false, // Disabled by default, use fallback extraction\n model: \"default\",\n },\n};\n\n// ============================================================================\n// Core Functions\n// ============================================================================\n\n// Freshness derivation (Ebbinghaus curve, from Co-Engram research)\nfunction deriveFreshness(engram: Engram, config: MemoryNewConfig): \"fresh\" | \"aging\" | \"stale\" | \"forgotten\" {\n if (!config.decay.importance.enabled) return \"fresh\";\n\n const ageDays = (Date.now() - engram.lastEffectiveAt) / (1000 * 60 * 60 * 24);\n const halflife = config.decay.importance.baseHalflifeDays * Math.pow(engram.importance + 0.1, 1.5);\n\n if (ageDays <= halflife) return \"fresh\";\n if (ageDays <= halflife * 2) return \"aging\";\n if (ageDays <= halflife * 4) return \"stale\";\n return \"forgotten\";\n}\n\n// Hotness derivation (from Co-Engram research)\nfunction deriveHotness(retrievalCount: number, ageDays: number): number {\n return 1 / (1 + Math.exp(-Math.log(1 + retrievalCount))) * Math.exp(-Math.LN2 * ageDays / 7);\n}\n\n// 5-factor scoring\nfunction calculateScore(\n relevance: number,\n recency: number,\n importance: number,\n strength: number,\n hotness: number,\n weights = { relevance: 0.50, recency: 0.15, importance: 0.25, strength: 0.05, hotness: 0.05 }\n): number {\n return (\n weights.relevance * relevance +\n weights.recency * recency +\n weights.importance * importance +\n weights.strength * strength +\n weights.hotness * hotness\n );\n}\n\n// Visibility gate (from Co-Engram research)\nfunction validateVisibilityTransition(\n from: EngramVisibility,\n to: EngramVisibility,\n config: MemoryNewConfig\n): boolean {\n if (!config.teamMemory.visibilityGate) return true;\n if (from === to) return true;\n if (to === \"private\" && from !== \"private\") return false;\n if (from === \"private\") return true;\n return true;\n}\n\n// Generate unique ID\nfunction genId(): string {\n return `engram_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\n}\n\n// ============================================================================\n// Memory Plugin\n// ============================================================================\n\nexport default definePluginEntry({\n id: \"memory_new\",\n name: \"Memory New\",\n description: \"Multi-layered memory system with L0\u2192L1\u2192L2\u2192L3 distillation, persistent storage, and recall\",\n\n register(api: OpenClawPluginApi) {\n const config = (api.pluginConfig ?? DEFAULT_CONFIG) as MemoryNewConfig;\n\n // Ensure storage config exists\n const storageConfig = config.storage ?? { backend: \"memory\", dataDir: \"~/.openclaw/memory-new\" };\n\n // Initialize storage\n const storage = new StorageAdapter(storageConfig.dataDir);\n const store = new MemoryStore(storageConfig.dataDir);\n const recall = new RecallEngine(storage);\n\n // Initialize vector store for semantic search\n const vectorStore = new VectorStore();\n\n // Initialize distillation pipeline\n const pipeline = new DistillationPipeline(DEFAULT_DISTILLATION_CONFIG, store, vectorStore);\n\n // Wire up vector store to memory store\n store.setVectorStore(vectorStore);\n\n // Register embedding provider for vector search (if LLM enabled)\n if (config.llm?.enabled) {\n // Register our built-in embedding provider adapter\n api.registerEmbeddingProvider({\n id: \"memory-new-embedder\",\n defaultModel: config.llm.model ?? \"default\",\n transport: \"local\",\n create: async (options) => {\n // Create a simple hash-based embedder when no real provider is available\n const provider: EmbeddingProvider = {\n id: \"memory-new-embedder\",\n model: options.model,\n dimensions: 384,\n maxInputTokens: 8192,\n embed: async (input) => {\n const text = typeof input === \"string\" ? input : input.text;\n return vectorStore.generatePseudoEmbedding(text);\n },\n embedBatch: async (inputs) => {\n return inputs.map(input => {\n const text = typeof input === \"string\" ? input : input.text;\n return vectorStore.generatePseudoEmbedding(text);\n });\n },\n };\n return { provider, runtime: { id: \"memory-new-embedder\" } };\n },\n });\n\n // Set up subagent runner for LLM extraction\n pipeline.setSubagentRunner(async (prompt: string) => {\n try {\n const result = await api.runtime.subagent.run({\n sessionKey: `memory-${Date.now()}`,\n message: prompt,\n model: config.llm?.model,\n disableTools: true,\n });\n // Wait for completion\n const waitResult = await api.runtime.subagent.waitForRun({ runId: result.runId, timeoutMs: 30000 });\n // Get session messages to extract response\n const messages = await api.runtime.subagent.getSessionMessages({ sessionKey: result.sessionKey! });\n // Find assistant response\n const assistantMsg = messages.messages.find((m: any) => m.role === \"assistant\");\n return assistantMsg?.content?.[0]?.text ?? \"\";\n } catch (error) {\n api.logger.debug?.(`Subagent extraction failed: ${error}`);\n throw error;\n }\n });\n }\n\n // Track session messages for L0\n const sessionMessages = new Map<string, any[]>();\n\n // =========================================================================\n // Commands\n // =========================================================================\n\n api.registerCommand({\n name: \"mem\",\n description: \"Interact with memory system (L0\u2192L1\u2192L2\u2192L3)\",\n acceptsArgs: true,\n exposeSenderIsOwner: true,\n handler: async (ctx) => {\n const args = ctx.args ?? \"\";\n const [action, ...rest] = args.trim().split(/\\s+/);\n\n switch (action) {\n case \"add\": {\n const content = rest.join(\" \");\n if (!content) return { text: \"Usage: mem add <content>\" };\n\n // Store directly to L1\n const now = new Date().toISOString();\n await store.storeL1({\n content,\n type: \"episodic\",\n priority: 50,\n sceneName: \"User Added\",\n sourceMessageIds: [],\n metadata: { source: \"command\" },\n timestamps: [now],\n sessionKey: ctx.sessionKey ?? \"default\",\n sessionId: ctx.sessionKey ?? \"default\",\n userId: ctx.senderIsOwner ? \"owner\" : \"user\",\n agentId: \"self\",\n });\n\n return { text: `Added: ${content.slice(0, 50)}...` };\n }\n\n case \"search\": {\n const query = rest.join(\" \");\n if (!query) return { text: \"Usage: memory search <query>\" };\n\n // Use recall engine for search\n const result = await recall.recall({\n query,\n sessionKey: ctx.sessionKey ?? \"default\",\n userId: ctx.senderIsOwner ? \"owner\" : \"user\",\n agentId: \"self\",\n topK: config.retrieval.topK,\n });\n\n if (!result.prependContext && !result.appendSystemContext) {\n return { text: \"No relevant memories found.\" };\n }\n\n return {\n text: `Found memories:\\n\\n${result.prependContext ?? \"\"}\\n\\n${result.appendSystemContext ?? \"\"}`,\n };\n }\n\n case \"list\": {\n // Get recent L1 records\n const records = await store.searchL1(\"\", 20);\n\n if (records.length === 0) return { text: \"No memories stored.\" };\n\n const lines = records.map(r =>\n `[${r.type}] ${r.content.slice(0, 60)}${r.content.length > 60 ? \"...\" : \"\"}`\n );\n return { text: `Recent ${records.length} memories:\\n\\n${lines.join(\"\\n\")}` };\n }\n\n case \"reinforce\": {\n // Not applicable with new storage model\n return { text: \"Reinforce is not yet supported with persistent storage.\" };\n }\n\n case \"decay\": {\n // Apply decay - placeholder\n return { text: \"Decay is not yet fully implemented.\" };\n }\n\n case \"stats\": {\n const stats = await pipeline.getStats();\n return {\n text: `Memory Stats:\n L0 (buffered): ${stats.l0Count}\n L1 (stored): ${stats.l1Count}\n L2 (scenes): ${stats.l2Count}\n L3 (persona): ${stats.l3Count}`,\n };\n }\n\n case \"config\": {\n return { text: JSON.stringify(config, null, 2) };\n }\n\n default:\n return {\n text: `Memory New commands:\n mem add <content> - Add a memory\n mem search <query> - Search memories\n mem list - List recent memories\n mem stats - Show memory statistics\n mem config - Show configuration\n\nMemory layers: L0 (raw) \u2192 L1 (atomic) \u2192 L2 (scene) \u2192 L3 (persona)`,\n };\n }\n },\n });\n\n // Team memory command\n api.registerCommand({\n name: \"team-mem\",\n description: \"Team memory operations\",\n acceptsArgs: true,\n exposeSenderIsOwner: true,\n handler: async (ctx) => {\n if (!config.teamMemory.enabled) {\n return { text: \"Team memory is disabled.\" };\n }\n\n const args = ctx.args ?? \"\";\n const [action, ...rest] = args.trim().split(/\\s+/);\n\n switch (action) {\n case \"share\": {\n return { text: \"Share is not yet implemented.\" };\n }\n\n case \"import\": {\n return { text: \"Import is not yet implemented.\" };\n }\n\n case \"status\": {\n const stats = await pipeline.getStats();\n return {\n text: `Team memory status:\n Enabled: ${config.teamMemory.enabled}\n Max imported agents: ${config.teamMemory.maxImportedAgents}\n Visibility gate: ${config.teamMemory.visibilityGate}\n Total L1 memories: ${stats.l1Count}\n Total L2 scenes: ${stats.l2Count}`,\n };\n }\n\n default:\n return {\n text: `Team memory commands:\n team-memory status - Show team memory status`,\n };\n }\n },\n });\n\n // =========================================================================\n // Lifecycle Hooks\n // =========================================================================\n\n // before_prompt_build: inject relevant memories\n api.on(\"before_prompt_build\", async (event, ctx) => {\n if (!config.enabled) return undefined;\n\n const sessionKey = ctx.sessionKey ?? \"default\";\n const userId = \"user\"; // Default user\n\n try {\n // Recall relevant memories\n const query = event.prompt?.slice(0, 200) ?? \"\";\n const recallResult = await recall.recall({\n query,\n sessionKey,\n userId,\n agentId: \"self\",\n topK: config.retrieval.topK,\n vectorStore: config.retrieval.hybridSearch ? vectorStore : undefined,\n });\n\n // If no memories, skip\n if (!recallResult.prependContext && !recallResult.appendSystemContext) {\n return undefined;\n }\n\n return {\n prependContext: recallResult.prependContext,\n appendContext: recallResult.appendSystemContext,\n };\n } catch (error) {\n api.logger.debug?.(`Memory recall failed: ${error}`);\n return undefined;\n }\n });\n\n // after_prompt_build: capture messages to L0 (using session_end for cleanup)\n api.on(\"session_end\", async (event, ctx) => {\n if (!config.enabled || !config.layersEnabled.L0) return;\n\n const sessionKey = ctx.sessionKey ?? \"default\";\n\n try {\n // Get messages from event (if available)\n const messages = (event as any).messages ?? [];\n\n if (messages.length > 0) {\n // Ingest messages into L0\n for (const msg of messages) {\n const l0Msg: Omit<L0Message, \"id\" | \"recordedAt\"> = {\n role: msg.role === \"user\" ? \"user\" : \"assistant\",\n content: msg.content?.slice(0, 10000) ?? \"\", // Limit length\n timestamp: msg.timestamp ?? Date.now(),\n sessionKey,\n sessionId: sessionKey,\n userId: \"user\",\n agentId: \"self\",\n };\n\n await store.ingestMessage(l0Msg);\n }\n\n // Trigger L1 extraction if threshold met\n if (config.layersEnabled.L1 && config.llm?.enabled) {\n await pipeline.distill(\"L1\");\n }\n }\n } catch (error) {\n api.logger.debug?.(`Memory capture failed: ${error}`);\n }\n });\n\n // agent_end: process remaining messages\n api.on(\"agent_end\", (event, ctx) => {\n if (!config.enabled) return;\n\n const runId = event.runId ?? ctx.runId;\n api.logger.debug?.(`Memory: agent ended for run ${runId}`);\n });\n\n // session_end: cleanup and final processing\n api.on(\"session_end\", async (event, ctx) => {\n if (!config.enabled) return;\n\n const sessionKey = ctx.sessionKey ?? \"default\";\n\n try {\n // Trigger L2/L3 distillation if enabled\n if (config.layersEnabled.L2) {\n await pipeline.distill(\"L2\");\n }\n if (config.layersEnabled.L3) {\n await pipeline.distill(\"L3\");\n }\n\n // Clear session message buffer\n sessionMessages.delete(sessionKey);\n\n api.logger.debug?.(`Memory: session ended for ${sessionKey}`);\n } catch (error) {\n api.logger.debug?.(`Memory session cleanup failed: ${error}`);\n }\n });\n\n // =========================================================================\n // Tools\n // =========================================================================\n\n api.registerTool({\n name: \"mem_new_search\",\n description: \"Search memory store using hybrid retrieval\",\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query\" },\n limit: { type: \"number\", description: \"Max results\", default: 10 },\n visibility: {\n type: \"string\",\n enum: [\"all\", \"public\", \"team\", \"private\"],\n default: \"all\",\n },\n },\n required: [\"query\"],\n },\n execute: async (params, ctx) => {\n const result = await recall.recall({\n query: params.query,\n sessionKey: ctx.sessionKey ?? \"default\",\n userId: \"user\",\n agentId: \"self\",\n topK: params.limit ?? 10,\n });\n\n return {\n memories: result.recalledL1Memories ?? [],\n prependContext: result.prependContext,\n appendContext: result.appendSystemContext,\n };\n },\n });\n\n api.registerTool({\n name: \"mem_new_store\",\n description: \"Store a new memory engram\",\n parameters: {\n type: \"object\",\n properties: {\n content: { type: \"string\", description: \"Memory content\" },\n type: {\n type: \"string\",\n enum: [\"persona\", \"episodic\", \"instruction\"],\n default: \"episodic\",\n description: \"Memory type\",\n },\n priority: {\n type: \"number\",\n default: 50,\n description: \"Priority 0-100\",\n },\n sceneName: {\n type: \"string\",\n default: \"General\",\n description: \"Scene name\",\n },\n },\n required: [\"content\"],\n },\n execute: async (params, ctx) => {\n const record = await store.storeL1({\n content: params.content,\n type: params.type as \"persona\" | \"episodic\" | \"instruction\" ?? \"episodic\",\n priority: params.priority ?? 50,\n sceneName: params.sceneName ?? \"General\",\n sourceMessageIds: [],\n metadata: { source: \"tool\" },\n timestamps: [new Date().toISOString()],\n sessionKey: ctx.sessionKey ?? \"default\",\n sessionId: ctx.sessionKey ?? \"default\",\n userId: \"user\",\n agentId: \"self\",\n });\n\n return { engramId: record.id, stored: true };\n },\n });\n\n api.registerTool({\n name: \"mem_new_get\",\n description: \"Get a specific memory by ID\",\n parameters: {\n type: \"object\",\n properties: {\n layer: {\n type: \"string\",\n enum: [\"L0\", \"L1\", \"L2\", \"L3\"],\n default: \"L1\",\n description: \"Memory layer\",\n },\n id: { type: \"string\", description: \"Memory ID (for L2/L3)\" },\n },\n required: [],\n },\n execute: async (params, ctx) => {\n if (params.layer === \"L2\" && params.id) {\n const scene = await store.getScene(params.id);\n return scene ?? { error: \"Scene not found\" };\n }\n\n if (params.layer === \"L3\") {\n const persona = await store.getPersona();\n return persona ?? { error: \"Persona not found\" };\n }\n\n // L1 search\n const records = await store.searchL1(\"\", 10);\n return { records };\n },\n });\n\n api.registerTool({\n name: \"mem_new_distill\",\n description: \"Trigger memory distillation manually\",\n parameters: {\n type: \"object\",\n properties: {\n layer: {\n type: \"string\",\n enum: [\"L1\", \"L2\", \"L3\"],\n default: \"L1\",\n description: \"Layer to distill\",\n },\n },\n required: [\"layer\"],\n },\n execute: async (params, ctx) => {\n const layer = params.layer as MemoryLayer;\n const result = await pipeline.distill(layer);\n\n return {\n layer: result.stage,\n produced: result.produced,\n errors: result.errors,\n };\n },\n });\n\n // =========================================================================\n // HTTP Routes (team memory sync - reserved interface)\n // =========================================================================\n\n api.registerHttpRoute({\n method: \"GET\",\n path: \"/memory/team/status\",\n auth: \"none\",\n handler: async (req, ctx) => {\n if (!config.teamMemory.enabled) {\n return { status: 403, body: { error: \"Team memory disabled\" } };\n }\n\n const stats = await pipeline.getStats();\n return {\n status: 200,\n body: {\n enabled: true,\n maxImportedAgents: config.teamMemory.maxImportedAgents,\n l1Count: stats.l1Count,\n l2Count: stats.l2Count,\n },\n };\n },\n });\n\n api.registerHttpRoute({\n method: \"POST\",\n path: \"/memory/team/share\",\n auth: \"none\",\n handler: async (req, ctx) => {\n if (!config.teamMemory.enabled) {\n return { status: 403, body: { error: \"Team memory disabled\" } };\n }\n return { status: 501, body: { error: \"Not implemented\" } };\n },\n });\n\n api.registerHttpRoute({\n method: \"POST\",\n path: \"/memory/team/import\",\n auth: \"none\",\n handler: async (req, ctx) => {\n if (!config.teamMemory.enabled) {\n return { status: 403, body: { error: \"Team memory disabled\" } };\n }\n return { status: 501, body: { error: \"Not implemented\" } };\n },\n });\n\n api.logger.info?.(\"Memory New plugin registered with storage and pipeline\");\n\n // Auto-configure plugin settings when installed\n api.registerConfigMigration?.({\n id: \"memory-new-default-config\",\n migrate: (existingConfig) => {\n const current = existingConfig?.memory_new;\n if (!current) {\n // First install - set defaults\n return {\n memory_new: {\n enabled: true,\n layersEnabled: { L0: true, L1: true, L2: true, L3: false },\n llm: { enabled: false, model: \"default\" },\n retrieval: {\n hybridSearch: true,\n semanticWeight: 0.5,\n bm25Weight: 0.25,\n entityBoostWeight: 0.25,\n topK: 10,\n overFetch: 4,\n },\n storage: { backend: \"memory\", dataDir: \"~/.openclaw/memory-new\" },\n decay: {\n ttl: { enabled: true, retentionDays: 30, safetyThreshold: 0.8, minRetainL0: 50, minRetainL1: 20 },\n importance: { enabled: true, baseHalflifeDays: 50 },\n accessFrequency: { enabled: true },\n stateMachine: { enabled: true },\n },\n teamMemory: { enabled: true, maxImportedAgents: 2, visibilityGate: true },\n },\n };\n }\n return {}; // No migration needed\n },\n });\n\n // Auto-enable probe - allows OpenClaw to auto-enable this plugin\n api.registerAutoEnableProbe?.({\n id: \"memory-new\",\n check: async (config) => {\n // Check if memory_new config exists or if any memory-related files are present\n const hasConfig = config?.plugins?.memory_new?.enabled === true;\n const hasStorageDir = false; // Could check for ~/.openclaw/memory-new\n return hasConfig || hasStorageDir;\n },\n });\n },\n});\n\n// ============================================================================\n// Exports for testing\n// ============================================================================\n\nexport const testing = {\n deriveFreshness,\n deriveHotness,\n calculateScore,\n validateVisibilityTransition,\n};\n", "/**\n * Memory Storage - Complete L0/L1/L2/L3 Implementation\n *\n * Reference: TDB (TencentDB-Agent-Memory) storage architecture\n *\n * Storage model:\n * - L0: SQLite (messages) + FTS5 (search)\n * - L1: SQLite (atomic memories) + VectorStore (embeddings)\n * - L2: File system (Markdown scene blocks)\n * - L3: File system (persona.md)\n */\n\nimport { mkdirSync, writeFileSync, readFileSync, existsSync, appendFileSync, readdirSync } from \"fs\";\nimport { join, dirname } from \"path\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface L0Message {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n timestamp: number; // epoch ms\n sessionKey: string;\n sessionId: string;\n teamId?: string;\n userId: string;\n agentId: string;\n taskId?: string;\n recordedAt: string; // ISO timestamp\n}\n\nexport interface L1Record {\n id: string;\n content: string;\n type: \"persona\" | \"episodic\" | \"instruction\";\n priority: number; // 0-100\n sceneName: string;\n sourceMessageIds: string[];\n metadata: Record<string, unknown>;\n timestamps: string[];\n createdAt: string;\n updatedAt: string;\n version: number;\n sessionKey: string;\n sessionId: string;\n teamId?: string;\n userId: string;\n agentId: string;\n // Vector embedding stored separately\n}\n\nexport interface L2Scene {\n id: string;\n title: string;\n content: string; // Markdown\n summary: string;\n tags: string[];\n metadata: {\n layer: \"L2\";\n heat: number; // Number of related L1s\n sourceRecords: string[];\n };\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface L3Persona {\n id: string;\n content: string; // Markdown\n summary: string;\n metadata: {\n layer: \"L3\";\n sourceScenes: string[];\n };\n createdAt: string;\n updatedAt: string;\n}\n\n// ============================================================================\n// Storage Paths\n// ============================================================================\n\nexport const STORAGE_PATHS = {\n l0: \"memory/l0/\",\n l1: \"memory/l1/\",\n l2: \"memory/scenes/\",\n l3: \"persona.md\",\n index: {\n l2: \"memory/scenes/index.json\",\n l3: \"persona.md.meta\",\n },\n};\n\n// ============================================================================\n// Storage Adapter (TDB's StorageAdapter pattern)\n// ============================================================================\n\nexport class StorageAdapter {\n private baseDir: string;\n\n constructor(baseDir: string = \"~/.openclaw/memory-new\") {\n this.baseDir = baseDir.replace(\"~\", process.env.HOME || \"/root\");\n mkdirSync(this.baseDir, { recursive: true });\n }\n\n private resolve(path: string): string {\n return join(this.baseDir, path);\n }\n\n // ========== File Operations ==========\n\n async readFile(key: string): Promise<string | null> {\n const filePath = this.resolve(key);\n if (!existsSync(filePath)) return null;\n return readFileSync(filePath, \"utf-8\");\n }\n\n async writeFile(key: string, content: string): Promise<void> {\n const filePath = this.resolve(key);\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, content, \"utf-8\");\n }\n\n async appendFile(key: string, content: string): Promise<void> {\n const filePath = this.resolve(key);\n mkdirSync(dirname(filePath), { recursive: true });\n appendFileSync(filePath, content, \"utf-8\");\n }\n\n async exists(key: string): Promise<boolean> {\n return existsSync(this.resolve(key));\n }\n\n // ========== L0 Operations (JSONL per session) ==========\n\n /**\n * L0: Append message to session's JSONL file (TDB pattern: append-only)\n */\n async appendL0(record: L0Message): Promise<void> {\n const sessionFile = `${STORAGE_PATHS.l0}${record.sessionKey}.jsonl`;\n const line = JSON.stringify(record) + \"\\n\";\n await this.appendFile(sessionFile, line);\n }\n\n /**\n * L0: Batch read messages from session\n */\n async readL0(sessionKey: string, limit: number = 100): Promise<L0Message[]> {\n const sessionFile = `${STORAGE_PATHS.l0}${sessionKey}.jsonl`;\n const content = await this.readFile(sessionFile);\n if (!content) return [];\n\n const lines = content.split(\"\\n\").filter(l => l.trim());\n const messages = lines.slice(-limit).map(line => JSON.parse(line) as L0Message);\n return messages;\n }\n\n // ========== L1 Operations (JSONL) ==========\n\n /**\n * L1: Append atomic memory to session's JSONL file\n */\n async appendL1(record: L1Record): Promise<void> {\n const sessionFile = `${STORAGE_PATHS.l1}${record.sessionKey}.jsonl`;\n const line = JSON.stringify(record) + \"\\n\";\n await this.appendFile(sessionFile, line);\n }\n\n /**\n * L1: Search memories by content (simple full-text scan)\n */\n async searchL1(query: string, limit: number = 10): Promise<L1Record[]> {\n const l1Dir = this.resolve(STORAGE_PATHS.l1);\n\n console.log(`[DEBUG searchL1] l1Dir: ${l1Dir}`);\n\n // Check if directory exists\n if (!existsSync(l1Dir)) {\n console.log(`[DEBUG searchL1] Directory does not exist: ${l1Dir}`);\n return [];\n }\n\n // Read all JSONL files in the directory\n let allRecords: L1Record[] = [];\n try {\n const files = readdirSync(l1Dir).filter(f => f.endsWith('.jsonl'));\n console.log(`[DEBUG searchL1] Found files: ${files}`);\n\n for (const file of files) {\n const filePath = `${STORAGE_PATHS.l1}${file}`;\n console.log(`[DEBUG searchL1] Reading file: ${filePath}`);\n const content = await this.readFile(filePath);\n if (content) {\n const lines = content.split(\"\\n\").filter(l => l.trim());\n const records = lines.map(line => {\n try {\n return JSON.parse(line) as L1Record;\n } catch {\n return null;\n }\n }).filter((r): r is L1Record => r !== null);\n allRecords = allRecords.concat(records);\n }\n }\n console.log(`[DEBUG searchL1] Total records found: ${allRecords.length}`);\n } catch (e) {\n console.log(`[DEBUG searchL1] Error: ${e}`);\n // Directory might not exist\n return [];\n }\n\n // Filter by query if provided\n if (query) {\n const queryLower = query.toLowerCase();\n allRecords = allRecords.filter(r => r.content.toLowerCase().includes(queryLower));\n }\n\n // Sort by createdAt descending (newest first)\n allRecords.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n\n return allRecords.slice(0, limit);\n }\n\n // ========== L2 Operations (Markdown files) ==========\n\n /**\n * L2: Write scene block as Markdown file\n */\n async writeScene(scene: L2Scene): Promise<void> {\n const sceneFile = `${STORAGE_PATHS.l2}${scene.id}.md`;\n const frontmatter = `---\nid: ${scene.id}\ntitle: ${scene.title}\nsummary: ${scene.summary}\ntags: ${JSON.stringify(scene.tags)}\ncreated_at: ${scene.createdAt}\nupdated_at: ${scene.updatedAt}\n---\n\n`;\n await this.writeFile(sceneFile, frontmatter + scene.content);\n await this.updateSceneIndex(scene);\n }\n\n /**\n * L2: Read scene block\n */\n async readScene(sceneId: string): Promise<L2Scene | null> {\n const content = await this.readFile(`${STORAGE_PATHS.l2}${sceneId}.md`);\n if (!content) return null;\n\n // Parse frontmatter (simplified)\n const lines = content.split(\"\\n\");\n const frontmatterEnd = lines.findIndex(l => l === \"---\", 1);\n if (frontmatterEnd <= 1) return null;\n\n const frontmatter: Record<string, string> = {};\n for (let i = 1; i < frontmatterEnd; i++) {\n const [key, ...valueParts] = lines[i].split(\":\");\n if (key && valueParts.length > 0) {\n frontmatter[key.trim()] = valueParts.join(\":\").trim();\n }\n }\n\n return {\n id: scene.id,\n title: frontmatter.title || \"\",\n content: lines.slice(frontmatterEnd + 1).join(\"\\n\"),\n summary: frontmatter.summary || \"\",\n tags: JSON.parse(frontmatter.tags || \"[]\"),\n metadata: { layer: \"L2\", heat: 0, sourceRecords: [] },\n createdAt: frontmatter.created_at || \"\",\n updatedAt: frontmatter.updated_at || \"\",\n };\n }\n\n /**\n * L2: Maintain scene index for navigation\n */\n private async updateSceneIndex(scene: L2Scene): Promise<void> {\n const indexFile = STORAGE_PATHS.index.l2;\n let index: Record<string, { id: string; title: string; summary: string; tags: string[] }> = {};\n\n const existing = await this.readFile(indexFile);\n if (existing) {\n try {\n index = JSON.parse(existing);\n } catch { /* ignore */ }\n }\n\n index[scene.id] = {\n id: scene.id,\n title: scene.title,\n summary: scene.summary,\n tags: scene.tags,\n };\n\n await this.writeFile(indexFile, JSON.stringify(index, null, 2));\n }\n\n /**\n * L2: Read scene index for navigation\n */\n async readSceneIndex(): Promise<Array<{ id: string; title: string; summary: string }>> {\n const indexFile = STORAGE_PATHS.index.l2;\n const content = await this.readFile(indexFile);\n if (!content) return [];\n\n try {\n const index = JSON.parse(content);\n return Object.values(index);\n } catch {\n return [];\n }\n }\n\n // ========== L3 Operations (persona.md) ==========\n\n /**\n * L3: Write persona file\n */\n async writePersona(persona: L3Persona): Promise<void> {\n const frontmatter = `---\nid: ${persona.id}\ncreated_at: ${persona.createdAt}\nupdated_at: ${persona.updatedAt}\n---\n\n`;\n await this.writeFile(STORAGE_PATHS.l3, frontmatter + persona.content);\n }\n\n /**\n * L3: Read persona file\n */\n async readPersona(): Promise<L3Persona | null> {\n const content = await this.readFile(STORAGE_PATHS.l3);\n if (!content) return null;\n\n const lines = content.split(\"\\n\");\n const frontmatterEnd = lines.findIndex(l => l === \"---\", 1);\n if (frontmatterEnd <= 1) return null;\n\n const frontmatter: Record<string, string> = {};\n for (let i = 1; i < frontmatterEnd; i++) {\n const [key, ...valueParts] = lines[i].split(\":\");\n if (key && valueParts.length > 0) {\n frontmatter[key.trim()] = valueParts.join(\":\").trim();\n }\n }\n\n return {\n id: frontmatter.id || \"\",\n content: lines.slice(frontmatterEnd + 1).join(\"\\n\"),\n summary: \"\",\n metadata: { layer: \"L3\", sourceScenes: [] },\n createdAt: frontmatter.created_at || \"\",\n updatedAt: frontmatter.updated_at || \"\",\n };\n }\n}\n\n// ============================================================================\n// Recall Result (TDB's RecallResult pattern)\n// ============================================================================\n\nexport interface RecallResult {\n /** L1 relevant memories \u2014 prepended to user prompt (dynamic, per-turn) */\n prependContext?: string;\n /** Stable recall context appended to system prompt (L2/L3, cacheable) */\n appendSystemContext?: string;\n /** L1 memories with scores (for metrics) */\n recalledL1Memories?: Array<{ content: string; score: number; type: string }>;\n /** L3 persona raw content */\n recalledL3Persona?: string | null;\n /** Search strategy used */\n recallStrategy?: string;\n}\n\nconst RECALL_LINE_SEPARATOR = \"\\n\";\n\n/**\n * Memory tools usage guide (TDB's MEMORY_TOOLS_GUIDE)\n */\nconst MEMORY_TOOLS_GUIDE = `<memory-tools-guide>\n## \u8BB0\u5FC6\u5DE5\u5177\u8C03\u7528\u6307\u5357\n\n\u5F53\u4E0A\u65B9\u6CE8\u5165\u7684\u8BB0\u5FC6\u7247\u6BB5\u4E0D\u8DB3\u4EE5\u56DE\u7B54\u7528\u6237\u95EE\u9898\u65F6\uFF0C\u53EF\u4E3B\u52A8\u8C03\u7528\u4EE5\u4E0B\u5DE5\u5177\u83B7\u53D6\u66F4\u591A\u4FE1\u606F\uFF1A\n\n- **memory_search**\uFF1A\u641C\u7D22\u7ED3\u6784\u5316\u8BB0\u5FC6\uFF08L1\uFF09\uFF0C\u9002\u7528\u4E8E\u56DE\u5FC6\u7528\u6237\u504F\u597D\u3001\u5386\u53F2\u4E8B\u4EF6\u8282\u70B9\u3001\u89C4\u5219\u7B49\u5173\u952E\u4FE1\u606F\u3002\n- **memory_get**\uFF1A\u83B7\u53D6\u7279\u5B9A\u8BB0\u5FC6\u8BE6\u60C5\u3002\n\n### \u8C03\u7528\u6B21\u6570\u9650\u5236\n\u6BCF\u8F6E\u5BF9\u8BDD\u4E2D\uFF0C\u8BB0\u5FC6\u641C\u7D22\u5DE5\u5177**\u5408\u8BA1\u6700\u591A\u8C03\u7528 3 \u6B21**\u3002\n</memory-tools-guide>`;\n\n/**\n * Scene navigation template (TDB's generateSceneNavigation)\n */\nfunction generateSceneNavigation(scenes: Array<{ id: string; title: string; summary: string }>): string {\n if (scenes.length === 0) return \"\";\n\n const lines = scenes.map(s =>\n `- [${s.title}](memory://scene/${s.id}): ${s.summary}`\n );\n\n return `## \u60C5\u5883\u5BFC\u822A\\n${lines.join(RECALL_LINE_SEPARATOR)}`;\n}\n\n// ============================================================================\n// Recall Engine (TDB's performAutoRecall pattern)\n// ============================================================================\n\nexport interface RecallEngineOptions {\n hybridSearch?: boolean;\n semanticWeight?: number;\n bm25Weight?: number;\n entityBoostWeight?: number;\n}\n\nexport class RecallEngine {\n private storage: StorageAdapter;\n private options: RecallEngineOptions;\n\n constructor(storage: StorageAdapter, options: RecallEngineOptions = {}) {\n this.storage = storage;\n this.options = {\n hybridSearch: options.hybridSearch ?? true,\n semanticWeight: options.semanticWeight ?? 0.5,\n bm25Weight: options.bm25Weight ?? 0.25,\n entityBoostWeight: options.entityBoostWeight ?? 0.25,\n };\n }\n\n /**\n * Perform recall: search L1 + read L2 + read L3\n * (Reference: TDB's performAutoRecallCore)\n *\n * Uses hybrid search when vector store is available via hybridSearch option.\n */\n async recall(params: {\n query: string;\n sessionKey: string;\n userId: string;\n agentId: string;\n topK?: number;\n vectorStore?: import(\"../vector/vector-store.js\").VectorStore;\n }): Promise<RecallResult> {\n const { query, sessionKey, topK = 10, vectorStore } = params;\n\n let memories: L1Record[] = [];\n let recallStrategy = \"text\";\n\n // 1. Search L1 memories - use hybrid or text search\n if (vectorStore && this.options.hybridSearch) {\n // Hybrid semantic search using vector store\n const searchResults = await vectorStore.hybridSearch({\n query,\n topK,\n semanticWeight: this.options.semanticWeight!,\n bm25Weight: this.options.bm25Weight!,\n entityBoostWeight: this.options.entityBoostWeight!,\n });\n\n // Get full records from storage for matched IDs\n const matchedRecords: L1Record[] = [];\n for (const result of searchResults) {\n const records = await this.storage.searchL1(\"\", 100);\n const record = records.find(r => r.id === result.id);\n if (record) {\n matchedRecords.push(record);\n }\n }\n memories = matchedRecords;\n recallStrategy = \"hybrid\";\n } else {\n // Text search fallback\n memories = await this.storage.searchL1(query, topK);\n recallStrategy = \"text\";\n }\n\n // 2. Read L2 scene navigation\n const sceneIndex = await this.storage.readSceneIndex();\n\n // 3. Read L3 persona\n const persona = await this.storage.readPersona();\n\n // Build prependContext (L1 - dynamic, per-turn)\n let prependContext: string | undefined;\n if (memories.length > 0) {\n const memoryLines = memories.map(m =>\n `- [${m.type}] ${m.content}`\n );\n prependContext = `<relevant-memories>\n\u4EE5\u4E0B\u662F\u4E0E\u5F53\u524D\u5BF9\u8BDD\u76F8\u5173\u7684\u8BB0\u5FC6\uFF1A\n\n${memoryLines.join(RECALL_LINE_SEPARATOR)}\n</relevant-memories>`;\n }\n\n // Build appendSystemContext (L2/L3 + tools guide - stable, cacheable)\n const stableParts: string[] = [];\n\n if (persona) {\n stableParts.push(`<user-persona>\n${persona.content}\n</user-persona>`);\n }\n\n if (sceneIndex.length > 0) {\n stableParts.push(`<scene-navigation>\n${generateSceneNavigation(sceneIndex)}\n</scene-navigation>`);\n }\n\n if (stableParts.length > 0 || prependContext) {\n stableParts.push(MEMORY_TOOLS_GUIDE);\n }\n\n const appendSystemContext = stableParts.length > 0\n ? stableParts.join(\"\\n\\n\")\n : undefined;\n\n return {\n prependContext,\n appendSystemContext,\n recalledL1Memories: memories.map(m => ({\n content: m.content,\n score: 0.5, // TODO: calculate real score\n type: m.type,\n })),\n recalledL3Persona: persona?.content ?? null,\n recallStrategy,\n };\n }\n}\n\n// ============================================================================\n// Memory Store (combining all layers)\n// ============================================================================\n\nexport class MemoryStore {\n private storage: StorageAdapter;\n private recall: RecallEngine;\n private _vectorStore?: import(\"../vector/vector-store.js\").VectorStore;\n\n constructor(baseDir: string = \"~/.openclaw/memory-new\") {\n this.storage = new StorageAdapter(baseDir);\n this.recall = new RecallEngine(this.storage);\n }\n\n // ========== Vector Store (for semantic search) ==========\n\n get vectorStore(): import(\"../vector/vector-store.js\").VectorStore | undefined {\n return this._vectorStore;\n }\n\n setVectorStore(store: import(\"../vector/vector-store.js\").VectorStore): void {\n this._vectorStore = store;\n }\n\n // ========== L0 Operations ==========\n\n async ingestMessage(message: Omit<L0Message, \"id\" | \"recordedAt\">): Promise<L0Message> {\n const record: L0Message = {\n ...message,\n id: `l0_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n recordedAt: new Date().toISOString(),\n };\n await this.storage.appendL0(record);\n return record;\n }\n\n async getMessages(sessionKey: string, limit: number = 100): Promise<L0Message[]> {\n return this.storage.readL0(sessionKey, limit);\n }\n\n // ========== L1 Operations ==========\n\n async storeL1(record: Omit<L1Record, \"id\" | \"createdAt\" | \"updatedAt\" | \"version\">): Promise<L1Record> {\n const now = new Date().toISOString();\n const fullRecord: L1Record = {\n ...record,\n id: `l1_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n createdAt: now,\n updatedAt: now,\n version: 1,\n };\n await this.storage.appendL1(fullRecord);\n return fullRecord;\n }\n\n async searchL1(query: string, limit: number = 10): Promise<L1Record[]> {\n return this.storage.searchL1(query, limit);\n }\n\n // ========== L2 Operations ==========\n\n async storeL2(scene: Omit<L2Scene, \"id\" | \"createdAt\" | \"updatedAt\">): Promise<L2Scene> {\n const now = new Date().toISOString();\n const fullScene: L2Scene = {\n ...scene,\n id: `scene_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,\n createdAt: now,\n updatedAt: now,\n };\n await this.storage.writeScene(fullScene);\n return fullScene;\n }\n\n async getScene(sceneId: string): Promise<L2Scene | null> {\n return this.storage.readScene(sceneId);\n }\n\n async getSceneIndex(): Promise<Array<{ id: string; title: string; summary: string }>> {\n return this.storage.readSceneIndex();\n }\n\n // ========== L3 Operations ==========\n\n async storeL3(persona: Omit<L3Persona, \"id\" | \"createdAt\" | \"updatedAt\">): Promise<L3Persona> {\n const now = new Date().toISOString();\n const fullPersona: L3Persona = {\n ...persona,\n id: `persona_${Date.now()}`,\n createdAt: now,\n updatedAt: now,\n };\n await this.storage.writePersona(fullPersona);\n return fullPersona;\n }\n\n async getPersona(): Promise<L3Persona | null> {\n return this.storage.readPersona();\n }\n\n // ========== Recall ==========\n\n async recallMemories(query: string, sessionKey: string, userId: string, agentId: string, topK?: number): Promise<RecallResult> {\n return this.recall.recall({ query, sessionKey, userId, agentId, topK });\n }\n}\n", "/**\n * Vector Store - Embedding-based semantic search\n *\n * Uses OpenClaw's embedding provider for L1 semantic search.\n * Supports hybrid search: vector + BM25 + entity boost.\n */\n\nimport type { EmbeddingProvider } from \"openclaw/plugin-sdk/embedding-providers\";\n\nexport interface VectorRecord {\n id: string;\n content: string;\n embedding: number[];\n metadata: Record<string, unknown>;\n createdAt: number;\n}\n\nexport interface SearchResult {\n id: string;\n content: string;\n score: number;\n metadata: Record<string, unknown>;\n}\n\nexport interface HybridSearchOptions {\n query: string;\n queryEmbedding?: number[];\n topK: number;\n semanticWeight: number;\n bm25Weight: number;\n entityBoostWeight: number;\n minScore?: number;\n}\n\n// ============================================================================\n// Simple in-memory vector store (production would use SQLite FTS5)\n// ============================================================================\n\nexport class VectorStore {\n private records: Map<string, VectorRecord> = new Map();\n private embeddingProvider: EmbeddingProvider | null = null;\n private dimension: number = 384;\n\n constructor(dimension: number = 384) {\n this.dimension = dimension;\n }\n\n setEmbeddingProvider(provider: EmbeddingProvider): void {\n this.embeddingProvider = provider;\n }\n\n // ========== Record Operations ==========\n\n async add(record: Omit<VectorRecord, \"createdAt\">): Promise<VectorRecord> {\n const fullRecord: VectorRecord = {\n ...record,\n createdAt: Date.now(),\n };\n this.records.set(record.id, fullRecord);\n return fullRecord;\n }\n\n async get(id: string): Promise<VectorRecord | null> {\n return this.records.get(id) ?? null;\n }\n\n async delete(id: string): Promise<boolean> {\n return this.records.delete(id);\n }\n\n async update(id: string, updates: Partial<VectorRecord>): Promise<VectorRecord | null> {\n const existing = this.records.get(id);\n if (!existing) return null;\n\n const updated = { ...existing, ...updates };\n this.records.set(id, updated);\n return updated;\n }\n\n // ========== Embedding Operations ==========\n\n async embedContent(content: string): Promise<number[]> {\n if (!this.embeddingProvider) {\n // Fallback: generate simple hash-based pseudo-embedding\n return this.fallbackEmbed(content);\n }\n\n try {\n const embedding = await this.embeddingProvider.embed(content, { inputType: \"query\" });\n return embedding;\n } catch (error) {\n console.error(\"Embedding failed, using fallback:\", error);\n return this.fallbackEmbed(content);\n }\n }\n\n async embedBatch(contents: string[]): Promise<number[][]> {\n if (!this.embeddingProvider) {\n return contents.map(c => this.fallbackEmbed(c));\n }\n\n try {\n return await this.embeddingProvider.embedBatch(contents, { inputType: \"document\" });\n } catch (error) {\n console.error(\"Batch embedding failed, using fallback:\", error);\n return contents.map(c => this.fallbackEmbed(c));\n }\n }\n\n // Fallback pseudo-embedding using hash (for testing without API)\n private fallbackEmbed(content: string): number[] {\n return this.generatePseudoEmbedding(content);\n }\n\n /**\n * Generate pseudo-embedding from text content.\n * Used as fallback when no embedding provider is available.\n */\n generatePseudoEmbedding(content: string): number[] {\n const embedding = new Array(this.dimension).fill(0);\n let hash = 0;\n for (let i = 0; i < content.length; i++) {\n hash = ((hash << 5) - hash) + content.charCodeAt(i);\n hash = hash & hash;\n }\n\n // Seed random with hash for reproducibility\n const seed = Math.abs(hash);\n for (let i = 0; i < this.dimension; i++) {\n // Simple pseudo-random based on content\n const charCode = content.charCodeAt(i % content.length) || 1;\n embedding[i] = Math.sin(seed * (i + 1) * charCode) * 0.5 + 0.5;\n }\n\n // Normalize\n const magnitude = Math.sqrt(embedding.reduce((sum, v) => sum + v * v, 0));\n if (magnitude > 0) {\n for (let i = 0; i < embedding.length; i++) {\n embedding[i] /= magnitude;\n }\n }\n\n return embedding;\n }\n\n // ========== Vector Search ==========\n\n async searchByVector(\n queryEmbedding: number[],\n topK: number,\n minScore: number = 0.0\n ): Promise<SearchResult[]> {\n const results: SearchResult[] = [];\n\n for (const record of this.records.values()) {\n if (record.embedding.length !== queryEmbedding.length) continue;\n\n const score = this.cosineSimilarity(queryEmbedding, record.embedding);\n if (score >= minScore) {\n results.push({\n id: record.id,\n content: record.content,\n score,\n metadata: record.metadata,\n });\n }\n }\n\n // Sort by score descending\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, topK);\n }\n\n // ========== Hybrid Search ==========\n\n async hybridSearch(\n options: HybridSearchOptions,\n getTextScore: (content: string, query: string) => number = bm25Score\n ): Promise<SearchResult[]> {\n const { query, topK, semanticWeight, bm25Weight, entityBoostWeight, minScore = 0.1 } = options;\n\n // Get query embedding if not provided\n let queryEmbedding = options.queryEmbedding;\n if (!queryEmbedding) {\n queryEmbedding = await this.embedContent(query);\n }\n\n // Semantic search\n const semanticResults = await this.searchByVector(queryEmbedding, topK * 2, 0.0);\n\n // BM25 search (simple in-memory version)\n const bm25Results = this.bm25Search(query, topK * 2);\n\n // Entity boost (extract entities and boost matches)\n const entities = this.extractEntities(query);\n const entityBoostResults = this.entityBoostSearch(entities, topK * 2);\n\n // Merge scores\n const scoreMap = new Map<string, SearchResult>();\n\n for (const result of semanticResults) {\n const semanticScore = result.score * semanticWeight;\n scoreMap.set(result.id, {\n id: result.id,\n content: result.content,\n score: semanticScore,\n metadata: result.metadata,\n });\n }\n\n for (const result of bm25Results) {\n const existing = scoreMap.get(result.id);\n const bm25Contribution = result.score * bm25Weight;\n if (existing) {\n existing.score += bm25Contribution;\n } else {\n scoreMap.set(result.id, {\n id: result.id,\n content: result.content,\n score: bm25Contribution,\n metadata: result.metadata,\n });\n }\n }\n\n for (const result of entityBoostResults) {\n const existing = scoreMap.get(result.id);\n const boostContribution = result.score * entityBoostWeight;\n if (existing) {\n existing.score += boostContribution;\n } else {\n scoreMap.set(result.id, {\n id: result.id,\n content: result.content,\n score: boostContribution,\n metadata: result.metadata,\n });\n }\n }\n\n // Filter and sort\n const finalResults = Array.from(scoreMap.values())\n .filter(r => r.score >= minScore)\n .sort((a, b) => b.score - a.score)\n .slice(0, topK);\n\n return finalResults;\n }\n\n // ========== BM25 (in-memory simplified) ==========\n\n private bm25Search(query: string, topK: number): SearchResult[] {\n const queryTerms = query.toLowerCase().split(/\\s+/);\n const results: SearchResult[] = [];\n const avgDocLen = this.getAverageDocLength();\n const k1 = 1.5;\n const b = 0.75;\n\n for (const record of this.records.values()) {\n const terms = record.content.toLowerCase().split(/\\s+/);\n let score = 0;\n\n for (const term of queryTerms) {\n const tf = terms.filter(t => t === term).length;\n if (tf > 0) {\n // Simplified IDF (in production, calculate from corpus)\n const idf = Math.log((this.records.size + 1) / 2);\n const docLen = terms.length;\n const numerator = tf * (k1 + 1);\n const denominator = tf + k1 * (1 - b + b * (docLen / avgDocLen));\n score += idf * (numerator / denominator);\n }\n }\n\n if (score > 0) {\n results.push({\n id: record.id,\n content: record.content,\n score,\n metadata: record.metadata,\n });\n }\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, topK);\n }\n\n private getAverageDocLength(): number {\n if (this.records.size === 0) return 1;\n let total = 0;\n for (const record of this.records.values()) {\n total += record.content.split(/\\s+/).length;\n }\n return total / this.records.size;\n }\n\n // ========== Entity Extraction & Boost ==========\n\n private extractEntities(query: string): string[] {\n // Simple entity extraction (in production use NER)\n const entities: string[] = [];\n\n // Capitalized words (potential entities)\n const capitalizedPattern = /[A-Z][a-z]+/g;\n let match;\n while ((match = capitalizedPattern.exec(query)) !== null) {\n entities.push(match[0].toLowerCase());\n }\n\n // Quoted strings\n const quotedPattern = /\"([^\"]+)\"|'([^']+)'/g;\n while ((match = quotedPattern.exec(query)) !== null) {\n const entity = match[1] || match[2];\n entities.push(entity.toLowerCase());\n }\n\n return [...new Set(entities)];\n }\n\n private entityBoostSearch(entities: string[], topK: number): SearchResult[] {\n if (entities.length === 0) return [];\n\n const results: SearchResult[] = [];\n\n for (const record of this.records.values()) {\n const content = record.content.toLowerCase();\n let matchCount = 0;\n\n for (const entity of entities) {\n if (content.includes(entity)) {\n matchCount++;\n }\n }\n\n if (matchCount > 0) {\n // Score based on how many entities matched\n const score = matchCount / entities.length;\n results.push({\n id: record.id,\n content: record.content,\n score,\n metadata: record.metadata,\n });\n }\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, topK);\n }\n\n // ========== Utilities ==========\n\n private cosineSimilarity(a: number[], b: number[]): number {\n if (a.length !== b.length) return 0;\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n const denominator = Math.sqrt(normA) * Math.sqrt(normB);\n if (denominator === 0) return 0;\n\n return dotProduct / denominator;\n }\n\n async getAll(): Promise<VectorRecord[]> {\n return Array.from(this.records.values());\n }\n\n async count(): Promise<number> {\n return this.records.size;\n }\n\n async clear(): Promise<void> {\n this.records.clear();\n }\n}\n\n// BM25 score helper (exposed for external use)\nexport function bm25Score(content: string, query: string): number {\n const queryTerms = query.toLowerCase().split(/\\s+/);\n const terms = content.toLowerCase().split(/\\s+/);\n let score = 0;\n\n for (const term of queryTerms) {\n const tf = terms.filter(t => t === term).length;\n if (tf > 0) {\n // Simplified BM25\n score += 1 + Math.log(1 + tf);\n }\n }\n\n return score;\n}\n", "/**\n * Memory Distillation Pipeline with Storage Integration\n *\n * Reference: TDB (TencentDB-Agent-Memory) L0\u2192L1\u2192L2\u2192L3 distillation model\n *\n * This version integrates with:\n * - OpenClaw LLM runtime for L1 extraction via subagent\n * - Vector store for semantic search\n */\n\nimport type { Engram, EngramKind, MemoryLayer } from \"../index.js\";\nimport { StorageAdapter, MemoryStore, type L0Message, type L1Record, type L2Scene, type L3Persona } from \"../store/storage.js\";\nimport { VectorStore } from \"../vector/vector-store.js\";\n\nexport interface DistillationConfig {\n l1: {\n messageThreshold: number; // Extract after N messages (default: 5)\n idleSeconds: number; // Or after N seconds of idle (default: 60)\n batchSize: number; // Max messages per extraction (default: 10)\n enableDedup: boolean;\n maxMemoriesPerSession: number;\n };\n l2: {\n minIntervalMs: number;\n maxIntervalMs: number;\n topicThreshold: number;\n delayAfterL1Seconds: number;\n };\n l3: {\n conditions: Array<\"explicit_request\" | \"cold_start\" | \"restore\" | \"first_scene\" | \"threshold\">;\n importanceThreshold: number;\n };\n // LLM extraction config\n llm?: {\n provider?: string;\n model?: string;\n };\n}\n\nexport const DEFAULT_DISTILLATION_CONFIG: DistillationConfig = {\n l1: {\n messageThreshold: 5,\n idleSeconds: 60,\n batchSize: 10,\n enableDedup: true,\n maxMemoriesPerSession: 50,\n },\n l2: {\n minIntervalMs: 15 * 60 * 1000,\n maxIntervalMs: 60 * 60 * 1000,\n topicThreshold: 3,\n delayAfterL1Seconds: 90,\n },\n l3: {\n conditions: [\"explicit_request\", \"cold_start\", \"restore\", \"first_scene\", \"threshold\"],\n importanceThreshold: 0.6,\n },\n};\n\n// ============================================================================\n// LLM Prompt Templates (from TDB)\n// ============================================================================\n\nconst L1_EXTRACTION_SYSTEM_PROMPT = `\u4F60\u662F\u4E13\u4E1A\u7684\"\u5DE5\u4F5C\u60C5\u5883\u5207\u5206\u4E0E\u56E2\u961F\u5171\u4EAB\u8BB0\u5FC6\u63D0\u53D6\u4E13\u5BB6\"\u3002\n\u4F60\u7684\u4EFB\u52A1\u662F\u5206\u6790\u5DE5\u4F5C\u6D88\u606F\uFF0C\u5224\u65AD\u5DE5\u4F5C\u60C5\u5883\u5207\u6362\uFF0C\u5E76\u4ECE\u4E2D\u63D0\u53D6\u53EF\u5728\u56E2\u961F\u5185\u5171\u4EAB\u7684\u7ED3\u6784\u5316\u5DE5\u4F5C\u8BB0\u5FC6\u3002\n\n## \u8F93\u51FA\u8981\u6C42\n\n\u4E25\u683C\u6309\u4EE5\u4E0BJSON\u6570\u7EC4\u683C\u5F0F\u8F93\u51FA\uFF0C\u4E0D\u8981\u8F93\u51FA\u4EFB\u4F55\u989D\u5916\u7684 Markdown \u4EE3\u7801\u5757\u4FEE\u9970\u7B26\uFF08\u5982 \\`\\`\\`json\uFF09\u6216\u89E3\u91CA\u6587\u672C\uFF1A\n\n[\n {\n \"scene_name\": \"\u60C5\u5883\u540D\u79F0\uFF08\u7B80\u6D01\uFF0C1-10\u4E2A\u5B57\uFF09\",\n \"memories\": [\n {\n \"content\": \"\u8BB0\u5FC6\u5185\u5BB9\uFF08\u5B8C\u6574\u53E5\u5B50\uFF0C20-200\u5B57\uFF09\",\n \"type\": \"persona | episodic | instruction\",\n \"priority\": \u4F18\u5148\u7EA7(0-100, \u8D8A\u9AD8\u8D8A\u91CD\u8981),\n \"source_message_ids\": [\"\u76F8\u5173\u6D88\u606FID\"],\n \"metadata\": {}\n }\n ]\n }\n]\n\n## Memory Type \u5B9A\u4E49\n\n- **persona**: \u5173\u4E8E\u7528\u6237\u504F\u597D\u3001\u4E60\u60EF\u3001\u5DE5\u4F5C\u65B9\u5F0F\u7684\u8BB0\u5FC6\uFF08\u5982\"\u7528\u6237\u559C\u6B22\u5728\u4E0A\u5348\u5904\u7406\u590D\u6742\u4EFB\u52A1\"\uFF09\n- **episodic**: \u5177\u4F53\u7684\u9879\u76EE\u4E8B\u4EF6\u3001\u51B3\u7B56\u3001\u8BA8\u8BBA\u8981\u70B9\uFF08\u5982\"\u9879\u76EEX\u51B3\u5B9A\u4F7F\u7528\u5FAE\u670D\u52A1\u67B6\u6784\"\uFF09\n- **instruction**: \u7528\u6237\u7684\u660E\u786E\u6307\u4EE4\u6216\u9700\u6C42\uFF08\u5982\"\u7528\u6237\u8981\u6C42\u6BCF\u5468\u4E94\u540C\u6B65\u8FDB\u5EA6\"\uFF09\n\n## \u573A\u666F\u5207\u6362\u5224\u65AD\n\n\u5F53\u51FA\u73B0\u4EE5\u4E0B\u60C5\u51B5\u65F6\uFF0C\u5E94\u8BE5\u5207\u6362\u5230\u65B0\u573A\u666F\uFF1A\n1. \u8BDD\u9898\u53D1\u751F\u5B9E\u8D28\u6027\u53D8\u5316\n2. \u53C2\u4E0E\u4EBA\u5458\u53D1\u751F\u660E\u663E\u53D8\u5316\n3. \u4EFB\u52A1\u76EE\u6807\u53D1\u751F\u5207\u6362\n4. \u65F6\u95F4\u95F4\u9694\u8D85\u8FC730\u5206\u949F`;\n\nfunction formatExtractionPrompt(\n newMessages: L0Message[],\n backgroundMessages: L0Message[],\n previousSceneName: string\n): { systemPrompt: string; userPrompt: string } {\n const bgText = backgroundMessages.length > 0\n ? backgroundMessages\n .map(m => `[${m.id}] [${m.role}] [${new Date(m.timestamp).toISOString()}]: ${m.content}`)\n .join(\"\\n\\n\")\n : \"\u65E0\";\n\n const newText = newMessages\n .map(m => `[${m.id}] [${m.role}] [${new Date(m.timestamp).toISOString()}]: ${m.content}`)\n .join(\"\\n\\n\");\n\n const userPrompt = `**\u8F93\u51FA\u8BED\u8A00**\uFF1A\u6839\u636E\u4E0B\u65B9\"\u5F85\u63D0\u53D6\u7684\u65B0\u6D88\u606F\"\u4E2D user \u53D1\u8A00\u7684\u4E3B\u5BFC\u8BED\u8A00\u4E66\u5199 \\`scene_name\\` \u548C memory \\`content\\`\u3002\n\n\u3010\u4E0A\u4E00\u4E2A\u60C5\u5883\u3011\uFF1A${previousSceneName || \"\u65E0\"}\n\n\u3010\u80CC\u666F\u5BF9\u8BDD\u3011\uFF08\u4EC5\u4F9B\u7406\u89E3\u4E0A\u4E0B\u6587\u63A8\u65AD\u5173\u7CFB/\u65F6\u95F4\uFF0C\u4E25\u7981\u4ECE\u4E2D\u63D0\u53D6\u8BB0\u5FC6\uFF09\uFF1A\n${bgText}\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n\u3010\u5F85\u63D0\u53D6\u7684\u65B0\u6D88\u606F\u3011\uFF08\u52A1\u5FC5\u7ED3\u5408 timestamp \u63A8\u7B97\u65F6\u95F4\uFF0C\u53EA\u4ECE\u8FD9\u91CC\u63D0\u53D6\u8BB0\u5FC6\uFF01\uFF09\uFF1A\n${newText}`;\n\n return {\n systemPrompt: L1_EXTRACTION_SYSTEM_PROMPT,\n userPrompt,\n };\n}\n\n// ============================================================================\n// Pipeline with Storage Integration\n// ============================================================================\n\nexport class DistillationPipeline {\n private config: DistillationConfig;\n private store: MemoryStore;\n private vectorStore: VectorStore;\n private llmRunner?: (systemPrompt: string, userPrompt: string) => Promise<string>;\n private subagentRunner?: (message: string) => Promise<string>;\n\n private lastL1At: number | null = null;\n private lastL2At: number | null = null;\n private lastL3At: number | null = null;\n\n private pendingL1Extraction: ReturnType<typeof setTimeout> | null = null;\n\n // In-memory buffers (TDB uses VectorStore + JSONL)\n private messageBuffer: L0Message[] = [];\n\n constructor(\n config: DistillationConfig = DEFAULT_DISTILLATION_CONFIG,\n store?: MemoryStore,\n vectorStore?: VectorStore,\n llmRunner?: (systemPrompt: string, userPrompt: string) => Promise<string>\n ) {\n this.config = config;\n this.store = store || new MemoryStore();\n this.vectorStore = vectorStore || new VectorStore();\n this.llmRunner = llmRunner;\n }\n\n /**\n * Set LLM runner for simple prompt-completion style extraction\n */\n setLLMRunner(runner: (systemPrompt: string, userPrompt: string) => Promise<string>): void {\n this.llmRunner = runner;\n }\n\n /**\n * Set subagent runner for L1 extraction via OpenClaw subagent runtime\n */\n setSubagentRunner(runner: (message: string) => Promise<string>): void {\n this.subagentRunner = runner;\n }\n\n /**\n * Set vector store for embedding-based search\n */\n setVectorStore(store: VectorStore): void {\n this.vectorStore = store;\n }\n\n // ============================================================================\n // Ingestion (L0)\n // ============================================================================\n\n /**\n * Ingest messages into L0 layer (TDB's captureAtomic pattern)\n */\n async ingest(messages: Array<Omit<L0Message, \"id\" | \"recordedAt\">>): Promise<L0Message[]> {\n const records: L0Message[] = [];\n\n for (const msg of messages) {\n // Quality gate\n if (!shouldExtractL1(msg.content)) continue;\n\n const record = await this.store.ingestMessage(msg);\n records.push(record);\n this.messageBuffer.push(record);\n }\n\n // Check L1 trigger\n if (this.messageBuffer.length >= this.config.l1.messageThreshold) {\n await this.triggerL1Extraction();\n } else {\n this.scheduleL1Extraction();\n }\n\n return records;\n }\n\n private scheduleL1Extraction(): void {\n if (this.pendingL1Extraction) return;\n\n this.pendingL1Extraction = setTimeout(async () => {\n this.pendingL1Extraction = null;\n if (this.messageBuffer.length > 0) {\n await this.distill(\"L1\");\n }\n }, this.config.l1.idleSeconds * 1000);\n }\n\n private async triggerL1Extraction(): Promise<void> {\n if (this.pendingL1Extraction) {\n clearTimeout(this.pendingL1Extraction);\n this.pendingL1Extraction = null;\n }\n\n await this.distill(\"L1\");\n }\n\n // ============================================================================\n // Distillation\n // ============================================================================\n\n async distill(stage: MemoryLayer): Promise<{ stage: MemoryLayer; produced: number; errors: string[] }> {\n switch (stage) {\n case \"L1\":\n return this.runL1Distillation();\n case \"L2\":\n return this.runL2Distillation();\n case \"L3\":\n return this.runL3Distillation();\n default:\n return { stage, produced: 0, errors: [\"Unknown stage\"] };\n }\n }\n\n /**\n * L1 Distillation: Extract atomic memories from L0 messages\n * (Reference: TDB's extractL1Memories)\n */\n private async runL1Distillation(): Promise<{ stage: MemoryLayer; produced: number; errors: string[] }> {\n const errors: string[] = [];\n let produced = 0;\n\n try {\n // Get batch of messages\n const messages = this.messageBuffer.slice(-this.config.l1.batchSize);\n if (messages.length === 0) {\n return { stage: \"L1\", produced: 0, errors: [] };\n }\n\n // Get previous scene name for continuity\n const lastScene = await this.getLastSceneName();\n\n // Split into new + background\n const maxNew = 5;\n const newMessages = messages.slice(-maxNew);\n const backgroundMessages = messages.slice(0, -maxNew);\n\n // Format prompt\n const { systemPrompt, userPrompt } = formatExtractionPrompt(\n newMessages,\n backgroundMessages,\n lastScene\n );\n\n // Call LLM via subagent runner, llmRunner, or use fallback\n let extractionOutput = \"\";\n if (this.subagentRunner) {\n // Use OpenClaw subagent runtime for LLM extraction\n const fullPrompt = `${systemPrompt}\\n\\n${userPrompt}`;\n extractionOutput = await this.subagentRunner(fullPrompt);\n } else if (this.llmRunner) {\n extractionOutput = await this.llmRunner(systemPrompt, userPrompt);\n } else {\n extractionOutput = this.fallbackExtract(messages, lastScene);\n }\n\n // Parse output\n const extractedMemories = parseExtractionOutput(extractionOutput);\n\n // Store L1 records\n for (const mem of extractedMemories) {\n await this.store.storeL1({\n content: mem.content,\n type: mem.type,\n priority: mem.priority,\n sceneName: mem.scene_name,\n sourceMessageIds: mem.source_message_ids,\n metadata: mem.metadata,\n timestamps: messages.map(m => new Date(m.timestamp).toISOString()),\n sessionKey: messages[0]?.sessionKey || \"default\",\n sessionId: messages[0]?.sessionId || \"\",\n teamId: messages[0]?.teamId,\n userId: messages[0]?.userId || \"\",\n agentId: messages[0]?.agentId || \"\",\n });\n produced++;\n }\n\n // Clear processed messages\n this.messageBuffer = this.messageBuffer.slice(0, Math.max(0, this.messageBuffer.length - messages.length));\n\n this.lastL1At = Date.now();\n\n // Schedule L2 after L1 completes (TDB's delayAfterL1Seconds)\n setTimeout(() => this.distill(\"L2\"), this.config.l2.delayAfterL1Seconds * 1000);\n\n } catch (e) {\n errors.push(String(e));\n }\n\n return { stage: \"L1\", produced, errors };\n }\n\n private async getLastSceneName(): Promise<string> {\n // Try to get from L1 records\n const recent = await this.store.searchL1(\"\", 1);\n return recent[0]?.sceneName || \"\u65E0\";\n }\n\n /**\n * L2 Distillation: Cluster L1 memories into scene blocks\n * (Reference: TDB's SceneExtractor)\n */\n private async runL2Distillation(): Promise<{ stage: MemoryLayer; produced: number; errors: string[] }> {\n const errors: string[] = [];\n let produced = 0;\n\n try {\n // Check time constraints\n const now = Date.now();\n if (this.lastL2At && now - this.lastL2At < this.config.l2.minIntervalMs) {\n return { stage: \"L2\", produced: 0, errors: [\"Too soon since last L2\"] };\n }\n\n // Search all L1 records\n const l1Records = await this.store.searchL1(\"\", 100);\n if (l1Records.length < this.config.l2.topicThreshold) {\n return { stage: \"L2\", produced: 0, errors: [\"Not enough L1 records\"] };\n }\n\n // Group by scene name\n const sceneGroups = new Map<string, typeof l1Records>();\n for (const record of l1Records) {\n if (!sceneGroups.has(record.sceneName)) {\n sceneGroups.set(record.sceneName, []);\n }\n sceneGroups.get(record.sceneName)!.push(record);\n }\n\n // Create scene blocks\n for (const [sceneName, records] of sceneGroups) {\n if (records.length < this.config.l2.topicThreshold) continue;\n\n const avgPriority = records.reduce((sum, r) => sum + r.priority, 0) / records.length;\n const content = this.buildSceneContent(sceneName, records);\n\n await this.store.storeL2({\n title: sceneName,\n content,\n summary: `\u5E73\u5747\u4F18\u5148\u7EA7: ${avgPriority.toFixed(0)}`,\n tags: [sceneName],\n metadata: {\n layer: \"L2\" as const,\n heat: records.length,\n sourceRecords: records.map(r => r.id),\n },\n });\n produced++;\n }\n\n this.lastL2At = now;\n\n // Schedule L3 after L2\n setTimeout(() => this.distill(\"L3\"), 5000);\n\n } catch (e) {\n errors.push(String(e));\n }\n\n return { stage: \"L2\", produced, errors };\n }\n\n private buildSceneContent(sceneName: string, records: L1Record[]): string {\n const points = records.map(r => `- [${r.type}] ${r.content}`).join(\"\\n\");\n const avgPriority = records.reduce((sum, r) => sum + r.priority, 0) / records.length;\n\n return `# ${sceneName}\n\n## Key Points\n${points}\n\n## Summary\n\u5E73\u5747\u4F18\u5148\u7EA7: ${avgPriority.toFixed(0)}\n\u5171 ${records.length} \u6761\u76F8\u5173\u8BB0\u5FC6\n\n---\nGenerated: ${new Date().toISOString()}\n`;\n }\n\n /**\n * L3 Distillation: Build persona from high-value scenes\n * (Reference: TDB's PersonaExtractor)\n */\n private async runL3Distillation(): Promise<{ stage: MemoryLayer; produced: number; errors: string[] }> {\n const errors: string[] = [];\n let produced = 0;\n\n try {\n // Check if threshold met\n const l1Records = await this.store.searchL1(\"\", 100);\n if (l1Records.length === 0) {\n return { stage: \"L3\", produced: 0, errors: [\"No L1 records\"] };\n }\n\n const avgImportance = l1Records.reduce((sum, r) => sum + r.priority, 0) / l1Records.length / 100;\n if (avgImportance < this.config.l3.importanceThreshold) {\n return { stage: \"L3\", produced: 0, errors: [\"Avg importance below threshold\"] };\n }\n\n // Get high-value scenes\n const sceneIndex = await this.store.getSceneIndex();\n const highValueScenes = sceneIndex.filter(s => {\n const avg = l1Records\n .filter(r => r.sceneName === s.title)\n .reduce((sum, r) => sum + r.priority, 0) / Math.max(1, l1Records.filter(r => r.sceneName === s.title).length);\n return avg >= this.config.l3.importanceThreshold * 100;\n });\n\n if (highValueScenes.length === 0) {\n return { stage: \"L3\", produced: 0, errors: [\"No high-value scenes\"] };\n }\n\n // Build persona\n const personaContent = this.buildPersona(highValueScenes, l1Records);\n\n await this.store.storeL3({\n content: personaContent,\n summary: \"Agent Self-Model\",\n metadata: {\n layer: \"L3\" as const,\n sourceScenes: highValueScenes.map(s => s.id),\n },\n });\n\n produced = 1;\n this.lastL3At = Date.now();\n\n } catch (e) {\n errors.push(String(e));\n }\n\n return { stage: \"L3\", produced, errors };\n }\n\n private buildPersona(\n scenes: Array<{ id: string; title: string; summary: string }>,\n l1Records: L1Record[]\n ): string {\n const sceneContents = scenes.map(scene => {\n const relatedMemories = l1Records.filter(r => r.sceneName === scene.title);\n return `### ${scene.title}\\n${relatedMemories.map(m => `- ${m.content}`).join(\"\\n\")}`;\n }).join(\"\\n\\n\");\n\n const avgImportance = l1Records.reduce((sum, r) => sum + r.priority, 0) / l1Records.length / 100;\n\n return `# Agent Self-Model\n\n## Core Knowledge\n${sceneContents}\n\n## Behavioral Patterns\n- \u5171 ${scenes.length} \u4E2A\u9AD8\u4EF7\u503C\u573A\u666F\n- \u5E73\u5747\u91CD\u8981\u6027: ${avgImportance.toFixed(2)}\n\n## Preferences\n(\u4ECE persona \u7C7B\u578B\u8BB0\u5FC6\u4E2D\u63D0\u53D6)\n\n## Communication Style\n(\u4ECE\u4EA4\u4E92\u6A21\u5F0F\u4E2D\u5B66\u4E60)\n\n---\nGenerated: ${new Date().toISOString()}\n`;\n }\n\n // ============================================================================\n // Utilities\n // ============================================================================\n\n private fallbackExtract(messages: L0Message[], previousSceneName: string): string {\n const contents = messages.map(m => m.content).join(\"\\n\");\n const facts: string[] = [];\n\n // Simple patterns\n const patterns = [\n /(?:decided|\u51B3\u5B9A)(.+)/gi,\n /(?:learned|\u5B66\u4E60)(.+)/gi,\n /(?:remember|\u8BB0\u4F4F)(.+)/gi,\n ];\n\n for (const pattern of patterns) {\n let match;\n while ((match = pattern.exec(contents)) !== null) {\n facts.push(match[1].trim());\n }\n }\n\n if (facts.length === 0 && messages[0]) {\n const content = messages[0].content;\n if (content.length > 20) {\n facts.push(content.slice(0, 100));\n }\n }\n\n const sceneName = previousSceneName || \"General\";\n\n return JSON.stringify([{\n scene_name: sceneName,\n memories: facts.slice(0, 3).map((content, i) => ({\n content,\n type: \"episodic\",\n priority: 50 + i * 10,\n source_message_ids: [messages[0]?.id || \"unknown\"],\n metadata: {},\n })),\n }]);\n }\n\n checkTriggers(): { l1: boolean; l2: boolean; l3: boolean } {\n const now = Date.now();\n\n return {\n l1: this.messageBuffer.length >= this.config.l1.messageThreshold,\n l2: this.lastL2At ? now - this.lastL2At >= this.config.l2.minIntervalMs : this.messageBuffer.length >= this.config.l2.topicThreshold,\n l3: this.lastL3At === null,\n };\n }\n\n async getStats(): Promise<{\n l0Count: number;\n l1Count: number;\n l2Count: number;\n l3Count: number;\n }> {\n const l1Records = await this.store.searchL1(\"\", 1000);\n const l2Scenes = await this.store.getSceneIndex();\n const persona = await this.store.getPersona();\n\n return {\n l0Count: this.messageBuffer.length,\n l1Count: l1Records.length,\n l2Count: l2Scenes.length,\n l3Count: persona ? 1 : 0,\n };\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction shouldExtractL1(content: string): boolean {\n if (content.length < 10) return false;\n if (content.length > 10000) return false;\n return true;\n}\n\ninterface ExtractedMemory {\n content: string;\n type: \"persona\" | \"episodic\" | \"instruction\";\n priority: number;\n source_message_ids: string[];\n metadata: Record<string, unknown>;\n scene_name: string;\n}\n\nfunction parseExtractionOutput(output: string): ExtractedMemory[] {\n try {\n const jsonMatch = output.match(/\\[[\\s\\S]*\\]/);\n if (!jsonMatch) {\n const objMatch = output.match(/\\{[\\s\\S]*\\}/);\n if (objMatch) {\n return JSON.parse(objMatch[0]);\n }\n return [];\n }\n\n const parsed = JSON.parse(jsonMatch[0]);\n\n if (parsed.scene_name) {\n return (parsed.memories || []).map((m: any) => ({\n content: m.content,\n type: normalizeMemoryType(m.type),\n priority: Math.min(100, Math.max(0, Number(m.priority) || 50)),\n source_message_ids: Array.isArray(m.source_message_ids) ? m.source_message_ids : [],\n metadata: m.metadata || {},\n scene_name: parsed.scene_name,\n }));\n }\n\n const memories: ExtractedMemory[] = [];\n for (const scene of parsed) {\n for (const m of scene.memories || []) {\n memories.push({\n content: m.content,\n type: normalizeMemoryType(m.type),\n priority: Math.min(100, Math.max(0, Number(m.priority) || 50)),\n source_message_ids: Array.isArray(m.source_message_ids) ? m.source_message_ids : [],\n metadata: m.metadata || {},\n scene_name: scene.scene_name,\n });\n }\n }\n return memories;\n } catch (e) {\n console.error(\"Failed to parse LLM output:\", e);\n return [];\n }\n}\n\nfunction normalizeMemoryType(type: string): \"persona\" | \"episodic\" | \"instruction\" {\n const t = type?.toLowerCase();\n if (t === \"persona\" || t === \"episodic\" || t === \"instruction\") {\n return t as \"persona\" | \"episodic\" | \"instruction\";\n }\n return \"episodic\";\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["scene", "b", "scene", "scene", "config"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yhc3577/memory-new",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "Memory New - A new memory extension for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,6 +35,7 @@
35
35
  "registry": "https://registry.npmjs.org/"
36
36
  },
37
37
  "scripts": {
38
- "build": "node scripts/build.mjs"
38
+ "build": "node scripts/build.mjs",
39
+ "preuninstall": "node scripts/preuninstall.mjs"
39
40
  }
40
41
  }