@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.
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +7 -0
- package/dist/cli.js.map +7 -0
- package/dist/index.d.ts +128 -0
- package/dist/index.d.ts.map +1 -0
- package/{index.ts → dist/index.js} +526 -1333
- package/dist/index.js.map +7 -0
- package/dist/src/access-tracker.d.ts +97 -0
- package/dist/src/access-tracker.d.ts.map +1 -0
- package/dist/src/access-tracker.js +184 -0
- package/dist/src/access-tracker.js.map +7 -0
- package/dist/src/adapters/chroma.d.ts +31 -0
- package/dist/src/adapters/chroma.d.ts.map +1 -0
- package/{src/adapters/chroma.ts → dist/src/adapters/chroma.js} +45 -107
- package/dist/src/adapters/chroma.js.map +7 -0
- package/dist/src/adapters/lancedb.d.ts +29 -0
- package/dist/src/adapters/lancedb.d.ts.map +1 -0
- package/{src/adapters/lancedb.ts → dist/src/adapters/lancedb.js} +41 -109
- package/dist/src/adapters/lancedb.js.map +7 -0
- package/dist/src/adapters/pgvector.d.ts +33 -0
- package/dist/src/adapters/pgvector.d.ts.map +1 -0
- package/{src/adapters/pgvector.ts → dist/src/adapters/pgvector.js} +42 -104
- package/dist/src/adapters/pgvector.js.map +7 -0
- package/dist/src/adapters/qdrant.d.ts +34 -0
- package/dist/src/adapters/qdrant.d.ts.map +1 -0
- package/dist/src/adapters/qdrant.js +132 -0
- package/dist/src/adapters/qdrant.js.map +7 -0
- package/dist/src/adaptive-retrieval.d.ts +14 -0
- package/dist/src/adaptive-retrieval.d.ts.map +1 -0
- package/dist/src/adaptive-retrieval.js +52 -0
- package/dist/src/adaptive-retrieval.js.map +7 -0
- package/dist/src/audit-log.d.ts +56 -0
- package/dist/src/audit-log.d.ts.map +1 -0
- package/dist/src/audit-log.js +139 -0
- package/dist/src/audit-log.js.map +7 -0
- package/dist/src/chunker.d.ts +45 -0
- package/dist/src/chunker.d.ts.map +1 -0
- package/dist/src/chunker.js +157 -0
- package/dist/src/chunker.js.map +7 -0
- package/dist/src/config.d.ts +70 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +142 -0
- package/dist/src/config.js.map +7 -0
- package/dist/src/decay-engine.d.ts +73 -0
- package/dist/src/decay-engine.d.ts.map +1 -0
- package/dist/src/decay-engine.js +119 -0
- package/dist/src/decay-engine.js.map +7 -0
- package/dist/src/embedder.d.ts +94 -0
- package/dist/src/embedder.d.ts.map +1 -0
- package/{src/embedder.ts → dist/src/embedder.js} +119 -317
- package/dist/src/embedder.js.map +7 -0
- package/dist/src/extraction-prompts.d.ts +12 -0
- package/dist/src/extraction-prompts.d.ts.map +1 -0
- package/dist/src/extraction-prompts.js +311 -0
- package/dist/src/extraction-prompts.js.map +7 -0
- package/dist/src/license.d.ts +29 -0
- package/dist/src/license.d.ts.map +1 -0
- package/{src/license.ts → dist/src/license.js} +42 -113
- package/dist/src/license.js.map +7 -0
- package/dist/src/llm-client.d.ts +23 -0
- package/dist/src/llm-client.d.ts.map +1 -0
- package/{src/llm-client.ts → dist/src/llm-client.js} +22 -55
- package/dist/src/llm-client.js.map +7 -0
- package/dist/src/logger.d.ts +33 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +35 -0
- package/dist/src/logger.js.map +7 -0
- package/dist/src/mcp-server.d.ts +16 -0
- package/dist/src/mcp-server.d.ts.map +1 -0
- package/{src/mcp-server.ts → dist/src/mcp-server.js} +81 -181
- package/dist/src/mcp-server.js.map +7 -0
- package/dist/src/memory-categories.d.ts +40 -0
- package/dist/src/memory-categories.d.ts.map +1 -0
- package/dist/src/memory-categories.js +33 -0
- package/dist/src/memory-categories.js.map +7 -0
- package/dist/src/memory-upgrader.d.ts +71 -0
- package/dist/src/memory-upgrader.d.ts.map +1 -0
- package/dist/src/memory-upgrader.js +238 -0
- package/dist/src/memory-upgrader.js.map +7 -0
- package/dist/src/migrate.d.ts +47 -0
- package/dist/src/migrate.d.ts.map +1 -0
- package/{src/migrate.ts → dist/src/migrate.js} +57 -165
- package/dist/src/migrate.js.map +7 -0
- package/dist/src/mnemo.d.ts +67 -0
- package/dist/src/mnemo.d.ts.map +1 -0
- package/dist/src/mnemo.js +66 -0
- package/dist/src/mnemo.js.map +7 -0
- package/dist/src/noise-filter.d.ts +23 -0
- package/dist/src/noise-filter.d.ts.map +1 -0
- package/dist/src/noise-filter.js +62 -0
- package/dist/src/noise-filter.js.map +7 -0
- package/dist/src/noise-prototypes.d.ts +40 -0
- package/dist/src/noise-prototypes.d.ts.map +1 -0
- package/dist/src/noise-prototypes.js +116 -0
- package/dist/src/noise-prototypes.js.map +7 -0
- package/dist/src/observability.d.ts +16 -0
- package/dist/src/observability.d.ts.map +1 -0
- package/dist/src/observability.js +53 -0
- package/dist/src/observability.js.map +7 -0
- package/dist/src/query-tracker.d.ts +27 -0
- package/dist/src/query-tracker.d.ts.map +1 -0
- package/dist/src/query-tracker.js +32 -0
- package/dist/src/query-tracker.js.map +7 -0
- package/dist/src/reflection-event-store.d.ts +44 -0
- package/dist/src/reflection-event-store.d.ts.map +1 -0
- package/dist/src/reflection-event-store.js +50 -0
- package/dist/src/reflection-event-store.js.map +7 -0
- package/dist/src/reflection-item-store.d.ts +58 -0
- package/dist/src/reflection-item-store.d.ts.map +1 -0
- package/dist/src/reflection-item-store.js +69 -0
- package/dist/src/reflection-item-store.js.map +7 -0
- package/dist/src/reflection-mapped-metadata.d.ts +47 -0
- package/dist/src/reflection-mapped-metadata.d.ts.map +1 -0
- package/dist/src/reflection-mapped-metadata.js +40 -0
- package/dist/src/reflection-mapped-metadata.js.map +7 -0
- package/dist/src/reflection-metadata.d.ts +11 -0
- package/dist/src/reflection-metadata.d.ts.map +1 -0
- package/dist/src/reflection-metadata.js +24 -0
- package/dist/src/reflection-metadata.js.map +7 -0
- package/dist/src/reflection-ranking.d.ts +13 -0
- package/dist/src/reflection-ranking.d.ts.map +1 -0
- package/{src/reflection-ranking.ts → dist/src/reflection-ranking.js} +12 -21
- package/dist/src/reflection-ranking.js.map +7 -0
- package/dist/src/reflection-retry.d.ts +30 -0
- package/dist/src/reflection-retry.d.ts.map +1 -0
- package/{src/reflection-retry.ts → dist/src/reflection-retry.js} +24 -64
- package/dist/src/reflection-retry.js.map +7 -0
- package/dist/src/reflection-slices.d.ts +42 -0
- package/dist/src/reflection-slices.d.ts.map +1 -0
- package/{src/reflection-slices.ts → dist/src/reflection-slices.js} +60 -136
- package/dist/src/reflection-slices.js.map +7 -0
- package/dist/src/reflection-store.d.ts +85 -0
- package/dist/src/reflection-store.d.ts.map +1 -0
- package/dist/src/reflection-store.js +407 -0
- package/dist/src/reflection-store.js.map +7 -0
- package/dist/src/resonance-state.d.ts +19 -0
- package/dist/src/resonance-state.d.ts.map +1 -0
- package/{src/resonance-state.ts → dist/src/resonance-state.js} +13 -42
- package/dist/src/resonance-state.js.map +7 -0
- package/dist/src/retriever.d.ts +228 -0
- package/dist/src/retriever.d.ts.map +1 -0
- package/dist/src/retriever.js +1006 -0
- package/dist/src/retriever.js.map +7 -0
- package/dist/src/scopes.d.ts +58 -0
- package/dist/src/scopes.d.ts.map +1 -0
- package/dist/src/scopes.js +252 -0
- package/dist/src/scopes.js.map +7 -0
- package/dist/src/self-improvement-files.d.ts +20 -0
- package/dist/src/self-improvement-files.d.ts.map +1 -0
- package/{src/self-improvement-files.ts → dist/src/self-improvement-files.js} +24 -49
- package/dist/src/self-improvement-files.js.map +7 -0
- package/dist/src/semantic-gate.d.ts +24 -0
- package/dist/src/semantic-gate.d.ts.map +1 -0
- package/dist/src/semantic-gate.js +86 -0
- package/dist/src/semantic-gate.js.map +7 -0
- package/dist/src/session-recovery.d.ts +9 -0
- package/dist/src/session-recovery.d.ts.map +1 -0
- package/{src/session-recovery.ts → dist/src/session-recovery.js} +40 -57
- package/dist/src/session-recovery.js.map +7 -0
- package/dist/src/smart-extractor.d.ts +107 -0
- package/dist/src/smart-extractor.d.ts.map +1 -0
- package/{src/smart-extractor.ts → dist/src/smart-extractor.js} +130 -383
- package/dist/src/smart-extractor.js.map +7 -0
- package/dist/src/smart-metadata.d.ts +103 -0
- package/dist/src/smart-metadata.d.ts.map +1 -0
- package/dist/src/smart-metadata.js +361 -0
- package/dist/src/smart-metadata.js.map +7 -0
- package/dist/src/storage-adapter.d.ts +102 -0
- package/dist/src/storage-adapter.d.ts.map +1 -0
- package/dist/src/storage-adapter.js +22 -0
- package/dist/src/storage-adapter.js.map +7 -0
- package/dist/src/store.d.ts +108 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/store.js +939 -0
- package/dist/src/store.js.map +7 -0
- package/dist/src/tier-manager.d.ts +57 -0
- package/dist/src/tier-manager.d.ts.map +1 -0
- package/dist/src/tier-manager.js +80 -0
- package/dist/src/tier-manager.js.map +7 -0
- package/dist/src/tools.d.ts +43 -0
- package/dist/src/tools.d.ts.map +1 -0
- package/dist/src/tools.js +1075 -0
- package/dist/src/tools.js.map +7 -0
- package/dist/src/wal-recovery.d.ts +30 -0
- package/dist/src/wal-recovery.d.ts.map +1 -0
- package/{src/wal-recovery.ts → dist/src/wal-recovery.js} +26 -79
- package/dist/src/wal-recovery.js.map +7 -0
- package/package.json +21 -2
- package/openclaw.plugin.json +0 -815
- package/src/access-tracker.ts +0 -341
- package/src/adapters/README.md +0 -78
- package/src/adapters/qdrant.ts +0 -191
- package/src/adaptive-retrieval.ts +0 -90
- package/src/audit-log.ts +0 -238
- package/src/chunker.ts +0 -254
- package/src/config.ts +0 -271
- package/src/decay-engine.ts +0 -238
- package/src/extraction-prompts.ts +0 -339
- package/src/memory-categories.ts +0 -71
- package/src/memory-upgrader.ts +0 -388
- package/src/mnemo.ts +0 -142
- package/src/noise-filter.ts +0 -97
- package/src/noise-prototypes.ts +0 -164
- package/src/observability.ts +0 -81
- package/src/query-tracker.ts +0 -57
- package/src/reflection-event-store.ts +0 -98
- package/src/reflection-item-store.ts +0 -112
- package/src/reflection-mapped-metadata.ts +0 -84
- package/src/reflection-metadata.ts +0 -23
- package/src/reflection-store.ts +0 -602
- package/src/retriever.ts +0 -1510
- package/src/scopes.ts +0 -375
- package/src/semantic-gate.ts +0 -121
- package/src/smart-metadata.ts +0 -561
- package/src/storage-adapter.ts +0 -153
- package/src/store.ts +0 -1330
- package/src/tier-manager.ts +0 -189
- package/src/tools.ts +0 -1292
- 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
|
-
|
|
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
|
-
|
|
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)
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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": "AASA,SAAS,YAAY,UAAU,aAAa;AAC5C,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,MAAM,eAAe;AAC9B,SAAS,WAAW;AAMpB,MAAM,WAAW,KAAK,QAAQ,GAAG,aAAa,UAAU,oBAAoB;AAsB5E,eAAe,eAA8B;AAC3C,QAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACpD;AAEA,eAAsB,UAAU,OAAgC;AAC9D,QAAM,aAAa;AACnB,QAAM,OAAO,KAAK,UAAU,KAAK,IAAI;AACrC,QAAM,WAAW,UAAU,MAAM,MAAM;AACzC;AAEA,eAAsB,iBAAiB,IAA2B;AAChE,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AACA,QAAM,aAAa;AACnB,QAAM,WAAW,UAAU,KAAK,UAAU,KAAK,IAAI,MAAM,MAAM;AACjE;AAEA,eAAsB,cAAc,IAAY,OAA8B;AAC5E,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR;AAAA,EACF;AACA,QAAM,aAAa;AACnB,QAAM,WAAW,UAAU,KAAK,UAAU,KAAK,IAAI,MAAM,MAAM;AACjE;AAUA,eAAsB,uBAAuE;AAC3F,MAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,WAAO,EAAE,WAAW,GAAG,QAAQ,EAAE;AAAA,EACnC;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,SAAS,UAAU,MAAM;AAAA,EACvC,QAAQ;AACN,WAAO,EAAE,WAAW,GAAG,QAAQ,EAAE;AAAA,EACnC;AAEA,QAAM,QAAQ,IAAI,MAAM,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC;AAG/D,QAAM,YAAY,oBAAI,IAAsB;AAC5C,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,QAAQ,KAAK,MAAM,IAAI;AAE7B,YAAM,WAAW,UAAU,IAAI,MAAM,EAAE;AACvC,UAAI,CAAC,YAAY,MAAM,WAAW,WAAW;AAC3C,kBAAU,IAAI,MAAM,IAAI,KAAK;AAAA,MAC/B;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,QAAM,aAAa,KAAK,IAAI,IAAI,KAAK,KAAK;AAC1C,QAAM,UAAsB,CAAC;AAC7B,aAAW,SAAS,UAAU,OAAO,GAAG;AACtC,QAAI,MAAM,WAAW,WAAW;AAC9B,YAAM,YAAY,IAAI,KAAK,MAAM,EAAE,EAAE,QAAQ;AAC7C,UAAI,YAAY,YAAY;AAC1B,gBAAQ,KAAK,KAAK;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,EAAE,WAAW,GAAG,QAAQ,EAAE;AAAA,EACnC;AAEA,QAAM,eAAe,QAAQ,IAAI,qBAAqB;AACtD,MAAI,YAAY;AAChB,MAAI,SAAS;AAEb,aAAW,SAAS,SAAS;AAC3B,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,YAAY,aAAa;AAAA,QACvD,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU;AAAA,UACnB,MAAM,IAAI,MAAM,QAAQ,KAAK,MAAM,IAAI;AAAA,UACvC,UAAU,MAAM;AAAA,UAChB,gBAAgB,MAAM;AAAA,UACtB,QAAQ,qBAAqB,MAAM,OAAO;AAAA,UAC1C,UAAU,MAAM;AAAA,QAClB,CAAC;AAAA,QACD,QAAQ,YAAY,QAAQ,IAAK;AAAA,MACnC,CAAC;AAED,UAAI,SAAS,IAAI;AACf,cAAM,iBAAiB,MAAM,EAAE;AAC/B;AAAA,MACF,OAAO;AACL,cAAM,cAAc,MAAM,IAAI,QAAQ,SAAS,MAAM,EAAE;AACvD;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,cAAc,MAAM,IAAI,OAAO,GAAG,CAAC;AACzC;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AAAA,IACF,iCAA4B,SAAS,YAAY,MAAM,mBAAmB,QAAQ,MAAM;AAAA,EAC1F;AAEA,SAAO,EAAE,WAAW,OAAO;AAC7B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mnemoai/core",
|
|
3
|
-
"version": "1.1.
|
|
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.
|
|
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
|
}
|