@mem9/mem9 0.3.5-rc.5 → 0.3.6
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/hooks.ts +5 -2
- package/index.ts +35 -3
- package/package.json +1 -1
- package/server-backend.ts +1 -0
- package/types.ts +3 -0
package/hooks.ts
CHANGED
|
@@ -130,11 +130,14 @@ function formatMemoriesBlock(memories: Memory[]): string {
|
|
|
130
130
|
let idx = 1;
|
|
131
131
|
|
|
132
132
|
const formatMem = (m: Memory): string => {
|
|
133
|
-
const
|
|
133
|
+
const tagStr = m.tags?.length ? `[${m.tags.join(", ")}]` : "";
|
|
134
|
+
const age = m.relative_age ? `(${m.relative_age})` : "";
|
|
135
|
+
const middle = [tagStr, age].filter(Boolean).join(" ");
|
|
136
|
+
const sep = middle ? " " + middle + " " : " ";
|
|
134
137
|
const content = m.content.length > MAX_CONTENT_LEN
|
|
135
138
|
? m.content.slice(0, MAX_CONTENT_LEN) + "..."
|
|
136
139
|
: m.content;
|
|
137
|
-
return `${idx++}.${
|
|
140
|
+
return `${idx++}.${sep}${escapeForPrompt(content)}`;
|
|
138
141
|
};
|
|
139
142
|
|
|
140
143
|
if (pinned.length > 0) {
|
package/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { ServerBackend } from "./server-backend.js";
|
|
|
3
3
|
import { registerHooks } from "./hooks.js";
|
|
4
4
|
import type {
|
|
5
5
|
PluginConfig,
|
|
6
|
+
Memory,
|
|
6
7
|
CreateMemoryInput,
|
|
7
8
|
UpdateMemoryInput,
|
|
8
9
|
SearchInput,
|
|
@@ -26,6 +27,13 @@ function jsonResult(data: unknown) {
|
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
interface MemoryCapability {
|
|
31
|
+
search: (query: string, opts?: { limit?: number }) => Promise<{ data: Memory[]; total: number }>;
|
|
32
|
+
store: (content: string, opts?: { tags?: string[]; source?: string }) => Promise<unknown>;
|
|
33
|
+
get: (id: string) => Promise<Memory | null>;
|
|
34
|
+
remove: (id: string) => Promise<boolean>;
|
|
35
|
+
}
|
|
36
|
+
|
|
29
37
|
interface OpenClawPluginApi {
|
|
30
38
|
pluginConfig?: unknown;
|
|
31
39
|
logger: {
|
|
@@ -36,6 +44,7 @@ interface OpenClawPluginApi {
|
|
|
36
44
|
factory: ToolFactory | (() => AnyAgentTool[]),
|
|
37
45
|
opts: { names: string[] }
|
|
38
46
|
) => void;
|
|
47
|
+
registerCapability?: (slot: string, capability: MemoryCapability) => void;
|
|
39
48
|
on: (hookName: string, handler: (...args: unknown[]) => unknown, opts?: { priority?: number }) => void;
|
|
40
49
|
}
|
|
41
50
|
|
|
@@ -123,6 +132,10 @@ function buildTools(backend: MemoryBackend): AnyAgentTool[] {
|
|
|
123
132
|
description: "Max results (default 20, max 200)",
|
|
124
133
|
},
|
|
125
134
|
offset: { type: "number", description: "Pagination offset" },
|
|
135
|
+
memory_type: {
|
|
136
|
+
type: "string",
|
|
137
|
+
description: "Comma-separated memory types to filter by (e.g. insight,pinned)",
|
|
138
|
+
},
|
|
126
139
|
},
|
|
127
140
|
required: [],
|
|
128
141
|
},
|
|
@@ -238,7 +251,7 @@ const mnemoPlugin = {
|
|
|
238
251
|
description:
|
|
239
252
|
"AI agent memory — server mode (mnemo-server) with hybrid vector + keyword search.",
|
|
240
253
|
|
|
241
|
-
|
|
254
|
+
register(api: OpenClawPluginApi) {
|
|
242
255
|
const cfg = (api.pluginConfig ?? {}) as PluginConfig;
|
|
243
256
|
const effectiveApiUrl = cfg.apiUrl ?? DEFAULT_API_URL;
|
|
244
257
|
if (!cfg.apiUrl) {
|
|
@@ -284,13 +297,32 @@ const mnemoPlugin = {
|
|
|
284
297
|
|
|
285
298
|
api.registerTool(factory, { names: toolNames });
|
|
286
299
|
|
|
287
|
-
//
|
|
288
|
-
// Uses the default workspace/agent context for hook-triggered operations.
|
|
300
|
+
// Shared lazy backend for hooks and capability registration.
|
|
289
301
|
const hookBackend = new LazyServerBackend(
|
|
290
302
|
effectiveApiUrl,
|
|
291
303
|
() => resolveAPIKey(hookAgentId),
|
|
292
304
|
hookAgentId,
|
|
293
305
|
);
|
|
306
|
+
|
|
307
|
+
// Register memory capability so OpenClaw 2026.4.2+ binds this plugin to
|
|
308
|
+
// the memory slot. Without this, the plugin is treated as a legacy
|
|
309
|
+
// hook-only plugin and automatic context injection won't work.
|
|
310
|
+
// Guard with typeof check for backward compatibility with older hosts.
|
|
311
|
+
if (typeof api.registerCapability === "function") {
|
|
312
|
+
api.registerCapability("memory", {
|
|
313
|
+
search: async (query, opts) => {
|
|
314
|
+
const result = await hookBackend.search({ q: query, limit: opts?.limit });
|
|
315
|
+
return { data: result.data, total: result.total };
|
|
316
|
+
},
|
|
317
|
+
store: async (content, opts) => {
|
|
318
|
+
return hookBackend.store({ content, tags: opts?.tags, source: opts?.source });
|
|
319
|
+
},
|
|
320
|
+
get: (id) => hookBackend.get(id),
|
|
321
|
+
remove: (id) => hookBackend.remove(id),
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Register hooks with lazy backend for lifecycle memory management.
|
|
294
326
|
registerHooks(api, hookBackend, api.logger, {
|
|
295
327
|
maxIngestBytes: cfg.maxIngestBytes,
|
|
296
328
|
fallbackAgentId: hookAgentId,
|
package/package.json
CHANGED
package/server-backend.ts
CHANGED
|
@@ -67,6 +67,7 @@ export class ServerBackend implements MemoryBackend {
|
|
|
67
67
|
if (input.source) params.set("source", input.source);
|
|
68
68
|
if (input.limit != null) params.set("limit", String(input.limit));
|
|
69
69
|
if (input.offset != null) params.set("offset", String(input.offset));
|
|
70
|
+
if (input.memory_type) params.set("memory_type", input.memory_type);
|
|
70
71
|
|
|
71
72
|
const qs = params.toString();
|
|
72
73
|
const raw = await this.request<{
|
package/types.ts
CHANGED
|
@@ -31,6 +31,8 @@ export interface Memory {
|
|
|
31
31
|
state?: string;
|
|
32
32
|
agent_id?: string;
|
|
33
33
|
session_id?: string;
|
|
34
|
+
|
|
35
|
+
relative_age?: string;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
export interface SearchResult {
|
|
@@ -60,6 +62,7 @@ export interface SearchInput {
|
|
|
60
62
|
source?: string;
|
|
61
63
|
limit?: number;
|
|
62
64
|
offset?: number;
|
|
65
|
+
memory_type?: string;
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
export interface IngestMessage {
|