openclaw-engram 0.2.0
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/availability.d.ts +34 -0
- package/dist/availability.d.ts.map +1 -0
- package/dist/availability.js +70 -0
- package/dist/availability.js.map +1 -0
- package/dist/client.d.ts +147 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +199 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/memory.d.ts +11 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +49 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/remember.d.ts +15 -0
- package/dist/commands/remember.d.ts.map +1 -0
- package/dist/commands/remember.js +61 -0
- package/dist/commands/remember.js.map +1 -0
- package/dist/config.d.ts +73 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +81 -0
- package/dist/config.js.map +1 -0
- package/dist/context/formatter.d.ts +33 -0
- package/dist/context/formatter.d.ts.map +1 -0
- package/dist/context/formatter.js +193 -0
- package/dist/context/formatter.js.map +1 -0
- package/dist/hooks/after-tool-call.d.ts +19 -0
- package/dist/hooks/after-tool-call.d.ts.map +1 -0
- package/dist/hooks/after-tool-call.js +53 -0
- package/dist/hooks/after-tool-call.js.map +1 -0
- package/dist/hooks/before-compaction.d.ts +19 -0
- package/dist/hooks/before-compaction.d.ts.map +1 -0
- package/dist/hooks/before-compaction.js +60 -0
- package/dist/hooks/before-compaction.js.map +1 -0
- package/dist/hooks/before-prompt-build.d.ts +20 -0
- package/dist/hooks/before-prompt-build.d.ts.map +1 -0
- package/dist/hooks/before-prompt-build.js +76 -0
- package/dist/hooks/before-prompt-build.js.map +1 -0
- package/dist/hooks/session-end.d.ts +18 -0
- package/dist/hooks/session-end.d.ts.map +1 -0
- package/dist/hooks/session-end.js +57 -0
- package/dist/hooks/session-end.js.map +1 -0
- package/dist/hooks/session-start.d.ts +17 -0
- package/dist/hooks/session-start.d.ts.map +1 -0
- package/dist/hooks/session-start.js +77 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/identity.d.ts +36 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +106 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +208 -0
- package/dist/index.js.map +1 -0
- package/dist/services/file-watcher.d.ts +11 -0
- package/dist/services/file-watcher.d.ts.map +1 -0
- package/dist/services/file-watcher.js +139 -0
- package/dist/services/file-watcher.js.map +1 -0
- package/dist/tools/engram-decisions.d.ts +8 -0
- package/dist/tools/engram-decisions.d.ts.map +1 -0
- package/dist/tools/engram-decisions.js +70 -0
- package/dist/tools/engram-decisions.js.map +1 -0
- package/dist/tools/engram-remember.d.ts +9 -0
- package/dist/tools/engram-remember.d.ts.map +1 -0
- package/dist/tools/engram-remember.js +116 -0
- package/dist/tools/engram-remember.js.map +1 -0
- package/dist/tools/engram-search.d.ts +9 -0
- package/dist/tools/engram-search.d.ts.map +1 -0
- package/dist/tools/engram-search.js +62 -0
- package/dist/tools/engram-search.js.map +1 -0
- package/dist/tools/memory-forget.d.ts +10 -0
- package/dist/tools/memory-forget.d.ts.map +1 -0
- package/dist/tools/memory-forget.js +41 -0
- package/dist/tools/memory-forget.js.map +1 -0
- package/dist/tools/memory-get.d.ts +11 -0
- package/dist/tools/memory-get.d.ts.map +1 -0
- package/dist/tools/memory-get.js +86 -0
- package/dist/tools/memory-get.js.map +1 -0
- package/dist/tools/memory-migrate.d.ts +11 -0
- package/dist/tools/memory-migrate.d.ts.map +1 -0
- package/dist/tools/memory-migrate.js +180 -0
- package/dist/tools/memory-migrate.js.map +1 -0
- package/dist/types/openclaw.d.ts +212 -0
- package/dist/types/openclaw.d.ts.map +1 -0
- package/dist/types/openclaw.js +9 -0
- package/dist/types/openclaw.js.map +1 -0
- package/dist/utils/memory-files.d.ts +25 -0
- package/dist/utils/memory-files.d.ts.map +1 -0
- package/dist/utils/memory-files.js +187 -0
- package/dist/utils/memory-files.js.map +1 -0
- package/openclaw.plugin.json +86 -0
- package/package.json +45 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenClaw Engram Plugin
|
|
4
|
+
*
|
|
5
|
+
* Connects OpenClaw agents to engram persistent memory via REST API.
|
|
6
|
+
* Provides:
|
|
7
|
+
* - Session-level static context injection (appendSystemContext)
|
|
8
|
+
* - Per-turn dynamic context search (prependContext)
|
|
9
|
+
* - Automatic self-learning via tool event ingestion
|
|
10
|
+
* - Transcript backfill on compaction / session end
|
|
11
|
+
* - Agent tools: engram_search, engram_remember, engram_decisions,
|
|
12
|
+
* memory_search, memory_store, memory_forget, memory_get,
|
|
13
|
+
* memory_migrate
|
|
14
|
+
* - Slash commands: /memory, /remember, /migrate
|
|
15
|
+
* - CLI: openclaw memory status|search|store|migrate
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.AvailabilityTracker = exports.formatContext = exports.projectIDFromWorkspace = exports.resolveIdentity = exports.getJsonSchema = exports.parseConfig = exports.EngramRestClient = void 0;
|
|
19
|
+
const config_js_1 = require("./config.js");
|
|
20
|
+
const client_js_1 = require("./client.js");
|
|
21
|
+
const node_os_1 = require("node:os");
|
|
22
|
+
const node_path_1 = require("node:path");
|
|
23
|
+
const identity_js_1 = require("./identity.js");
|
|
24
|
+
const session_start_js_1 = require("./hooks/session-start.js");
|
|
25
|
+
const before_prompt_build_js_1 = require("./hooks/before-prompt-build.js");
|
|
26
|
+
const after_tool_call_js_1 = require("./hooks/after-tool-call.js");
|
|
27
|
+
const before_compaction_js_1 = require("./hooks/before-compaction.js");
|
|
28
|
+
const session_end_js_1 = require("./hooks/session-end.js");
|
|
29
|
+
const engram_search_js_1 = require("./tools/engram-search.js");
|
|
30
|
+
const engram_remember_js_1 = require("./tools/engram-remember.js");
|
|
31
|
+
const engram_decisions_js_1 = require("./tools/engram-decisions.js");
|
|
32
|
+
const memory_forget_js_1 = require("./tools/memory-forget.js");
|
|
33
|
+
const memory_get_js_1 = require("./tools/memory-get.js");
|
|
34
|
+
const memory_migrate_js_1 = require("./tools/memory-migrate.js");
|
|
35
|
+
const memory_js_1 = require("./commands/memory.js");
|
|
36
|
+
const remember_js_1 = require("./commands/remember.js");
|
|
37
|
+
const file_watcher_js_1 = require("./services/file-watcher.js");
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Plugin definition
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
const plugin = {
|
|
42
|
+
id: 'engram',
|
|
43
|
+
name: 'Engram Memory',
|
|
44
|
+
description: 'Persistent shared memory via engram server',
|
|
45
|
+
version: '0.2.0',
|
|
46
|
+
kind: 'memory',
|
|
47
|
+
configSchema: (0, config_js_1.getJsonSchema)(),
|
|
48
|
+
register(api) {
|
|
49
|
+
const config = (0, config_js_1.parseConfig)(api.pluginConfig ?? {});
|
|
50
|
+
const client = new client_js_1.EngramRestClient(config);
|
|
51
|
+
api.logger.info(`[engram] initializing — server: ${config.url}`);
|
|
52
|
+
// ------------------------------------------------------------------
|
|
53
|
+
// Hooks
|
|
54
|
+
// ------------------------------------------------------------------
|
|
55
|
+
api.on('session_start', (event) => (0, session_start_js_1.handleSessionStart)(event, client, config, api.logger));
|
|
56
|
+
api.on('before_prompt_build', (event) => (0, before_prompt_build_js_1.handleBeforePromptBuild)(event, client, config, api.logger));
|
|
57
|
+
api.on('after_tool_call', (event) => {
|
|
58
|
+
(0, after_tool_call_js_1.handleAfterToolCall)(event, client, config);
|
|
59
|
+
});
|
|
60
|
+
api.on('before_compaction', (event) => {
|
|
61
|
+
(0, before_compaction_js_1.handleBeforeCompaction)(event, client, config, api.logger);
|
|
62
|
+
});
|
|
63
|
+
api.on('session_end', (event) => {
|
|
64
|
+
(0, session_end_js_1.handleSessionEnd)(event, client, config, api.logger);
|
|
65
|
+
});
|
|
66
|
+
// ------------------------------------------------------------------
|
|
67
|
+
// Tools (factory pattern)
|
|
68
|
+
// ------------------------------------------------------------------
|
|
69
|
+
const toolFactory = (ctx) => [
|
|
70
|
+
(0, engram_search_js_1.createEngramSearchTool)(ctx, client, config),
|
|
71
|
+
(0, engram_search_js_1.createMemorySearchTool)(ctx, client, config),
|
|
72
|
+
(0, engram_remember_js_1.createEngramRememberTool)(ctx, client, config),
|
|
73
|
+
(0, engram_remember_js_1.createMemoryStoreTool)(ctx, client, config),
|
|
74
|
+
(0, engram_decisions_js_1.createEngramDecisionsTool)(ctx, client, config),
|
|
75
|
+
(0, memory_forget_js_1.createMemoryForgetTool)(ctx, client, config),
|
|
76
|
+
(0, memory_get_js_1.createMemoryGetTool)(ctx, client, config, api),
|
|
77
|
+
(0, memory_migrate_js_1.createMemoryMigrateTool)(ctx, client, config, api),
|
|
78
|
+
];
|
|
79
|
+
api.registerTool(toolFactory, {
|
|
80
|
+
names: [
|
|
81
|
+
'engram_search', 'memory_search',
|
|
82
|
+
'engram_remember', 'memory_store',
|
|
83
|
+
'engram_decisions',
|
|
84
|
+
'memory_forget',
|
|
85
|
+
'memory_get',
|
|
86
|
+
'memory_migrate',
|
|
87
|
+
],
|
|
88
|
+
});
|
|
89
|
+
// ------------------------------------------------------------------
|
|
90
|
+
// Commands
|
|
91
|
+
// ------------------------------------------------------------------
|
|
92
|
+
api.registerCommand((0, memory_js_1.buildMemoryCommand)(client, config));
|
|
93
|
+
api.registerCommand((0, remember_js_1.buildRememberCommand)(client, config));
|
|
94
|
+
api.registerCommand({
|
|
95
|
+
name: 'migrate',
|
|
96
|
+
description: 'Import local memory files (MEMORY.md, memory/**/*.md) into engram',
|
|
97
|
+
acceptsArgs: true,
|
|
98
|
+
async handler(ctx) {
|
|
99
|
+
const rawArgs = (ctx.args ?? '').trim();
|
|
100
|
+
const parts = rawArgs.split(/\s+/).filter(Boolean);
|
|
101
|
+
const dryRun = parts.includes('--dry-run');
|
|
102
|
+
const force = parts.includes('--force');
|
|
103
|
+
const pathArgs = parts.filter((a) => !a.startsWith('--'));
|
|
104
|
+
const migratePath = pathArgs.length > 0 ? pathArgs.join(' ') : undefined;
|
|
105
|
+
// Resolve workspace: slash commands (Telegram, Discord) don't carry
|
|
106
|
+
// workspaceDir in PluginCommandContext. Use plugin config or default agent path.
|
|
107
|
+
const workspaceDir = config.workspaceDir
|
|
108
|
+
?? (0, node_path_1.join)((0, node_os_1.homedir)(), '.openclaw', 'workspace');
|
|
109
|
+
const toolCtx = { workspaceDir };
|
|
110
|
+
const tool = (0, memory_migrate_js_1.createMemoryMigrateTool)(toolCtx, client, config, api);
|
|
111
|
+
const result = await tool.execute('cmd-migrate', { dryRun, force, path: migratePath });
|
|
112
|
+
return { text: result };
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
// ------------------------------------------------------------------
|
|
116
|
+
// CLI: openclaw memory <subcommand>
|
|
117
|
+
// ------------------------------------------------------------------
|
|
118
|
+
api.registerCli(({ program }) => {
|
|
119
|
+
const memCmd = program.command('memory').description('Engram memory operations');
|
|
120
|
+
memCmd
|
|
121
|
+
.command('status')
|
|
122
|
+
.description('Show engram server status')
|
|
123
|
+
.action(async () => {
|
|
124
|
+
const health = await client.health();
|
|
125
|
+
const status = health?.status ?? 'UNKNOWN';
|
|
126
|
+
const version = health?.version ? ` v${health.version}` : '';
|
|
127
|
+
console.log(`engram: ${status}${version} (${config.url})`);
|
|
128
|
+
});
|
|
129
|
+
memCmd
|
|
130
|
+
.command('search')
|
|
131
|
+
.description('Search engram memory')
|
|
132
|
+
.argument('<query>', 'Search query')
|
|
133
|
+
.action(async (query) => {
|
|
134
|
+
const identity = (0, identity_js_1.resolveIdentity)('', process.cwd());
|
|
135
|
+
const response = await client.searchContext({
|
|
136
|
+
project: config.project ?? identity.projectId,
|
|
137
|
+
query: String(query),
|
|
138
|
+
});
|
|
139
|
+
const obs = response?.observations ?? [];
|
|
140
|
+
if (obs.length === 0) {
|
|
141
|
+
console.log('No results found.');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
for (const o of obs) {
|
|
145
|
+
const score = typeof o.similarity === 'number' ? ` [${o.similarity.toFixed(2)}]` : '';
|
|
146
|
+
console.log(`- ${o.title}${score}`);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
memCmd
|
|
150
|
+
.command('store')
|
|
151
|
+
.description('Store a memory')
|
|
152
|
+
.argument('<text>', 'Text to remember')
|
|
153
|
+
.action(async (text) => {
|
|
154
|
+
const textStr = String(text);
|
|
155
|
+
const title = textStr.length > 80 ? textStr.slice(0, 77) + '...' : textStr;
|
|
156
|
+
const storeIdentity = (0, identity_js_1.resolveIdentity)('', process.cwd());
|
|
157
|
+
const response = await client.bulkImport([{
|
|
158
|
+
title,
|
|
159
|
+
content: textStr.slice(0, 900),
|
|
160
|
+
type: 'change',
|
|
161
|
+
project: config.project ?? storeIdentity.projectId,
|
|
162
|
+
scope: 'project',
|
|
163
|
+
}]);
|
|
164
|
+
if (response && response.imported > 0) {
|
|
165
|
+
console.log(`Stored: "${title}"`);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
console.log('Failed to store memory.');
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
// CLI context is stable per process — cache the tool instance.
|
|
172
|
+
const cliMigrateTool = (0, memory_migrate_js_1.createMemoryMigrateTool)({ workspaceDir: process.cwd() }, client, config, api);
|
|
173
|
+
memCmd
|
|
174
|
+
.command('migrate')
|
|
175
|
+
.description('Import local memory files into engram')
|
|
176
|
+
.option('--dry-run', 'Preview without importing')
|
|
177
|
+
.option('--force', 'Re-import already migrated files')
|
|
178
|
+
.action(async (...args) => {
|
|
179
|
+
const opts = (args[args.length - 1] ?? {});
|
|
180
|
+
const dryRun = Boolean(opts['dryRun'] ?? opts['dry-run']);
|
|
181
|
+
const force = Boolean(opts.force);
|
|
182
|
+
const result = await cliMigrateTool.execute('cli-migrate', { dryRun, force });
|
|
183
|
+
console.log(result);
|
|
184
|
+
});
|
|
185
|
+
}, { commands: ['memory'] });
|
|
186
|
+
// File watcher service (replaces memory-core chokidar watcher)
|
|
187
|
+
// Use configured workspace, or default agent workspace path.
|
|
188
|
+
const watcherWorkspaceDir = config.workspaceDir
|
|
189
|
+
?? (0, node_path_1.join)((0, node_os_1.homedir)(), '.openclaw', 'workspace');
|
|
190
|
+
api.registerService((0, file_watcher_js_1.createFileWatcherService)(watcherWorkspaceDir, client, config, api.logger));
|
|
191
|
+
api.logger.info('[engram] plugin registered successfully');
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
exports.default = plugin;
|
|
195
|
+
// Named exports for consumers that prefer explicit imports
|
|
196
|
+
var client_js_2 = require("./client.js");
|
|
197
|
+
Object.defineProperty(exports, "EngramRestClient", { enumerable: true, get: function () { return client_js_2.EngramRestClient; } });
|
|
198
|
+
var config_js_2 = require("./config.js");
|
|
199
|
+
Object.defineProperty(exports, "parseConfig", { enumerable: true, get: function () { return config_js_2.parseConfig; } });
|
|
200
|
+
Object.defineProperty(exports, "getJsonSchema", { enumerable: true, get: function () { return config_js_2.getJsonSchema; } });
|
|
201
|
+
var identity_js_2 = require("./identity.js");
|
|
202
|
+
Object.defineProperty(exports, "resolveIdentity", { enumerable: true, get: function () { return identity_js_2.resolveIdentity; } });
|
|
203
|
+
Object.defineProperty(exports, "projectIDFromWorkspace", { enumerable: true, get: function () { return identity_js_2.projectIDFromWorkspace; } });
|
|
204
|
+
var formatter_js_1 = require("./context/formatter.js");
|
|
205
|
+
Object.defineProperty(exports, "formatContext", { enumerable: true, get: function () { return formatter_js_1.formatContext; } });
|
|
206
|
+
var availability_js_1 = require("./availability.js");
|
|
207
|
+
Object.defineProperty(exports, "AvailabilityTracker", { enumerable: true, get: function () { return availability_js_1.AvailabilityTracker; } });
|
|
208
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FileWatcherService — watches workspace memory files and syncs them to engram.
|
|
3
|
+
*
|
|
4
|
+
* Replaces memory-core chokidar watcher. Watches MEMORY.md and memory directory,
|
|
5
|
+
* debounces changes per file, and bulk-imports updated chunks into engram.
|
|
6
|
+
*/
|
|
7
|
+
import type { EngramRestClient } from '../client.js';
|
|
8
|
+
import type { PluginConfig } from '../config.js';
|
|
9
|
+
import type { OpenClawPluginService, PluginLogger } from '../types/openclaw.js';
|
|
10
|
+
export declare function createFileWatcherService(workspaceDir: string, client: EngramRestClient, config: PluginConfig, logger: PluginLogger): OpenClawPluginService;
|
|
11
|
+
//# sourceMappingURL=file-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-watcher.d.ts","sourceRoot":"","sources":["../../src/services/file-watcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAqB,MAAM,cAAc,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAgC,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAkI9G,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,YAAY,GACnB,qBAAqB,CAEvB"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* FileWatcherService — watches workspace memory files and syncs them to engram.
|
|
4
|
+
*
|
|
5
|
+
* Replaces memory-core chokidar watcher. Watches MEMORY.md and memory directory,
|
|
6
|
+
* debounces changes per file, and bulk-imports updated chunks into engram.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createFileWatcherService = createFileWatcherService;
|
|
13
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
14
|
+
const node_path_1 = require("node:path");
|
|
15
|
+
const node_crypto_1 = require("node:crypto");
|
|
16
|
+
const identity_js_1 = require("../identity.js");
|
|
17
|
+
const memory_files_js_1 = require("../utils/memory-files.js");
|
|
18
|
+
const DEBOUNCE_MS = 1500;
|
|
19
|
+
class FileWatcherService {
|
|
20
|
+
workspaceDir;
|
|
21
|
+
client;
|
|
22
|
+
config;
|
|
23
|
+
logger;
|
|
24
|
+
id = 'file-watcher';
|
|
25
|
+
watcher = null;
|
|
26
|
+
debounceTimers = new Map();
|
|
27
|
+
inFlight = new Set();
|
|
28
|
+
stopped = false;
|
|
29
|
+
projectId;
|
|
30
|
+
constructor(workspaceDir, client, config, logger) {
|
|
31
|
+
this.workspaceDir = workspaceDir;
|
|
32
|
+
this.client = client;
|
|
33
|
+
this.config = config;
|
|
34
|
+
this.logger = logger;
|
|
35
|
+
const identity = (0, identity_js_1.resolveIdentity)('file-watcher', workspaceDir);
|
|
36
|
+
this.projectId = config.project ?? identity.projectId;
|
|
37
|
+
}
|
|
38
|
+
start(_ctx) {
|
|
39
|
+
const watchPaths = [
|
|
40
|
+
(0, node_path_1.join)(this.workspaceDir, 'MEMORY.md'),
|
|
41
|
+
(0, node_path_1.join)(this.workspaceDir, 'memory'),
|
|
42
|
+
];
|
|
43
|
+
this.watcher = chokidar_1.default.watch(watchPaths, {
|
|
44
|
+
ignoreInitial: true,
|
|
45
|
+
awaitWriteFinish: { stabilityThreshold: 500 },
|
|
46
|
+
persistent: false,
|
|
47
|
+
});
|
|
48
|
+
this.watcher.on('add', (filePath) => this.scheduleSync(filePath));
|
|
49
|
+
this.watcher.on('change', (filePath) => this.scheduleSync(filePath));
|
|
50
|
+
this.watcher.on('unlink', (filePath) => {
|
|
51
|
+
const relPath = (0, node_path_1.relative)(this.workspaceDir, filePath);
|
|
52
|
+
this.logger.debug(`[file-watcher] file deleted: ${relPath} — sync skipped (server-side cleanup not yet supported)`);
|
|
53
|
+
});
|
|
54
|
+
this.watcher.on('error', (err) => {
|
|
55
|
+
this.logger.warn(`[file-watcher] watcher error: ${String(err)}`);
|
|
56
|
+
});
|
|
57
|
+
this.logger.debug(`[file-watcher] watching ${this.workspaceDir}`);
|
|
58
|
+
}
|
|
59
|
+
stop(_ctx) {
|
|
60
|
+
this.stopped = true;
|
|
61
|
+
for (const timer of this.debounceTimers.values()) {
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
}
|
|
64
|
+
this.debounceTimers.clear();
|
|
65
|
+
if (this.watcher) {
|
|
66
|
+
void this.watcher.close();
|
|
67
|
+
this.watcher = null;
|
|
68
|
+
}
|
|
69
|
+
this.logger.debug('[file-watcher] stopped');
|
|
70
|
+
}
|
|
71
|
+
scheduleSync(filePath) {
|
|
72
|
+
const existing = this.debounceTimers.get(filePath);
|
|
73
|
+
if (existing !== undefined) {
|
|
74
|
+
clearTimeout(existing);
|
|
75
|
+
}
|
|
76
|
+
const timer = setTimeout(() => {
|
|
77
|
+
this.debounceTimers.delete(filePath);
|
|
78
|
+
void this.syncFile(filePath);
|
|
79
|
+
}, DEBOUNCE_MS);
|
|
80
|
+
this.debounceTimers.set(filePath, timer);
|
|
81
|
+
}
|
|
82
|
+
async syncFile(filePath) {
|
|
83
|
+
if (this.stopped)
|
|
84
|
+
return;
|
|
85
|
+
if (this.inFlight.has(filePath)) {
|
|
86
|
+
this.scheduleSync(filePath); // retry after debounce — don't drop concurrent changes
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (!this.client.isAvailable())
|
|
90
|
+
return;
|
|
91
|
+
this.inFlight.add(filePath);
|
|
92
|
+
try {
|
|
93
|
+
const content = await (0, memory_files_js_1.safeReadFile)(filePath);
|
|
94
|
+
if (content === null) {
|
|
95
|
+
this.logger.debug(`[file-watcher] skipping unreadable file: ${filePath}`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const hash = (0, node_crypto_1.createHash)('sha256').update(content).digest('hex');
|
|
99
|
+
const markerPath = (0, node_path_1.join)(this.workspaceDir, memory_files_js_1.MARKER_FILE);
|
|
100
|
+
const marker = await (0, memory_files_js_1.loadMarker)(markerPath);
|
|
101
|
+
const relPath = (0, node_path_1.relative)(this.workspaceDir, filePath);
|
|
102
|
+
if (marker?.files[relPath] === hash) {
|
|
103
|
+
this.logger.debug(`[file-watcher] no changes: ${relPath}`);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const chunks = (0, memory_files_js_1.splitIntoChunks)(content, relPath);
|
|
107
|
+
if (chunks.length === 0)
|
|
108
|
+
return;
|
|
109
|
+
const project = this.projectId;
|
|
110
|
+
const requests = chunks.map((chunk) => ({
|
|
111
|
+
title: chunk.title,
|
|
112
|
+
content: chunk.content,
|
|
113
|
+
type: chunk.type,
|
|
114
|
+
project,
|
|
115
|
+
scope: 'project',
|
|
116
|
+
tags: ['synced', `source:${relPath}`],
|
|
117
|
+
}));
|
|
118
|
+
const response = await this.client.bulkImport(requests);
|
|
119
|
+
if (response) {
|
|
120
|
+
this.logger.debug(`[file-watcher] synced ${relPath}: ${response.imported} imported`);
|
|
121
|
+
}
|
|
122
|
+
const updatedMarker = {
|
|
123
|
+
lastMigrated: new Date().toISOString(),
|
|
124
|
+
files: { ...(marker?.files ?? {}), [relPath]: hash },
|
|
125
|
+
};
|
|
126
|
+
await (0, memory_files_js_1.saveMarker)(markerPath, updatedMarker);
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
this.logger.warn(`[file-watcher] sync failed for ${filePath}: ${String(err)}`);
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
this.inFlight.delete(filePath);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function createFileWatcherService(workspaceDir, client, config, logger) {
|
|
137
|
+
return new FileWatcherService(workspaceDir, client, config, logger);
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=file-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-watcher.js","sourceRoot":"","sources":["../../src/services/file-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engram_decisions — query architectural decisions stored in engram.
|
|
3
|
+
*/
|
|
4
|
+
import type { EngramRestClient } from '../client.js';
|
|
5
|
+
import type { PluginConfig } from '../config.js';
|
|
6
|
+
import type { AnyAgentTool, OpenClawPluginToolContext } from '../types/openclaw.js';
|
|
7
|
+
export declare function createEngramDecisionsTool(ctx: OpenClawPluginToolContext, client: EngramRestClient, config: PluginConfig): AnyAgentTool;
|
|
8
|
+
//# sourceMappingURL=engram-decisions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engram-decisions.d.ts","sourceRoot":"","sources":["../../src/tools/engram-decisions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAe,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAUpF,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,yBAAyB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,YAAY,GACnB,YAAY,CA0Cd"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* engram_decisions — query architectural decisions stored in engram.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createEngramDecisionsTool = createEngramDecisionsTool;
|
|
7
|
+
const zod_1 = require("zod");
|
|
8
|
+
const typebox_1 = require("@sinclair/typebox");
|
|
9
|
+
const identity_js_1 = require("../identity.js");
|
|
10
|
+
const DecisionsParamsSchema = zod_1.z.object({
|
|
11
|
+
query: zod_1.z.string().min(1),
|
|
12
|
+
});
|
|
13
|
+
const decisionsParameters = typebox_1.Type.Object({
|
|
14
|
+
query: typebox_1.Type.String({ description: 'Query to search for relevant architectural decisions' }),
|
|
15
|
+
});
|
|
16
|
+
function createEngramDecisionsTool(ctx, client, config) {
|
|
17
|
+
return {
|
|
18
|
+
name: 'engram_decisions',
|
|
19
|
+
description: 'Query architectural decisions and design choices stored in engram. ' +
|
|
20
|
+
'Use this before making architectural decisions to surface prior reasoning and constraints.',
|
|
21
|
+
parameters: decisionsParameters,
|
|
22
|
+
async execute(_toolCallId, params) {
|
|
23
|
+
const parsed = DecisionsParamsSchema.safeParse(params);
|
|
24
|
+
if (!parsed.success) {
|
|
25
|
+
return `Invalid parameters: ${parsed.error.message}`;
|
|
26
|
+
}
|
|
27
|
+
if (!client.isAvailable()) {
|
|
28
|
+
return 'engram is currently unreachable — decisions query unavailable';
|
|
29
|
+
}
|
|
30
|
+
const identity = (0, identity_js_1.resolveIdentity)(ctx.agentId ?? '', ctx.workspaceDir);
|
|
31
|
+
const project = config.project ?? identity.projectId;
|
|
32
|
+
const response = await client.searchContext({
|
|
33
|
+
project,
|
|
34
|
+
query: parsed.data.query,
|
|
35
|
+
cwd: ctx.workspaceDir,
|
|
36
|
+
agent_id: ctx.agentId,
|
|
37
|
+
});
|
|
38
|
+
if (!response) {
|
|
39
|
+
return 'engram decisions query failed — server returned no response';
|
|
40
|
+
}
|
|
41
|
+
const observations = (Array.isArray(response.observations) ? response.observations : [])
|
|
42
|
+
.filter((obs) => obs.type?.toLowerCase() === 'decision');
|
|
43
|
+
if (observations.length === 0) {
|
|
44
|
+
return 'No architectural decisions found for this query.';
|
|
45
|
+
}
|
|
46
|
+
return formatDecisions(observations);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function formatDecisions(decisions) {
|
|
51
|
+
let out = '# Relevant Architectural Decisions\n\n';
|
|
52
|
+
decisions.forEach((d, i) => {
|
|
53
|
+
const score = typeof d.similarity === 'number' ? ` [relevance: ${d.similarity.toFixed(2)}]` : '';
|
|
54
|
+
const scopeTag = d.scope === 'global' ? ' [GLOBAL]' : '';
|
|
55
|
+
out += `## ${i + 1}. ${d.title}${scopeTag}${score}\n`;
|
|
56
|
+
const facts = Array.isArray(d.facts) ? d.facts : [];
|
|
57
|
+
if (facts.length > 0) {
|
|
58
|
+
out += 'Rationale:\n';
|
|
59
|
+
for (const fact of facts) {
|
|
60
|
+
if (typeof fact === 'string' && fact)
|
|
61
|
+
out += `- ${fact}\n`;
|
|
62
|
+
}
|
|
63
|
+
out += '\n';
|
|
64
|
+
}
|
|
65
|
+
if (d.narrative)
|
|
66
|
+
out += `${d.narrative}\n\n`;
|
|
67
|
+
});
|
|
68
|
+
return out.trimEnd();
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=engram-decisions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engram-decisions.js","sourceRoot":"","sources":["../../src/tools/engram-decisions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engram_remember + memory_store — store observations in engram memory.
|
|
3
|
+
*/
|
|
4
|
+
import type { EngramRestClient } from '../client.js';
|
|
5
|
+
import type { PluginConfig } from '../config.js';
|
|
6
|
+
import type { AnyAgentTool, OpenClawPluginToolContext } from '../types/openclaw.js';
|
|
7
|
+
export declare function createEngramRememberTool(ctx: OpenClawPluginToolContext, client: EngramRestClient, config: PluginConfig): AnyAgentTool;
|
|
8
|
+
export declare function createMemoryStoreTool(ctx: OpenClawPluginToolContext, client: EngramRestClient, config: PluginConfig): AnyAgentTool;
|
|
9
|
+
//# sourceMappingURL=engram-remember.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engram-remember.d.ts","sourceRoot":"","sources":["../../src/tools/engram-remember.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAqB,MAAM,cAAc,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAgGpF,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,yBAAyB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,YAAY,GACnB,YAAY,CAmBd;AAED,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,yBAAyB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,YAAY,GACnB,YAAY,CAqBd"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* engram_remember + memory_store — store observations in engram memory.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createEngramRememberTool = createEngramRememberTool;
|
|
7
|
+
exports.createMemoryStoreTool = createMemoryStoreTool;
|
|
8
|
+
const zod_1 = require("zod");
|
|
9
|
+
const typebox_1 = require("@sinclair/typebox");
|
|
10
|
+
const identity_js_1 = require("../identity.js");
|
|
11
|
+
const CONTENT_MAX_CHARS = 900;
|
|
12
|
+
const RememberParamsSchema = zod_1.z.object({
|
|
13
|
+
title: zod_1.z.string().min(1),
|
|
14
|
+
content: zod_1.z.string().min(1),
|
|
15
|
+
type: zod_1.z.enum(['decision', 'feature', 'change', 'refactor', 'discovery', 'bugfix']).default('change'),
|
|
16
|
+
scope: zod_1.z.enum(['project', 'global']).default('project'),
|
|
17
|
+
tags: zod_1.z.array(zod_1.z.string()).optional(),
|
|
18
|
+
});
|
|
19
|
+
const StoreParamsSchema = zod_1.z.object({
|
|
20
|
+
text: zod_1.z.string().min(1).optional(),
|
|
21
|
+
content: zod_1.z.string().min(1).optional(),
|
|
22
|
+
title: zod_1.z.string().optional(),
|
|
23
|
+
category: zod_1.z.enum(['preference', 'decision', 'entity', 'fact', 'other']).optional(),
|
|
24
|
+
tags: zod_1.z.array(zod_1.z.string()).optional(),
|
|
25
|
+
}).refine((d) => Boolean(d.text || d.content), { message: 'Either text or content is required' });
|
|
26
|
+
const rememberParameters = typebox_1.Type.Object({
|
|
27
|
+
title: typebox_1.Type.String({ description: 'Short descriptive title for the observation' }),
|
|
28
|
+
content: typebox_1.Type.String({ description: 'Content/narrative to remember (max 900 chars)' }),
|
|
29
|
+
type: typebox_1.Type.Optional(typebox_1.Type.Union([
|
|
30
|
+
typebox_1.Type.Literal('decision'), typebox_1.Type.Literal('feature'), typebox_1.Type.Literal('change'),
|
|
31
|
+
typebox_1.Type.Literal('refactor'), typebox_1.Type.Literal('discovery'), typebox_1.Type.Literal('bugfix'),
|
|
32
|
+
], { description: 'Observation type', default: 'change' })),
|
|
33
|
+
scope: typebox_1.Type.Optional(typebox_1.Type.Union([
|
|
34
|
+
typebox_1.Type.Literal('project'), typebox_1.Type.Literal('global'),
|
|
35
|
+
], { description: 'Scope: project-local or global', default: 'project' })),
|
|
36
|
+
tags: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String(), { description: 'Optional tags' })),
|
|
37
|
+
});
|
|
38
|
+
const storeParameters = typebox_1.Type.Object({
|
|
39
|
+
text: typebox_1.Type.Optional(typebox_1.Type.String({ description: 'Text to remember (compat alias for content)' })),
|
|
40
|
+
content: typebox_1.Type.Optional(typebox_1.Type.String({ description: 'Content to remember' })),
|
|
41
|
+
title: typebox_1.Type.Optional(typebox_1.Type.String({ description: 'Short title (auto-generated if omitted)' })),
|
|
42
|
+
category: typebox_1.Type.Optional(typebox_1.Type.Union([
|
|
43
|
+
typebox_1.Type.Literal('preference'), typebox_1.Type.Literal('decision'), typebox_1.Type.Literal('entity'),
|
|
44
|
+
typebox_1.Type.Literal('fact'), typebox_1.Type.Literal('other'),
|
|
45
|
+
], { description: 'Memory category' })),
|
|
46
|
+
tags: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String(), { description: 'Optional tags' })),
|
|
47
|
+
});
|
|
48
|
+
const CATEGORY_TO_TYPE = {
|
|
49
|
+
preference: 'change',
|
|
50
|
+
decision: 'decision',
|
|
51
|
+
entity: 'change',
|
|
52
|
+
fact: 'discovery',
|
|
53
|
+
other: 'change',
|
|
54
|
+
};
|
|
55
|
+
async function storeObservation(title, content, type, scope, tags, ctx, client, config) {
|
|
56
|
+
if (!client.isAvailable()) {
|
|
57
|
+
return 'engram is currently unreachable — memory store unavailable';
|
|
58
|
+
}
|
|
59
|
+
const identity = (0, identity_js_1.resolveIdentity)(ctx.agentId ?? '', ctx.workspaceDir);
|
|
60
|
+
const project = config.project ?? identity.projectId;
|
|
61
|
+
const trimmedContent = content.length > CONTENT_MAX_CHARS ? content.slice(0, CONTENT_MAX_CHARS) : content;
|
|
62
|
+
const observation = {
|
|
63
|
+
title,
|
|
64
|
+
content: trimmedContent,
|
|
65
|
+
type,
|
|
66
|
+
project,
|
|
67
|
+
scope,
|
|
68
|
+
tags,
|
|
69
|
+
};
|
|
70
|
+
const response = await client.bulkImport([observation]);
|
|
71
|
+
if (!response) {
|
|
72
|
+
return 'engram store failed — server returned no response';
|
|
73
|
+
}
|
|
74
|
+
if (response.imported > 0) {
|
|
75
|
+
return `Stored: "${title}" (type: ${type}, scope: ${scope})`;
|
|
76
|
+
}
|
|
77
|
+
if (response.skipped_duplicates > 0) {
|
|
78
|
+
return `Observation skipped (likely a near-duplicate): "${title}"`;
|
|
79
|
+
}
|
|
80
|
+
const errMsg = response.errors?.join(', ') ?? 'unknown error';
|
|
81
|
+
return `Failed to store observation: ${errMsg}`;
|
|
82
|
+
}
|
|
83
|
+
function createEngramRememberTool(ctx, client, config) {
|
|
84
|
+
return {
|
|
85
|
+
name: 'engram_remember',
|
|
86
|
+
description: 'Store an observation in engram persistent memory. ' +
|
|
87
|
+
'Use this to record decisions, discoveries, patterns, or important context for future sessions.',
|
|
88
|
+
parameters: rememberParameters,
|
|
89
|
+
async execute(_toolCallId, params) {
|
|
90
|
+
const parsed = RememberParamsSchema.safeParse(params);
|
|
91
|
+
if (!parsed.success) {
|
|
92
|
+
return `Invalid parameters: ${parsed.error.message}`;
|
|
93
|
+
}
|
|
94
|
+
return storeObservation(parsed.data.title, parsed.data.content, parsed.data.type, parsed.data.scope, parsed.data.tags, ctx, client, config);
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function createMemoryStoreTool(ctx, client, config) {
|
|
99
|
+
return {
|
|
100
|
+
name: 'memory_store',
|
|
101
|
+
label: 'Store Memory',
|
|
102
|
+
description: 'Store a memory for future sessions. Accepts text or content parameter.',
|
|
103
|
+
parameters: storeParameters,
|
|
104
|
+
async execute(_toolCallId, params) {
|
|
105
|
+
const parsed = StoreParamsSchema.safeParse(params);
|
|
106
|
+
if (!parsed.success) {
|
|
107
|
+
return `Invalid parameters: ${parsed.error.message}`;
|
|
108
|
+
}
|
|
109
|
+
const content = parsed.data.text ?? parsed.data.content ?? '';
|
|
110
|
+
const title = parsed.data.title ?? (content.length > 80 ? content.slice(0, 77) + '...' : content);
|
|
111
|
+
const type = parsed.data.category ? (CATEGORY_TO_TYPE[parsed.data.category] ?? 'change') : 'change';
|
|
112
|
+
return storeObservation(title, content, type, 'project', parsed.data.tags, ctx, client, config);
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=engram-remember.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engram-remember.js","sourceRoot":"","sources":["../../src/tools/engram-remember.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engram_search + memory_search — search engram memory.
|
|
3
|
+
*/
|
|
4
|
+
import type { EngramRestClient } from '../client.js';
|
|
5
|
+
import type { PluginConfig } from '../config.js';
|
|
6
|
+
import type { AnyAgentTool, OpenClawPluginToolContext } from '../types/openclaw.js';
|
|
7
|
+
export declare function createEngramSearchTool(ctx: OpenClawPluginToolContext, client: EngramRestClient, config: PluginConfig): AnyAgentTool;
|
|
8
|
+
export declare function createMemorySearchTool(ctx: OpenClawPluginToolContext, client: EngramRestClient, config: PluginConfig): AnyAgentTool;
|
|
9
|
+
//# sourceMappingURL=engram-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engram-search.d.ts","sourceRoot":"","sources":["../../src/tools/engram-search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,KAAK,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AA+DpF,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,yBAAyB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,YAAY,GACnB,YAAY,CAEd;AAED,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,yBAAyB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,YAAY,GACnB,YAAY,CAEd"}
|