@mnemoai/core 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +7 -0
  4. package/dist/cli.js.map +7 -0
  5. package/dist/index.d.ts +128 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/{index.ts → dist/index.js} +526 -1333
  8. package/dist/index.js.map +7 -0
  9. package/dist/src/access-tracker.d.ts +97 -0
  10. package/dist/src/access-tracker.d.ts.map +1 -0
  11. package/dist/src/access-tracker.js +184 -0
  12. package/dist/src/access-tracker.js.map +7 -0
  13. package/dist/src/adapters/chroma.d.ts +31 -0
  14. package/dist/src/adapters/chroma.d.ts.map +1 -0
  15. package/{src/adapters/chroma.ts → dist/src/adapters/chroma.js} +45 -107
  16. package/dist/src/adapters/chroma.js.map +7 -0
  17. package/dist/src/adapters/lancedb.d.ts +29 -0
  18. package/dist/src/adapters/lancedb.d.ts.map +1 -0
  19. package/{src/adapters/lancedb.ts → dist/src/adapters/lancedb.js} +41 -109
  20. package/dist/src/adapters/lancedb.js.map +7 -0
  21. package/dist/src/adapters/pgvector.d.ts +33 -0
  22. package/dist/src/adapters/pgvector.d.ts.map +1 -0
  23. package/{src/adapters/pgvector.ts → dist/src/adapters/pgvector.js} +42 -104
  24. package/dist/src/adapters/pgvector.js.map +7 -0
  25. package/dist/src/adapters/qdrant.d.ts +34 -0
  26. package/dist/src/adapters/qdrant.d.ts.map +1 -0
  27. package/dist/src/adapters/qdrant.js +132 -0
  28. package/dist/src/adapters/qdrant.js.map +7 -0
  29. package/dist/src/adaptive-retrieval.d.ts +14 -0
  30. package/dist/src/adaptive-retrieval.d.ts.map +1 -0
  31. package/dist/src/adaptive-retrieval.js +52 -0
  32. package/dist/src/adaptive-retrieval.js.map +7 -0
  33. package/dist/src/audit-log.d.ts +56 -0
  34. package/dist/src/audit-log.d.ts.map +1 -0
  35. package/dist/src/audit-log.js +139 -0
  36. package/dist/src/audit-log.js.map +7 -0
  37. package/dist/src/chunker.d.ts +45 -0
  38. package/dist/src/chunker.d.ts.map +1 -0
  39. package/dist/src/chunker.js +157 -0
  40. package/dist/src/chunker.js.map +7 -0
  41. package/dist/src/config.d.ts +70 -0
  42. package/dist/src/config.d.ts.map +1 -0
  43. package/dist/src/config.js +142 -0
  44. package/dist/src/config.js.map +7 -0
  45. package/dist/src/decay-engine.d.ts +73 -0
  46. package/dist/src/decay-engine.d.ts.map +1 -0
  47. package/dist/src/decay-engine.js +119 -0
  48. package/dist/src/decay-engine.js.map +7 -0
  49. package/dist/src/embedder.d.ts +94 -0
  50. package/dist/src/embedder.d.ts.map +1 -0
  51. package/{src/embedder.ts → dist/src/embedder.js} +119 -317
  52. package/dist/src/embedder.js.map +7 -0
  53. package/dist/src/extraction-prompts.d.ts +12 -0
  54. package/dist/src/extraction-prompts.d.ts.map +1 -0
  55. package/dist/src/extraction-prompts.js +311 -0
  56. package/dist/src/extraction-prompts.js.map +7 -0
  57. package/dist/src/license.d.ts +29 -0
  58. package/dist/src/license.d.ts.map +1 -0
  59. package/{src/license.ts → dist/src/license.js} +42 -113
  60. package/dist/src/license.js.map +7 -0
  61. package/dist/src/llm-client.d.ts +23 -0
  62. package/dist/src/llm-client.d.ts.map +1 -0
  63. package/{src/llm-client.ts → dist/src/llm-client.js} +22 -55
  64. package/dist/src/llm-client.js.map +7 -0
  65. package/dist/src/logger.d.ts +33 -0
  66. package/dist/src/logger.d.ts.map +1 -0
  67. package/dist/src/logger.js +35 -0
  68. package/dist/src/logger.js.map +7 -0
  69. package/dist/src/mcp-server.d.ts +16 -0
  70. package/dist/src/mcp-server.d.ts.map +1 -0
  71. package/{src/mcp-server.ts → dist/src/mcp-server.js} +81 -181
  72. package/dist/src/mcp-server.js.map +7 -0
  73. package/dist/src/memory-categories.d.ts +40 -0
  74. package/dist/src/memory-categories.d.ts.map +1 -0
  75. package/dist/src/memory-categories.js +33 -0
  76. package/dist/src/memory-categories.js.map +7 -0
  77. package/dist/src/memory-upgrader.d.ts +71 -0
  78. package/dist/src/memory-upgrader.d.ts.map +1 -0
  79. package/dist/src/memory-upgrader.js +238 -0
  80. package/dist/src/memory-upgrader.js.map +7 -0
  81. package/dist/src/migrate.d.ts +47 -0
  82. package/dist/src/migrate.d.ts.map +1 -0
  83. package/{src/migrate.ts → dist/src/migrate.js} +57 -165
  84. package/dist/src/migrate.js.map +7 -0
  85. package/dist/src/mnemo.d.ts +67 -0
  86. package/dist/src/mnemo.d.ts.map +1 -0
  87. package/dist/src/mnemo.js +66 -0
  88. package/dist/src/mnemo.js.map +7 -0
  89. package/dist/src/noise-filter.d.ts +23 -0
  90. package/dist/src/noise-filter.d.ts.map +1 -0
  91. package/dist/src/noise-filter.js +62 -0
  92. package/dist/src/noise-filter.js.map +7 -0
  93. package/dist/src/noise-prototypes.d.ts +40 -0
  94. package/dist/src/noise-prototypes.d.ts.map +1 -0
  95. package/dist/src/noise-prototypes.js +116 -0
  96. package/dist/src/noise-prototypes.js.map +7 -0
  97. package/dist/src/observability.d.ts +16 -0
  98. package/dist/src/observability.d.ts.map +1 -0
  99. package/dist/src/observability.js +53 -0
  100. package/dist/src/observability.js.map +7 -0
  101. package/dist/src/query-tracker.d.ts +27 -0
  102. package/dist/src/query-tracker.d.ts.map +1 -0
  103. package/dist/src/query-tracker.js +32 -0
  104. package/dist/src/query-tracker.js.map +7 -0
  105. package/dist/src/reflection-event-store.d.ts +44 -0
  106. package/dist/src/reflection-event-store.d.ts.map +1 -0
  107. package/dist/src/reflection-event-store.js +50 -0
  108. package/dist/src/reflection-event-store.js.map +7 -0
  109. package/dist/src/reflection-item-store.d.ts +58 -0
  110. package/dist/src/reflection-item-store.d.ts.map +1 -0
  111. package/dist/src/reflection-item-store.js +69 -0
  112. package/dist/src/reflection-item-store.js.map +7 -0
  113. package/dist/src/reflection-mapped-metadata.d.ts +47 -0
  114. package/dist/src/reflection-mapped-metadata.d.ts.map +1 -0
  115. package/dist/src/reflection-mapped-metadata.js +40 -0
  116. package/dist/src/reflection-mapped-metadata.js.map +7 -0
  117. package/dist/src/reflection-metadata.d.ts +11 -0
  118. package/dist/src/reflection-metadata.d.ts.map +1 -0
  119. package/dist/src/reflection-metadata.js +24 -0
  120. package/dist/src/reflection-metadata.js.map +7 -0
  121. package/dist/src/reflection-ranking.d.ts +13 -0
  122. package/dist/src/reflection-ranking.d.ts.map +1 -0
  123. package/{src/reflection-ranking.ts → dist/src/reflection-ranking.js} +12 -21
  124. package/dist/src/reflection-ranking.js.map +7 -0
  125. package/dist/src/reflection-retry.d.ts +30 -0
  126. package/dist/src/reflection-retry.d.ts.map +1 -0
  127. package/{src/reflection-retry.ts → dist/src/reflection-retry.js} +24 -64
  128. package/dist/src/reflection-retry.js.map +7 -0
  129. package/dist/src/reflection-slices.d.ts +42 -0
  130. package/dist/src/reflection-slices.d.ts.map +1 -0
  131. package/{src/reflection-slices.ts → dist/src/reflection-slices.js} +60 -136
  132. package/dist/src/reflection-slices.js.map +7 -0
  133. package/dist/src/reflection-store.d.ts +85 -0
  134. package/dist/src/reflection-store.d.ts.map +1 -0
  135. package/dist/src/reflection-store.js +407 -0
  136. package/dist/src/reflection-store.js.map +7 -0
  137. package/dist/src/resonance-state.d.ts +19 -0
  138. package/dist/src/resonance-state.d.ts.map +1 -0
  139. package/{src/resonance-state.ts → dist/src/resonance-state.js} +13 -42
  140. package/dist/src/resonance-state.js.map +7 -0
  141. package/dist/src/retriever.d.ts +228 -0
  142. package/dist/src/retriever.d.ts.map +1 -0
  143. package/dist/src/retriever.js +1006 -0
  144. package/dist/src/retriever.js.map +7 -0
  145. package/dist/src/scopes.d.ts +58 -0
  146. package/dist/src/scopes.d.ts.map +1 -0
  147. package/dist/src/scopes.js +252 -0
  148. package/dist/src/scopes.js.map +7 -0
  149. package/dist/src/self-improvement-files.d.ts +20 -0
  150. package/dist/src/self-improvement-files.d.ts.map +1 -0
  151. package/{src/self-improvement-files.ts → dist/src/self-improvement-files.js} +24 -49
  152. package/dist/src/self-improvement-files.js.map +7 -0
  153. package/dist/src/semantic-gate.d.ts +24 -0
  154. package/dist/src/semantic-gate.d.ts.map +1 -0
  155. package/dist/src/semantic-gate.js +86 -0
  156. package/dist/src/semantic-gate.js.map +7 -0
  157. package/dist/src/session-recovery.d.ts +9 -0
  158. package/dist/src/session-recovery.d.ts.map +1 -0
  159. package/{src/session-recovery.ts → dist/src/session-recovery.js} +40 -57
  160. package/dist/src/session-recovery.js.map +7 -0
  161. package/dist/src/smart-extractor.d.ts +107 -0
  162. package/dist/src/smart-extractor.d.ts.map +1 -0
  163. package/{src/smart-extractor.ts → dist/src/smart-extractor.js} +130 -383
  164. package/dist/src/smart-extractor.js.map +7 -0
  165. package/dist/src/smart-metadata.d.ts +103 -0
  166. package/dist/src/smart-metadata.d.ts.map +1 -0
  167. package/dist/src/smart-metadata.js +361 -0
  168. package/dist/src/smart-metadata.js.map +7 -0
  169. package/dist/src/storage-adapter.d.ts +102 -0
  170. package/dist/src/storage-adapter.d.ts.map +1 -0
  171. package/dist/src/storage-adapter.js +22 -0
  172. package/dist/src/storage-adapter.js.map +7 -0
  173. package/dist/src/store.d.ts +108 -0
  174. package/dist/src/store.d.ts.map +1 -0
  175. package/dist/src/store.js +939 -0
  176. package/dist/src/store.js.map +7 -0
  177. package/dist/src/tier-manager.d.ts +57 -0
  178. package/dist/src/tier-manager.d.ts.map +1 -0
  179. package/dist/src/tier-manager.js +80 -0
  180. package/dist/src/tier-manager.js.map +7 -0
  181. package/dist/src/tools.d.ts +43 -0
  182. package/dist/src/tools.d.ts.map +1 -0
  183. package/dist/src/tools.js +1075 -0
  184. package/dist/src/tools.js.map +7 -0
  185. package/dist/src/wal-recovery.d.ts +30 -0
  186. package/dist/src/wal-recovery.d.ts.map +1 -0
  187. package/{src/wal-recovery.ts → dist/src/wal-recovery.js} +26 -79
  188. package/dist/src/wal-recovery.js.map +7 -0
  189. package/package.json +21 -2
  190. package/openclaw.plugin.json +0 -815
  191. package/src/access-tracker.ts +0 -341
  192. package/src/adapters/README.md +0 -78
  193. package/src/adapters/qdrant.ts +0 -191
  194. package/src/adaptive-retrieval.ts +0 -90
  195. package/src/audit-log.ts +0 -238
  196. package/src/chunker.ts +0 -254
  197. package/src/config.ts +0 -271
  198. package/src/decay-engine.ts +0 -238
  199. package/src/extraction-prompts.ts +0 -339
  200. package/src/memory-categories.ts +0 -71
  201. package/src/memory-upgrader.ts +0 -388
  202. package/src/mnemo.ts +0 -142
  203. package/src/noise-filter.ts +0 -97
  204. package/src/noise-prototypes.ts +0 -164
  205. package/src/observability.ts +0 -81
  206. package/src/query-tracker.ts +0 -57
  207. package/src/reflection-event-store.ts +0 -98
  208. package/src/reflection-item-store.ts +0 -112
  209. package/src/reflection-mapped-metadata.ts +0 -84
  210. package/src/reflection-metadata.ts +0 -23
  211. package/src/reflection-store.ts +0 -602
  212. package/src/retriever.ts +0 -1510
  213. package/src/scopes.ts +0 -375
  214. package/src/semantic-gate.ts +0 -121
  215. package/src/smart-metadata.ts +0 -561
  216. package/src/storage-adapter.ts +0 -153
  217. package/src/store.ts +0 -1330
  218. package/src/tier-manager.ts +0 -189
  219. package/src/tools.ts +0 -1292
  220. package/test/core.test.mjs +0 -301
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/tools.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: LicenseRef-Mnemo-Pro\n/**\n * Agent Tool Definitions\n * Memory management tools for AI agents\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport type { OpenClawPluginApi } from \"openclaw/plugin-sdk\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { MemoryRetriever, RetrievalResult } from \"./retriever.js\";\nimport type { MemoryStore } from \"./store.js\";\nimport { isNoise } from \"./noise-filter.js\";\nimport type { MemoryScopeManager } from \"./scopes.js\";\nimport type { Embedder } from \"./embedder.js\";\nimport {\n buildSmartMetadata,\n parseSmartMetadata,\n stringifySmartMetadata,\n} from \"./smart-metadata.js\";\nimport { appendSelfImprovementEntry, ensureSelfImprovementLearningFiles } from \"./self-improvement-files.js\";\nimport { getDisplayCategoryTag } from \"./reflection-metadata.js\";\nimport { log } from \"./logger.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport const MEMORY_CATEGORIES = [\n \"preference\",\n \"fact\",\n \"decision\",\n \"entity\",\n \"reflection\",\n \"other\",\n] as const;\n\nfunction stringEnum<T extends readonly [string, ...string[]]>(values: T) {\n return Type.Unsafe<T[number]>({\n type: \"string\",\n enum: [...values],\n });\n}\nexport type MdMirrorWriter = (\n entry: { text: string; category: string; scope: string; timestamp?: number },\n meta?: { source?: string; agentId?: string },\n) => Promise<void>;\n\ninterface ToolContext {\n retriever: MemoryRetriever;\n store: MemoryStore;\n scopeManager: MemoryScopeManager;\n embedder: Embedder;\n agentId?: string;\n workspaceDir?: string;\n mdMirror?: MdMirrorWriter | null;\n}\n\nfunction resolveAgentId(runtimeAgentId: unknown, fallback?: string): string | undefined {\n if (typeof runtimeAgentId === \"string\" && runtimeAgentId.trim().length > 0) return runtimeAgentId;\n if (typeof fallback === \"string\" && fallback.trim().length > 0) return fallback;\n return undefined;\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nfunction clampInt(value: number, min: number, max: number): number {\n if (!Number.isFinite(value)) return min;\n return Math.min(max, Math.max(min, Math.floor(value)));\n}\n\nfunction clamp01(value: number, fallback = 0.7): number {\n if (!Number.isFinite(value)) return fallback;\n return Math.min(1, Math.max(0, value));\n}\n\nfunction sanitizeMemoryForSerialization(results: RetrievalResult[]) {\n return results.map((r) => ({\n id: r.entry.id,\n text: r.entry.text,\n category: getDisplayCategoryTag(r.entry),\n rawCategory: r.entry.category,\n scope: r.entry.scope,\n importance: r.entry.importance,\n score: r.score,\n sources: r.sources,\n }));\n}\n\nfunction parseAgentIdFromSessionKey(sessionKey: string | undefined): string | undefined {\n if (!sessionKey) return undefined;\n const m = /^agent:([^:]+):/.exec(sessionKey);\n return m?.[1];\n}\n\nfunction resolveRuntimeAgentId(\n staticAgentId: string | undefined,\n runtimeCtx: unknown,\n): string | undefined {\n if (!runtimeCtx || typeof runtimeCtx !== \"object\") return staticAgentId;\n const ctx = runtimeCtx as Record<string, unknown>;\n const ctxAgentId = typeof ctx.agentId === \"string\" ? ctx.agentId : undefined;\n const ctxSessionKey = typeof ctx.sessionKey === \"string\" ? ctx.sessionKey : undefined;\n return ctxAgentId || parseAgentIdFromSessionKey(ctxSessionKey) || staticAgentId;\n}\n\nfunction resolveToolContext(\n base: ToolContext,\n runtimeCtx: unknown,\n): ToolContext {\n return {\n ...base,\n agentId: resolveRuntimeAgentId(base.agentId, runtimeCtx),\n };\n}\n\nasync function sleep(ms: number): Promise<void> {\n await new Promise(resolve => setTimeout(resolve, ms));\n}\n\nasync function retrieveWithRetry(\n retriever: MemoryRetriever,\n params: {\n query: string;\n limit: number;\n scopeFilter?: string[];\n category?: string;\n },\n): Promise<RetrievalResult[]> {\n let results = await retriever.retrieve(params);\n if (results.length === 0) {\n await sleep(75);\n results = await retriever.retrieve(params);\n }\n return results;\n}\n\nfunction resolveWorkspaceDir(toolCtx: unknown, fallback?: string): string {\n const runtime = toolCtx as Record<string, unknown> | undefined;\n const runtimePath = typeof runtime?.workspaceDir === \"string\" ? runtime.workspaceDir.trim() : \"\";\n if (runtimePath) return runtimePath;\n if (fallback && fallback.trim()) return fallback;\n return join(homedir(), \".openclaw\", \"workspace\");\n}\n\nfunction escapeRegExp(input: string): string {\n return input.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nexport function registerSelfImprovementLogTool(api: OpenClawPluginApi, context: ToolContext) {\n api.registerTool(\n (toolCtx) => ({\n name: \"self_improvement_log\",\n label: \"Self-Improvement Log\",\n description: \"Log structured learning/error entries into .learnings for governance and later distillation.\",\n parameters: Type.Object({\n type: stringEnum([\"learning\", \"error\"]),\n summary: Type.String({ description: \"One-line summary\" }),\n details: Type.Optional(Type.String({ description: \"Detailed context or error output\" })),\n suggestedAction: Type.Optional(Type.String({ description: \"Concrete action to prevent recurrence\" })),\n category: Type.Optional(Type.String({ description: \"learning category (correction/best_practice/knowledge_gap) when type=learning\" })),\n area: Type.Optional(Type.String({ description: \"frontend|backend|infra|tests|docs|config or custom area\" })),\n priority: Type.Optional(Type.String({ description: \"low|medium|high|critical\" })),\n }),\n async execute(_toolCallId, params) {\n const {\n type,\n summary,\n details = \"\",\n suggestedAction = \"\",\n category = \"best_practice\",\n area = \"config\",\n priority = \"medium\",\n } = params as {\n type: \"learning\" | \"error\";\n summary: string;\n details?: string;\n suggestedAction?: string;\n category?: string;\n area?: string;\n priority?: string;\n };\n try {\n const workspaceDir = resolveWorkspaceDir(toolCtx, context.workspaceDir);\n const { id: entryId, filePath } = await appendSelfImprovementEntry({\n baseDir: workspaceDir,\n type,\n summary,\n details,\n suggestedAction,\n category,\n area,\n priority,\n source: \"mnemo/self_improvement_log\",\n });\n const fileName = type === \"learning\" ? \"LEARNINGS.md\" : \"ERRORS.md\";\n\n return {\n content: [{ type: \"text\", text: `Logged ${type} entry ${entryId} to .learnings/${fileName}` }],\n details: { action: \"logged\", type, id: entryId, filePath },\n };\n } catch (error) {\n return {\n content: [{ type: \"text\", text: `Failed to log self-improvement entry: ${error instanceof Error ? error.message : String(error)}` }],\n details: { error: \"self_improvement_log_failed\", message: String(error) },\n };\n }\n },\n }),\n { name: \"self_improvement_log\" }\n );\n}\n\nexport function registerSelfImprovementExtractSkillTool(api: OpenClawPluginApi, context: ToolContext) {\n api.registerTool(\n (toolCtx) => ({\n name: \"self_improvement_extract_skill\",\n label: \"Extract Skill From Learning\",\n description: \"Create a new skill scaffold from a learning entry and mark the source learning as promoted_to_skill.\",\n parameters: Type.Object({\n learningId: Type.String({ description: \"Learning ID like LRN-YYYYMMDD-001\" }),\n skillName: Type.String({ description: \"Skill folder name, lowercase with hyphens\" }),\n sourceFile: Type.Optional(stringEnum([\"LEARNINGS.md\", \"ERRORS.md\"])),\n outputDir: Type.Optional(Type.String({ description: \"Relative output dir under workspace (default: skills)\" })),\n }),\n async execute(_toolCallId, params) {\n const { learningId, skillName, sourceFile = \"LEARNINGS.md\", outputDir = \"skills\" } = params as {\n learningId: string;\n skillName: string;\n sourceFile?: \"LEARNINGS.md\" | \"ERRORS.md\";\n outputDir?: string;\n };\n try {\n if (!/^(LRN|ERR)-\\d{8}-\\d{3}$/.test(learningId)) {\n return {\n content: [{ type: \"text\", text: \"Invalid learningId format. Use LRN-YYYYMMDD-001 / ERR-...\" }],\n details: { error: \"invalid_learning_id\" },\n };\n }\n if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(skillName)) {\n return {\n content: [{ type: \"text\", text: \"Invalid skillName. Use lowercase letters, numbers, and hyphens only.\" }],\n details: { error: \"invalid_skill_name\" },\n };\n }\n\n const workspaceDir = resolveWorkspaceDir(toolCtx, context.workspaceDir);\n await ensureSelfImprovementLearningFiles(workspaceDir);\n const learningsPath = join(workspaceDir, \".learnings\", sourceFile);\n const learningBody = await readFile(learningsPath, \"utf-8\");\n const escapedLearningId = escapeRegExp(learningId.trim());\n const entryRegex = new RegExp(`## \\\\[${escapedLearningId}\\\\][\\\\s\\\\S]*?(?=\\\\n## \\\\[|$)`, \"m\");\n const match = learningBody.match(entryRegex);\n if (!match) {\n return {\n content: [{ type: \"text\", text: `Learning entry ${learningId} not found in .learnings/${sourceFile}` }],\n details: { error: \"learning_not_found\", learningId, sourceFile },\n };\n }\n\n const summaryMatch = match[0].match(/### Summary\\n([\\s\\S]*?)\\n###/m);\n const summary = (summaryMatch?.[1] ?? \"Summarize the source learning here.\").trim();\n const safeOutputDir = outputDir\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .filter((segment) => segment && segment !== \".\" && segment !== \"..\")\n .join(\"/\");\n const skillDir = join(workspaceDir, safeOutputDir || \"skills\", skillName);\n await mkdir(skillDir, { recursive: true });\n const skillPath = join(skillDir, \"SKILL.md\");\n const skillTitle = skillName\n .split(\"-\")\n .map((s) => s.charAt(0).toUpperCase() + s.slice(1))\n .join(\" \");\n const skillContent = [\n \"---\",\n `name: ${skillName}`,\n `description: \"Extracted from learning ${learningId}. Replace with a concise description.\"`,\n \"---\",\n \"\",\n `# ${skillTitle}`,\n \"\",\n \"## Why\",\n summary,\n \"\",\n \"## When To Use\",\n \"- [TODO] Define trigger conditions\",\n \"\",\n \"## Steps\",\n \"1. [TODO] Add repeatable workflow steps\",\n \"2. [TODO] Add verification steps\",\n \"\",\n \"## Source Learning\",\n `- Learning ID: ${learningId}`,\n `- Source File: .learnings/${sourceFile}`,\n \"\",\n ].join(\"\\n\");\n await writeFile(skillPath, skillContent, \"utf-8\");\n\n const promotedMarker = `**Status**: promoted_to_skill`;\n const skillPathMarker = `- Skill-Path: ${safeOutputDir || \"skills\"}/${skillName}`;\n let updatedEntry = match[0];\n updatedEntry = updatedEntry.includes(\"**Status**:\")\n ? updatedEntry.replace(/\\*\\*Status\\*\\*:\\s*.+/m, promotedMarker)\n : `${updatedEntry.trimEnd()}\\n${promotedMarker}\\n`;\n if (!updatedEntry.includes(\"Skill-Path:\")) {\n updatedEntry = `${updatedEntry.trimEnd()}\\n${skillPathMarker}\\n`;\n }\n const updatedLearningBody = learningBody.replace(match[0], updatedEntry);\n await writeFile(learningsPath, updatedLearningBody, \"utf-8\");\n\n return {\n content: [{ type: \"text\", text: `Extracted skill scaffold to ${safeOutputDir || \"skills\"}/${skillName}/SKILL.md and updated ${learningId}.` }],\n details: {\n action: \"skill_extracted\",\n learningId,\n sourceFile,\n skillPath: `${safeOutputDir || \"skills\"}/${skillName}/SKILL.md`,\n },\n };\n } catch (error) {\n return {\n content: [{ type: \"text\", text: `Failed to extract skill: ${error instanceof Error ? error.message : String(error)}` }],\n details: { error: \"self_improvement_extract_skill_failed\", message: String(error) },\n };\n }\n },\n }),\n { name: \"self_improvement_extract_skill\" }\n );\n}\n\nexport function registerSelfImprovementReviewTool(api: OpenClawPluginApi, context: ToolContext) {\n api.registerTool(\n (toolCtx) => ({\n name: \"self_improvement_review\",\n label: \"Self-Improvement Review\",\n description: \"Summarize governance backlog from .learnings files (pending/high-priority/promoted counts).\",\n parameters: Type.Object({}),\n async execute() {\n try {\n const workspaceDir = resolveWorkspaceDir(toolCtx, context.workspaceDir);\n await ensureSelfImprovementLearningFiles(workspaceDir);\n const learningsDir = join(workspaceDir, \".learnings\");\n const files = [\"LEARNINGS.md\", \"ERRORS.md\"] as const;\n const stats = { pending: 0, high: 0, promoted: 0, total: 0 };\n\n for (const f of files) {\n const content = await readFile(join(learningsDir, f), \"utf-8\").catch(() => \"\");\n stats.total += (content.match(/^## \\[/gm) || []).length;\n stats.pending += (content.match(/\\*\\*Status\\*\\*:\\s*pending/gi) || []).length;\n stats.high += (content.match(/\\*\\*Priority\\*\\*:\\s*(high|critical)/gi) || []).length;\n stats.promoted += (content.match(/\\*\\*Status\\*\\*:\\s*promoted(_to_skill)?/gi) || []).length;\n }\n\n const text = [\n \"Self-Improvement Governance Snapshot:\",\n `- Total entries: ${stats.total}`,\n `- Pending: ${stats.pending}`,\n `- High/Critical: ${stats.high}`,\n `- Promoted: ${stats.promoted}`,\n \"\",\n \"Recommended loop:\",\n \"1) Resolve high-priority pending entries\",\n \"2) Distill reusable rules into AGENTS.md / SOUL.md / TOOLS.md\",\n \"3) Extract repeatable patterns as skills\",\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text }],\n details: { action: \"review\", stats },\n };\n } catch (error) {\n return {\n content: [{ type: \"text\", text: `Failed to review self-improvement backlog: ${error instanceof Error ? error.message : String(error)}` }],\n details: { error: \"self_improvement_review_failed\", message: String(error) },\n };\n }\n },\n }),\n { name: \"self_improvement_review\" }\n );\n}\n\n// ============================================================================\n// Core Tools (Backward Compatible)\n// ============================================================================\n\nexport function registerMemoryRecallTool(\n api: OpenClawPluginApi,\n context: ToolContext,\n) {\n api.registerTool(\n (toolCtx) => {\n const runtimeContext = resolveToolContext(context, toolCtx);\n return {\n name: \"memory_recall\",\n label: \"Memory Recall\",\n description:\n \"Search through long-term memories using hybrid retrieval (vector + keyword search). Use when you need context about user preferences, past decisions, or previously discussed topics.\",\n parameters: Type.Object({\n query: Type.String({\n description: \"Search query for finding relevant memories\",\n }),\n limit: Type.Optional(\n Type.Number({\n description: \"Max results to return (default: 5, max: 20)\",\n }),\n ),\n scope: Type.Optional(\n Type.String({\n description: \"Specific memory scope to search in (optional)\",\n }),\n ),\n category: Type.Optional(stringEnum(MEMORY_CATEGORIES)),\n }),\n async execute(_toolCallId, params) {\n const {\n query,\n limit = 5,\n scope,\n category,\n } = params as {\n query: string;\n limit?: number;\n scope?: string;\n category?: string;\n };\n\n try {\n const safeLimit = clampInt(limit, 1, 20);\n const agentId = runtimeContext.agentId;\n\n // Determine accessible scopes\n let scopeFilter = runtimeContext.scopeManager.getAccessibleScopes(agentId);\n if (scope) {\n if (runtimeContext.scopeManager.isAccessible(scope, agentId)) {\n scopeFilter = [scope];\n } else {\n return {\n content: [\n { type: \"text\", text: `Access denied to scope: ${scope}` },\n ],\n details: {\n error: \"scope_access_denied\",\n requestedScope: scope,\n },\n };\n }\n }\n\n const results = await retrieveWithRetry(runtimeContext.retriever, {\n query,\n limit: safeLimit,\n scopeFilter,\n category,\n source: \"manual\",\n });\n\n if (results.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No relevant memories found.\" }],\n details: { count: 0, query, scopes: scopeFilter },\n };\n }\n\n const now = Date.now();\n await Promise.allSettled(\n results.map((result) => {\n const meta = parseSmartMetadata(result.entry.metadata, result.entry);\n return runtimeContext.store.patchMetadata(\n result.entry.id,\n {\n access_count: meta.access_count + 1,\n last_accessed_at: now,\n },\n scopeFilter,\n );\n }),\n );\n\n const text = results\n .map((r, i) => {\n const categoryTag = getDisplayCategoryTag(r.entry);\n return `${i + 1}. [${r.entry.id}] [${categoryTag}] ${r.entry.text}`;\n })\n .join(\"\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: `Found ${results.length} memories:\\n\\n${text}`,\n },\n ],\n details: {\n count: results.length,\n memories: sanitizeMemoryForSerialization(results),\n query,\n scopes: scopeFilter,\n retrievalMode: runtimeContext.retriever.getConfig().mode,\n },\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\",\n text: `Memory recall failed: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n details: { error: \"recall_failed\", message: String(error) },\n };\n }\n },\n };\n },\n { name: \"memory_recall\" },\n );\n}\n\nexport function registerMemoryStoreTool(\n api: OpenClawPluginApi,\n context: ToolContext,\n) {\n api.registerTool(\n (toolCtx) => {\n const runtimeContext = resolveToolContext(context, toolCtx);\n return {\n name: \"memory_store\",\n label: \"Memory Store\",\n description:\n \"Save important information in long-term memory. Use for preferences, facts, decisions, and other notable information.\",\n parameters: Type.Object({\n text: Type.String({ description: \"Information to remember\" }),\n importance: Type.Optional(\n Type.Number({ description: \"Importance score 0-1 (default: 0.7)\" }),\n ),\n category: Type.Optional(stringEnum(MEMORY_CATEGORIES)),\n scope: Type.Optional(\n Type.String({\n description: \"Memory scope (optional, defaults to agent scope)\",\n }),\n ),\n }),\n async execute(_toolCallId, params) {\n const {\n text,\n importance = 0.7,\n category = \"other\",\n scope,\n } = params as {\n text: string;\n importance?: number;\n category?: string;\n scope?: string;\n };\n\n try {\n const agentId = runtimeContext.agentId;\n // Determine target scope\n let targetScope = scope || runtimeContext.scopeManager.getDefaultScope(agentId);\n\n // Validate scope access\n if (!runtimeContext.scopeManager.isAccessible(targetScope, agentId)) {\n return {\n content: [\n {\n type: \"text\",\n text: `Access denied to scope: ${targetScope}`,\n },\n ],\n details: {\n error: \"scope_access_denied\",\n requestedScope: targetScope,\n },\n };\n }\n\n // Reject noise before wasting an embedding API call\n if (isNoise(text)) {\n return {\n content: [\n {\n type: \"text\",\n text: `Skipped: text detected as noise (greeting, boilerplate, or meta-question)`,\n },\n ],\n details: { action: \"noise_filtered\", text: text.slice(0, 60) },\n };\n }\n\n const safeImportance = clamp01(importance, 0.7);\n const vector = await runtimeContext.embedder.embedPassage(text);\n\n // Check for duplicates using raw vector similarity (bypasses importance/recency weighting)\n // Fail-open by design: dedup must never block a legitimate memory write.\n let existing: Awaited<ReturnType<MemoryStore[\"vectorSearch\"]>> = [];\n try {\n existing = await runtimeContext.store.vectorSearch(vector, 1, 0.1, [\n targetScope,\n ]);\n } catch (err) {\n log.warn(\n `duplicate pre-check failed, continue store: ${String(err)}`,\n );\n }\n\n if (existing.length > 0 && existing[0].score > 0.98) {\n return {\n content: [\n {\n type: \"text\",\n text: `Similar memory already exists: \"${existing[0].entry.text}\"`,\n },\n ],\n details: {\n action: \"duplicate\",\n existingId: existing[0].entry.id,\n existingText: existing[0].entry.text,\n existingScope: existing[0].entry.scope,\n similarity: existing[0].score,\n },\n };\n }\n\n const entry = await runtimeContext.store.store({\n text,\n vector,\n importance: safeImportance,\n category: category as any,\n scope: targetScope,\n metadata: stringifySmartMetadata(\n buildSmartMetadata(\n {\n text,\n category: category as any,\n importance: safeImportance,\n },\n {\n l0_abstract: text,\n l1_overview: `- ${text}`,\n l2_content: text,\n },\n ),\n ),\n });\n\n // Dual-write to Markdown mirror if enabled\n if (context.mdMirror) {\n await context.mdMirror(\n { text, category: category as string, scope: targetScope, timestamp: entry.timestamp },\n { source: \"memory_store\", agentId },\n );\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `Stored: \"${text.slice(0, 100)}${text.length > 100 ? \"...\" : \"\"}\" in scope '${targetScope}'`,\n },\n ],\n details: {\n action: \"created\",\n id: entry.id,\n scope: entry.scope,\n category: entry.category,\n importance: entry.importance,\n },\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\",\n text: `Memory storage failed: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n details: { error: \"store_failed\", message: String(error) },\n };\n }\n },\n };\n },\n { name: \"memory_store\" },\n );\n}\n\nexport function registerMemoryForgetTool(\n api: OpenClawPluginApi,\n context: ToolContext,\n) {\n api.registerTool(\n (toolCtx) => {\n const agentId = resolveAgentId((toolCtx as any)?.agentId, context.agentId) ?? \"main\";\n return {\n name: \"memory_forget\",\n label: \"Memory Forget\",\n description:\n \"Delete specific memories. Supports both search-based and direct ID-based deletion.\",\n parameters: Type.Object({\n query: Type.Optional(\n Type.String({ description: \"Search query to find memory to delete\" }),\n ),\n memoryId: Type.Optional(\n Type.String({ description: \"Specific memory ID to delete\" }),\n ),\n scope: Type.Optional(\n Type.String({\n description: \"Scope to search/delete from (optional)\",\n }),\n ),\n }),\n async execute(_toolCallId, params, _signal, _onUpdate, runtimeCtx) {\n const { query, memoryId, scope } = params as {\n query?: string;\n memoryId?: string;\n scope?: string;\n };\n\n try {\n const agentId = resolveRuntimeAgentId(context.agentId, runtimeCtx);\n // Determine accessible scopes\n let scopeFilter = context.scopeManager.getAccessibleScopes(agentId);\n if (scope) {\n if (context.scopeManager.isAccessible(scope, agentId)) {\n scopeFilter = [scope];\n } else {\n return {\n content: [\n { type: \"text\", text: `Access denied to scope: ${scope}` },\n ],\n details: {\n error: \"scope_access_denied\",\n requestedScope: scope,\n },\n };\n }\n }\n\n if (memoryId) {\n const deleted = await context.store.delete(memoryId, scopeFilter);\n if (deleted) {\n return {\n content: [\n { type: \"text\", text: `Memory ${memoryId} forgotten.` },\n ],\n details: { action: \"deleted\", id: memoryId },\n };\n } else {\n return {\n content: [\n {\n type: \"text\",\n text: `Memory ${memoryId} not found or access denied.`,\n },\n ],\n details: { error: \"not_found\", id: memoryId },\n };\n }\n }\n\n if (query) {\n const results = await retrieveWithRetry(context.retriever, {\n query,\n limit: 5,\n scopeFilter,\n });\n\n if (results.length === 0) {\n return {\n content: [\n { type: \"text\", text: \"No matching memories found.\" },\n ],\n details: { found: 0, query },\n };\n }\n\n if (results.length === 1 && results[0].score > 0.9) {\n const deleted = await context.store.delete(\n results[0].entry.id,\n scopeFilter,\n );\n if (deleted) {\n return {\n content: [\n {\n type: \"text\",\n text: `Forgotten: \"${results[0].entry.text}\"`,\n },\n ],\n details: { action: \"deleted\", id: results[0].entry.id },\n };\n }\n }\n\n const list = results\n .map(\n (r) =>\n `- [${r.entry.id.slice(0, 8)}] ${r.entry.text.slice(0, 60)}${r.entry.text.length > 60 ? \"...\" : \"\"}`,\n )\n .join(\"\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: `Found ${results.length} candidates. Specify memoryId to delete:\\n${list}`,\n },\n ],\n details: {\n action: \"candidates\",\n candidates: sanitizeMemoryForSerialization(results),\n },\n };\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: \"Provide either 'query' to search for memories or 'memoryId' to delete specific memory.\",\n },\n ],\n details: { error: \"missing_param\" },\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\",\n text: `Memory deletion failed: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n details: { error: \"delete_failed\", message: String(error) },\n };\n }\n },\n };\n },\n { name: \"memory_forget\" },\n );\n}\n\n// ============================================================================\n// Update Tool\n// ============================================================================\n\nexport function registerMemoryUpdateTool(\n api: OpenClawPluginApi,\n context: ToolContext,\n) {\n api.registerTool(\n (toolCtx) => {\n const agentId = resolveAgentId((toolCtx as any)?.agentId, context.agentId) ?? \"main\";\n return {\n name: \"memory_update\",\n label: \"Memory Update\",\n description:\n \"Update an existing memory in-place. Preserves original timestamp. Use when correcting outdated info or adjusting importance/category without losing creation date.\",\n parameters: Type.Object({\n memoryId: Type.String({\n description:\n \"ID of the memory to update (full UUID or 8+ char prefix)\",\n }),\n text: Type.Optional(\n Type.String({\n description: \"New text content (triggers re-embedding)\",\n }),\n ),\n importance: Type.Optional(\n Type.Number({ description: \"New importance score 0-1\" }),\n ),\n category: Type.Optional(stringEnum(MEMORY_CATEGORIES)),\n }),\n async execute(_toolCallId, params, _signal, _onUpdate, runtimeCtx) {\n const { memoryId, text, importance, category } = params as {\n memoryId: string;\n text?: string;\n importance?: number;\n category?: string;\n };\n\n try {\n if (!text && importance === undefined && !category) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Nothing to update. Provide at least one of: text, importance, category.\",\n },\n ],\n details: { error: \"no_updates\" },\n };\n }\n\n // Determine accessible scopes\n const agentId = resolveRuntimeAgentId(context.agentId, runtimeCtx);\n const scopeFilter = context.scopeManager.getAccessibleScopes(agentId);\n\n // Resolve memoryId: if it doesn't look like a UUID, try search\n let resolvedId = memoryId;\n const uuidLike = /^[0-9a-f]{8}(-[0-9a-f]{4}){0,4}/i.test(memoryId);\n if (!uuidLike) {\n // Treat as search query\n const results = await retrieveWithRetry(context.retriever, {\n query: memoryId,\n limit: 3,\n scopeFilter,\n });\n if (results.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: `No memory found matching \"${memoryId}\".`,\n },\n ],\n details: { error: \"not_found\", query: memoryId },\n };\n }\n if (results.length === 1 || results[0].score > 0.85) {\n resolvedId = results[0].entry.id;\n } else {\n const list = results\n .map(\n (r) =>\n `- [${r.entry.id.slice(0, 8)}] ${r.entry.text.slice(0, 60)}${r.entry.text.length > 60 ? \"...\" : \"\"}`,\n )\n .join(\"\\n\");\n return {\n content: [\n {\n type: \"text\",\n text: `Multiple matches. Specify memoryId:\\n${list}`,\n },\n ],\n details: {\n action: \"candidates\",\n candidates: sanitizeMemoryForSerialization(results),\n },\n };\n }\n }\n\n // If text changed, re-embed; reject noise\n let newVector: number[] | undefined;\n if (text) {\n if (isNoise(text)) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Skipped: updated text detected as noise\",\n },\n ],\n details: { action: \"noise_filtered\" },\n };\n }\n newVector = await context.embedder.embedPassage(text);\n }\n\n const updates: Record<string, any> = {};\n if (text) updates.text = text;\n if (newVector) updates.vector = newVector;\n if (importance !== undefined)\n updates.importance = clamp01(importance, 0.7);\n if (category) updates.category = category;\n\n const updated = await context.store.update(\n resolvedId,\n updates,\n scopeFilter,\n );\n\n if (!updated) {\n return {\n content: [\n {\n type: \"text\",\n text: `Memory ${resolvedId.slice(0, 8)}... not found or access denied.`,\n },\n ],\n details: { error: \"not_found\", id: resolvedId },\n };\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `Updated memory ${updated.id.slice(0, 8)}...: \"${updated.text.slice(0, 80)}${updated.text.length > 80 ? \"...\" : \"\"}\"`,\n },\n ],\n details: {\n action: \"updated\",\n id: updated.id,\n scope: updated.scope,\n category: updated.category,\n importance: updated.importance,\n fieldsUpdated: Object.keys(updates),\n },\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\",\n text: `Memory update failed: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n details: { error: \"update_failed\", message: String(error) },\n };\n }\n },\n };\n },\n { name: \"memory_update\" },\n );\n}\n\n// ============================================================================\n// Management Tools (Optional)\n// ============================================================================\n\nexport function registerMemoryStatsTool(\n api: OpenClawPluginApi,\n context: ToolContext,\n) {\n api.registerTool(\n (toolCtx) => {\n const agentId = resolveAgentId((toolCtx as any)?.agentId, context.agentId) ?? \"main\";\n return {\n name: \"memory_stats\",\n label: \"Memory Statistics\",\n description: \"Get statistics about memory usage, scopes, and categories.\",\n parameters: Type.Object({\n scope: Type.Optional(\n Type.String({\n description: \"Specific scope to get stats for (optional)\",\n }),\n ),\n }),\n async execute(_toolCallId, params, _signal, _onUpdate, runtimeCtx) {\n const { scope } = params as { scope?: string };\n\n try {\n const agentId = resolveRuntimeAgentId(context.agentId, runtimeCtx);\n // Determine accessible scopes\n let scopeFilter = context.scopeManager.getAccessibleScopes(agentId);\n if (scope) {\n if (context.scopeManager.isAccessible(scope, agentId)) {\n scopeFilter = [scope];\n } else {\n return {\n content: [\n { type: \"text\", text: `Access denied to scope: ${scope}` },\n ],\n details: {\n error: \"scope_access_denied\",\n requestedScope: scope,\n },\n };\n }\n }\n\n const stats = await context.store.stats(scopeFilter);\n const scopeManagerStats = context.scopeManager.getStats();\n const retrievalConfig = context.retriever.getConfig();\n\n const text = [\n `Memory Statistics:`,\n `\u2022 Total memories: ${stats.totalCount}`,\n `\u2022 Available scopes: ${scopeManagerStats.totalScopes}`,\n `\u2022 Retrieval mode: ${retrievalConfig.mode}`,\n `\u2022 FTS support: ${context.store.hasFtsSupport ? \"Yes\" : \"No\"}`,\n ``,\n `Memories by scope:`,\n ...Object.entries(stats.scopeCounts).map(\n ([s, count]) => ` \u2022 ${s}: ${count}`,\n ),\n ``,\n `Memories by category:`,\n ...Object.entries(stats.categoryCounts).map(\n ([c, count]) => ` \u2022 ${c}: ${count}`,\n ),\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text }],\n details: {\n stats,\n scopeManagerStats,\n retrievalConfig: {\n ...retrievalConfig,\n rerankApiKey: retrievalConfig.rerankApiKey ? \"***\" : undefined,\n },\n hasFtsSupport: context.store.hasFtsSupport,\n },\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\",\n text: `Failed to get memory stats: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n details: { error: \"stats_failed\", message: String(error) },\n };\n }\n },\n };\n },\n { name: \"memory_stats\" },\n );\n}\n\nexport function registerMemoryListTool(\n api: OpenClawPluginApi,\n context: ToolContext,\n) {\n api.registerTool(\n (toolCtx) => {\n const agentId = resolveAgentId((toolCtx as any)?.agentId, context.agentId) ?? \"main\";\n return {\n name: \"memory_list\",\n label: \"Memory List\",\n description:\n \"List recent memories with optional filtering by scope and category.\",\n parameters: Type.Object({\n limit: Type.Optional(\n Type.Number({\n description: \"Max memories to list (default: 10, max: 50)\",\n }),\n ),\n scope: Type.Optional(\n Type.String({ description: \"Filter by specific scope (optional)\" }),\n ),\n category: Type.Optional(stringEnum(MEMORY_CATEGORIES)),\n offset: Type.Optional(\n Type.Number({\n description: \"Number of memories to skip (default: 0)\",\n }),\n ),\n }),\n async execute(_toolCallId, params, _signal, _onUpdate, runtimeCtx) {\n const {\n limit = 10,\n scope,\n category,\n offset = 0,\n } = params as {\n limit?: number;\n scope?: string;\n category?: string;\n offset?: number;\n };\n\n try {\n const safeLimit = clampInt(limit, 1, 50);\n const safeOffset = clampInt(offset, 0, 1000);\n const agentId = resolveRuntimeAgentId(context.agentId, runtimeCtx);\n\n // Determine accessible scopes\n let scopeFilter = context.scopeManager.getAccessibleScopes(agentId);\n if (scope) {\n if (context.scopeManager.isAccessible(scope, agentId)) {\n scopeFilter = [scope];\n } else {\n return {\n content: [\n { type: \"text\", text: `Access denied to scope: ${scope}` },\n ],\n details: {\n error: \"scope_access_denied\",\n requestedScope: scope,\n },\n };\n }\n }\n\n const entries = await context.store.list(\n scopeFilter,\n category,\n safeLimit,\n safeOffset,\n );\n\n if (entries.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No memories found.\" }],\n details: {\n count: 0,\n filters: {\n scope,\n category,\n limit: safeLimit,\n offset: safeOffset,\n },\n },\n };\n }\n\n const text = entries\n .map((entry, i) => {\n const date = new Date(entry.timestamp)\n .toISOString()\n .split(\"T\")[0];\n const categoryTag = getDisplayCategoryTag(entry);\n return `${safeOffset + i + 1}. [${entry.id}] [${categoryTag}] ${entry.text.slice(0, 100)}${entry.text.length > 100 ? \"...\" : \"\"} (${date})`;\n })\n .join(\"\\n\");\n\n return {\n content: [\n {\n type: \"text\",\n text: `Recent memories (showing ${entries.length}):\\n\\n${text}`,\n },\n ],\n details: {\n count: entries.length,\n memories: entries.map((e) => ({\n id: e.id,\n text: e.text,\n category: getDisplayCategoryTag(e),\n rawCategory: e.category,\n scope: e.scope,\n importance: e.importance,\n timestamp: e.timestamp,\n })),\n filters: {\n scope,\n category,\n limit: safeLimit,\n offset: safeOffset,\n },\n },\n };\n } catch (error) {\n return {\n content: [\n {\n type: \"text\",\n text: `Failed to list memories: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n details: { error: \"list_failed\", message: String(error) },\n };\n }\n },\n };\n },\n { name: \"memory_list\" },\n );\n}\n\n// ============================================================================\n// Tool Registration Helper\n// ============================================================================\n\nexport function registerAllMemoryTools(\n api: OpenClawPluginApi,\n context: ToolContext,\n options: {\n enableManagementTools?: boolean;\n enableSelfImprovementTools?: boolean;\n } = {},\n) {\n // Core tools (always enabled)\n registerMemoryRecallTool(api, context);\n registerMemoryStoreTool(api, context);\n registerMemoryForgetTool(api, context);\n registerMemoryUpdateTool(api, context);\n\n // Management tools (optional)\n if (options.enableManagementTools) {\n registerMemoryStatsTool(api, context);\n registerMemoryListTool(api, context);\n }\n if (options.enableSelfImprovementTools !== false) {\n registerSelfImprovementLogTool(api, context);\n if (options.enableManagementTools) {\n registerSelfImprovementExtractSkillTool(api, context);\n registerSelfImprovementReviewTool(api, context);\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["agentId"]
7
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Graphiti Write-Ahead Log (WAL) + Recovery
3
+ *
4
+ * Ensures Graphiti writes survive transient failures by logging pending writes
5
+ * to a JSONL file. On plugin startup, pending entries older than 1 hour are
6
+ * retried automatically.
7
+ */
8
+ export interface WalEntry {
9
+ ts: string;
10
+ action: "write";
11
+ text: string;
12
+ scope: string;
13
+ category: string;
14
+ groupId: string;
15
+ importance: number;
16
+ status: "pending" | "committed" | "failed";
17
+ error?: string;
18
+ }
19
+ export declare function walAppend(entry: WalEntry): Promise<void>;
20
+ export declare function walMarkCommitted(ts: string): Promise<void>;
21
+ export declare function walMarkFailed(ts: string, error: string): Promise<void>;
22
+ /**
23
+ * Scan the WAL file for entries with status=pending whose ts > 1 hour ago.
24
+ * Retry writing them to Graphiti and mark as committed or failed.
25
+ */
26
+ export declare function recoverPendingWrites(): Promise<{
27
+ recovered: number;
28
+ failed: number;
29
+ }>;
30
+ //# sourceMappingURL=wal-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wal-recovery.d.ts","sourceRoot":"","sources":["../../src/wal-recovery.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAkBH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAUD,wBAAsB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9D;AAED,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAahE;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc5E;AAMD;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAkF3F"}
@@ -1,55 +1,19 @@
1
- // SPDX-License-Identifier: LicenseRef-Mnemo-Pro
2
- /**
3
- * Graphiti Write-Ahead Log (WAL) + Recovery
4
- *
5
- * Ensures Graphiti writes survive transient failures by logging pending writes
6
- * to a JSONL file. On plugin startup, pending entries older than 1 hour are
7
- * retried automatically.
8
- */
9
-
10
1
  import { appendFile, readFile, mkdir } from "node:fs/promises";
