@contextableai/openclaw-memory-rebac 0.5.0 → 0.5.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/dist/index.js +32 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -99,9 +99,14 @@ const rebacMemoryPlugin = {
|
|
|
99
99
|
const isHybrid = cfg.isHybrid;
|
|
100
100
|
const spicedb = new SpiceDbClient(cfg.spicedb);
|
|
101
101
|
const backendDefaultGroupId = defaultGroupId(cfg);
|
|
102
|
-
const
|
|
102
|
+
const liminalBaseGroupId = isHybrid
|
|
103
103
|
? (cfg.liminalConfig["defaultGroupId"] ?? "main")
|
|
104
104
|
: backendDefaultGroupId;
|
|
105
|
+
/** Per-agent liminal group — each agent gets its own conversational memory. */
|
|
106
|
+
function liminalGroupId(agentId) {
|
|
107
|
+
const id = agentId ?? cfg.subjectId;
|
|
108
|
+
return `${liminalBaseGroupId}:${id}`;
|
|
109
|
+
}
|
|
105
110
|
// Suppress transient gRPC rejections from @grpc/grpc-js during connection setup
|
|
106
111
|
const grpcRejectionHandler = (reason) => {
|
|
107
112
|
const msg = String(reason);
|
|
@@ -598,7 +603,7 @@ const rebacMemoryPlugin = {
|
|
|
598
603
|
// 1. Search the liminal backend
|
|
599
604
|
const liminalResults = await searchAuthorizedMemories(liminal, {
|
|
600
605
|
query,
|
|
601
|
-
groupIds: [
|
|
606
|
+
groupIds: [liminalGroupId(ctx.agentId)],
|
|
602
607
|
limit: promoteLimit,
|
|
603
608
|
});
|
|
604
609
|
if (liminalResults.length === 0) {
|
|
@@ -678,7 +683,7 @@ const rebacMemoryPlugin = {
|
|
|
678
683
|
const autoRecallLimit = 8;
|
|
679
684
|
const liminalResults = await searchAuthorizedMemories(liminal, {
|
|
680
685
|
query: event.prompt,
|
|
681
|
-
groupIds: [
|
|
686
|
+
groupIds: [liminalGroupId(ctx?.agentId)],
|
|
682
687
|
limit: autoRecallLimit,
|
|
683
688
|
sessionId: state.sessionId,
|
|
684
689
|
});
|
|
@@ -686,6 +691,8 @@ const rebacMemoryPlugin = {
|
|
|
686
691
|
"You have memory tools:\n" +
|
|
687
692
|
"- memory_recall: Use this BEFORE saying you don't know or remember something. Search the long-term knowledge graph for facts, preferences, people, decisions.\n" +
|
|
688
693
|
"- memory_store: Save important new information to the knowledge graph.\n" +
|
|
694
|
+
"- memory_share: Share a specific memory with other people/agents by ID.\n" +
|
|
695
|
+
"- memory_unshare: Revoke view access to a memory from people/agents.\n" +
|
|
689
696
|
"- memory_promote: Promote recent memories into the long-term knowledge graph.\n" +
|
|
690
697
|
"</memory-tools>";
|
|
691
698
|
if (liminalResults.length === 0)
|
|
@@ -725,6 +732,8 @@ const rebacMemoryPlugin = {
|
|
|
725
732
|
"You have memory tools:\n" +
|
|
726
733
|
"- memory_recall: Use this BEFORE saying you don't know or remember something. Search for facts, preferences, people, decisions.\n" +
|
|
727
734
|
"- memory_store: Save important new information (preferences, decisions, facts about people).\n" +
|
|
735
|
+
"- memory_share: Share a specific memory with other people/agents by ID.\n" +
|
|
736
|
+
"- memory_unshare: Revoke view access to a memory from people/agents.\n" +
|
|
728
737
|
"</memory-tools>";
|
|
729
738
|
if (totalCount === 0)
|
|
730
739
|
return { prependContext: toolHint };
|
|
@@ -794,10 +803,10 @@ const rebacMemoryPlugin = {
|
|
|
794
803
|
if (isHybrid) {
|
|
795
804
|
// Hybrid mode: store to liminal backend only (fire-and-forget, no SpiceDB).
|
|
796
805
|
// Primary backend (Graphiti) gets data only via explicit memory_store or memory_promote.
|
|
797
|
-
const
|
|
806
|
+
const agentLiminalGroup = liminalGroupId(ctx?.agentId);
|
|
798
807
|
await liminal.store({
|
|
799
808
|
content: episodeBody,
|
|
800
|
-
groupId:
|
|
809
|
+
groupId: agentLiminalGroup,
|
|
801
810
|
sourceDescription: "auto-captured conversation",
|
|
802
811
|
});
|
|
803
812
|
// Liminal session enrichment
|
|
@@ -828,7 +837,7 @@ const rebacMemoryPlugin = {
|
|
|
828
837
|
if (userMsg && assistantMsg) {
|
|
829
838
|
liminal.enrichSession({
|
|
830
839
|
sessionId: state.sessionId,
|
|
831
|
-
groupId:
|
|
840
|
+
groupId: agentLiminalGroup,
|
|
832
841
|
userMsg,
|
|
833
842
|
assistantMsg,
|
|
834
843
|
}).catch(() => { });
|
|
@@ -947,19 +956,27 @@ const rebacMemoryPlugin = {
|
|
|
947
956
|
const defaultState = getDefaultState();
|
|
948
957
|
const backendStatus = await backend.getStatus();
|
|
949
958
|
let spicedbOk = false;
|
|
959
|
+
const schemaPath = join(dirname(fileURLToPath(import.meta.url)), "schema.zed");
|
|
960
|
+
const schema = readFileSync(schemaPath, "utf-8");
|
|
950
961
|
try {
|
|
951
|
-
|
|
962
|
+
// Always write — SpiceDB normalizes formatting so text comparison is unreliable
|
|
963
|
+
api.logger.info("openclaw-memory-rebac: writing SpiceDB schema");
|
|
964
|
+
await spicedb.writeSchema(schema);
|
|
952
965
|
spicedbOk = true;
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
966
|
+
api.logger.info("openclaw-memory-rebac: SpiceDB schema written successfully");
|
|
967
|
+
}
|
|
968
|
+
catch (err) {
|
|
969
|
+
// Retry once after a short delay (SpiceDB may still be starting)
|
|
970
|
+
api.logger.warn(`openclaw-memory-rebac: SpiceDB schema write failed, retrying in 2s: ${err instanceof Error ? err.message : String(err)}`);
|
|
971
|
+
try {
|
|
972
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
957
973
|
await spicedb.writeSchema(schema);
|
|
958
|
-
|
|
974
|
+
spicedbOk = true;
|
|
975
|
+
api.logger.info("openclaw-memory-rebac: SpiceDB schema written successfully (retry)");
|
|
976
|
+
}
|
|
977
|
+
catch (retryErr) {
|
|
978
|
+
api.logger.error(`openclaw-memory-rebac: SpiceDB schema write failed after retry: ${retryErr instanceof Error ? retryErr.message : String(retryErr)}`);
|
|
959
979
|
}
|
|
960
|
-
}
|
|
961
|
-
catch {
|
|
962
|
-
// Will be retried on first use
|
|
963
980
|
}
|
|
964
981
|
if (spicedbOk) {
|
|
965
982
|
// Ensure the config-level subject is a member of the default group
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contextableai/openclaw-memory-rebac",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "OpenClaw composite memory plugin: SpiceDB ReBAC authorization with Graphiti knowledge graph (primary) and optional EverMemOS liminal memory",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|