@memoryrelay/plugin-memoryrelay-ai 0.8.1 → 0.8.3
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/index.ts +84 -7
- package/openclaw.plugin.json +2 -2
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenClaw Memory Plugin - MemoryRelay
|
|
3
|
-
* Version: 0.8.
|
|
3
|
+
* Version: 0.8.3 (Security & Installation Fixes)
|
|
4
4
|
*
|
|
5
5
|
* Long-term memory with vector search using MemoryRelay API.
|
|
6
6
|
* Provides auto-recall and auto-capture via lifecycle hooks.
|
|
@@ -9,6 +9,18 @@
|
|
|
9
9
|
* API: https://api.memoryrelay.net
|
|
10
10
|
* Docs: https://memoryrelay.ai
|
|
11
11
|
*
|
|
12
|
+
* ENHANCEMENTS (v0.8.3):
|
|
13
|
+
* - Security fix: logFile now restricted to relative paths only
|
|
14
|
+
* - Rejects absolute paths and path traversal attempts
|
|
15
|
+
* - Passes OpenClaw security validation for npm installation
|
|
16
|
+
* - Clean installation without security warnings
|
|
17
|
+
*
|
|
18
|
+
* ENHANCEMENTS (v0.8.2):
|
|
19
|
+
* - Human-readable gateway logs with memory previews
|
|
20
|
+
* - Show similarity scores and memory snippets during auto-recall
|
|
21
|
+
* - Performance indicators (✓/✗ and timing with SLOW warnings)
|
|
22
|
+
* - Cleaner error messages in gateway logs
|
|
23
|
+
*
|
|
12
24
|
* ENHANCEMENTS (v0.8.0):
|
|
13
25
|
* - Debug mode with comprehensive API call logging
|
|
14
26
|
* - Enhanced status reporting with tool breakdown
|
|
@@ -148,6 +160,8 @@ async function fetchWithTimeout(
|
|
|
148
160
|
class MemoryRelayClient {
|
|
149
161
|
private debugLogger?: DebugLogger;
|
|
150
162
|
private statusReporter?: StatusReporter;
|
|
163
|
+
private config?: MemoryRelayConfig;
|
|
164
|
+
private api?: OpenClawPluginApi;
|
|
151
165
|
|
|
152
166
|
constructor(
|
|
153
167
|
private readonly apiKey: string,
|
|
@@ -155,9 +169,12 @@ class MemoryRelayClient {
|
|
|
155
169
|
private readonly apiUrl: string = DEFAULT_API_URL,
|
|
156
170
|
debugLogger?: DebugLogger,
|
|
157
171
|
statusReporter?: StatusReporter,
|
|
172
|
+
api?: OpenClawPluginApi,
|
|
158
173
|
) {
|
|
159
174
|
this.debugLogger = debugLogger;
|
|
160
175
|
this.statusReporter = statusReporter;
|
|
176
|
+
this.api = api;
|
|
177
|
+
this.config = api?.pluginConfig as MemoryRelayConfig | undefined;
|
|
161
178
|
}
|
|
162
179
|
|
|
163
180
|
/**
|
|
@@ -234,6 +251,14 @@ class MemoryRelayClient {
|
|
|
234
251
|
retries: retryCount,
|
|
235
252
|
requestBody: this.debugLogger && body ? body : undefined,
|
|
236
253
|
});
|
|
254
|
+
|
|
255
|
+
// Enhanced gateway logging (v0.8.2): Readable error summary
|
|
256
|
+
if (this.config.debug && this.api) {
|
|
257
|
+
const retryMsg = retryCount > 0 ? ` (retry ${retryCount}/${MAX_RETRIES})` : '';
|
|
258
|
+
this.api.logger.warn?.(
|
|
259
|
+
`memory-memoryrelay: ${toolName} → ${response.status} ${errorMsg || response.statusText}${retryMsg}`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
237
262
|
}
|
|
238
263
|
|
|
239
264
|
// Track failure
|
|
@@ -267,6 +292,15 @@ class MemoryRelayClient {
|
|
|
267
292
|
requestBody: this.debugLogger && body ? body : undefined,
|
|
268
293
|
responseBody: this.debugLogger && result ? result : undefined,
|
|
269
294
|
});
|
|
295
|
+
|
|
296
|
+
// Enhanced gateway logging (v0.8.2): Readable API call summary
|
|
297
|
+
if (this.config.debug && this.api) {
|
|
298
|
+
const statusSymbol = response.status < 400 ? '✓' : '✗';
|
|
299
|
+
const durationColor = duration > 1000 ? ' (SLOW)' : duration > 500 ? ' (slow)' : '';
|
|
300
|
+
this.api.logger.info?.(
|
|
301
|
+
`memory-memoryrelay: ${toolName} → ${duration}ms ${statusSymbol}${durationColor}`
|
|
302
|
+
);
|
|
303
|
+
}
|
|
270
304
|
}
|
|
271
305
|
|
|
272
306
|
// Track success
|
|
@@ -817,9 +851,34 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
817
851
|
|
|
818
852
|
const debugEnabled = cfg?.debug || false;
|
|
819
853
|
const verboseEnabled = cfg?.verbose || false;
|
|
820
|
-
const logFile = cfg?.logFile;
|
|
821
854
|
const maxLogEntries = cfg?.maxLogEntries || 100;
|
|
822
855
|
|
|
856
|
+
// Security fix (v0.8.3): logFile must be relative to workspace/plugin directory
|
|
857
|
+
// Absolute paths and path traversal are rejected
|
|
858
|
+
let logFile: string | undefined;
|
|
859
|
+
if (cfg?.logFile) {
|
|
860
|
+
const requestedPath = cfg.logFile;
|
|
861
|
+
|
|
862
|
+
// Reject absolute paths
|
|
863
|
+
if (requestedPath.startsWith('/') || requestedPath.startsWith('~') || /^[A-Za-z]:/.test(requestedPath)) {
|
|
864
|
+
api.logger.warn(
|
|
865
|
+
`memory-memoryrelay: logFile must be relative path (got: ${requestedPath}). Using default location.`
|
|
866
|
+
);
|
|
867
|
+
logFile = undefined;
|
|
868
|
+
}
|
|
869
|
+
// Reject path traversal
|
|
870
|
+
else if (requestedPath.includes('..')) {
|
|
871
|
+
api.logger.warn(
|
|
872
|
+
`memory-memoryrelay: logFile cannot contain '..' (got: ${requestedPath}). Using default location.`
|
|
873
|
+
);
|
|
874
|
+
logFile = undefined;
|
|
875
|
+
}
|
|
876
|
+
// Accept relative path (will be resolved by DebugLogger relative to workspace)
|
|
877
|
+
else {
|
|
878
|
+
logFile = requestedPath;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
|
|
823
882
|
let debugLogger: DebugLogger | undefined;
|
|
824
883
|
let statusReporter: StatusReporter | undefined;
|
|
825
884
|
|
|
@@ -830,12 +889,16 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
830
889
|
maxEntries: maxLogEntries,
|
|
831
890
|
logFile: logFile,
|
|
832
891
|
});
|
|
833
|
-
|
|
892
|
+
|
|
893
|
+
const logLocation = logFile ? ` → ${logFile}` : '';
|
|
894
|
+
api.logger.info(
|
|
895
|
+
`memory-memoryrelay: debug mode enabled (verbose: ${verboseEnabled}, maxEntries: ${maxLogEntries}${logLocation})`
|
|
896
|
+
);
|
|
834
897
|
}
|
|
835
898
|
|
|
836
899
|
statusReporter = new StatusReporter(debugLogger);
|
|
837
900
|
|
|
838
|
-
const client = new MemoryRelayClient(apiKey, agentId, apiUrl, debugLogger, statusReporter);
|
|
901
|
+
const client = new MemoryRelayClient(apiKey, agentId, apiUrl, debugLogger, statusReporter, api);
|
|
839
902
|
|
|
840
903
|
// Verify connection on startup (with timeout)
|
|
841
904
|
try {
|
|
@@ -3297,9 +3360,23 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
3297
3360
|
if (results.length > 0) {
|
|
3298
3361
|
const memoryContext = results.map((r) => `- ${r.memory.content}`).join("\n");
|
|
3299
3362
|
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3363
|
+
// Enhanced gateway logging (v0.8.2): Show memory previews
|
|
3364
|
+
if (cfg?.debug) {
|
|
3365
|
+
const snippets = results
|
|
3366
|
+
.map((r) => {
|
|
3367
|
+
const preview = r.memory.content.substring(0, 100).replace(/\n/g, ' ');
|
|
3368
|
+
const ellipsis = r.memory.content.length > 100 ? '...' : '';
|
|
3369
|
+
return ` • [${r.score.toFixed(2)}] ${preview}${ellipsis}`;
|
|
3370
|
+
})
|
|
3371
|
+
.join('\n');
|
|
3372
|
+
api.logger.info?.(
|
|
3373
|
+
`memory-memoryrelay: injecting ${results.length} memories into context:\n${snippets}`,
|
|
3374
|
+
);
|
|
3375
|
+
} else {
|
|
3376
|
+
api.logger.info?.(
|
|
3377
|
+
`memory-memoryrelay: injecting ${results.length} memories into context`,
|
|
3378
|
+
);
|
|
3379
|
+
}
|
|
3303
3380
|
|
|
3304
3381
|
prependContext +=
|
|
3305
3382
|
`\n\n<relevant-memories>\nThe following memories from MemoryRelay may be relevant:\n${memoryContext}\n</relevant-memories>`;
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"kind": "memory",
|
|
4
4
|
"name": "MemoryRelay AI",
|
|
5
5
|
"description": "AI memory service with sessions, decisions, patterns & projects (api.memoryrelay.net)",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.8.3",
|
|
7
7
|
"uiHints": {
|
|
8
8
|
"apiKey": {
|
|
9
9
|
"label": "MemoryRelay API Key",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
"logFile": {
|
|
115
115
|
"type": "string",
|
|
116
|
-
"description": "
|
|
116
|
+
"description": "Relative file path for persistent debug logs (e.g., 'memoryrelay-debug.log'). Absolute paths and path traversal (..) are rejected for security."
|
|
117
117
|
},
|
|
118
118
|
"maxLogEntries": {
|
|
119
119
|
"type": "number",
|
package/package.json
CHANGED