@contextableai/openclaw-memory-rebac 0.3.7 → 0.4.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/README.md +81 -15
- package/dist/authorization.d.ts +20 -0
- package/dist/authorization.js +60 -0
- package/dist/backend.d.ts +18 -0
- package/dist/backends/evermemos.d.ts +84 -0
- package/dist/backends/evermemos.defaults.json +10 -0
- package/dist/backends/evermemos.js +404 -0
- package/dist/backends/registry.js +2 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +15 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +169 -5
- package/docker/docker-compose.evermemos.yml +21 -0
- package/docker/{docker-compose.yml → docker-compose.graphiti.yml} +1 -1
- package/docker/evermemos/.env.example +85 -0
- package/docker/evermemos/Dockerfile +133 -0
- package/docker/evermemos/docker-compose.yml +52 -0
- package/docker/evermemos/trace_overlay.py +128 -0
- package/docker/graphiti/Dockerfile +4 -2
- package/docker/graphiti/startup.py +25 -0
- package/docker/spicedb/docker-compose.yml +4 -4
- package/package.json +6 -4
- package/schema.zed +6 -2
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
# 1. Install sentence-transformers for BGE reranker
|
|
7
7
|
# 2. Overlay per-component config + startup to wire separate clients
|
|
8
8
|
#
|
|
9
|
-
# UPGRADE AUDIT (vs upstream getzep/graphiti v0.28.2, audited 2026-03-
|
|
10
|
-
# Overlay patches in startup.py —
|
|
9
|
+
# UPGRADE AUDIT (vs upstream getzep/graphiti v0.28.2, audited 2026-03-24):
|
|
10
|
+
# Overlay patches in startup.py — 6 of 7 still needed:
|
|
11
11
|
# [NEEDED] AsyncWorker crash-on-error recovery (startup.py:109-126)
|
|
12
12
|
# [NEEDED] Neo4j nested attribute sanitization (startup.py:128-250)
|
|
13
13
|
# [SAFE] None-index extract_edges fix (startup.py:252-298)
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
# [NEEDED] IS_DUPLICATE_OF edge filtering (startup.py:152-169,216-227,310-318)
|
|
16
16
|
# [NEEDED] Self-referential edge filtering (startup.py:228-239)
|
|
17
17
|
# [NEEDED] Singleton client / per-request fix (startup.py:38-87)
|
|
18
|
+
# [NEEDED] resolve_extracted_edge IndexError guard (startup.py:325-349)
|
|
19
|
+
# — fixed upstream v0.28.2+; no Docker image published beyond 0.22.0
|
|
18
20
|
###############################################################################
|
|
19
21
|
|
|
20
22
|
FROM zepai/graphiti:0.22.0
|
|
@@ -322,6 +322,31 @@ def patch():
|
|
|
322
322
|
# Patch the local binding in graphiti.py
|
|
323
323
|
graphiti_mod.extract_edges = safe_extract_edges
|
|
324
324
|
|
|
325
|
+
# -- Guard resolve_extracted_edge against IndexError from out-of-bounds
|
|
326
|
+
# contradicted_facts indices (issue #22) --
|
|
327
|
+
# The LLM sometimes returns fact indices that exceed the existing_edges list
|
|
328
|
+
# length, crashing the list comprehension. Upstream v0.28.2+ adds bounds
|
|
329
|
+
# checking; this patch provides equivalent safety for pinned v0.22.0.
|
|
330
|
+
original_resolve_extracted_edge = edge_ops_mod.resolve_extracted_edge
|
|
331
|
+
|
|
332
|
+
async def safe_resolve_extracted_edge(*args, **kwargs):
|
|
333
|
+
try:
|
|
334
|
+
return await original_resolve_extracted_edge(*args, **kwargs)
|
|
335
|
+
except IndexError as e:
|
|
336
|
+
logger.warning(
|
|
337
|
+
"resolve_extracted_edge: IndexError caught (out-of-bounds "
|
|
338
|
+
"contradicted_facts index): %s — returning edge as-is with "
|
|
339
|
+
"no invalidations",
|
|
340
|
+
e,
|
|
341
|
+
)
|
|
342
|
+
# args[1] is extracted_edge per the function signature
|
|
343
|
+
extracted_edge = args[1] if len(args) > 1 else kwargs.get("extracted_edge")
|
|
344
|
+
if extracted_edge is None:
|
|
345
|
+
raise
|
|
346
|
+
return (extracted_edge, [], [])
|
|
347
|
+
|
|
348
|
+
edge_ops_mod.resolve_extracted_edge = safe_resolve_extracted_edge
|
|
349
|
+
|
|
325
350
|
return app
|
|
326
351
|
|
|
327
352
|
|
|
@@ -28,7 +28,7 @@ services:
|
|
|
28
28
|
POSTGRES_PASSWORD: ${SPICEDB_POSTGRES_PASSWORD:-spicedb}
|
|
29
29
|
POSTGRES_DB: spicedb
|
|
30
30
|
volumes:
|
|
31
|
-
-
|
|
31
|
+
- spicedb_postgres_data:/var/lib/postgresql/data
|
|
32
32
|
healthcheck:
|
|
33
33
|
test: ["CMD-SHELL", "pg_isready -U spicedb"]
|
|
34
34
|
interval: 5s
|
|
@@ -56,8 +56,8 @@ services:
|
|
|
56
56
|
command: serve
|
|
57
57
|
restart: unless-stopped
|
|
58
58
|
ports:
|
|
59
|
-
- "
|
|
60
|
-
- "
|
|
59
|
+
- "${SPICEDB_GRPC_PORT:-50051}:50051" # gRPC
|
|
60
|
+
- "${SPICEDB_HTTP_PORT:-8180}:8080" # HTTP metrics / healthz
|
|
61
61
|
environment:
|
|
62
62
|
SPICEDB_GRPC_PRESHARED_KEY: ${SPICEDB_PRESHARED_KEY:-dev_token}
|
|
63
63
|
SPICEDB_DATASTORE_ENGINE: postgres
|
|
@@ -76,4 +76,4 @@ services:
|
|
|
76
76
|
start_period: 10s
|
|
77
77
|
|
|
78
78
|
volumes:
|
|
79
|
-
|
|
79
|
+
spicedb_postgres_data:
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contextableai/openclaw-memory-rebac",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "OpenClaw two-layer memory plugin: SpiceDB ReBAC authorization + Graphiti
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "OpenClaw two-layer memory plugin: SpiceDB ReBAC authorization + pluggable storage (Graphiti, EverMemOS)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -34,13 +34,15 @@
|
|
|
34
34
|
"openclaw": "*"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
|
-
"build": "rm -rf dist && tsc -p tsconfig.build.json && cp plugin.defaults.json dist/ && mkdir -p dist/backends && cp backends/graphiti.defaults.json dist/backends/",
|
|
37
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && cp plugin.defaults.json dist/ && mkdir -p dist/backends && cp backends/graphiti.defaults.json backends/evermemos.defaults.json dist/backends/",
|
|
38
38
|
"prepublishOnly": "npm run build",
|
|
39
39
|
"cli": "tsx bin/rebac-mem.ts",
|
|
40
40
|
"typecheck": "tsc 2>&1 | grep -v '../openclaw/' | grep -c 'error TS' | xargs -I{} test {} -eq 0",
|
|
41
41
|
"test": "vitest run",
|
|
42
42
|
"test:watch": "vitest",
|
|
43
|
-
"test:e2e": "OPENCLAW_LIVE_TEST=1 vitest run --config vitest.e2e.config.ts"
|
|
43
|
+
"test:e2e": "OPENCLAW_LIVE_TEST=1 vitest run --config vitest.e2e.config.ts",
|
|
44
|
+
"test:e2e:backend": "OPENCLAW_LIVE_TEST=1 vitest run --config vitest.e2e.config.ts e2e-backend.test.ts",
|
|
45
|
+
"test:e2e:evermemos": "OPENCLAW_LIVE_TEST=1 E2E_BACKEND=evermemos vitest run --config vitest.e2e.config.ts e2e-evermemos.test.ts"
|
|
44
46
|
},
|
|
45
47
|
"dependencies": {
|
|
46
48
|
"@authzed/authzed-node": "1.6.1",
|
package/schema.zed
CHANGED
|
@@ -10,8 +10,10 @@ definition agent {
|
|
|
10
10
|
|
|
11
11
|
definition group {
|
|
12
12
|
relation member: person | agent
|
|
13
|
-
|
|
14
|
-
permission
|
|
13
|
+
relation owner: person | agent
|
|
14
|
+
permission access = member + owner
|
|
15
|
+
permission contribute = member + owner
|
|
16
|
+
permission admin = owner
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
definition memory_fragment {
|
|
@@ -24,4 +26,6 @@ definition memory_fragment {
|
|
|
24
26
|
permission view = involves + shared_by + source_group->access + involves->represents
|
|
25
27
|
// Can delete if: you shared it (owner-level control)
|
|
26
28
|
permission delete = shared_by
|
|
29
|
+
// Can share if: you shared it, or you are an admin of the source group
|
|
30
|
+
permission share = shared_by + source_group->admin
|
|
27
31
|
}
|