@ztorchan/openclaw-mem0 0.3.3
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 +195 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.js +1058 -0
- package/dist/index.js.map +1 -0
- package/openclaw.plugin.json +168 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# @mem0/openclaw-mem0
|
|
2
|
+
|
|
3
|
+
Long-term memory for [OpenClaw](https://github.com/openclaw/openclaw) agents, powered by [Mem0](https://mem0.ai).
|
|
4
|
+
|
|
5
|
+
Your agent forgets everything between sessions. This plugin fixes that. It watches conversations, extracts what matters, and brings it back when relevant — automatically.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<img src="https://raw.githubusercontent.com/mem0ai/mem0/main/docs/images/openclaw-architecture.png" alt="Architecture" width="800" />
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
**Auto-Recall** — Before the agent responds, the plugin searches Mem0 for memories that match the current message and injects them into context.
|
|
14
|
+
|
|
15
|
+
**Auto-Capture** — After the agent responds, the plugin sends the exchange to Mem0. Mem0 decides what's worth keeping — new facts get stored, stale ones updated, duplicates merged.
|
|
16
|
+
|
|
17
|
+
Both run silently. No prompting, no configuration, no manual calls.
|
|
18
|
+
|
|
19
|
+
### Short-term vs long-term memory
|
|
20
|
+
|
|
21
|
+
Memories are organized into two scopes:
|
|
22
|
+
|
|
23
|
+
- **Session (short-term)** — Auto-capture stores memories scoped to the current session via Mem0's `run_id` / `runId` parameter. These are contextual to the ongoing conversation and automatically recalled alongside long-term memories.
|
|
24
|
+
|
|
25
|
+
- **User (long-term)** — The agent can explicitly store long-term memories using the `memory_store` tool (with `longTerm: true`, the default). These persist across all sessions for the user.
|
|
26
|
+
|
|
27
|
+
During **auto-recall**, the plugin searches both scopes and presents them separately — long-term memories first, then session memories — so the agent has full context.
|
|
28
|
+
|
|
29
|
+
The agent tools (`memory_search`, `memory_list`) accept a `scope` parameter (`"session"`, `"long-term"`, or `"all"`) to control which memories are queried. The `memory_store` tool accepts a `longTerm` boolean (default: `true`) to choose where to store.
|
|
30
|
+
|
|
31
|
+
All new parameters are optional and backward-compatible — existing configurations work without changes.
|
|
32
|
+
|
|
33
|
+
### Per-agent memory isolation
|
|
34
|
+
|
|
35
|
+
In multi-agent setups, each agent automatically gets its own memory namespace. Session keys following the pattern `agent:<agentId>:<uuid>` are parsed to derive isolated namespaces (`${userId}:agent:${agentId}`). Single-agent deployments are unaffected — plain session keys and `agent:main:*` keys resolve to the configured `userId`.
|
|
36
|
+
|
|
37
|
+
**How it works:**
|
|
38
|
+
|
|
39
|
+
- The agent's session key is inspected on every recall/capture cycle
|
|
40
|
+
- If the key matches `agent:<name>:<uuid>`, memories are stored under `userId:agent:<name>`
|
|
41
|
+
- Different agents never see each other's memories unless explicitly queried
|
|
42
|
+
|
|
43
|
+
**Explicit cross-agent queries:**
|
|
44
|
+
|
|
45
|
+
All memory tools (`memory_search`, `memory_store`, `memory_list`, `memory_forget`) accept an optional `agentId` parameter to query another agent's namespace:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
memory_search({ query: "user's tech stack", agentId: "researcher" })
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Resolution priority: explicit `agentId` > explicit `userId` > session-derived > configured default.
|
|
52
|
+
|
|
53
|
+
## Setup
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
openclaw plugins install @mem0/openclaw-mem0
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Understanding `userId`
|
|
60
|
+
|
|
61
|
+
The `userId` field is a **string you choose** to uniquely identify the user whose memories are being stored. It is **not** something you look up in the Mem0 dashboard — you define it yourself.
|
|
62
|
+
|
|
63
|
+
Pick any stable, unique identifier for the user. Common choices:
|
|
64
|
+
|
|
65
|
+
- Your application's internal user ID (e.g. `"user_123"`, `"alice@example.com"`)
|
|
66
|
+
- A UUID (e.g. `"550e8400-e29b-41d4-a716-446655440000"`)
|
|
67
|
+
- A simple username (e.g. `"alice"`)
|
|
68
|
+
|
|
69
|
+
All memories are scoped to this `userId` — different values create separate memory namespaces. If you don't set it, it defaults to `"default"`, which means all users share the same memory space.
|
|
70
|
+
|
|
71
|
+
> **Tip:** In a multi-user application, set `userId` dynamically per user (e.g. from your auth system) rather than hardcoding a single value.
|
|
72
|
+
|
|
73
|
+
### Platform (Mem0 Cloud)
|
|
74
|
+
|
|
75
|
+
Get an API key from [app.mem0.ai](https://app.mem0.ai), then add to your `openclaw.json`:
|
|
76
|
+
|
|
77
|
+
```json5
|
|
78
|
+
// plugins.entries
|
|
79
|
+
"openclaw-mem0": {
|
|
80
|
+
"enabled": true,
|
|
81
|
+
"config": {
|
|
82
|
+
"apiKey": "${MEM0_API_KEY}",
|
|
83
|
+
"userId": "alice" // any unique identifier you choose for this user
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Open-Source (Self-hosted)
|
|
89
|
+
|
|
90
|
+
No Mem0 key needed. Requires `OPENAI_API_KEY` for default embeddings/LLM.
|
|
91
|
+
|
|
92
|
+
```json5
|
|
93
|
+
"openclaw-mem0": {
|
|
94
|
+
"enabled": true,
|
|
95
|
+
"config": {
|
|
96
|
+
"mode": "open-source",
|
|
97
|
+
"userId": "alice" // any unique identifier you choose for this user
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Sensible defaults out of the box. To customize the embedder, vector store, or LLM:
|
|
103
|
+
|
|
104
|
+
```json5
|
|
105
|
+
"config": {
|
|
106
|
+
"mode": "open-source",
|
|
107
|
+
"userId": "your-user-id",
|
|
108
|
+
"oss": {
|
|
109
|
+
"embedder": { "provider": "openai", "config": { "model": "text-embedding-3-small" } },
|
|
110
|
+
"vectorStore": { "provider": "qdrant", "config": { "host": "localhost", "port": 6333 } },
|
|
111
|
+
"llm": { "provider": "openai", "config": { "model": "gpt-4o" } }
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
All `oss` fields are optional. See [Mem0 OSS docs](https://docs.mem0.ai/open-source/node-quickstart) for providers.
|
|
117
|
+
|
|
118
|
+
## Agent tools
|
|
119
|
+
|
|
120
|
+
The agent gets five tools it can call during conversations:
|
|
121
|
+
|
|
122
|
+
| Tool | Description |
|
|
123
|
+
|------|-------------|
|
|
124
|
+
| `memory_search` | Search memories by natural language. Optional `agentId` to scope to a specific agent. |
|
|
125
|
+
| `memory_list` | List all stored memories for a user. Optional `agentId` to scope to a specific agent. |
|
|
126
|
+
| `memory_store` | Explicitly save a fact. Optional `agentId` to store under a specific agent's namespace. |
|
|
127
|
+
| `memory_get` | Retrieve a memory by ID |
|
|
128
|
+
| `memory_forget` | Delete by ID or by query. Optional `agentId` to scope deletion to a specific agent. |
|
|
129
|
+
|
|
130
|
+
## CLI
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Search all memories (long-term + session)
|
|
134
|
+
openclaw mem0 search "what languages does the user know"
|
|
135
|
+
|
|
136
|
+
# Search only long-term memories
|
|
137
|
+
openclaw mem0 search "what languages does the user know" --scope long-term
|
|
138
|
+
|
|
139
|
+
# Search only session/short-term memories
|
|
140
|
+
openclaw mem0 search "what languages does the user know" --scope session
|
|
141
|
+
|
|
142
|
+
# Stats
|
|
143
|
+
openclaw mem0 stats
|
|
144
|
+
|
|
145
|
+
# Search a specific agent's memories
|
|
146
|
+
openclaw mem0 search "user preferences" --agent researcher
|
|
147
|
+
|
|
148
|
+
# Stats for a specific agent
|
|
149
|
+
openclaw mem0 stats --agent researcher
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Options
|
|
153
|
+
|
|
154
|
+
### General
|
|
155
|
+
|
|
156
|
+
| Key | Type | Default | |
|
|
157
|
+
|-----|------|---------|---|
|
|
158
|
+
| `mode` | `"platform"` \| `"open-source"` | `"platform"` | Which backend to use |
|
|
159
|
+
| `userId` | `string` | `"default"` | Any unique identifier you choose for the user (e.g. `"alice"`, `"user_123"`). All memories are scoped to this value. Not found in any dashboard — you define it yourself. |
|
|
160
|
+
| `autoRecall` | `boolean` | `true` | Inject memories before each turn |
|
|
161
|
+
| `autoCapture` | `boolean` | `true` | Store facts after each turn |
|
|
162
|
+
| `topK` | `number` | `5` | Max memories per recall |
|
|
163
|
+
| `searchThreshold` | `number` | `0.3` | Min similarity (0–1) |
|
|
164
|
+
|
|
165
|
+
### Platform mode
|
|
166
|
+
|
|
167
|
+
| Key | Type | Default | |
|
|
168
|
+
|-----|------|---------|---|
|
|
169
|
+
| `apiKey` | `string` | — | **Required.** Mem0 API key (supports `${MEM0_API_KEY}`) |
|
|
170
|
+
| `orgId` | `string` | — | Organization ID |
|
|
171
|
+
| `projectId` | `string` | — | Project ID |
|
|
172
|
+
| `enableGraph` | `boolean` | `false` | Entity graph for relationships |
|
|
173
|
+
| `customInstructions` | `string` | *(built-in)* | Extraction rules — what to store, how to format |
|
|
174
|
+
| `customCategories` | `object` | *(12 defaults)* | Category name → description map for tagging |
|
|
175
|
+
|
|
176
|
+
### Open-source mode
|
|
177
|
+
|
|
178
|
+
Works with zero extra config. The `oss` block lets you swap out any component:
|
|
179
|
+
|
|
180
|
+
| Key | Type | Default | |
|
|
181
|
+
|-----|------|---------|---|
|
|
182
|
+
| `customPrompt` | `string` | *(built-in)* | Extraction prompt for memory processing |
|
|
183
|
+
| `oss.embedder.provider` | `string` | `"openai"` | Embedding provider (`"openai"`, `"ollama"`, etc.) |
|
|
184
|
+
| `oss.embedder.config` | `object` | — | Provider config: `apiKey`, `model`, `baseURL` |
|
|
185
|
+
| `oss.vectorStore.provider` | `string` | `"memory"` | Vector store (`"memory"`, `"qdrant"`, `"chroma"`, etc.) |
|
|
186
|
+
| `oss.vectorStore.config` | `object` | — | Provider config: `host`, `port`, `collectionName`, `dimension` |
|
|
187
|
+
| `oss.llm.provider` | `string` | `"openai"` | LLM provider (`"openai"`, `"anthropic"`, `"ollama"`, etc.) |
|
|
188
|
+
| `oss.llm.config` | `object` | — | Provider config: `apiKey`, `model`, `baseURL`, `temperature` |
|
|
189
|
+
| `oss.historyDbPath` | `string` | — | SQLite path for memory edit history |
|
|
190
|
+
|
|
191
|
+
Everything inside `oss` is optional — defaults use OpenAI embeddings (`text-embedding-3-small`), in-memory vector store, and OpenAI LLM. Override only what you need.
|
|
192
|
+
|
|
193
|
+
## License
|
|
194
|
+
|
|
195
|
+
Apache 2.0
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { OpenClawPluginApi } from 'openclaw/plugin-sdk';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OpenClaw Memory (Mem0) Plugin
|
|
5
|
+
*
|
|
6
|
+
* Long-term memory via Mem0 — supports both the Mem0 platform
|
|
7
|
+
* and the open-source self-hosted SDK. Uses the official `mem0ai` package.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - 5 tools: memory_search, memory_list, memory_store, memory_get, memory_forget
|
|
11
|
+
* (with session/long-term scope support via scope and longTerm parameters)
|
|
12
|
+
* - Short-term (session-scoped) and long-term (user-scoped) memory
|
|
13
|
+
* - Auto-recall: injects relevant memories (both scopes) before each agent turn
|
|
14
|
+
* - Auto-capture: stores key facts scoped to the current session after each agent turn
|
|
15
|
+
* - Per-agent isolation: multi-agent setups write/read from separate userId namespaces
|
|
16
|
+
* automatically via sessionKey routing (zero breaking changes for single-agent setups)
|
|
17
|
+
* - CLI: openclaw mem0 search, openclaw mem0 stats
|
|
18
|
+
* - Dual mode: platform or open-source (self-hosted)
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
type Mem0Mode = "platform" | "open-source";
|
|
22
|
+
type Mem0Config = {
|
|
23
|
+
mode: Mem0Mode;
|
|
24
|
+
apiKey?: string;
|
|
25
|
+
orgId?: string;
|
|
26
|
+
projectId?: string;
|
|
27
|
+
customInstructions: string;
|
|
28
|
+
customCategories: Record<string, string>;
|
|
29
|
+
enableGraph: boolean;
|
|
30
|
+
customPrompt?: string;
|
|
31
|
+
oss?: {
|
|
32
|
+
embedder?: {
|
|
33
|
+
provider: string;
|
|
34
|
+
config: Record<string, unknown>;
|
|
35
|
+
};
|
|
36
|
+
vectorStore?: {
|
|
37
|
+
provider: string;
|
|
38
|
+
config: Record<string, unknown>;
|
|
39
|
+
};
|
|
40
|
+
llm?: {
|
|
41
|
+
provider: string;
|
|
42
|
+
config: Record<string, unknown>;
|
|
43
|
+
};
|
|
44
|
+
historyDbPath?: string;
|
|
45
|
+
};
|
|
46
|
+
userId: string;
|
|
47
|
+
autoCapture: boolean;
|
|
48
|
+
autoRecall: boolean;
|
|
49
|
+
searchThreshold: number;
|
|
50
|
+
topK: number;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Parse an agent ID from a session key following the pattern `agent:<agentId>:<uuid>`.
|
|
54
|
+
* Returns undefined for non-agent sessions, the "main" sentinel, or malformed keys.
|
|
55
|
+
*/
|
|
56
|
+
declare function extractAgentId(sessionKey: string | undefined): string | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Derive the effective user_id from a session key, namespacing per-agent.
|
|
59
|
+
* Falls back to baseUserId when the session is not agent-scoped.
|
|
60
|
+
*/
|
|
61
|
+
declare function effectiveUserId(baseUserId: string, sessionKey?: string): string;
|
|
62
|
+
/** Build a user_id for an explicit agentId (e.g. from tool params). */
|
|
63
|
+
declare function agentUserId(baseUserId: string, agentId: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Resolve user_id with priority: explicit agentId > explicit userId > session-derived > configured.
|
|
66
|
+
*/
|
|
67
|
+
declare function resolveUserId(baseUserId: string, opts: {
|
|
68
|
+
agentId?: string;
|
|
69
|
+
userId?: string;
|
|
70
|
+
}, currentSessionId?: string): string;
|
|
71
|
+
declare const memoryPlugin: {
|
|
72
|
+
id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
description: string;
|
|
75
|
+
kind: "memory";
|
|
76
|
+
configSchema: {
|
|
77
|
+
parse(value: unknown): Mem0Config;
|
|
78
|
+
};
|
|
79
|
+
register(api: OpenClawPluginApi): void;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export { agentUserId, memoryPlugin as default, effectiveUserId, extractAgentId, resolveUserId };
|