@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
package/README.md
CHANGED
|
@@ -49,6 +49,26 @@ This means you can change your storage engine without touching authorization, an
|
|
|
49
49
|
- **Docker image**: Custom image (`docker/graphiti/`) with per-component LLM/embedder/reranker configuration, BGE reranker support, and runtime patches for local-model compatibility
|
|
50
50
|
- **Best for**: Rich entity-relationship extraction, structured knowledge
|
|
51
51
|
|
|
52
|
+
### EverMemOS
|
|
53
|
+
|
|
54
|
+
[EverMemOS](https://github.com/EverMind-AI/EverMemOS) is a memory system with MemCell boundary detection and parallel LLM extraction. It produces richer memory types — episodic memories, user profiles, foresight (predictions), and event logs.
|
|
55
|
+
|
|
56
|
+
- **Storage**: MongoDB + Milvus (vector) + Elasticsearch (keyword)
|
|
57
|
+
- **Transport**: REST API to EverMemOS FastAPI server (port 1995)
|
|
58
|
+
- **Extraction**: MemCell pipeline — automatic boundary detection, then parallel LLM extraction of multiple memory types
|
|
59
|
+
- **Search**: Hybrid (vector + keyword + reranking), configurable via `retrieveMethod`
|
|
60
|
+
- **Docker image**: Built from source (`docker/evermemos/Dockerfile`), pinned to upstream release tag (v1.1.0)
|
|
61
|
+
- **Best for**: Rich memory type diversity, foresight extraction, hybrid search
|
|
62
|
+
- **Limitation**: No `involves` at ingestion — use `memory_share` for post-hoc cross-group sharing
|
|
63
|
+
|
|
64
|
+
#### EverMemOS-specific config
|
|
65
|
+
|
|
66
|
+
| Key | Default | Description |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `retrieveMethod` | `"hybrid"` | Search method: `"hybrid"`, `"vector"`, `"keyword"` |
|
|
69
|
+
| `memoryTypes` | `["episodic_memory", "profile", "foresight", "event_log"]` | Which memory types to search |
|
|
70
|
+
| `defaultSenderId` | `"system"` | Sender ID for stored messages |
|
|
71
|
+
|
|
52
72
|
## Installation
|
|
53
73
|
|
|
54
74
|
```bash
|
|
@@ -68,22 +88,35 @@ Then restart the gateway. On first start, the plugin automatically:
|
|
|
68
88
|
### Prerequisites
|
|
69
89
|
|
|
70
90
|
- [Docker](https://docs.docker.com/get-docker/) and Docker Compose
|
|
71
|
-
- A running LLM endpoint (
|
|
91
|
+
- A running LLM endpoint (both backends use LLMs for memory extraction)
|
|
72
92
|
|
|
73
93
|
### 1. Start Infrastructure
|
|
74
94
|
|
|
95
|
+
**Option A: Graphiti backend (default)**
|
|
96
|
+
|
|
75
97
|
```bash
|
|
76
98
|
cd docker
|
|
77
99
|
cp graphiti/.env.example graphiti/.env
|
|
78
100
|
# Edit graphiti/.env — set your LLM endpoint and API key
|
|
79
|
-
docker compose up -d
|
|
101
|
+
docker compose -f docker-compose.graphiti.yml up -d
|
|
80
102
|
```
|
|
81
103
|
|
|
82
|
-
This starts
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
104
|
+
This starts: Neo4j (7687), Graphiti (8000), PostgreSQL (5432), SpiceDB (50051).
|
|
105
|
+
|
|
106
|
+
**Option B: EverMemOS backend**
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
cd docker/evermemos
|
|
110
|
+
cp .env.example .env
|
|
111
|
+
# Edit .env — set LLM_API_KEY, VECTORIZE_API_KEY, RERANK_API_KEY
|
|
112
|
+
|
|
113
|
+
cd docker
|
|
114
|
+
docker compose -f docker-compose.evermemos.yml up -d
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This starts: EverMemOS all-in-one container (1995), PostgreSQL (5432), SpiceDB (50051). First run builds the image from source (~5 min).
|
|
118
|
+
|
|
119
|
+
Both options share the same SpiceDB instance with the same authorization schema.
|
|
87
120
|
|
|
88
121
|
### 2. Restart the Gateway
|
|
89
122
|
|
|
@@ -446,14 +479,18 @@ rebac-mem import --include-sessions
|
|
|
446
479
|
|
|
447
480
|
## Docker Compose
|
|
448
481
|
|
|
449
|
-
The `docker/` directory contains
|
|
482
|
+
The `docker/` directory contains modular Docker Compose stacks. Two top-level compose files select which memory backend to pair with SpiceDB:
|
|
450
483
|
|
|
451
484
|
```bash
|
|
452
|
-
#
|
|
453
|
-
cd docker
|
|
454
|
-
|
|
485
|
+
# Graphiti + SpiceDB
|
|
486
|
+
cd docker && docker compose -f docker-compose.graphiti.yml up -d
|
|
487
|
+
|
|
488
|
+
# EverMemOS + SpiceDB
|
|
489
|
+
cd docker && docker compose -f docker-compose.evermemos.yml up -d
|
|
455
490
|
```
|
|
456
491
|
|
|
492
|
+
Both share the same SpiceDB sub-stack — same authorization schema, same permissions model.
|
|
493
|
+
|
|
457
494
|
### Graphiti Stack (`docker/graphiti/`)
|
|
458
495
|
|
|
459
496
|
| Service | Port | Description |
|
|
@@ -475,12 +512,31 @@ The custom Docker image extends `zepai/graphiti:latest` with:
|
|
|
475
512
|
| `spicedb-migrate` | — | One-shot: runs SpiceDB DB migrations |
|
|
476
513
|
| `spicedb` | 50051, 8080 | Authorization engine (gRPC, HTTP health) |
|
|
477
514
|
|
|
515
|
+
### EverMemOS Stack (`docker/evermemos/`)
|
|
516
|
+
|
|
517
|
+
Single all-in-one container bundling all required services via supervisord:
|
|
518
|
+
|
|
519
|
+
| Component | Internal Port | Description |
|
|
520
|
+
|-----------|---------------|-------------|
|
|
521
|
+
| MongoDB 7.0 | 27017 | Document store |
|
|
522
|
+
| Elasticsearch 8 | 9200 | Keyword search |
|
|
523
|
+
| Milvus v2.5.2 | 19530 | Vector database (standalone with embedded etcd) |
|
|
524
|
+
| Redis 7 | 6379 | Cache |
|
|
525
|
+
| EverMemOS API | **1995 (exposed)** | FastAPI server (built from source) |
|
|
526
|
+
|
|
527
|
+
The image is built from the [EverMemOS](https://github.com/EverMind-AI/EverMemOS) repository, pinned to release tag `v1.1.0`. Update `EVERMEMOS_VERSION` in `docker/evermemos/docker-compose.yml` to upgrade. Requires ~4 GB RAM.
|
|
528
|
+
|
|
529
|
+
Requires API keys in `docker/evermemos/.env` for LLM, embedding (vectorize), and reranking services. See `.env.example` for all options.
|
|
530
|
+
|
|
478
531
|
### Running Stacks Independently
|
|
479
532
|
|
|
480
533
|
```bash
|
|
481
534
|
# Graphiti only
|
|
482
535
|
cd docker/graphiti && docker compose up -d
|
|
483
536
|
|
|
537
|
+
# EverMemOS only (without SpiceDB)
|
|
538
|
+
cd docker/evermemos && docker compose up -d
|
|
539
|
+
|
|
484
540
|
# SpiceDB only
|
|
485
541
|
cd docker/spicedb && docker compose up -d
|
|
486
542
|
```
|
|
@@ -511,11 +567,14 @@ OPENCLAW_LIVE_TEST=1 npm run test:e2e
|
|
|
511
567
|
├── openclaw.plugin.json # Plugin manifest
|
|
512
568
|
├── package.json
|
|
513
569
|
├── backends/
|
|
514
|
-
│
|
|
570
|
+
│ ├── graphiti.ts # Graphiti REST backend implementation
|
|
571
|
+
│ ├── evermemos.ts # EverMemOS REST backend implementation
|
|
572
|
+
│ └── registry.ts # Static backend registry
|
|
515
573
|
├── bin/
|
|
516
574
|
│ └── rebac-mem.ts # Standalone CLI entry point
|
|
517
575
|
├── docker/
|
|
518
|
-
│ ├── docker-compose.yml
|
|
576
|
+
│ ├── docker-compose.graphiti.yml # Graphiti + SpiceDB
|
|
577
|
+
│ ├── docker-compose.evermemos.yml # EverMemOS + SpiceDB
|
|
519
578
|
│ ├── graphiti/
|
|
520
579
|
│ │ ├── docker-compose.yml
|
|
521
580
|
│ │ ├── Dockerfile # Custom Graphiti image with patches
|
|
@@ -523,10 +582,17 @@ OPENCLAW_LIVE_TEST=1 npm run test:e2e
|
|
|
523
582
|
│ │ ├── graphiti_overlay.py # OpenClawGraphiti class
|
|
524
583
|
│ │ ├── startup.py # Runtime patches and uvicorn launch
|
|
525
584
|
│ │ └── .env.example
|
|
585
|
+
│ ├── evermemos/
|
|
586
|
+
│ │ ├── docker-compose.yml # EverMemOS all-in-one container
|
|
587
|
+
│ │ ├── Dockerfile # All-in-one: MongoDB+ES+Milvus+Redis+EverMemOS
|
|
588
|
+
│ │ ├── supervisord.conf # Process manager config
|
|
589
|
+
│ │ └── .env.example # LLM, vectorize, rerank API keys
|
|
526
590
|
│ └── spicedb/
|
|
527
591
|
│ └── docker-compose.yml
|
|
528
|
-
├── *.test.ts # Unit tests (
|
|
529
|
-
├── e2e.test.ts #
|
|
592
|
+
├── *.test.ts # Unit tests (178)
|
|
593
|
+
├── e2e.test.ts # Graphiti E2E tests (14, live services)
|
|
594
|
+
├── e2e-backend.test.ts # Backend-agnostic E2E contract (13)
|
|
595
|
+
├── e2e-evermemos.test.ts # EverMemOS-specific E2E (7)
|
|
530
596
|
├── vitest.config.ts # Unit test config
|
|
531
597
|
└── vitest.e2e.config.ts # E2E test config
|
|
532
598
|
```
|
package/dist/authorization.d.ts
CHANGED
|
@@ -66,3 +66,23 @@ export declare function lookupFragmentSourceGroups(spicedb: SpiceDbClient, fragm
|
|
|
66
66
|
* Idempotent (uses TOUCH operation).
|
|
67
67
|
*/
|
|
68
68
|
export declare function ensureGroupMembership(spicedb: SpiceDbClient, groupId: string, member: Subject): Promise<string | undefined>;
|
|
69
|
+
/**
|
|
70
|
+
* Ensure a subject is registered as an owner of a group.
|
|
71
|
+
* Owners have admin permission (can share memories from their groups).
|
|
72
|
+
* Idempotent (uses TOUCH operation).
|
|
73
|
+
*/
|
|
74
|
+
export declare function ensureGroupOwnership(spicedb: SpiceDbClient, groupId: string, owner: Subject): Promise<string | undefined>;
|
|
75
|
+
/**
|
|
76
|
+
* Check if a subject has share permission on a memory fragment.
|
|
77
|
+
* Share is granted to: shared_by (storer) + source_group->admin (group owners).
|
|
78
|
+
*/
|
|
79
|
+
export declare function canShareFragment(spicedb: SpiceDbClient, subject: Subject, fragmentId: string, zedToken?: string): Promise<boolean>;
|
|
80
|
+
/**
|
|
81
|
+
* Share a memory fragment with one or more subjects by writing `involves` relationships.
|
|
82
|
+
* This grants view permission to the targets (and their agents via involves->represents).
|
|
83
|
+
*/
|
|
84
|
+
export declare function shareFragment(spicedb: SpiceDbClient, fragmentId: string, targets: Subject[]): Promise<string | undefined>;
|
|
85
|
+
/**
|
|
86
|
+
* Unshare a memory fragment by removing `involves` relationships for the given targets.
|
|
87
|
+
*/
|
|
88
|
+
export declare function unshareFragment(spicedb: SpiceDbClient, fragmentId: string, targets: Subject[]): Promise<void>;
|
package/dist/authorization.js
CHANGED
|
@@ -166,3 +166,63 @@ export async function ensureGroupMembership(spicedb, groupId, member) {
|
|
|
166
166
|
},
|
|
167
167
|
]);
|
|
168
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Ensure a subject is registered as an owner of a group.
|
|
171
|
+
* Owners have admin permission (can share memories from their groups).
|
|
172
|
+
* Idempotent (uses TOUCH operation).
|
|
173
|
+
*/
|
|
174
|
+
export async function ensureGroupOwnership(spicedb, groupId, owner) {
|
|
175
|
+
return spicedb.writeRelationships([
|
|
176
|
+
{
|
|
177
|
+
resourceType: "group",
|
|
178
|
+
resourceId: groupId,
|
|
179
|
+
relation: "owner",
|
|
180
|
+
subjectType: owner.type,
|
|
181
|
+
subjectId: owner.id,
|
|
182
|
+
},
|
|
183
|
+
]);
|
|
184
|
+
}
|
|
185
|
+
// ============================================================================
|
|
186
|
+
// Share / Unshare
|
|
187
|
+
// ============================================================================
|
|
188
|
+
/**
|
|
189
|
+
* Check if a subject has share permission on a memory fragment.
|
|
190
|
+
* Share is granted to: shared_by (storer) + source_group->admin (group owners).
|
|
191
|
+
*/
|
|
192
|
+
export async function canShareFragment(spicedb, subject, fragmentId, zedToken) {
|
|
193
|
+
return spicedb.checkPermission({
|
|
194
|
+
resourceType: "memory_fragment",
|
|
195
|
+
resourceId: fragmentId,
|
|
196
|
+
permission: "share",
|
|
197
|
+
subjectType: subject.type,
|
|
198
|
+
subjectId: subject.id,
|
|
199
|
+
consistency: tokenConsistency(zedToken),
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Share a memory fragment with one or more subjects by writing `involves` relationships.
|
|
204
|
+
* This grants view permission to the targets (and their agents via involves->represents).
|
|
205
|
+
*/
|
|
206
|
+
export async function shareFragment(spicedb, fragmentId, targets) {
|
|
207
|
+
const tuples = targets.map((target) => ({
|
|
208
|
+
resourceType: "memory_fragment",
|
|
209
|
+
resourceId: fragmentId,
|
|
210
|
+
relation: "involves",
|
|
211
|
+
subjectType: target.type,
|
|
212
|
+
subjectId: target.id,
|
|
213
|
+
}));
|
|
214
|
+
return spicedb.writeRelationships(tuples);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Unshare a memory fragment by removing `involves` relationships for the given targets.
|
|
218
|
+
*/
|
|
219
|
+
export async function unshareFragment(spicedb, fragmentId, targets) {
|
|
220
|
+
const tuples = targets.map((target) => ({
|
|
221
|
+
resourceType: "memory_fragment",
|
|
222
|
+
resourceId: fragmentId,
|
|
223
|
+
relation: "involves",
|
|
224
|
+
subjectType: target.type,
|
|
225
|
+
subjectId: target.id,
|
|
226
|
+
}));
|
|
227
|
+
await spicedb.deleteRelationships(tuples);
|
|
228
|
+
}
|
package/dist/backend.d.ts
CHANGED
|
@@ -31,6 +31,10 @@ export type SearchResult = {
|
|
|
31
31
|
* registered in SpiceDB.
|
|
32
32
|
*
|
|
33
33
|
* - Graphiti: Resolves once the server has processed the episode (polled in the background).
|
|
34
|
+
* - EverMemOS: Resolves immediately to our generated message_id UUID. This anchor is used
|
|
35
|
+
* for share/involves SpiceDB relationships. Note: search result IDs (MongoDB ObjectIds)
|
|
36
|
+
* differ from this anchor, so involves-based cross-group recall post-filtering won't
|
|
37
|
+
* match — group-level access handles the common path.
|
|
34
38
|
*
|
|
35
39
|
* index.ts chains SpiceDB writeFragmentRelationships() to this Promise,
|
|
36
40
|
* so it always fires at the right time.
|
|
@@ -138,6 +142,20 @@ export interface MemoryBackend {
|
|
|
138
142
|
* Optional: not all backends separate episodes from fragments.
|
|
139
143
|
*/
|
|
140
144
|
discoverFragmentIds?(episodeId: string): Promise<string[]>;
|
|
145
|
+
/**
|
|
146
|
+
* Resolve anchor IDs (e.g. message UUIDs written to SpiceDB during store)
|
|
147
|
+
* to actual searchable fragment IDs (e.g. MongoDB ObjectIds).
|
|
148
|
+
*
|
|
149
|
+
* Called during recall when viewable fragment IDs from SpiceDB don't match
|
|
150
|
+
* any search results — indicates the anchors were written before extraction
|
|
151
|
+
* completed (discoverFragmentIds timed out).
|
|
152
|
+
*
|
|
153
|
+
* Returns a Map of anchor → resolved fragment IDs. Only anchors that
|
|
154
|
+
* successfully resolved are included; unresolvable anchors are omitted.
|
|
155
|
+
*
|
|
156
|
+
* Optional: backends where store IDs match search IDs don't need this.
|
|
157
|
+
*/
|
|
158
|
+
resolveAnchors?(anchorIds: string[]): Promise<Map<string, string[]>>;
|
|
141
159
|
/**
|
|
142
160
|
* Register backend-specific CLI subcommands onto the shared `rebac-mem` command.
|
|
143
161
|
* Called once during CLI setup. Backend may register any commands it needs.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EverMemOSBackend — MemoryBackend implementation backed by the EverMemOS FastAPI REST server.
|
|
3
|
+
*
|
|
4
|
+
* EverMemOS communicates via standard HTTP REST endpoints on port 1995.
|
|
5
|
+
* Messages are processed through the MemCell pipeline: boundary detection →
|
|
6
|
+
* parallel LLM extraction of episodic memories, foresight, event logs, and profiles.
|
|
7
|
+
*
|
|
8
|
+
* store() returns immediately with a generated message_id as the fragment anchor.
|
|
9
|
+
* With @timeout_to_background(), store may return 202 Accepted for background processing.
|
|
10
|
+
*
|
|
11
|
+
* discoverFragmentIds() polls a custom trace overlay endpoint to resolve the message_id
|
|
12
|
+
* to actual MongoDB ObjectIds of derived memories. These ObjectIds are what search
|
|
13
|
+
* results return, enabling fragment-level SpiceDB authorization (involves, share).
|
|
14
|
+
*
|
|
15
|
+
* resolveAnchors() provides lazy resolution at recall time: if discoverFragmentIds()
|
|
16
|
+
* timed out during store, unresolved anchors can be resolved later when someone
|
|
17
|
+
* actually tries to recall the involved fragments.
|
|
18
|
+
*/
|
|
19
|
+
import type { Command } from "commander";
|
|
20
|
+
import type { MemoryBackend, SearchResult, StoreResult, ConversationTurn, BackendDataset } from "../backend.js";
|
|
21
|
+
export type EverMemOSConfig = {
|
|
22
|
+
endpoint: string;
|
|
23
|
+
defaultGroupId: string;
|
|
24
|
+
requestTimeoutMs: number;
|
|
25
|
+
retrieveMethod: string;
|
|
26
|
+
memoryTypes: string[];
|
|
27
|
+
defaultSenderId: string;
|
|
28
|
+
discoveryPollIntervalMs: number;
|
|
29
|
+
discoveryTimeoutMs: number;
|
|
30
|
+
};
|
|
31
|
+
export declare class EverMemOSBackend implements MemoryBackend {
|
|
32
|
+
private readonly config;
|
|
33
|
+
readonly name = "evermemos";
|
|
34
|
+
private readonly requestTimeoutMs;
|
|
35
|
+
/**
|
|
36
|
+
* Tracks pending stores: messageId → groupId.
|
|
37
|
+
* Populated by store(), consumed by discoverFragmentIds().
|
|
38
|
+
*/
|
|
39
|
+
private readonly pendingStores;
|
|
40
|
+
constructor(config: EverMemOSConfig);
|
|
41
|
+
private restCall;
|
|
42
|
+
store(params: {
|
|
43
|
+
content: string;
|
|
44
|
+
groupId: string;
|
|
45
|
+
sourceDescription?: string;
|
|
46
|
+
customPrompt?: string;
|
|
47
|
+
}): Promise<StoreResult>;
|
|
48
|
+
searchGroup(params: {
|
|
49
|
+
query: string;
|
|
50
|
+
groupId: string;
|
|
51
|
+
limit: number;
|
|
52
|
+
sessionId?: string;
|
|
53
|
+
}): Promise<SearchResult[]>;
|
|
54
|
+
enrichSession(params: {
|
|
55
|
+
sessionId: string;
|
|
56
|
+
groupId: string;
|
|
57
|
+
userMsg: string;
|
|
58
|
+
assistantMsg: string;
|
|
59
|
+
}): Promise<void>;
|
|
60
|
+
getConversationHistory(sessionId: string, lastN?: number): Promise<ConversationTurn[]>;
|
|
61
|
+
healthCheck(): Promise<boolean>;
|
|
62
|
+
getStatus(): Promise<Record<string, unknown>>;
|
|
63
|
+
deleteGroup(groupId: string): Promise<void>;
|
|
64
|
+
listGroups(): Promise<BackendDataset[]>;
|
|
65
|
+
deleteFragment(uuid: string, _type?: string): Promise<boolean>;
|
|
66
|
+
/**
|
|
67
|
+
* Poll the trace overlay endpoint to discover MongoDB ObjectIds of derived
|
|
68
|
+
* memories (episodic, foresight, event_log) produced from a stored message.
|
|
69
|
+
*
|
|
70
|
+
* Called by index.ts after store() resolves the fragmentId Promise.
|
|
71
|
+
* Returns ObjectIds that match what search results return, enabling
|
|
72
|
+
* fragment-level SpiceDB authorization (involves, share/unshare).
|
|
73
|
+
*/
|
|
74
|
+
discoverFragmentIds(messageId: string): Promise<string[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Lazy resolution: resolve unmatched SpiceDB anchor UUIDs to actual
|
|
77
|
+
* searchable fragment IDs. Called during recall when viewable fragment IDs
|
|
78
|
+
* from SpiceDB don't match any search results.
|
|
79
|
+
*/
|
|
80
|
+
resolveAnchors(anchorIds: string[]): Promise<Map<string, string[]>>;
|
|
81
|
+
registerCliCommands(cmd: Command): void;
|
|
82
|
+
}
|
|
83
|
+
export declare const defaults: Record<string, unknown>;
|
|
84
|
+
export declare function create(config: Record<string, unknown>): MemoryBackend;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"endpoint": "http://localhost:1995",
|
|
3
|
+
"defaultGroupId": "main",
|
|
4
|
+
"requestTimeoutMs": 30000,
|
|
5
|
+
"retrieveMethod": "hybrid",
|
|
6
|
+
"memoryTypes": ["episodic_memory", "profile", "foresight", "event_log"],
|
|
7
|
+
"defaultSenderId": "system",
|
|
8
|
+
"discoveryPollIntervalMs": 3000,
|
|
9
|
+
"discoveryTimeoutMs": 120000
|
|
10
|
+
}
|