@contextableai/openclaw-memory-graphiti 0.2.1 → 0.2.2
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/README.md +5 -5
- package/config.ts +2 -2
- package/docker/.env.example +1 -1
- package/docker/docker-compose.yml +1 -1
- package/index.ts +16 -16
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -346,16 +346,16 @@ When running inside Docker Compose, use service hostnames in the plugin config:
|
|
|
346
346
|
|
|
347
347
|
### Selecting the Memory Slot
|
|
348
348
|
|
|
349
|
-
OpenClaw has an exclusive `memory` slot — only one memory plugin is active at a time. To use memory-graphiti, set the slot in your OpenClaw config (`~/.openclaw/openclaw.json`):
|
|
349
|
+
OpenClaw has an exclusive `memory` slot — only one memory plugin is active at a time. To use openclaw-memory-graphiti, set the slot in your OpenClaw config (`~/.openclaw/openclaw.json`):
|
|
350
350
|
|
|
351
351
|
```json
|
|
352
352
|
{
|
|
353
353
|
"plugins": {
|
|
354
354
|
"slots": {
|
|
355
|
-
"memory": "memory-graphiti"
|
|
355
|
+
"memory": "openclaw-memory-graphiti"
|
|
356
356
|
},
|
|
357
357
|
"entries": {
|
|
358
|
-
"memory-graphiti": {
|
|
358
|
+
"openclaw-memory-graphiti": {
|
|
359
359
|
"enabled": true,
|
|
360
360
|
"config": {
|
|
361
361
|
"spicedb": {
|
|
@@ -378,7 +378,7 @@ OpenClaw has an exclusive `memory` slot — only one memory plugin is active at
|
|
|
378
378
|
}
|
|
379
379
|
```
|
|
380
380
|
|
|
381
|
-
The plugin must be discoverable — either symlinked into `extensions/memory-graphiti` in the OpenClaw installation, or loaded via `plugins.load.paths`.
|
|
381
|
+
The plugin must be discoverable — either symlinked into `extensions/openclaw-memory-graphiti` in the OpenClaw installation, or loaded via `plugins.load.paths`.
|
|
382
382
|
|
|
383
383
|
### Initialization
|
|
384
384
|
|
|
@@ -410,7 +410,7 @@ Workspace files are imported to the configured `defaultGroupId`. Session transcr
|
|
|
410
410
|
|
|
411
411
|
### Session Logging
|
|
412
412
|
|
|
413
|
-
OpenClaw's JSONL session logging is always-on core behavior — memory-graphiti does not replace it. The plugin augments session context by:
|
|
413
|
+
OpenClaw's JSONL session logging is always-on core behavior — openclaw-memory-graphiti does not replace it. The plugin augments session context by:
|
|
414
414
|
|
|
415
415
|
- **Auto-capture**: Extracting entities and facts from conversation turns into the knowledge graph (`agent_end` hook)
|
|
416
416
|
- **Auto-recall**: Injecting relevant memories into the agent's context before each turn (`before_agent_start` hook)
|
package/config.ts
CHANGED
|
@@ -55,7 +55,7 @@ function assertAllowedKeys(value: Record<string, unknown>, allowed: string[], la
|
|
|
55
55
|
export const graphitiMemoryConfigSchema = {
|
|
56
56
|
parse(value: unknown): GraphitiMemoryConfig {
|
|
57
57
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
58
|
-
throw new Error("memory-graphiti config required");
|
|
58
|
+
throw new Error("openclaw-memory-graphiti config required");
|
|
59
59
|
}
|
|
60
60
|
const cfg = value as Record<string, unknown>;
|
|
61
61
|
assertAllowedKeys(
|
|
@@ -64,7 +64,7 @@ export const graphitiMemoryConfigSchema = {
|
|
|
64
64
|
"spicedb", "graphiti", "subjectType", "subjectId",
|
|
65
65
|
"autoCapture", "autoRecall", "customInstructions", "maxCaptureMessages",
|
|
66
66
|
],
|
|
67
|
-
"memory-graphiti config",
|
|
67
|
+
"openclaw-memory-graphiti config",
|
|
68
68
|
);
|
|
69
69
|
|
|
70
70
|
// SpiceDB config
|
package/docker/.env.example
CHANGED
|
@@ -44,7 +44,7 @@ SPICEDB_DB_PASSWORD=spicedb_dev
|
|
|
44
44
|
# ===========================================================================
|
|
45
45
|
#
|
|
46
46
|
# When running via docker compose, services reach each other by hostname.
|
|
47
|
-
# Configure the memory-graphiti plugin in OpenClaw with:
|
|
47
|
+
# Configure the openclaw-memory-graphiti plugin in OpenClaw with:
|
|
48
48
|
#
|
|
49
49
|
# {
|
|
50
50
|
# "spicedb": {
|
package/index.ts
CHANGED
|
@@ -53,7 +53,7 @@ function isSessionGroup(groupId: string): boolean {
|
|
|
53
53
|
// ============================================================================
|
|
54
54
|
|
|
55
55
|
const memoryGraphitiPlugin = {
|
|
56
|
-
id: "memory-graphiti",
|
|
56
|
+
id: "openclaw-memory-graphiti",
|
|
57
57
|
name: "Memory (Graphiti + SpiceDB)",
|
|
58
58
|
description: "Two-layer memory: SpiceDB authorization + Graphiti knowledge graph",
|
|
59
59
|
kind: "memory" as const,
|
|
@@ -80,7 +80,7 @@ const memoryGraphitiPlugin = {
|
|
|
80
80
|
let lastWriteToken: string | undefined;
|
|
81
81
|
|
|
82
82
|
api.logger.info(
|
|
83
|
-
`memory-graphiti: registered (graphiti: ${cfg.graphiti.endpoint}, spicedb: ${cfg.spicedb.endpoint})`,
|
|
83
|
+
`openclaw-memory-graphiti: registered (graphiti: ${cfg.graphiti.endpoint}, spicedb: ${cfg.spicedb.endpoint})`,
|
|
84
84
|
);
|
|
85
85
|
|
|
86
86
|
// ========================================================================
|
|
@@ -268,7 +268,7 @@ const memoryGraphitiPlugin = {
|
|
|
268
268
|
const token = await ensureGroupMembership(spicedb, targetGroupId, currentSubject);
|
|
269
269
|
if (token) lastWriteToken = token;
|
|
270
270
|
} catch {
|
|
271
|
-
api.logger.warn(`memory-graphiti: failed to ensure membership in ${targetGroupId}`);
|
|
271
|
+
api.logger.warn(`openclaw-memory-graphiti: failed to ensure membership in ${targetGroupId}`);
|
|
272
272
|
}
|
|
273
273
|
} else {
|
|
274
274
|
// All other groups (non-session AND foreign session) require write permission
|
|
@@ -318,7 +318,7 @@ const memoryGraphitiPlugin = {
|
|
|
318
318
|
})
|
|
319
319
|
.catch((err) => {
|
|
320
320
|
api.logger.warn(
|
|
321
|
-
`memory-graphiti: deferred SpiceDB write failed for memory_store: ${err}`,
|
|
321
|
+
`openclaw-memory-graphiti: deferred SpiceDB write failed for memory_store: ${err}`,
|
|
322
322
|
);
|
|
323
323
|
});
|
|
324
324
|
|
|
@@ -555,14 +555,14 @@ const memoryGraphitiPlugin = {
|
|
|
555
555
|
|
|
556
556
|
const memoryContext = formatDualResults(longTermResults, sessionResults);
|
|
557
557
|
api.logger.info?.(
|
|
558
|
-
`memory-graphiti: injecting ${totalCount} memories (${longTermResults.length} long-term, ${sessionResults.length} session)`,
|
|
558
|
+
`openclaw-memory-graphiti: injecting ${totalCount} memories (${longTermResults.length} long-term, ${sessionResults.length} session)`,
|
|
559
559
|
);
|
|
560
560
|
|
|
561
561
|
return {
|
|
562
562
|
prependContext: `${toolHint}\n\n<relevant-memories>\nThe following memories from the knowledge graph may be relevant:\n${memoryContext}\n</relevant-memories>`,
|
|
563
563
|
};
|
|
564
564
|
} catch (err) {
|
|
565
|
-
api.logger.warn(`memory-graphiti: recall failed: ${String(err)}`);
|
|
565
|
+
api.logger.warn(`openclaw-memory-graphiti: recall failed: ${String(err)}`);
|
|
566
566
|
}
|
|
567
567
|
});
|
|
568
568
|
}
|
|
@@ -652,7 +652,7 @@ const memoryGraphitiPlugin = {
|
|
|
652
652
|
} else {
|
|
653
653
|
const allowed = await canWriteToGroup(spicedb, currentSubject, targetGroupId, lastWriteToken);
|
|
654
654
|
if (!allowed) {
|
|
655
|
-
api.logger.warn(`memory-graphiti: auto-capture denied for group ${targetGroupId}`);
|
|
655
|
+
api.logger.warn(`openclaw-memory-graphiti: auto-capture denied for group ${targetGroupId}`);
|
|
656
656
|
return;
|
|
657
657
|
}
|
|
658
658
|
}
|
|
@@ -677,15 +677,15 @@ const memoryGraphitiPlugin = {
|
|
|
677
677
|
})
|
|
678
678
|
.catch((err) => {
|
|
679
679
|
api.logger.warn(
|
|
680
|
-
`memory-graphiti: deferred SpiceDB write (auto-capture) failed: ${err}`,
|
|
680
|
+
`openclaw-memory-graphiti: deferred SpiceDB write (auto-capture) failed: ${err}`,
|
|
681
681
|
);
|
|
682
682
|
});
|
|
683
683
|
|
|
684
684
|
api.logger.info(
|
|
685
|
-
`memory-graphiti: auto-captured ${conversationLines.length} messages as batch episode to ${targetGroupId}`,
|
|
685
|
+
`openclaw-memory-graphiti: auto-captured ${conversationLines.length} messages as batch episode to ${targetGroupId}`,
|
|
686
686
|
);
|
|
687
687
|
} catch (err) {
|
|
688
|
-
api.logger.warn(`memory-graphiti: capture failed: ${String(err)}`);
|
|
688
|
+
api.logger.warn(`openclaw-memory-graphiti: capture failed: ${String(err)}`);
|
|
689
689
|
}
|
|
690
690
|
});
|
|
691
691
|
}
|
|
@@ -695,7 +695,7 @@ const memoryGraphitiPlugin = {
|
|
|
695
695
|
// ========================================================================
|
|
696
696
|
|
|
697
697
|
api.registerService({
|
|
698
|
-
id: "memory-graphiti",
|
|
698
|
+
id: "openclaw-memory-graphiti",
|
|
699
699
|
async start() {
|
|
700
700
|
// Verify connectivity on startup
|
|
701
701
|
const graphitiOk = await graphiti.healthCheck();
|
|
@@ -706,11 +706,11 @@ const memoryGraphitiPlugin = {
|
|
|
706
706
|
|
|
707
707
|
// Auto-write schema if SpiceDB has no schema yet
|
|
708
708
|
if (!existing || !existing.includes("memory_fragment")) {
|
|
709
|
-
api.logger.info("memory-graphiti: writing SpiceDB schema (first run)");
|
|
709
|
+
api.logger.info("openclaw-memory-graphiti: writing SpiceDB schema (first run)");
|
|
710
710
|
const schemaPath = join(dirname(fileURLToPath(import.meta.url)), "schema.zed");
|
|
711
711
|
const schema = readFileSync(schemaPath, "utf-8");
|
|
712
712
|
await spicedb.writeSchema(schema);
|
|
713
|
-
api.logger.info("memory-graphiti: SpiceDB schema written successfully");
|
|
713
|
+
api.logger.info("openclaw-memory-graphiti: SpiceDB schema written successfully");
|
|
714
714
|
}
|
|
715
715
|
} catch {
|
|
716
716
|
// Will be retried on first use
|
|
@@ -726,16 +726,16 @@ const memoryGraphitiPlugin = {
|
|
|
726
726
|
);
|
|
727
727
|
if (token) lastWriteToken = token;
|
|
728
728
|
} catch {
|
|
729
|
-
api.logger.warn("memory-graphiti: failed to ensure default group membership");
|
|
729
|
+
api.logger.warn("openclaw-memory-graphiti: failed to ensure default group membership");
|
|
730
730
|
}
|
|
731
731
|
}
|
|
732
732
|
|
|
733
733
|
api.logger.info(
|
|
734
|
-
`memory-graphiti: initialized (graphiti: ${graphitiOk ? "OK" : "UNREACHABLE"}, spicedb: ${spicedbOk ? "OK" : "UNREACHABLE"})`,
|
|
734
|
+
`openclaw-memory-graphiti: initialized (graphiti: ${graphitiOk ? "OK" : "UNREACHABLE"}, spicedb: ${spicedbOk ? "OK" : "UNREACHABLE"})`,
|
|
735
735
|
);
|
|
736
736
|
},
|
|
737
737
|
stop() {
|
|
738
|
-
api.logger.info("memory-graphiti: stopped");
|
|
738
|
+
api.logger.info("openclaw-memory-graphiti: stopped");
|
|
739
739
|
},
|
|
740
740
|
});
|
|
741
741
|
},
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contextableai/openclaw-memory-graphiti",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "OpenClaw two-layer memory plugin: SpiceDB authorization + Graphiti knowledge graph",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -50,11 +50,10 @@
|
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|
|
52
52
|
"openclaw": {
|
|
53
|
-
"
|
|
54
|
-
"extensions": [],
|
|
53
|
+
"extensions": ["./index.ts"],
|
|
55
54
|
"install": {
|
|
56
55
|
"npmSpec": "@contextableai/openclaw-memory-graphiti",
|
|
57
|
-
"localPath": "extensions/memory-graphiti",
|
|
56
|
+
"localPath": "extensions/openclaw-memory-graphiti",
|
|
58
57
|
"defaultChoice": "npm"
|
|
59
58
|
}
|
|
60
59
|
}
|