@theokit/memory-mem0 0.1.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/CHANGELOG.md +26 -0
- package/README.md +101 -0
- package/dist/index.cjs +315 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +53 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.js +309 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @theokit/sdk@1.3.0
|
|
9
|
+
|
|
10
|
+
## 1.0.0
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
- @theokit/sdk@1.2.0
|
|
16
|
+
|
|
17
|
+
## 0.1.0
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Initial release. Implements `MemoryAdapter` (ADR D141) over `mem0ai` `MemoryClient` cloud (D148 — OSS local mode NOT supported).
|
|
22
|
+
- `mem0Memory(options)` factory.
|
|
23
|
+
- Unique `history(id)` capability — version tracking per memory.
|
|
24
|
+
- Circuit breaker (EC-K): 5 consecutive 5xx trip; 429 does NOT count.
|
|
25
|
+
- EC-B: `MemoryId` prefix validation in `delete` + `history`.
|
|
26
|
+
- CVSS 8.1 (CVE-2026-XXXX) OSS-backend security disclosure in README.
|
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# @theokit/memory-mem0
|
|
2
|
+
|
|
3
|
+
Mem0 **cloud** memory adapter for [`@theokit/sdk`](../sdk).
|
|
4
|
+
|
|
5
|
+
Wraps [`mem0ai`](https://www.npmjs.com/package/mem0ai) `MemoryClient` with the
|
|
6
|
+
`MemoryAdapter` contract from ADR D141. Cloud-only path per ADR D148 (the
|
|
7
|
+
OSS local mode duplicates work already shipped in `@theokit/sdk` Memory).
|
|
8
|
+
|
|
9
|
+
**Unique among `@theokit/memory-*` adapters:** Mem0 supports
|
|
10
|
+
`history(id)` — version tracking per memory as facts evolve.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @theokit/memory-mem0 mem0ai
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { Agent } from "@theokit/sdk";
|
|
22
|
+
import { mem0Memory } from "@theokit/memory-mem0";
|
|
23
|
+
|
|
24
|
+
const agent = await Agent.create({
|
|
25
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
26
|
+
model: { id: "openai/gpt-4o-mini" },
|
|
27
|
+
local: {},
|
|
28
|
+
plugins: [mem0Memory({ apiKey: process.env.MEM0_API_KEY! })],
|
|
29
|
+
memoryContext: { userId: "alice" },
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Persist + recall (server-side fact extraction)
|
|
33
|
+
const id = await agent.memory.write("User likes Brazilian jazz");
|
|
34
|
+
const facts = await agent.memory.recall("music?");
|
|
35
|
+
|
|
36
|
+
// Version history — Mem0-unique capability
|
|
37
|
+
const revisions = await agent.memory.adapter()?.history(id);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Security Disclosure (CVE-2026-XXXX / CVSS 8.1)
|
|
41
|
+
|
|
42
|
+
On **2026-04-17**, a high-severity injection vulnerability (CVSS 8.1) was
|
|
43
|
+
disclosed in Mem0 OSS backends — **PGVector, MySQL, and Neptune** —
|
|
44
|
+
allowing SQL or Cypher injection via crafted memory text/metadata. The
|
|
45
|
+
**Mem0 managed cloud** (the only path this adapter uses) is reported
|
|
46
|
+
unaffected by the disclosure.
|
|
47
|
+
|
|
48
|
+
**Recommendations:**
|
|
49
|
+
|
|
50
|
+
- If you use this adapter's default configuration (cloud), you are NOT
|
|
51
|
+
exposed to CVE-2026-XXXX.
|
|
52
|
+
- If you self-host Mem0 OSS, upgrade to `mem0ai >= 3.0.5` and avoid the
|
|
53
|
+
PGVector / MySQL / Neptune backends until patched.
|
|
54
|
+
- Sanitize untrusted user input before passing it to `agent.memory.write`
|
|
55
|
+
regardless — defense in depth.
|
|
56
|
+
|
|
57
|
+
This adapter (D148) explicitly does NOT support the OSS local mode to
|
|
58
|
+
avoid this surface entirely. For local persistence, use `@theokit/sdk`'s
|
|
59
|
+
built-in Memory + Active Memory subsystems.
|
|
60
|
+
|
|
61
|
+
## Options
|
|
62
|
+
|
|
63
|
+
| Field | Type | Default | Description |
|
|
64
|
+
|---|---|---|---|
|
|
65
|
+
| `apiKey` | `string` | — | Mem0 API key. Required. |
|
|
66
|
+
| `host` | `string` | Mem0 cloud | Override host. |
|
|
67
|
+
| `organizationId` | `string` | — | Multi-tenant org scope. |
|
|
68
|
+
| `projectId` | `string` | — | Project scope. |
|
|
69
|
+
| `breaker.threshold` | `number` | 5 | Consecutive 5xx failures to trip. |
|
|
70
|
+
| `breaker.cooldownMs` | `number` | 120_000 | Cooldown duration. |
|
|
71
|
+
|
|
72
|
+
## Circuit breaker (EC-K)
|
|
73
|
+
|
|
74
|
+
A per-instance circuit breaker trips after 5 consecutive 5xx failures
|
|
75
|
+
and pauses calls for 2 minutes. **429 (rate limit) does NOT count**
|
|
76
|
+
toward the trip threshold — rate limits are caller-pace signals, not
|
|
77
|
+
provider-down signals.
|
|
78
|
+
|
|
79
|
+
Per-adapter-instance (EC-R): two `Agent.create({...})` calls with
|
|
80
|
+
distinct `mem0Memory({...})` instances have independent breakers. For
|
|
81
|
+
shared protection across many agents, pass the SAME plugin instance:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
const sharedPlugin = mem0Memory({ apiKey });
|
|
85
|
+
const a = await Agent.create({ plugins: [sharedPlugin] });
|
|
86
|
+
const b = await Agent.create({ plugins: [sharedPlugin] });
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Failure modes
|
|
90
|
+
|
|
91
|
+
| HTTP status | Maps to | Trips breaker? |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| 401 / 403 | `auth_failed` | no |
|
|
94
|
+
| 429 | `rate_limited` | **no** (EC-K) |
|
|
95
|
+
| 404 | `not_found` | no |
|
|
96
|
+
| 5xx | `network` | yes |
|
|
97
|
+
| Network/timeout | `network` | yes |
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
Apache-2.0. See [LICENSE](./LICENSE).
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sdk = require('@theokit/sdk');
|
|
4
|
+
var MemoryClient = require('mem0ai');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var MemoryClient__default = /*#__PURE__*/_interopDefault(MemoryClient);
|
|
9
|
+
|
|
10
|
+
// src/index.ts
|
|
11
|
+
var ADAPTER_ID = "mem0";
|
|
12
|
+
var CircuitBreaker = class {
|
|
13
|
+
threshold;
|
|
14
|
+
cooldownMs;
|
|
15
|
+
#failures = 0;
|
|
16
|
+
#openUntil = 0;
|
|
17
|
+
constructor(opts = {}) {
|
|
18
|
+
this.threshold = opts.threshold ?? 5;
|
|
19
|
+
this.cooldownMs = opts.cooldownMs ?? 2 * 60 * 1e3;
|
|
20
|
+
}
|
|
21
|
+
/** Throws `MemoryAdapterError(code: "rate_limited")` if breaker is open. */
|
|
22
|
+
ensureClosed(op) {
|
|
23
|
+
if (Date.now() < this.#openUntil) {
|
|
24
|
+
const secondsLeft = Math.ceil((this.#openUntil - Date.now()) / 1e3);
|
|
25
|
+
throw new sdk.MemoryAdapterError(
|
|
26
|
+
`Mem0 circuit breaker open (${op}): ${secondsLeft}s cooldown remaining.`,
|
|
27
|
+
{ adapterId: ADAPTER_ID, code: "rate_limited" }
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Increment failure counter. Trips when threshold reached. Only call for 5xx-class errors. */
|
|
32
|
+
recordFailure() {
|
|
33
|
+
this.#failures += 1;
|
|
34
|
+
if (this.#failures >= this.threshold) {
|
|
35
|
+
this.#openUntil = Date.now() + this.cooldownMs;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** Reset on first success — closes the breaker (EC-K). */
|
|
39
|
+
recordSuccess() {
|
|
40
|
+
this.#failures = 0;
|
|
41
|
+
this.#openUntil = 0;
|
|
42
|
+
}
|
|
43
|
+
/** Test-only inspector. @internal */
|
|
44
|
+
state() {
|
|
45
|
+
return {
|
|
46
|
+
failures: this.#failures,
|
|
47
|
+
isOpen: Date.now() < this.#openUntil,
|
|
48
|
+
openUntil: this.#openUntil
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// src/translate.ts
|
|
54
|
+
function toMem0Options(ctx) {
|
|
55
|
+
const out = { user_id: ctx.userId };
|
|
56
|
+
if (ctx.agentId !== void 0) out.agent_id = ctx.agentId;
|
|
57
|
+
if (ctx.sessionId !== void 0) out.run_id = ctx.sessionId;
|
|
58
|
+
if (ctx.tenantId !== void 0) out.app_id = ctx.tenantId;
|
|
59
|
+
if (ctx.tags !== void 0) out.categories = ctx.tags;
|
|
60
|
+
if (ctx.metadata !== void 0) out.metadata = ctx.metadata;
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/adapter.ts
|
|
65
|
+
var ADAPTER_ID2 = "mem0";
|
|
66
|
+
var CAPS = {
|
|
67
|
+
history: true,
|
|
68
|
+
// ← unique to Mem0
|
|
69
|
+
sessions: true,
|
|
70
|
+
tenancy: true,
|
|
71
|
+
reasoning: false,
|
|
72
|
+
toolSchemas: true,
|
|
73
|
+
prefetch: false
|
|
74
|
+
};
|
|
75
|
+
var Mem0Adapter = class {
|
|
76
|
+
id = ADAPTER_ID2;
|
|
77
|
+
capabilities = CAPS;
|
|
78
|
+
#opts;
|
|
79
|
+
#breaker;
|
|
80
|
+
#client;
|
|
81
|
+
constructor(opts) {
|
|
82
|
+
this.#opts = opts;
|
|
83
|
+
this.#breaker = new CircuitBreaker(opts.breaker);
|
|
84
|
+
}
|
|
85
|
+
isAvailable() {
|
|
86
|
+
return typeof this.#opts.apiKey === "string" && this.#opts.apiKey.length > 0;
|
|
87
|
+
}
|
|
88
|
+
async initialize() {
|
|
89
|
+
}
|
|
90
|
+
async write(content, ctx) {
|
|
91
|
+
this.#breaker.ensureClosed("write");
|
|
92
|
+
const messages = this.#toMessages(content);
|
|
93
|
+
if (messages.length === 0) {
|
|
94
|
+
throw new sdk.MemoryAdapterError("write: empty messages", {
|
|
95
|
+
adapterId: ADAPTER_ID2,
|
|
96
|
+
code: "invalid_input"
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const opts = toMem0Options(ctx);
|
|
101
|
+
const resp = await this.#sdk().add(messages, opts);
|
|
102
|
+
this.#breaker.recordSuccess();
|
|
103
|
+
const first = resp[0];
|
|
104
|
+
const rawId = first?.id ?? `mem0-${Date.now()}`;
|
|
105
|
+
return sdk.mkMemoryId(ADAPTER_ID2, rawId);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
throw this.#translateError(err, "write");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async recall(query, ctx, k = 10) {
|
|
111
|
+
if (k <= 0) return [];
|
|
112
|
+
this.#breaker.ensureClosed("recall");
|
|
113
|
+
try {
|
|
114
|
+
const opts = toMem0Options(ctx);
|
|
115
|
+
const resp = await this.#sdk().search(query, {
|
|
116
|
+
// Read filter: cross-session recall keyed by user_id (Hermes pattern).
|
|
117
|
+
...opts.user_id !== void 0 ? { filters: { user_id: opts.user_id } } : {},
|
|
118
|
+
topK: k,
|
|
119
|
+
rerank: true
|
|
120
|
+
});
|
|
121
|
+
this.#breaker.recordSuccess();
|
|
122
|
+
const list = Array.isArray(resp) ? resp : resp.results ?? [];
|
|
123
|
+
return list.map((r) => ({
|
|
124
|
+
id: sdk.mkMemoryId(ADAPTER_ID2, String(r.id ?? "")),
|
|
125
|
+
content: String(r.memory ?? r.content ?? ""),
|
|
126
|
+
...typeof r.score === "number" ? { score: r.score } : {},
|
|
127
|
+
...r.createdAt !== void 0 ? { createdAt: String(r.createdAt) } : {},
|
|
128
|
+
...r.metadata !== void 0 ? { metadata: r.metadata } : {}
|
|
129
|
+
}));
|
|
130
|
+
} catch (err) {
|
|
131
|
+
throw this.#translateError(err, "recall");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async delete(id) {
|
|
135
|
+
this.#breaker.ensureClosed("delete");
|
|
136
|
+
const rawId = sdk.extractRawId(id, ADAPTER_ID2);
|
|
137
|
+
try {
|
|
138
|
+
await this.#sdk().delete(rawId);
|
|
139
|
+
this.#breaker.recordSuccess();
|
|
140
|
+
} catch (err) {
|
|
141
|
+
throw this.#translateError(err, "delete");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async history(id) {
|
|
145
|
+
this.#breaker.ensureClosed("history");
|
|
146
|
+
const rawId = sdk.extractRawId(id, ADAPTER_ID2);
|
|
147
|
+
try {
|
|
148
|
+
const rows = await this.#sdk().history(rawId);
|
|
149
|
+
this.#breaker.recordSuccess();
|
|
150
|
+
return rows.map((r, i) => {
|
|
151
|
+
const u = r.updatedAt;
|
|
152
|
+
const changedAt = u instanceof Date ? u.toISOString() : typeof u === "string" ? u : (/* @__PURE__ */ new Date()).toISOString();
|
|
153
|
+
return {
|
|
154
|
+
id: sdk.mkMemoryId(ADAPTER_ID2, r.memoryId ?? rawId),
|
|
155
|
+
content: String(r.newMemory ?? r.oldMemory ?? ""),
|
|
156
|
+
version: i + 1,
|
|
157
|
+
changedAt
|
|
158
|
+
};
|
|
159
|
+
});
|
|
160
|
+
} catch (err) {
|
|
161
|
+
throw this.#translateError(err, "history");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
getToolSchemas() {
|
|
165
|
+
return [
|
|
166
|
+
{
|
|
167
|
+
name: "memory_write",
|
|
168
|
+
description: "Persist a turn to Mem0 long-term memory. Server-side extraction populates facts.",
|
|
169
|
+
parameters: {
|
|
170
|
+
type: "object",
|
|
171
|
+
properties: {
|
|
172
|
+
content: { type: "string", description: "Turn text to persist." }
|
|
173
|
+
},
|
|
174
|
+
required: ["content"]
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: "memory_recall",
|
|
179
|
+
description: "Retrieve up to k semantically relevant facts from Mem0 (server-side rerank).",
|
|
180
|
+
parameters: {
|
|
181
|
+
type: "object",
|
|
182
|
+
properties: {
|
|
183
|
+
query: { type: "string" },
|
|
184
|
+
k: { type: "integer", minimum: 1, maximum: 50 }
|
|
185
|
+
},
|
|
186
|
+
required: ["query"]
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: "memory_history",
|
|
191
|
+
description: "Retrieve the version history of a specific memory by id. Mem0-unique capability \u2014 shows how a fact has evolved over time (e.g., user changed preferences).",
|
|
192
|
+
parameters: {
|
|
193
|
+
type: "object",
|
|
194
|
+
properties: { memoryId: { type: "string" } },
|
|
195
|
+
required: ["memoryId"]
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
];
|
|
199
|
+
}
|
|
200
|
+
async handleToolCall(name, args, ctx) {
|
|
201
|
+
if (name === "memory_write") {
|
|
202
|
+
const id = await this.write(String(args.content ?? ""), ctx);
|
|
203
|
+
return JSON.stringify({ ok: true, id });
|
|
204
|
+
}
|
|
205
|
+
if (name === "memory_recall") {
|
|
206
|
+
const k = typeof args.k === "number" ? args.k : 10;
|
|
207
|
+
const facts = await this.recall(String(args.query ?? ""), ctx, k);
|
|
208
|
+
return JSON.stringify({ ok: true, facts });
|
|
209
|
+
}
|
|
210
|
+
if (name === "memory_history") {
|
|
211
|
+
const rawId = String(args.memoryId ?? "");
|
|
212
|
+
const wrapped = rawId.startsWith(`${ADAPTER_ID2}:`) ? rawId : sdk.mkMemoryId(ADAPTER_ID2, rawId);
|
|
213
|
+
const revisions = await this.history(wrapped);
|
|
214
|
+
return JSON.stringify({ ok: true, revisions });
|
|
215
|
+
}
|
|
216
|
+
throw new sdk.MemoryAdapterError(`Unknown tool name: ${name}`, {
|
|
217
|
+
adapterId: ADAPTER_ID2,
|
|
218
|
+
code: "invalid_input"
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
async shutdown() {
|
|
222
|
+
this.#client = void 0;
|
|
223
|
+
}
|
|
224
|
+
/** Test-only: inspect breaker state. @internal */
|
|
225
|
+
_breakerState() {
|
|
226
|
+
return this.#breaker.state();
|
|
227
|
+
}
|
|
228
|
+
// ── helpers ────────────────────────────────────────────────────────
|
|
229
|
+
#toMessages(content) {
|
|
230
|
+
if (typeof content === "string") {
|
|
231
|
+
return content.trim().length === 0 ? [] : [{ role: "user", content }];
|
|
232
|
+
}
|
|
233
|
+
return content.filter((m) => m.content.trim().length > 0).map(
|
|
234
|
+
(m) => m.role === "system" ? { role: "user", content: `[system] ${m.content}` } : { role: m.role, content: m.content }
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
#sdk() {
|
|
238
|
+
if (this.#client === void 0) {
|
|
239
|
+
this.#client = new MemoryClient__default.default({
|
|
240
|
+
apiKey: this.#opts.apiKey,
|
|
241
|
+
...this.#opts.host !== void 0 ? { host: this.#opts.host } : {},
|
|
242
|
+
...this.#opts.organizationId !== void 0 ? { organizationId: this.#opts.organizationId } : {},
|
|
243
|
+
...this.#opts.projectId !== void 0 ? { projectId: this.#opts.projectId } : {}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
return this.#client;
|
|
247
|
+
}
|
|
248
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: error-translation ladder maps provider error classes to typed codes + breaker policy (EC-K: 429 does NOT trip); inlining keeps the policy decisions in one place.
|
|
249
|
+
#translateError(err, op) {
|
|
250
|
+
if (err instanceof sdk.MemoryAdapterError) {
|
|
251
|
+
if (err.code === "rate_limited") ; else if (err.code === "auth_failed" || err.code === "not_found" || err.code === "invalid_input") ; else {
|
|
252
|
+
this.#breaker.recordFailure();
|
|
253
|
+
}
|
|
254
|
+
return err;
|
|
255
|
+
}
|
|
256
|
+
const status = err?.status ?? err?.statusCode ?? err?.response?.status;
|
|
257
|
+
const message = err?.message ?? String(err);
|
|
258
|
+
if (status === 401 || status === 403) {
|
|
259
|
+
return new sdk.MemoryAdapterError(`Mem0 auth failed (${op}): ${message}`, {
|
|
260
|
+
adapterId: ADAPTER_ID2,
|
|
261
|
+
code: "auth_failed",
|
|
262
|
+
cause: err
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
if (status === 429) {
|
|
266
|
+
return new sdk.MemoryAdapterError(`Mem0 rate limited (${op}): ${message}`, {
|
|
267
|
+
adapterId: ADAPTER_ID2,
|
|
268
|
+
code: "rate_limited",
|
|
269
|
+
cause: err
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
if (status === 404) {
|
|
273
|
+
return new sdk.MemoryAdapterError(`Mem0 not found (${op}): ${message}`, {
|
|
274
|
+
adapterId: ADAPTER_ID2,
|
|
275
|
+
code: "not_found",
|
|
276
|
+
cause: err
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
if (typeof status === "number" && status >= 500) {
|
|
280
|
+
this.#breaker.recordFailure();
|
|
281
|
+
return new sdk.MemoryAdapterError(`Mem0 server error (${op}): ${message}`, {
|
|
282
|
+
adapterId: ADAPTER_ID2,
|
|
283
|
+
code: "network",
|
|
284
|
+
cause: err
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
if (status === void 0 && message.toLowerCase().includes("network")) {
|
|
288
|
+
this.#breaker.recordFailure();
|
|
289
|
+
return new sdk.MemoryAdapterError(`Mem0 network error (${op}): ${message}`, {
|
|
290
|
+
adapterId: ADAPTER_ID2,
|
|
291
|
+
code: "network",
|
|
292
|
+
cause: err
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
return new sdk.MemoryAdapterError(`Mem0 error (${op}): ${message}`, {
|
|
296
|
+
adapterId: ADAPTER_ID2,
|
|
297
|
+
code: "unknown",
|
|
298
|
+
cause: err
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
// src/index.ts
|
|
304
|
+
function mem0Memory(options) {
|
|
305
|
+
return sdk.definePlugin({
|
|
306
|
+
name: "@theokit/memory-mem0",
|
|
307
|
+
version: "0.1.0",
|
|
308
|
+
kind: "memory",
|
|
309
|
+
createProvider: () => new Mem0Adapter(options)
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
exports.mem0Memory = mem0Memory;
|
|
314
|
+
//# sourceMappingURL=index.cjs.map
|
|
315
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/circuit-breaker.ts","../src/translate.ts","../src/adapter.ts","../src/index.ts"],"names":["MemoryAdapterError","ADAPTER_ID","mkMemoryId","extractRawId","MemoryClient","definePlugin"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * In-memory circuit breaker for Mem0Adapter (T5.1, EC-K).\n *\n * Trips after `threshold` consecutive 5xx-class failures. 429 / 401 /\n * 404 / invalid_input do NOT count toward the threshold — rate limits\n * are a caller-pace signal, not a provider-down signal (EC-K).\n *\n * @internal\n */\n\nimport { MemoryAdapterError } from \"@theokit/sdk\";\n\nconst ADAPTER_ID = \"mem0\";\n\nexport interface CircuitBreakerOptions {\n threshold?: number;\n cooldownMs?: number;\n}\n\nexport class CircuitBreaker {\n readonly threshold: number;\n readonly cooldownMs: number;\n #failures = 0;\n #openUntil = 0;\n\n constructor(opts: CircuitBreakerOptions = {}) {\n this.threshold = opts.threshold ?? 5;\n this.cooldownMs = opts.cooldownMs ?? 2 * 60 * 1000;\n }\n\n /** Throws `MemoryAdapterError(code: \"rate_limited\")` if breaker is open. */\n ensureClosed(op: string): void {\n if (Date.now() < this.#openUntil) {\n const secondsLeft = Math.ceil((this.#openUntil - Date.now()) / 1000);\n throw new MemoryAdapterError(\n `Mem0 circuit breaker open (${op}): ${secondsLeft}s cooldown remaining.`,\n { adapterId: ADAPTER_ID, code: \"rate_limited\" },\n );\n }\n }\n\n /** Increment failure counter. Trips when threshold reached. Only call for 5xx-class errors. */\n recordFailure(): void {\n this.#failures += 1;\n if (this.#failures >= this.threshold) {\n this.#openUntil = Date.now() + this.cooldownMs;\n }\n }\n\n /** Reset on first success — closes the breaker (EC-K). */\n recordSuccess(): void {\n this.#failures = 0;\n this.#openUntil = 0;\n }\n\n /** Test-only inspector. @internal */\n state(): { failures: number; isOpen: boolean; openUntil: number } {\n return {\n failures: this.#failures,\n isOpen: Date.now() < this.#openUntil,\n openUntil: this.#openUntil,\n };\n }\n}\n","/**\n * `MemoryContext` → Mem0 add/search options translation (T5.1).\n *\n * Mem0 keeps `user_id`, `agent_id`, `app_id`, `run_id` orthogonal —\n * we map each `MemoryContext` field onto its native primitive.\n *\n * @internal\n */\n\nimport type { MemoryContext } from \"@theokit/sdk\";\n\ninterface Mem0Options {\n user_id?: string;\n agent_id?: string;\n run_id?: string;\n app_id?: string;\n categories?: string[];\n metadata?: Record<string, unknown>;\n}\n\nexport function toMem0Options(ctx: MemoryContext): Mem0Options {\n const out: Mem0Options = { user_id: ctx.userId };\n if (ctx.agentId !== undefined) out.agent_id = ctx.agentId;\n if (ctx.sessionId !== undefined) out.run_id = ctx.sessionId;\n if (ctx.tenantId !== undefined) out.app_id = ctx.tenantId;\n if (ctx.tags !== undefined) out.categories = ctx.tags;\n if (ctx.metadata !== undefined) out.metadata = ctx.metadata;\n return out;\n}\n","/**\n * Mem0Adapter — `@theokit/memory-mem0` core (T5.1, ADR D141 / D148).\n *\n * Wraps `mem0ai` `MemoryClient` (cloud-only per D148). Implements\n * `MemoryAdapter` with the unique `history(id)` capability — the only\n * adapter today that exposes per-memory versioning.\n *\n * Includes a circuit breaker (EC-K: 5xx counts; 429 does NOT trip).\n *\n * @public\n */\n\nimport {\n extractRawId,\n type MemoryAdapter,\n type MemoryAdapterCapabilities,\n MemoryAdapterError,\n type MemoryContext,\n type MemoryFact,\n type MemoryId,\n type MemoryRevision,\n type MemoryToolSchema,\n type MemoryTurnMessage,\n mkMemoryId,\n} from \"@theokit/sdk\";\nimport MemoryClient from \"mem0ai\";\n\nimport { CircuitBreaker, type CircuitBreakerOptions } from \"./circuit-breaker.js\";\nimport { toMem0Options } from \"./translate.js\";\n\n/** Configuration accepted by the `mem0Memory(...)` factory. @public */\nexport interface Mem0AdapterOptions {\n /** Mem0 API key. Required. */\n apiKey: string;\n /** Override host (default mem0 cloud). */\n host?: string;\n organizationId?: string;\n projectId?: string;\n /** Circuit breaker tuning (EC-K). */\n breaker?: CircuitBreakerOptions;\n}\n\nconst ADAPTER_ID = \"mem0\";\n\nconst CAPS: MemoryAdapterCapabilities = {\n history: true, // ← unique to Mem0\n sessions: true,\n tenancy: true,\n reasoning: false,\n toolSchemas: true,\n prefetch: false,\n};\n\n/** @internal */\nexport class Mem0Adapter implements MemoryAdapter {\n readonly id = ADAPTER_ID;\n readonly capabilities = CAPS;\n readonly #opts: Mem0AdapterOptions;\n readonly #breaker: CircuitBreaker;\n #client?: MemoryClient;\n\n constructor(opts: Mem0AdapterOptions) {\n this.#opts = opts;\n this.#breaker = new CircuitBreaker(opts.breaker);\n }\n\n isAvailable(): boolean {\n return typeof this.#opts.apiKey === \"string\" && this.#opts.apiKey.length > 0;\n }\n\n async initialize(): Promise<void> {\n // Lazy: client constructed on first call.\n }\n\n async write(content: string | MemoryTurnMessage[], ctx: MemoryContext): Promise<MemoryId> {\n this.#breaker.ensureClosed(\"write\");\n const messages = this.#toMessages(content);\n if (messages.length === 0) {\n throw new MemoryAdapterError(\"write: empty messages\", {\n adapterId: ADAPTER_ID,\n code: \"invalid_input\",\n });\n }\n try {\n const opts = toMem0Options(ctx);\n const resp = await this.#sdk().add(messages, opts);\n this.#breaker.recordSuccess();\n const first = resp[0];\n const rawId = first?.id ?? `mem0-${Date.now()}`;\n return mkMemoryId(ADAPTER_ID, rawId);\n } catch (err) {\n throw this.#translateError(err, \"write\");\n }\n }\n\n async recall(query: string, ctx: MemoryContext, k = 10): Promise<MemoryFact[]> {\n if (k <= 0) return [];\n this.#breaker.ensureClosed(\"recall\");\n try {\n const opts = toMem0Options(ctx);\n const resp = await this.#sdk().search(query, {\n // Read filter: cross-session recall keyed by user_id (Hermes pattern).\n ...(opts.user_id !== undefined ? { filters: { user_id: opts.user_id } } : {}),\n topK: k,\n rerank: true,\n });\n this.#breaker.recordSuccess();\n const list = Array.isArray(resp) ? resp : ((resp as { results?: unknown[] }).results ?? []);\n return (list as Array<Record<string, unknown>>).map((r) => ({\n id: mkMemoryId(ADAPTER_ID, String(r.id ?? \"\")),\n content: String(r.memory ?? r.content ?? \"\"),\n ...(typeof r.score === \"number\" ? { score: r.score as number } : {}),\n ...(r.createdAt !== undefined ? { createdAt: String(r.createdAt) } : {}),\n ...(r.metadata !== undefined ? { metadata: r.metadata as Record<string, unknown> } : {}),\n }));\n } catch (err) {\n throw this.#translateError(err, \"recall\");\n }\n }\n\n async delete(id: MemoryId): Promise<void> {\n this.#breaker.ensureClosed(\"delete\");\n const rawId = extractRawId(id, ADAPTER_ID);\n try {\n await this.#sdk().delete(rawId);\n this.#breaker.recordSuccess();\n } catch (err) {\n throw this.#translateError(err, \"delete\");\n }\n }\n\n async history(id: MemoryId): Promise<MemoryRevision[]> {\n this.#breaker.ensureClosed(\"history\");\n const rawId = extractRawId(id, ADAPTER_ID);\n try {\n const rows = await this.#sdk().history(rawId);\n this.#breaker.recordSuccess();\n return rows.map((r, i) => {\n const u = (r as unknown as { updatedAt?: unknown }).updatedAt;\n const changedAt =\n u instanceof Date\n ? u.toISOString()\n : typeof u === \"string\"\n ? u\n : new Date().toISOString();\n return {\n id: mkMemoryId(ADAPTER_ID, r.memoryId ?? rawId),\n content: String(r.newMemory ?? r.oldMemory ?? \"\"),\n version: i + 1,\n changedAt,\n };\n });\n } catch (err) {\n throw this.#translateError(err, \"history\");\n }\n }\n\n getToolSchemas(): MemoryToolSchema[] {\n return [\n {\n name: \"memory_write\",\n description:\n \"Persist a turn to Mem0 long-term memory. Server-side extraction populates facts.\",\n parameters: {\n type: \"object\",\n properties: {\n content: { type: \"string\", description: \"Turn text to persist.\" },\n },\n required: [\"content\"],\n },\n },\n {\n name: \"memory_recall\",\n description: \"Retrieve up to k semantically relevant facts from Mem0 (server-side rerank).\",\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\" },\n k: { type: \"integer\", minimum: 1, maximum: 50 },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"memory_history\",\n description:\n \"Retrieve the version history of a specific memory by id. Mem0-unique capability — \" +\n \"shows how a fact has evolved over time (e.g., user changed preferences).\",\n parameters: {\n type: \"object\",\n properties: { memoryId: { type: \"string\" } },\n required: [\"memoryId\"],\n },\n },\n ];\n }\n\n async handleToolCall(\n name: string,\n args: Record<string, unknown>,\n ctx: MemoryContext,\n ): Promise<string> {\n if (name === \"memory_write\") {\n const id = await this.write(String(args.content ?? \"\"), ctx);\n return JSON.stringify({ ok: true, id });\n }\n if (name === \"memory_recall\") {\n const k = typeof args.k === \"number\" ? args.k : 10;\n const facts = await this.recall(String(args.query ?? \"\"), ctx, k);\n return JSON.stringify({ ok: true, facts });\n }\n if (name === \"memory_history\") {\n const rawId = String(args.memoryId ?? \"\");\n const wrapped = rawId.startsWith(`${ADAPTER_ID}:`)\n ? (rawId as MemoryId)\n : mkMemoryId(ADAPTER_ID, rawId);\n const revisions = await this.history(wrapped);\n return JSON.stringify({ ok: true, revisions });\n }\n throw new MemoryAdapterError(`Unknown tool name: ${name}`, {\n adapterId: ADAPTER_ID,\n code: \"invalid_input\",\n });\n }\n\n async shutdown(): Promise<void> {\n this.#client = undefined;\n }\n\n /** Test-only: inspect breaker state. @internal */\n _breakerState(): { failures: number; isOpen: boolean; openUntil: number } {\n return this.#breaker.state();\n }\n\n // ── helpers ────────────────────────────────────────────────────────\n\n #toMessages(\n content: string | MemoryTurnMessage[],\n ): Array<{ role: \"user\" | \"assistant\"; content: string }> {\n if (typeof content === \"string\") {\n return content.trim().length === 0 ? [] : [{ role: \"user\", content }];\n }\n // Mem0 SDK accepts only user/assistant roles. System turns are merged\n // into user content with a \"[system] \" prefix.\n return content\n .filter((m) => m.content.trim().length > 0)\n .map((m) =>\n m.role === \"system\"\n ? { role: \"user\" as const, content: `[system] ${m.content}` }\n : { role: m.role, content: m.content },\n );\n }\n\n #sdk(): MemoryClient {\n if (this.#client === undefined) {\n this.#client = new MemoryClient({\n apiKey: this.#opts.apiKey,\n ...(this.#opts.host !== undefined ? { host: this.#opts.host } : {}),\n ...(this.#opts.organizationId !== undefined\n ? { organizationId: this.#opts.organizationId }\n : {}),\n ...(this.#opts.projectId !== undefined ? { projectId: this.#opts.projectId } : {}),\n });\n }\n return this.#client;\n }\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: error-translation ladder maps provider error classes to typed codes + breaker policy (EC-K: 429 does NOT trip); inlining keeps the policy decisions in one place.\n #translateError(err: unknown, op: string): MemoryAdapterError {\n if (err instanceof MemoryAdapterError) {\n if (err.code === \"rate_limited\") {\n // EC-K: do NOT trip breaker on rate limit.\n } else if (\n err.code === \"auth_failed\" ||\n err.code === \"not_found\" ||\n err.code === \"invalid_input\"\n ) {\n // No trip — these are caller-side or stateful conditions.\n } else {\n this.#breaker.recordFailure();\n }\n return err;\n }\n const status =\n (err as { status?: number; statusCode?: number; response?: { status?: number } })?.status ??\n (err as { statusCode?: number })?.statusCode ??\n (err as { response?: { status?: number } })?.response?.status;\n const message = (err as Error)?.message ?? String(err);\n if (status === 401 || status === 403) {\n return new MemoryAdapterError(`Mem0 auth failed (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"auth_failed\",\n cause: err,\n });\n }\n if (status === 429) {\n // EC-K: rate-limited; do NOT increment breaker.\n return new MemoryAdapterError(`Mem0 rate limited (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"rate_limited\",\n cause: err,\n });\n }\n if (status === 404) {\n return new MemoryAdapterError(`Mem0 not found (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"not_found\",\n cause: err,\n });\n }\n if (typeof status === \"number\" && status >= 500) {\n this.#breaker.recordFailure();\n return new MemoryAdapterError(`Mem0 server error (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"network\",\n cause: err,\n });\n }\n if (status === undefined && message.toLowerCase().includes(\"network\")) {\n this.#breaker.recordFailure();\n return new MemoryAdapterError(`Mem0 network error (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"network\",\n cause: err,\n });\n }\n return new MemoryAdapterError(`Mem0 error (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"unknown\",\n cause: err,\n });\n }\n}\n","/**\n * `@theokit/memory-mem0` — Mem0 cloud memory adapter for @theokit/sdk.\n *\n * Cloud-only per ADR D148. Wraps `mem0ai` `MemoryClient`. Unique\n * capability among `@theokit/memory-*` adapters: `history(id)`.\n *\n * @public\n */\n\nimport type { Plugin } from \"@theokit/sdk\";\nimport { definePlugin } from \"@theokit/sdk\";\n\nimport { Mem0Adapter, type Mem0AdapterOptions } from \"./adapter.js\";\n\nexport type { Mem0AdapterOptions } from \"./adapter.js\";\n\n/** Build a `Plugin { kind: \"memory\" }`. @public */\nexport function mem0Memory(options: Mem0AdapterOptions): Plugin {\n return definePlugin({\n name: \"@theokit/memory-mem0\",\n version: \"0.1.0\",\n kind: \"memory\",\n createProvider: () => new Mem0Adapter(options),\n });\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Plugin } from '@theokit/sdk';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* In-memory circuit breaker for Mem0Adapter (T5.1, EC-K).
|
|
5
|
+
*
|
|
6
|
+
* Trips after `threshold` consecutive 5xx-class failures. 429 / 401 /
|
|
7
|
+
* 404 / invalid_input do NOT count toward the threshold — rate limits
|
|
8
|
+
* are a caller-pace signal, not a provider-down signal (EC-K).
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
interface CircuitBreakerOptions {
|
|
13
|
+
threshold?: number;
|
|
14
|
+
cooldownMs?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Mem0Adapter — `@theokit/memory-mem0` core (T5.1, ADR D141 / D148).
|
|
19
|
+
*
|
|
20
|
+
* Wraps `mem0ai` `MemoryClient` (cloud-only per D148). Implements
|
|
21
|
+
* `MemoryAdapter` with the unique `history(id)` capability — the only
|
|
22
|
+
* adapter today that exposes per-memory versioning.
|
|
23
|
+
*
|
|
24
|
+
* Includes a circuit breaker (EC-K: 5xx counts; 429 does NOT trip).
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** Configuration accepted by the `mem0Memory(...)` factory. @public */
|
|
30
|
+
interface Mem0AdapterOptions {
|
|
31
|
+
/** Mem0 API key. Required. */
|
|
32
|
+
apiKey: string;
|
|
33
|
+
/** Override host (default mem0 cloud). */
|
|
34
|
+
host?: string;
|
|
35
|
+
organizationId?: string;
|
|
36
|
+
projectId?: string;
|
|
37
|
+
/** Circuit breaker tuning (EC-K). */
|
|
38
|
+
breaker?: CircuitBreakerOptions;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* `@theokit/memory-mem0` — Mem0 cloud memory adapter for @theokit/sdk.
|
|
43
|
+
*
|
|
44
|
+
* Cloud-only per ADR D148. Wraps `mem0ai` `MemoryClient`. Unique
|
|
45
|
+
* capability among `@theokit/memory-*` adapters: `history(id)`.
|
|
46
|
+
*
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/** Build a `Plugin { kind: "memory" }`. @public */
|
|
51
|
+
declare function mem0Memory(options: Mem0AdapterOptions): Plugin;
|
|
52
|
+
|
|
53
|
+
export { type Mem0AdapterOptions, mem0Memory };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Plugin } from '@theokit/sdk';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* In-memory circuit breaker for Mem0Adapter (T5.1, EC-K).
|
|
5
|
+
*
|
|
6
|
+
* Trips after `threshold` consecutive 5xx-class failures. 429 / 401 /
|
|
7
|
+
* 404 / invalid_input do NOT count toward the threshold — rate limits
|
|
8
|
+
* are a caller-pace signal, not a provider-down signal (EC-K).
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
interface CircuitBreakerOptions {
|
|
13
|
+
threshold?: number;
|
|
14
|
+
cooldownMs?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Mem0Adapter — `@theokit/memory-mem0` core (T5.1, ADR D141 / D148).
|
|
19
|
+
*
|
|
20
|
+
* Wraps `mem0ai` `MemoryClient` (cloud-only per D148). Implements
|
|
21
|
+
* `MemoryAdapter` with the unique `history(id)` capability — the only
|
|
22
|
+
* adapter today that exposes per-memory versioning.
|
|
23
|
+
*
|
|
24
|
+
* Includes a circuit breaker (EC-K: 5xx counts; 429 does NOT trip).
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** Configuration accepted by the `mem0Memory(...)` factory. @public */
|
|
30
|
+
interface Mem0AdapterOptions {
|
|
31
|
+
/** Mem0 API key. Required. */
|
|
32
|
+
apiKey: string;
|
|
33
|
+
/** Override host (default mem0 cloud). */
|
|
34
|
+
host?: string;
|
|
35
|
+
organizationId?: string;
|
|
36
|
+
projectId?: string;
|
|
37
|
+
/** Circuit breaker tuning (EC-K). */
|
|
38
|
+
breaker?: CircuitBreakerOptions;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* `@theokit/memory-mem0` — Mem0 cloud memory adapter for @theokit/sdk.
|
|
43
|
+
*
|
|
44
|
+
* Cloud-only per ADR D148. Wraps `mem0ai` `MemoryClient`. Unique
|
|
45
|
+
* capability among `@theokit/memory-*` adapters: `history(id)`.
|
|
46
|
+
*
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/** Build a `Plugin { kind: "memory" }`. @public */
|
|
51
|
+
declare function mem0Memory(options: Mem0AdapterOptions): Plugin;
|
|
52
|
+
|
|
53
|
+
export { type Mem0AdapterOptions, mem0Memory };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { definePlugin, MemoryAdapterError, mkMemoryId, extractRawId } from '@theokit/sdk';
|
|
2
|
+
import MemoryClient from 'mem0ai';
|
|
3
|
+
|
|
4
|
+
// src/index.ts
|
|
5
|
+
var ADAPTER_ID = "mem0";
|
|
6
|
+
var CircuitBreaker = class {
|
|
7
|
+
threshold;
|
|
8
|
+
cooldownMs;
|
|
9
|
+
#failures = 0;
|
|
10
|
+
#openUntil = 0;
|
|
11
|
+
constructor(opts = {}) {
|
|
12
|
+
this.threshold = opts.threshold ?? 5;
|
|
13
|
+
this.cooldownMs = opts.cooldownMs ?? 2 * 60 * 1e3;
|
|
14
|
+
}
|
|
15
|
+
/** Throws `MemoryAdapterError(code: "rate_limited")` if breaker is open. */
|
|
16
|
+
ensureClosed(op) {
|
|
17
|
+
if (Date.now() < this.#openUntil) {
|
|
18
|
+
const secondsLeft = Math.ceil((this.#openUntil - Date.now()) / 1e3);
|
|
19
|
+
throw new MemoryAdapterError(
|
|
20
|
+
`Mem0 circuit breaker open (${op}): ${secondsLeft}s cooldown remaining.`,
|
|
21
|
+
{ adapterId: ADAPTER_ID, code: "rate_limited" }
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** Increment failure counter. Trips when threshold reached. Only call for 5xx-class errors. */
|
|
26
|
+
recordFailure() {
|
|
27
|
+
this.#failures += 1;
|
|
28
|
+
if (this.#failures >= this.threshold) {
|
|
29
|
+
this.#openUntil = Date.now() + this.cooldownMs;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Reset on first success — closes the breaker (EC-K). */
|
|
33
|
+
recordSuccess() {
|
|
34
|
+
this.#failures = 0;
|
|
35
|
+
this.#openUntil = 0;
|
|
36
|
+
}
|
|
37
|
+
/** Test-only inspector. @internal */
|
|
38
|
+
state() {
|
|
39
|
+
return {
|
|
40
|
+
failures: this.#failures,
|
|
41
|
+
isOpen: Date.now() < this.#openUntil,
|
|
42
|
+
openUntil: this.#openUntil
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// src/translate.ts
|
|
48
|
+
function toMem0Options(ctx) {
|
|
49
|
+
const out = { user_id: ctx.userId };
|
|
50
|
+
if (ctx.agentId !== void 0) out.agent_id = ctx.agentId;
|
|
51
|
+
if (ctx.sessionId !== void 0) out.run_id = ctx.sessionId;
|
|
52
|
+
if (ctx.tenantId !== void 0) out.app_id = ctx.tenantId;
|
|
53
|
+
if (ctx.tags !== void 0) out.categories = ctx.tags;
|
|
54
|
+
if (ctx.metadata !== void 0) out.metadata = ctx.metadata;
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/adapter.ts
|
|
59
|
+
var ADAPTER_ID2 = "mem0";
|
|
60
|
+
var CAPS = {
|
|
61
|
+
history: true,
|
|
62
|
+
// ← unique to Mem0
|
|
63
|
+
sessions: true,
|
|
64
|
+
tenancy: true,
|
|
65
|
+
reasoning: false,
|
|
66
|
+
toolSchemas: true,
|
|
67
|
+
prefetch: false
|
|
68
|
+
};
|
|
69
|
+
var Mem0Adapter = class {
|
|
70
|
+
id = ADAPTER_ID2;
|
|
71
|
+
capabilities = CAPS;
|
|
72
|
+
#opts;
|
|
73
|
+
#breaker;
|
|
74
|
+
#client;
|
|
75
|
+
constructor(opts) {
|
|
76
|
+
this.#opts = opts;
|
|
77
|
+
this.#breaker = new CircuitBreaker(opts.breaker);
|
|
78
|
+
}
|
|
79
|
+
isAvailable() {
|
|
80
|
+
return typeof this.#opts.apiKey === "string" && this.#opts.apiKey.length > 0;
|
|
81
|
+
}
|
|
82
|
+
async initialize() {
|
|
83
|
+
}
|
|
84
|
+
async write(content, ctx) {
|
|
85
|
+
this.#breaker.ensureClosed("write");
|
|
86
|
+
const messages = this.#toMessages(content);
|
|
87
|
+
if (messages.length === 0) {
|
|
88
|
+
throw new MemoryAdapterError("write: empty messages", {
|
|
89
|
+
adapterId: ADAPTER_ID2,
|
|
90
|
+
code: "invalid_input"
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const opts = toMem0Options(ctx);
|
|
95
|
+
const resp = await this.#sdk().add(messages, opts);
|
|
96
|
+
this.#breaker.recordSuccess();
|
|
97
|
+
const first = resp[0];
|
|
98
|
+
const rawId = first?.id ?? `mem0-${Date.now()}`;
|
|
99
|
+
return mkMemoryId(ADAPTER_ID2, rawId);
|
|
100
|
+
} catch (err) {
|
|
101
|
+
throw this.#translateError(err, "write");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async recall(query, ctx, k = 10) {
|
|
105
|
+
if (k <= 0) return [];
|
|
106
|
+
this.#breaker.ensureClosed("recall");
|
|
107
|
+
try {
|
|
108
|
+
const opts = toMem0Options(ctx);
|
|
109
|
+
const resp = await this.#sdk().search(query, {
|
|
110
|
+
// Read filter: cross-session recall keyed by user_id (Hermes pattern).
|
|
111
|
+
...opts.user_id !== void 0 ? { filters: { user_id: opts.user_id } } : {},
|
|
112
|
+
topK: k,
|
|
113
|
+
rerank: true
|
|
114
|
+
});
|
|
115
|
+
this.#breaker.recordSuccess();
|
|
116
|
+
const list = Array.isArray(resp) ? resp : resp.results ?? [];
|
|
117
|
+
return list.map((r) => ({
|
|
118
|
+
id: mkMemoryId(ADAPTER_ID2, String(r.id ?? "")),
|
|
119
|
+
content: String(r.memory ?? r.content ?? ""),
|
|
120
|
+
...typeof r.score === "number" ? { score: r.score } : {},
|
|
121
|
+
...r.createdAt !== void 0 ? { createdAt: String(r.createdAt) } : {},
|
|
122
|
+
...r.metadata !== void 0 ? { metadata: r.metadata } : {}
|
|
123
|
+
}));
|
|
124
|
+
} catch (err) {
|
|
125
|
+
throw this.#translateError(err, "recall");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async delete(id) {
|
|
129
|
+
this.#breaker.ensureClosed("delete");
|
|
130
|
+
const rawId = extractRawId(id, ADAPTER_ID2);
|
|
131
|
+
try {
|
|
132
|
+
await this.#sdk().delete(rawId);
|
|
133
|
+
this.#breaker.recordSuccess();
|
|
134
|
+
} catch (err) {
|
|
135
|
+
throw this.#translateError(err, "delete");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async history(id) {
|
|
139
|
+
this.#breaker.ensureClosed("history");
|
|
140
|
+
const rawId = extractRawId(id, ADAPTER_ID2);
|
|
141
|
+
try {
|
|
142
|
+
const rows = await this.#sdk().history(rawId);
|
|
143
|
+
this.#breaker.recordSuccess();
|
|
144
|
+
return rows.map((r, i) => {
|
|
145
|
+
const u = r.updatedAt;
|
|
146
|
+
const changedAt = u instanceof Date ? u.toISOString() : typeof u === "string" ? u : (/* @__PURE__ */ new Date()).toISOString();
|
|
147
|
+
return {
|
|
148
|
+
id: mkMemoryId(ADAPTER_ID2, r.memoryId ?? rawId),
|
|
149
|
+
content: String(r.newMemory ?? r.oldMemory ?? ""),
|
|
150
|
+
version: i + 1,
|
|
151
|
+
changedAt
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
} catch (err) {
|
|
155
|
+
throw this.#translateError(err, "history");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
getToolSchemas() {
|
|
159
|
+
return [
|
|
160
|
+
{
|
|
161
|
+
name: "memory_write",
|
|
162
|
+
description: "Persist a turn to Mem0 long-term memory. Server-side extraction populates facts.",
|
|
163
|
+
parameters: {
|
|
164
|
+
type: "object",
|
|
165
|
+
properties: {
|
|
166
|
+
content: { type: "string", description: "Turn text to persist." }
|
|
167
|
+
},
|
|
168
|
+
required: ["content"]
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: "memory_recall",
|
|
173
|
+
description: "Retrieve up to k semantically relevant facts from Mem0 (server-side rerank).",
|
|
174
|
+
parameters: {
|
|
175
|
+
type: "object",
|
|
176
|
+
properties: {
|
|
177
|
+
query: { type: "string" },
|
|
178
|
+
k: { type: "integer", minimum: 1, maximum: 50 }
|
|
179
|
+
},
|
|
180
|
+
required: ["query"]
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: "memory_history",
|
|
185
|
+
description: "Retrieve the version history of a specific memory by id. Mem0-unique capability \u2014 shows how a fact has evolved over time (e.g., user changed preferences).",
|
|
186
|
+
parameters: {
|
|
187
|
+
type: "object",
|
|
188
|
+
properties: { memoryId: { type: "string" } },
|
|
189
|
+
required: ["memoryId"]
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
];
|
|
193
|
+
}
|
|
194
|
+
async handleToolCall(name, args, ctx) {
|
|
195
|
+
if (name === "memory_write") {
|
|
196
|
+
const id = await this.write(String(args.content ?? ""), ctx);
|
|
197
|
+
return JSON.stringify({ ok: true, id });
|
|
198
|
+
}
|
|
199
|
+
if (name === "memory_recall") {
|
|
200
|
+
const k = typeof args.k === "number" ? args.k : 10;
|
|
201
|
+
const facts = await this.recall(String(args.query ?? ""), ctx, k);
|
|
202
|
+
return JSON.stringify({ ok: true, facts });
|
|
203
|
+
}
|
|
204
|
+
if (name === "memory_history") {
|
|
205
|
+
const rawId = String(args.memoryId ?? "");
|
|
206
|
+
const wrapped = rawId.startsWith(`${ADAPTER_ID2}:`) ? rawId : mkMemoryId(ADAPTER_ID2, rawId);
|
|
207
|
+
const revisions = await this.history(wrapped);
|
|
208
|
+
return JSON.stringify({ ok: true, revisions });
|
|
209
|
+
}
|
|
210
|
+
throw new MemoryAdapterError(`Unknown tool name: ${name}`, {
|
|
211
|
+
adapterId: ADAPTER_ID2,
|
|
212
|
+
code: "invalid_input"
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
async shutdown() {
|
|
216
|
+
this.#client = void 0;
|
|
217
|
+
}
|
|
218
|
+
/** Test-only: inspect breaker state. @internal */
|
|
219
|
+
_breakerState() {
|
|
220
|
+
return this.#breaker.state();
|
|
221
|
+
}
|
|
222
|
+
// ── helpers ────────────────────────────────────────────────────────
|
|
223
|
+
#toMessages(content) {
|
|
224
|
+
if (typeof content === "string") {
|
|
225
|
+
return content.trim().length === 0 ? [] : [{ role: "user", content }];
|
|
226
|
+
}
|
|
227
|
+
return content.filter((m) => m.content.trim().length > 0).map(
|
|
228
|
+
(m) => m.role === "system" ? { role: "user", content: `[system] ${m.content}` } : { role: m.role, content: m.content }
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
#sdk() {
|
|
232
|
+
if (this.#client === void 0) {
|
|
233
|
+
this.#client = new MemoryClient({
|
|
234
|
+
apiKey: this.#opts.apiKey,
|
|
235
|
+
...this.#opts.host !== void 0 ? { host: this.#opts.host } : {},
|
|
236
|
+
...this.#opts.organizationId !== void 0 ? { organizationId: this.#opts.organizationId } : {},
|
|
237
|
+
...this.#opts.projectId !== void 0 ? { projectId: this.#opts.projectId } : {}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
return this.#client;
|
|
241
|
+
}
|
|
242
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: error-translation ladder maps provider error classes to typed codes + breaker policy (EC-K: 429 does NOT trip); inlining keeps the policy decisions in one place.
|
|
243
|
+
#translateError(err, op) {
|
|
244
|
+
if (err instanceof MemoryAdapterError) {
|
|
245
|
+
if (err.code === "rate_limited") ; else if (err.code === "auth_failed" || err.code === "not_found" || err.code === "invalid_input") ; else {
|
|
246
|
+
this.#breaker.recordFailure();
|
|
247
|
+
}
|
|
248
|
+
return err;
|
|
249
|
+
}
|
|
250
|
+
const status = err?.status ?? err?.statusCode ?? err?.response?.status;
|
|
251
|
+
const message = err?.message ?? String(err);
|
|
252
|
+
if (status === 401 || status === 403) {
|
|
253
|
+
return new MemoryAdapterError(`Mem0 auth failed (${op}): ${message}`, {
|
|
254
|
+
adapterId: ADAPTER_ID2,
|
|
255
|
+
code: "auth_failed",
|
|
256
|
+
cause: err
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
if (status === 429) {
|
|
260
|
+
return new MemoryAdapterError(`Mem0 rate limited (${op}): ${message}`, {
|
|
261
|
+
adapterId: ADAPTER_ID2,
|
|
262
|
+
code: "rate_limited",
|
|
263
|
+
cause: err
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
if (status === 404) {
|
|
267
|
+
return new MemoryAdapterError(`Mem0 not found (${op}): ${message}`, {
|
|
268
|
+
adapterId: ADAPTER_ID2,
|
|
269
|
+
code: "not_found",
|
|
270
|
+
cause: err
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
if (typeof status === "number" && status >= 500) {
|
|
274
|
+
this.#breaker.recordFailure();
|
|
275
|
+
return new MemoryAdapterError(`Mem0 server error (${op}): ${message}`, {
|
|
276
|
+
adapterId: ADAPTER_ID2,
|
|
277
|
+
code: "network",
|
|
278
|
+
cause: err
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
if (status === void 0 && message.toLowerCase().includes("network")) {
|
|
282
|
+
this.#breaker.recordFailure();
|
|
283
|
+
return new MemoryAdapterError(`Mem0 network error (${op}): ${message}`, {
|
|
284
|
+
adapterId: ADAPTER_ID2,
|
|
285
|
+
code: "network",
|
|
286
|
+
cause: err
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
return new MemoryAdapterError(`Mem0 error (${op}): ${message}`, {
|
|
290
|
+
adapterId: ADAPTER_ID2,
|
|
291
|
+
code: "unknown",
|
|
292
|
+
cause: err
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// src/index.ts
|
|
298
|
+
function mem0Memory(options) {
|
|
299
|
+
return definePlugin({
|
|
300
|
+
name: "@theokit/memory-mem0",
|
|
301
|
+
version: "0.1.0",
|
|
302
|
+
kind: "memory",
|
|
303
|
+
createProvider: () => new Mem0Adapter(options)
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export { mem0Memory };
|
|
308
|
+
//# sourceMappingURL=index.js.map
|
|
309
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/circuit-breaker.ts","../src/translate.ts","../src/adapter.ts","../src/index.ts"],"names":["ADAPTER_ID","MemoryAdapterError"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * In-memory circuit breaker for Mem0Adapter (T5.1, EC-K).\n *\n * Trips after `threshold` consecutive 5xx-class failures. 429 / 401 /\n * 404 / invalid_input do NOT count toward the threshold — rate limits\n * are a caller-pace signal, not a provider-down signal (EC-K).\n *\n * @internal\n */\n\nimport { MemoryAdapterError } from \"@theokit/sdk\";\n\nconst ADAPTER_ID = \"mem0\";\n\nexport interface CircuitBreakerOptions {\n threshold?: number;\n cooldownMs?: number;\n}\n\nexport class CircuitBreaker {\n readonly threshold: number;\n readonly cooldownMs: number;\n #failures = 0;\n #openUntil = 0;\n\n constructor(opts: CircuitBreakerOptions = {}) {\n this.threshold = opts.threshold ?? 5;\n this.cooldownMs = opts.cooldownMs ?? 2 * 60 * 1000;\n }\n\n /** Throws `MemoryAdapterError(code: \"rate_limited\")` if breaker is open. */\n ensureClosed(op: string): void {\n if (Date.now() < this.#openUntil) {\n const secondsLeft = Math.ceil((this.#openUntil - Date.now()) / 1000);\n throw new MemoryAdapterError(\n `Mem0 circuit breaker open (${op}): ${secondsLeft}s cooldown remaining.`,\n { adapterId: ADAPTER_ID, code: \"rate_limited\" },\n );\n }\n }\n\n /** Increment failure counter. Trips when threshold reached. Only call for 5xx-class errors. */\n recordFailure(): void {\n this.#failures += 1;\n if (this.#failures >= this.threshold) {\n this.#openUntil = Date.now() + this.cooldownMs;\n }\n }\n\n /** Reset on first success — closes the breaker (EC-K). */\n recordSuccess(): void {\n this.#failures = 0;\n this.#openUntil = 0;\n }\n\n /** Test-only inspector. @internal */\n state(): { failures: number; isOpen: boolean; openUntil: number } {\n return {\n failures: this.#failures,\n isOpen: Date.now() < this.#openUntil,\n openUntil: this.#openUntil,\n };\n }\n}\n","/**\n * `MemoryContext` → Mem0 add/search options translation (T5.1).\n *\n * Mem0 keeps `user_id`, `agent_id`, `app_id`, `run_id` orthogonal —\n * we map each `MemoryContext` field onto its native primitive.\n *\n * @internal\n */\n\nimport type { MemoryContext } from \"@theokit/sdk\";\n\ninterface Mem0Options {\n user_id?: string;\n agent_id?: string;\n run_id?: string;\n app_id?: string;\n categories?: string[];\n metadata?: Record<string, unknown>;\n}\n\nexport function toMem0Options(ctx: MemoryContext): Mem0Options {\n const out: Mem0Options = { user_id: ctx.userId };\n if (ctx.agentId !== undefined) out.agent_id = ctx.agentId;\n if (ctx.sessionId !== undefined) out.run_id = ctx.sessionId;\n if (ctx.tenantId !== undefined) out.app_id = ctx.tenantId;\n if (ctx.tags !== undefined) out.categories = ctx.tags;\n if (ctx.metadata !== undefined) out.metadata = ctx.metadata;\n return out;\n}\n","/**\n * Mem0Adapter — `@theokit/memory-mem0` core (T5.1, ADR D141 / D148).\n *\n * Wraps `mem0ai` `MemoryClient` (cloud-only per D148). Implements\n * `MemoryAdapter` with the unique `history(id)` capability — the only\n * adapter today that exposes per-memory versioning.\n *\n * Includes a circuit breaker (EC-K: 5xx counts; 429 does NOT trip).\n *\n * @public\n */\n\nimport {\n extractRawId,\n type MemoryAdapter,\n type MemoryAdapterCapabilities,\n MemoryAdapterError,\n type MemoryContext,\n type MemoryFact,\n type MemoryId,\n type MemoryRevision,\n type MemoryToolSchema,\n type MemoryTurnMessage,\n mkMemoryId,\n} from \"@theokit/sdk\";\nimport MemoryClient from \"mem0ai\";\n\nimport { CircuitBreaker, type CircuitBreakerOptions } from \"./circuit-breaker.js\";\nimport { toMem0Options } from \"./translate.js\";\n\n/** Configuration accepted by the `mem0Memory(...)` factory. @public */\nexport interface Mem0AdapterOptions {\n /** Mem0 API key. Required. */\n apiKey: string;\n /** Override host (default mem0 cloud). */\n host?: string;\n organizationId?: string;\n projectId?: string;\n /** Circuit breaker tuning (EC-K). */\n breaker?: CircuitBreakerOptions;\n}\n\nconst ADAPTER_ID = \"mem0\";\n\nconst CAPS: MemoryAdapterCapabilities = {\n history: true, // ← unique to Mem0\n sessions: true,\n tenancy: true,\n reasoning: false,\n toolSchemas: true,\n prefetch: false,\n};\n\n/** @internal */\nexport class Mem0Adapter implements MemoryAdapter {\n readonly id = ADAPTER_ID;\n readonly capabilities = CAPS;\n readonly #opts: Mem0AdapterOptions;\n readonly #breaker: CircuitBreaker;\n #client?: MemoryClient;\n\n constructor(opts: Mem0AdapterOptions) {\n this.#opts = opts;\n this.#breaker = new CircuitBreaker(opts.breaker);\n }\n\n isAvailable(): boolean {\n return typeof this.#opts.apiKey === \"string\" && this.#opts.apiKey.length > 0;\n }\n\n async initialize(): Promise<void> {\n // Lazy: client constructed on first call.\n }\n\n async write(content: string | MemoryTurnMessage[], ctx: MemoryContext): Promise<MemoryId> {\n this.#breaker.ensureClosed(\"write\");\n const messages = this.#toMessages(content);\n if (messages.length === 0) {\n throw new MemoryAdapterError(\"write: empty messages\", {\n adapterId: ADAPTER_ID,\n code: \"invalid_input\",\n });\n }\n try {\n const opts = toMem0Options(ctx);\n const resp = await this.#sdk().add(messages, opts);\n this.#breaker.recordSuccess();\n const first = resp[0];\n const rawId = first?.id ?? `mem0-${Date.now()}`;\n return mkMemoryId(ADAPTER_ID, rawId);\n } catch (err) {\n throw this.#translateError(err, \"write\");\n }\n }\n\n async recall(query: string, ctx: MemoryContext, k = 10): Promise<MemoryFact[]> {\n if (k <= 0) return [];\n this.#breaker.ensureClosed(\"recall\");\n try {\n const opts = toMem0Options(ctx);\n const resp = await this.#sdk().search(query, {\n // Read filter: cross-session recall keyed by user_id (Hermes pattern).\n ...(opts.user_id !== undefined ? { filters: { user_id: opts.user_id } } : {}),\n topK: k,\n rerank: true,\n });\n this.#breaker.recordSuccess();\n const list = Array.isArray(resp) ? resp : ((resp as { results?: unknown[] }).results ?? []);\n return (list as Array<Record<string, unknown>>).map((r) => ({\n id: mkMemoryId(ADAPTER_ID, String(r.id ?? \"\")),\n content: String(r.memory ?? r.content ?? \"\"),\n ...(typeof r.score === \"number\" ? { score: r.score as number } : {}),\n ...(r.createdAt !== undefined ? { createdAt: String(r.createdAt) } : {}),\n ...(r.metadata !== undefined ? { metadata: r.metadata as Record<string, unknown> } : {}),\n }));\n } catch (err) {\n throw this.#translateError(err, \"recall\");\n }\n }\n\n async delete(id: MemoryId): Promise<void> {\n this.#breaker.ensureClosed(\"delete\");\n const rawId = extractRawId(id, ADAPTER_ID);\n try {\n await this.#sdk().delete(rawId);\n this.#breaker.recordSuccess();\n } catch (err) {\n throw this.#translateError(err, \"delete\");\n }\n }\n\n async history(id: MemoryId): Promise<MemoryRevision[]> {\n this.#breaker.ensureClosed(\"history\");\n const rawId = extractRawId(id, ADAPTER_ID);\n try {\n const rows = await this.#sdk().history(rawId);\n this.#breaker.recordSuccess();\n return rows.map((r, i) => {\n const u = (r as unknown as { updatedAt?: unknown }).updatedAt;\n const changedAt =\n u instanceof Date\n ? u.toISOString()\n : typeof u === \"string\"\n ? u\n : new Date().toISOString();\n return {\n id: mkMemoryId(ADAPTER_ID, r.memoryId ?? rawId),\n content: String(r.newMemory ?? r.oldMemory ?? \"\"),\n version: i + 1,\n changedAt,\n };\n });\n } catch (err) {\n throw this.#translateError(err, \"history\");\n }\n }\n\n getToolSchemas(): MemoryToolSchema[] {\n return [\n {\n name: \"memory_write\",\n description:\n \"Persist a turn to Mem0 long-term memory. Server-side extraction populates facts.\",\n parameters: {\n type: \"object\",\n properties: {\n content: { type: \"string\", description: \"Turn text to persist.\" },\n },\n required: [\"content\"],\n },\n },\n {\n name: \"memory_recall\",\n description: \"Retrieve up to k semantically relevant facts from Mem0 (server-side rerank).\",\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\" },\n k: { type: \"integer\", minimum: 1, maximum: 50 },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"memory_history\",\n description:\n \"Retrieve the version history of a specific memory by id. Mem0-unique capability — \" +\n \"shows how a fact has evolved over time (e.g., user changed preferences).\",\n parameters: {\n type: \"object\",\n properties: { memoryId: { type: \"string\" } },\n required: [\"memoryId\"],\n },\n },\n ];\n }\n\n async handleToolCall(\n name: string,\n args: Record<string, unknown>,\n ctx: MemoryContext,\n ): Promise<string> {\n if (name === \"memory_write\") {\n const id = await this.write(String(args.content ?? \"\"), ctx);\n return JSON.stringify({ ok: true, id });\n }\n if (name === \"memory_recall\") {\n const k = typeof args.k === \"number\" ? args.k : 10;\n const facts = await this.recall(String(args.query ?? \"\"), ctx, k);\n return JSON.stringify({ ok: true, facts });\n }\n if (name === \"memory_history\") {\n const rawId = String(args.memoryId ?? \"\");\n const wrapped = rawId.startsWith(`${ADAPTER_ID}:`)\n ? (rawId as MemoryId)\n : mkMemoryId(ADAPTER_ID, rawId);\n const revisions = await this.history(wrapped);\n return JSON.stringify({ ok: true, revisions });\n }\n throw new MemoryAdapterError(`Unknown tool name: ${name}`, {\n adapterId: ADAPTER_ID,\n code: \"invalid_input\",\n });\n }\n\n async shutdown(): Promise<void> {\n this.#client = undefined;\n }\n\n /** Test-only: inspect breaker state. @internal */\n _breakerState(): { failures: number; isOpen: boolean; openUntil: number } {\n return this.#breaker.state();\n }\n\n // ── helpers ────────────────────────────────────────────────────────\n\n #toMessages(\n content: string | MemoryTurnMessage[],\n ): Array<{ role: \"user\" | \"assistant\"; content: string }> {\n if (typeof content === \"string\") {\n return content.trim().length === 0 ? [] : [{ role: \"user\", content }];\n }\n // Mem0 SDK accepts only user/assistant roles. System turns are merged\n // into user content with a \"[system] \" prefix.\n return content\n .filter((m) => m.content.trim().length > 0)\n .map((m) =>\n m.role === \"system\"\n ? { role: \"user\" as const, content: `[system] ${m.content}` }\n : { role: m.role, content: m.content },\n );\n }\n\n #sdk(): MemoryClient {\n if (this.#client === undefined) {\n this.#client = new MemoryClient({\n apiKey: this.#opts.apiKey,\n ...(this.#opts.host !== undefined ? { host: this.#opts.host } : {}),\n ...(this.#opts.organizationId !== undefined\n ? { organizationId: this.#opts.organizationId }\n : {}),\n ...(this.#opts.projectId !== undefined ? { projectId: this.#opts.projectId } : {}),\n });\n }\n return this.#client;\n }\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: error-translation ladder maps provider error classes to typed codes + breaker policy (EC-K: 429 does NOT trip); inlining keeps the policy decisions in one place.\n #translateError(err: unknown, op: string): MemoryAdapterError {\n if (err instanceof MemoryAdapterError) {\n if (err.code === \"rate_limited\") {\n // EC-K: do NOT trip breaker on rate limit.\n } else if (\n err.code === \"auth_failed\" ||\n err.code === \"not_found\" ||\n err.code === \"invalid_input\"\n ) {\n // No trip — these are caller-side or stateful conditions.\n } else {\n this.#breaker.recordFailure();\n }\n return err;\n }\n const status =\n (err as { status?: number; statusCode?: number; response?: { status?: number } })?.status ??\n (err as { statusCode?: number })?.statusCode ??\n (err as { response?: { status?: number } })?.response?.status;\n const message = (err as Error)?.message ?? String(err);\n if (status === 401 || status === 403) {\n return new MemoryAdapterError(`Mem0 auth failed (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"auth_failed\",\n cause: err,\n });\n }\n if (status === 429) {\n // EC-K: rate-limited; do NOT increment breaker.\n return new MemoryAdapterError(`Mem0 rate limited (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"rate_limited\",\n cause: err,\n });\n }\n if (status === 404) {\n return new MemoryAdapterError(`Mem0 not found (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"not_found\",\n cause: err,\n });\n }\n if (typeof status === \"number\" && status >= 500) {\n this.#breaker.recordFailure();\n return new MemoryAdapterError(`Mem0 server error (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"network\",\n cause: err,\n });\n }\n if (status === undefined && message.toLowerCase().includes(\"network\")) {\n this.#breaker.recordFailure();\n return new MemoryAdapterError(`Mem0 network error (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"network\",\n cause: err,\n });\n }\n return new MemoryAdapterError(`Mem0 error (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"unknown\",\n cause: err,\n });\n }\n}\n","/**\n * `@theokit/memory-mem0` — Mem0 cloud memory adapter for @theokit/sdk.\n *\n * Cloud-only per ADR D148. Wraps `mem0ai` `MemoryClient`. Unique\n * capability among `@theokit/memory-*` adapters: `history(id)`.\n *\n * @public\n */\n\nimport type { Plugin } from \"@theokit/sdk\";\nimport { definePlugin } from \"@theokit/sdk\";\n\nimport { Mem0Adapter, type Mem0AdapterOptions } from \"./adapter.js\";\n\nexport type { Mem0AdapterOptions } from \"./adapter.js\";\n\n/** Build a `Plugin { kind: \"memory\" }`. @public */\nexport function mem0Memory(options: Mem0AdapterOptions): Plugin {\n return definePlugin({\n name: \"@theokit/memory-mem0\",\n version: \"0.1.0\",\n kind: \"memory\",\n createProvider: () => new Mem0Adapter(options),\n });\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@theokit/memory-mem0",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Mem0 cloud memory adapter for @theokit/sdk — wraps mem0ai MemoryClient with the MemoryAdapter contract (ADR D141).",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.12.0"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.cjs",
|
|
11
|
+
"module": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"require": {
|
|
20
|
+
"types": "./dist/index.d.cts",
|
|
21
|
+
"default": "./dist/index.cjs"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE",
|
|
29
|
+
"CHANGELOG.md"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"test": "vitest run"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"@theokit/sdk": "workspace:^",
|
|
38
|
+
"mem0ai": "^3.0.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@theokit/sdk": "workspace:*",
|
|
42
|
+
"mem0ai": "^3.0.3",
|
|
43
|
+
"tsup": "^8.5.0",
|
|
44
|
+
"typescript": "^5.8.0",
|
|
45
|
+
"vitest": "^3.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|