11
2
  import { existsSync } from "node:fs";
12
3
  import { homedir } from "node:os";
13
4
  import { join, dirname } from "node:path";
14
-
15
- // ============================================================================
16
- // WAL Path
17
- // ============================================================================
18
-
5
+ import { log } from "./logger.js";
19
6
  const WAL_PATH = join(homedir(), ".openclaw", "memory", "graphiti-wal.jsonl");
20
-
21
- // ============================================================================
22
- // WAL Entry Types
23
- // ============================================================================
24
-
25
- export interface WalEntry {
26
- ts: string;
27
- action: "write";
28
- text: string;
29
- scope: string;
30
- category: string;
31
- groupId: string;
32
- importance: number;
33
- status: "pending" | "committed" | "failed";
34
- error?: string;
35
- }
36
-
37
- // ============================================================================
38
- // WAL Writer
39
- // ============================================================================
40
-
41
- async function ensureWalDir(): Promise<void> {
7
+ async function ensureWalDir() {
42
8
  await mkdir(dirname(WAL_PATH), { recursive: true });
43
9
  }
44
-
45
- export async function walAppend(entry: WalEntry): Promise<void> {
10
+ async function walAppend(entry) {
46
11
  await ensureWalDir();
47
12
  const line = JSON.stringify(entry) + "\n";
48
13
  await appendFile(WAL_PATH, line, "utf8");
49
14
  }
50
-
51
- export async function walMarkCommitted(ts: string): Promise<void> {
52
- const entry: WalEntry = {
15
+ async function walMarkCommitted(ts) {
16
+ const entry = {
53
17
  ts,
54
18
  action: "write",
55
19
  text: "",
@@ -57,14 +21,13 @@ export async function walMarkCommitted(ts: string): Promise<void> {
57
21
  category: "",
58
22
  groupId: "",
59
23
  importance: 0,
60
- status: "committed",
24
+ status: "committed"
61
25
  };
62
26
  await ensureWalDir();
63
27
  await appendFile(WAL_PATH, JSON.stringify(entry) + "\n", "utf8");
64
28
  }
65
-
66
- export async function walMarkFailed(ts: string, error: string): Promise<void> {
67
- const entry: WalEntry = {
29
+ async function walMarkFailed(ts, error) {
30
+ const entry = {
68
31
  ts,
69
32
  action: "write",
70
33
  text: "",
@@ -73,52 +36,35 @@ export async function walMarkFailed(ts: string, error: string): Promise<void> {
73
36
  groupId: "",
74
37
  importance: 0,
75
38
  status: "failed",
76
- error,
39
+ error
77
40
  };
78
41
  await ensureWalDir();
79
42
  await appendFile(WAL_PATH, JSON.stringify(entry) + "\n", "utf8");
80
43
  }
81
-
82
- // ============================================================================
83
- // WAL Recovery
84
- // ============================================================================
85
-
86
- /**
87
- * Scan the WAL file for entries with status=pending whose ts > 1 hour ago.
88
- * Retry writing them to Graphiti and mark as committed or failed.
89
- */
90
- export async function recoverPendingWrites(): Promise<{ recovered: number; failed: number }> {
44
+ async function recoverPendingWrites() {
91
45
  if (!existsSync(WAL_PATH)) {
92
46
  return { recovered: 0, failed: 0 };
93
47
  }
94
-
95
- let raw: string;
48
+ let raw;
96
49
  try {
97
50
  raw = await readFile(WAL_PATH, "utf8");
98
51
  } catch {
99
52
  return { recovered: 0, failed: 0 };
100
53
  }
101
-
102
54
  const lines = raw.split("\n").filter((l) => l.trim().length > 0);
103
-
104
- // Build a map of latest status per ts
105
- const statusMap = new Map<string, WalEntry>();
55
+ const statusMap = /* @__PURE__ */ new Map();
106
56
  for (const line of lines) {
107
57
  try {
108
- const entry = JSON.parse(line) as WalEntry;
109
- // Later entries for the same ts override earlier ones
58
+ const entry = JSON.parse(line);
110
59
  const existing = statusMap.get(entry.ts);
111
60
  if (!existing || entry.status !== "pending") {
112
61
  statusMap.set(entry.ts, entry);
113
62
  }
114
63
  } catch {
115
- // Skip malformed lines
116
64
  }
117
65
  }
118
-
119
- // Find pending entries older than 1 hour
120
- const oneHourAgo = Date.now() - 60 * 60 * 1000;
121
- const pending: WalEntry[] = [];
66
+ const oneHourAgo = Date.now() - 60 * 60 * 1e3;
67
+ const pending = [];
122
68
  for (const entry of statusMap.values()) {
123
69
  if (entry.status === "pending") {
124
70
  const entryTime = new Date(entry.ts).getTime();
@@ -127,15 +73,12 @@ export async function recoverPendingWrites(): Promise<{ recovered: number; faile
127
73
  }
128
74
  }
129
75
  }
130
-
131
76
  if (pending.length === 0) {
132
77
  return { recovered: 0, failed: 0 };
133
78
  }
134
-
135
79
  const graphitiBase = process.env.GRAPHITI_BASE_URL || "http://127.0.0.1:18799";
136
80
  let recovered = 0;
137
81
  let failed = 0;
138
-
139
82
  for (const entry of pending) {
140
83
  try {
141
84
  const response = await fetch(`${graphitiBase}/episodes`, {
@@ -146,11 +89,10 @@ export async function recoverPendingWrites(): Promise<{ recovered: number; faile
146
89
  group_id: entry.groupId,
147
90
  reference_time: entry.ts,
148
91
  source: `lancedb-pro-store-${entry.groupId}`,
149
- category: entry.category,
92
+ category: entry.category
150
93
  }),
151
- signal: AbortSignal.timeout(15000),
94
+ signal: AbortSignal.timeout(15e3)
152
95
  });
153
-
154
96
  if (response.ok) {
155
97
  await walMarkCommitted(entry.ts);
156
98
  recovered++;
@@ -163,10 +105,15 @@ export async function recoverPendingWrites(): Promise<{ recovered: number; faile
163
105
  failed++;
164
106
  }
165
107
  }
166
-
167
- console.log(
168
- `mnemo: WAL recovery — recovered=${recovered}, failed=${failed}, total_pending=${pending.length}`,
108
+ log.info(
109
+ `WAL recovery \u2014 recovered=${recovered}, failed=${failed}, total_pending=${pending.length}`
169
110
  );
170
-
171
111
  return { recovered, failed };
172
112
  }
113
+ export {
114
+ recoverPendingWrites,
115
+ walAppend,
116
+ walMarkCommitted,
117
+ walMarkFailed
118
+ };
119
+ //# sourceMappingURL=wal-recovery.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/wal-recovery.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: LicenseRef-Mnemo-Pro\n/**\n * Graphiti Write-Ahead Log (WAL) + Recovery\n *\n * Ensures Graphiti writes survive transient failures by logging pending writes\n * to a JSONL file. On plugin startup, pending entries older than 1 hour are\n * retried automatically.\n */\n\nimport { appendFile, readFile, mkdir } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, dirname } from \"node:path\";\nimport { log } from \"./logger.js\";\n\n// ============================================================================\n// WAL Path\n// ============================================================================\n\nconst WAL_PATH = join(homedir(), \".openclaw\", \"memory\", \"graphiti-wal.jsonl\");\n\n// ============================================================================\n// WAL Entry Types\n// ============================================================================\n\nexport interface WalEntry {\n ts: string;\n action: \"write\";\n text: string;\n scope: string;\n category: string;\n groupId: string;\n importance: number;\n status: \"pending\" | \"committed\" | \"failed\";\n error?: string;\n}\n\n// ============================================================================\n// WAL Writer\n// ============================================================================\n\nasync function ensureWalDir(): Promise<void> {\n await mkdir(dirname(WAL_PATH), { recursive: true });\n}\n\nexport async function walAppend(entry: WalEntry): Promise<void> {\n await ensureWalDir();\n const line = JSON.stringify(entry) + \"\\n\";\n await appendFile(WAL_PATH, line, \"utf8\");\n}\n\nexport async function walMarkCommitted(ts: string): Promise<void> {\n const entry: WalEntry = {\n ts,\n action: \"write\",\n text: \"\",\n scope: \"\",\n category: \"\",\n groupId: \"\",\n importance: 0,\n status: \"committed\",\n };\n await ensureWalDir();\n await appendFile(WAL_PATH, JSON.stringify(entry) + \"\\n\", \"utf8\");\n}\n\nexport async function walMarkFailed(ts: string, error: string): Promise<void> {\n const entry: WalEntry = {\n ts,\n action: \"write\",\n text: \"\",\n scope: \"\",\n category: \"\",\n groupId: \"\",\n importance: 0,\n status: \"failed\",\n error,\n };\n await ensureWalDir();\n await appendFile(WAL_PATH, JSON.stringify(entry) + \"\\n\", \"utf8\");\n}\n\n// ============================================================================\n// WAL Recovery\n// ============================================================================\n\n/**\n * Scan the WAL file for entries with status=pending whose ts > 1 hour ago.\n * Retry writing them to Graphiti and mark as committed or failed.\n */\nexport async function recoverPendingWrites(): Promise<{ recovered: number; failed: number }> {\n if (!existsSync(WAL_PATH)) {\n return { recovered: 0, failed: 0 };\n }\n\n let raw: string;\n try {\n raw = await readFile(WAL_PATH, \"utf8\");\n } catch {\n return { recovered: 0, failed: 0 };\n }\n\n const lines = raw.split(\"\\n\").filter((l) => l.trim().length > 0);\n\n // Build a map of latest status per ts\n const statusMap = new Map<string, WalEntry>();\n for (const line of lines) {\n try {\n const entry = JSON.parse(line) as WalEntry;\n // Later entries for the same ts override earlier ones\n const existing = statusMap.get(entry.ts);\n if (!existing || entry.status !== \"pending\") {\n statusMap.set(entry.ts, entry);\n }\n } catch {\n // Skip malformed lines\n }\n }\n\n // Find pending entries older than 1 hour\n const oneHourAgo = Date.now() - 60 * 60 * 1000;\n const pending: WalEntry[] = [];\n for (const entry of statusMap.values()) {\n if (entry.status === \"pending\") {\n const entryTime = new Date(entry.ts).getTime();\n if (entryTime < oneHourAgo) {\n pending.push(entry);\n }\n }\n }\n\n if (pending.length === 0) {\n return { recovered: 0, failed: 0 };\n }\n\n const graphitiBase = process.env.GRAPHITI_BASE_URL || \"http://127.0.0.1:18799\";\n let recovered = 0;\n let failed = 0;\n\n for (const entry of pending) {\n try {\n const response = await fetch(`${graphitiBase}/episodes`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n text: `[${entry.category}] ${entry.text}`,\n group_id: entry.groupId,\n reference_time: entry.ts,\n source: `lancedb-pro-store-${entry.groupId}`,\n category: entry.category,\n }),\n signal: AbortSignal.timeout(15000),\n });\n\n if (response.ok) {\n await walMarkCommitted(entry.ts);\n recovered++;\n } else {\n await walMarkFailed(entry.ts, `HTTP ${response.status}`);\n failed++;\n }\n } catch (err) {\n await walMarkFailed(entry.ts, String(err));\n failed++;\n }\n }\n\n log.info(\n `WAL recovery \u2014 recovered=${recovered}, failed=${failed}, total_pending=${pending.length}`,\n );\n\n return { recovered, failed };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,9 +1,25 @@
1
1
  {
2
2
  "name": "@mnemoai/core",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Cognitive science-based AI memory framework — Weibull decay, triple-path retrieval, multi-backend storage",
5
5
  "type": "module",
6
- "main": "index.ts",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./storage-adapter": {
14
+ "import": "./dist/src/storage-adapter.js",
15
+ "types": "./dist/src/storage-adapter.d.ts"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "LICENSE",
21
+ "README.md"
22
+ ],
7
23
  "keywords": [
8
24
  "ai-memory",
9
25
  "long-term-memory",
@@ -47,12 +63,15 @@
47
63
  ]
48
64
  },
49
65
  "scripts": {
66
+ "build": "node build.mjs",
67
+ "prepublishOnly": "npm run build",
50
68
  "test": "node --test test/*.test.mjs",
51
69
  "test:openclaw-host": "node test/openclaw-host-functional.mjs",
52
70
  "version": "node scripts/sync-plugin-version.mjs openclaw.plugin.json package.json && git add openclaw.plugin.json"
53
71
  },
54
72
  "devDependencies": {
55
73
  "commander": "^14.0.0",
74
+ "esbuild": "^0.27.4",
56
75
  "jiti": "^2.6.0",
57
76
  "typescript": "^5.9.3"
58
77
  }