@theokit/memory-mem0 3.0.2 → 3.0.4-next.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 CHANGED
@@ -1,5 +1,139 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.0.4-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [01630ec]
8
+ - @theokit/sdk@4.63.4-next.0
9
+
10
+ ## 3.0.3
11
+
12
+ ### Patch Changes
13
+
14
+ - e3f2a82: Public-API documentation reviewed file by file, and corrected wherever it disagreed
15
+ with the code. The docblocks ship in the `.d.ts`, so these read as behaviour changes
16
+ in an editor even though no behaviour changed.
17
+
18
+ The corrections that change what a caller would do:
19
+
20
+ - **`sdk-cache` documented its own premise backwards.** The header example labelled a
21
+ semantic hit as if it avoided the provider call. `asPlugin()` returns the cached
22
+ answer as `recalledContext`, which the agent loop injects as a `<memory-context>`
23
+ block _before_ the prompt — the request still goes to the provider. The two modes
24
+ are now labelled separately, with a table saying which one short-circuits and which
25
+ one seeds.
26
+ - **`sdk-handoff`'s five error classes said "throw".** Under the plugin wiring the
27
+ handler never throws; every failure becomes a tool result `{"ok":false,…}` handed
28
+ back to the model. Each class now says where it is actually observable. The header
29
+ also told readers to `import { Handoff } from "@theokit/sdk"`, from which it was
30
+ extracted.
31
+ - **`sdk-budget`'s `charge()` claimed idempotency across concurrent calls.** The mutex
32
+ serialises, it does not deduplicate: two identical calls record twice. Related, and
33
+ newly documented: with `maxUsd` set, a model missing from the pricing table denies
34
+ every request rather than passing it — and the table matches by exact string, so
35
+ `"openai/gpt-4o"` does not match `"gpt-4o"`.
36
+ - **The three `memory-*` adapters advertised an env-var fallback they do not read**,
37
+ and their peer dependencies are required rather than optional. Their behavioural
38
+ differences are now stated where they break the "interchangeable adapter"
39
+ assumption — honcho ignores `k` and always throws on `delete`; mem0 recalls across
40
+ sessions by design; supermemory ignores `sessionId` entirely.
41
+ - **`sdk-memory`'s `truncated` flag was documented as its own inverse**, and its
42
+ dreaming sweep claimed a mutex it never takes against the writer it names.
43
+ - **`sdk-tools`** corrected `run_vitest`'s unreachable `no_vitest` code, `truncation`'s
44
+ replacement-character claim, and two return shapes missing a live error code.
45
+ - **`acp`/`cli`** corrected sixteen statements including a named error class that is
46
+ not the one raised, a handler documented as calling `fork()` that refuses
47
+ unconditionally, handlers described as pure that mint ids and mutate a store, a
48
+ config loader credited to Zod in a package that does not import it, and a `--force`
49
+ scaffold described as atomic that deletes the destination before the rename.
50
+
51
+ Undocumented public symbols were documented across every package, with each claim
52
+ checked against the implementation rather than inferred from the name.
53
+
54
+ - e368fc1: Every published declaration file now compiles without `skipLibCheck` (#345). The
55
+ DTS rollup emitted symbols as a re-export from a chunk while omitting them from
56
+ that chunk's `import`, and dropped type-only imports from external packages —
57
+ leaving 51 unresolved references across ten of the twelve packages. Nothing broke
58
+ at runtime, and `tsc` stayed green for anyone with `skipLibCheck` on, but a
59
+ consumer running type-aware lint saw every type reached through one degrade to
60
+ `error`.
61
+
62
+ The declarations are repaired at build time from the compiler's own diagnostics.
63
+ No source or API change.
64
+
65
+ - 1ac974f: **`@theokit/sdk-pty` declares its licence.** Every published version up to now shipped with no `license` field in the manifest. npm reads the field, not the directory, so the tarball was all-rights-reserved to whoever installed it — the terms were sitting in the `LICENSE` file it already shipped, saying nothing. The field now says `Apache-2.0`, which is what that file has always been and what all eleven sibling packages declare.
66
+
67
+ **Four packages now ship the licence they declare.** `@theokit/cli`, `@theokit/memory-honcho`, `@theokit/memory-mem0` and `@theokit/memory-supermemory` declared `Apache-2.0` and listed `LICENSE` in `files`, and no such file existed. npm omits a declared-but-absent path in silence, so every published tarball asserted the licence while carrying none of its terms — and §4(a) requires a copy to travel with the distribution. The file is there now, byte-identical to the one the other packages ship.
68
+
69
+ **Six packages complete the rest of their published metadata.** Each field is here for what its absence costs a consumer:
70
+
71
+ - `homepage` and `bugs` — the npm page renders both; without them someone who hits a defect has no route back to the project.
72
+ - `engines.node` — npm warns on an unsupported runtime only when the range is declared. `@theokit/sdk-pty` declared none, so a Node 18 install failed later and somewhere unrelated.
73
+ - `sideEffects` — a bundler keeps every module of a package that stays silent. Declared only after checking: a clean scan of each built ESM entry found zero top-level statements, the residual hits being closing tokens of declarations. `@theokit/sdk` keeps its path-array form, which is the honest shape for a package whose agent entry registers on import.
74
+ - `publishConfig.access` — a scoped package defaults to `restricted`. Three declared none and reached npm public only because the release flow supplied the flag; the manifest states it now instead of depending on how it is invoked.
75
+ - `@theokit/sdk-pty` also ships its `CHANGELOG.md`, which existed on disk and was absent from `files`.
76
+
77
+ The gate that should have caught any of this covered three packages out of twelve, by way of a hand-written list. It now derives the list from `packages/`, asserts the whole contract, and fails when the sweep discovers nothing rather than passing by having nothing to check.
78
+
79
+ - 926a2a6: Two adapters could not work against the real vendor APIs. Both bugs were invisible to their existing
80
+ tests, because those tests replaced the vendor SDK with a hand-written mock and asserted against the
81
+ mock's shape rather than the vendor's.
82
+
83
+ **The Honcho adapter could not talk to a Honcho server at all.** It built session identifiers as
84
+ `userId:session`, and the vendor SDK's schema rejects every character outside letters, digits,
85
+ underscore and hyphen — a colon is illegal. Every `write()` and every `recall()` raised a validation
86
+ error before a single HTTP request left the process. The separator is now `--`. No migration is
87
+ needed and none is possible: because the old identifier was rejected at the boundary, no session was
88
+ ever created under it.
89
+
90
+ **The Mem0 adapter misclassified every vendor error.** It read `status` and `statusCode` off thrown
91
+ errors; the vendor sets neither, carrying the code as `errorCode: "HTTP_429"` instead. So every real
92
+ failure fell through to an unknown classification — rate limits never received the rate-limit
93
+ exemption, and server errors never counted toward the circuit breaker, which is precisely the
94
+ protection those classifications exist to provide. The status is now derived from the vendor's own
95
+ field as well.
96
+
97
+ The reason neither surfaced earlier is worth stating: the existing test mocked the vendor and
98
+ fabricated a `status` property on thrown errors — a value the real library never produces. The test
99
+ asserted the adapter reads a field the mock invented.
100
+
101
+ All three cloud memory adapters now carry a recorded-wire contract test that pins the actual request
102
+ put on the wire and the vendor response shape it must survive, plus a live smoke that runs when a
103
+ vendor key is present and reports itself as skipped, with the reason, when one is not.
104
+
105
+ - e699569: **The repository moved to the official `usetheokit` organization.** Every `repository`, `bugs` and `homepage` field now points there, along with the README, `CONTRIBUTING.md`, `SECURITY.md` and the issue templates. Existing clones and any URL already published keep working — GitHub redirects a transferred repository permanently — so this is a correctness fix for the metadata npm renders, not a break.
106
+
107
+ **The Apache-2.0 text every package ships was replaced with the official one.** The copy distributed until now had paragraph 4(d) truncated: it read "except as required for describing the origin of the Work and reproducing the content of the NOTICE file", dropping "reasonable and customary use" from the licensed clause. §4(d) governs what a redistributor must do with attribution notices, and the omission narrowed it.
108
+
109
+ That matters more than a typo would. The manifests declare the SPDX identifier `Apache-2.0`, which is an assertion that the terms are _the_ Apache-2.0 terms — a licence scanner resolves the identifier and never reads the file. A consumer's compliance review, which does read the file, would find a body that no longer matches the identifier and has no name of its own. Every `LICENSE` in this repository is now byte-identical to the canonical text, with the appendix filled in.
110
+
111
+ Nothing else about the terms changed: the licence is the same licence it has always been meant to be, and no package changes what it grants.
112
+
113
+ - c7385d2: Test runs no longer claim every core on the host.
114
+
115
+ None of the package configs capped `maxWorkers`, so vitest's default applied: `os.availableParallelism()`,
116
+ one fork per core, each booting a full test environment. The repo's `test` script is
117
+ `turbo run test --filter='./packages/*'`, so that default is paid once per package _concurrently_ —
118
+ nproc forks times turbo's concurrency, on nproc cores. Measured on a 12-thread machine during an
119
+ unrelated investigation, two vitest pools alone were enough to reach load average 33.89 with the
120
+ desktop unusable; a full fan-out is several times that.
121
+
122
+ `@theokit/sdk` is the interesting case. B-104 recorded on 2026-08-19 that the `poolOptions.forks.*`
123
+ block was 100% dead in Vitest 4, deleted it, and noted that `fileParallelism: false` was forcing
124
+ `maxWorkers` to 1 unconditionally, so a fork-count knob could not act. B-059 then flipped
125
+ `fileParallelism` to `true` on 2026-08-20, which made the knob able to act again — and nothing
126
+ reintroduced one, so the package silently went back to the uncapped default. That comment has been
127
+ corrected along with the config; it claimed no knob existed, which is no longer true.
128
+
129
+ The cap leaves 4 cores free (`Math.max(2, cpus().length - 4)`), scaling with the runner rather than
130
+ hard-coding one machine's core count. It costs no wall-clock: measured in `theokit-ui`, the full
131
+ suite ran 73.96s at 4 workers against 74.36s at 12, so the parallelism above the cap was already
132
+ noise. Verified as resolved config rather than as file contents — `createVitest` reports
133
+ `maxWorkers: 8` on a 12-thread host, which is the formula, not the default.
134
+
135
+ This changes no published behaviour; it is test tooling only. Refs usetheokit/theokit-ui#51.
136
+
3
137
  ## 3.0.2
4
138
 
5
139
  ### Patch Changes
package/LICENSE CHANGED
@@ -137,8 +137,8 @@
137
137
 
138
138
  6. Trademarks. This License does not grant permission to use the trade
139
139
  names, trademarks, service marks, or product names of the Licensor,
140
- except as required for describing the origin of the Work and
141
- reproducing the content of the NOTICE file.
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
142
 
143
143
  7. Disclaimer of Warranty. Unless required by applicable law or
144
144
  agreed to in writing, Licensor provides the Work (and each
package/README.md CHANGED
@@ -88,13 +88,32 @@ const b = await Agent.create({ plugins: [sharedPlugin] });
88
88
 
89
89
  ## Failure modes
90
90
 
91
- | HTTP status | Maps to | Trips breaker? |
91
+ | What was thrown | Maps to | Trips breaker? |
92
92
  |---|---|---|
93
93
  | 401 / 403 | `auth_failed` | no |
94
94
  | 429 | `rate_limited` | **no** (EC-K) |
95
95
  | 404 | `not_found` | no |
96
96
  | 5xx | `network` | yes |
97
- | Network/timeout | `network` | yes |
97
+ | No status, message contains "network" | `network` | yes |
98
+ | No status, any other message (e.g. `"fetch failed"`) | `unknown` | **no** |
99
+
100
+ The status is read from `.status`, `.statusCode`, `.response.status`, or an `errorCode` of the form
101
+ `HTTP_<nnn>` — the last is what `mem0ai` actually attaches. Transport failures are recognised only
102
+ by the literal substring `network` in the message, so a DNS or connection error worded differently
103
+ lands in `unknown` and leaves the breaker closed.
104
+
105
+ ## API reference
106
+
107
+ Every symbol this package exports, with the exact specifier to import it from, is in the generated
108
+ capability map that ships inside `@theokit/sdk`:
109
+
110
+ ```
111
+ node_modules/@theokit/sdk/docs/harness-capability-map.md # symbol -> import specifier
112
+ node_modules/@theokit/sdk/docs/error-codes.md # every `code` an error can carry
113
+ ```
114
+
115
+ Both are generated from the built type declarations, so they describe the version you installed
116
+ rather than the version someone wrote a page about.
98
117
 
99
118
  ## License
100
119
 
package/dist/index.cjs CHANGED
@@ -28,7 +28,7 @@ var CircuitBreaker = class {
28
28
  );
29
29
  }
30
30
  }
31
- /** Increment failure counter. Trips when threshold reached. Only call for 5xx-class errors. */
31
+ /** Increment failure counter. Trips when threshold reached. Call only for provider-down errors. */
32
32
  recordFailure() {
33
33
  this.#failures += 1;
34
34
  if (this.#failures >= this.threshold) {
@@ -253,7 +253,9 @@ var Mem0Adapter = class {
253
253
  }
254
254
  return err;
255
255
  }
256
- const status = err?.status ?? err?.statusCode ?? err?.response?.status;
256
+ const errorCode = err?.errorCode;
257
+ const statusFromErrorCode = typeof errorCode === "string" && /^HTTP_(\d{3})$/.test(errorCode) ? Number(errorCode.slice(5)) : void 0;
258
+ const status = err?.status ?? err?.statusCode ?? err?.response?.status ?? statusFromErrorCode;
257
259
  const message = err?.message ?? String(err);
258
260
  if (status === 401 || status === 403) {
259
261
  return new sdk.MemoryAdapterError(`Mem0 auth failed (${op}): ${message}`, {
@@ -1 +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","Plugin"],"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","import { Plugin } 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 Plugin.create({\n name: \"@theokit/memory-mem0\",\n version: \"0.1.0\",\n kind: \"memory\",\n createProvider: () => new Mem0Adapter(options),\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/circuit-breaker.ts","../src/translate.ts","../src/adapter.ts","../src/index.ts"],"names":["MemoryAdapterError","ADAPTER_ID","mkMemoryId","extractRawId","MemoryClient","Plugin"],"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 failures that `Mem0Adapter#translateError`\n * decides are provider-down signals: an HTTP 5xx, or a status-less error whose\n * message contains \"network\". 429 / 401 / 403 / 404 / invalid_input do NOT count\n * toward the threshold — rate limits are a caller-pace signal, not a\n * provider-down signal (EC-K).\n *\n * @internal\n */\n\nimport { MemoryAdapterError } from \"@theokit/sdk\";\n\nconst ADAPTER_ID = \"mem0\";\n\n/**\n * Tuning for the Mem0 adapter's circuit breaker, passed as `mem0Memory({ breaker })`.\n *\n * @public\n */\nexport interface CircuitBreakerOptions {\n /**\n * Failures required to open the breaker. Default `5`.\n *\n * TWO kinds of failure count, not one: an HTTP 5xx, and a status-less error whose message\n * contains the substring `network` (case-insensitive) — that substring match is the only way a\n * transport failure is recognised, so a DNS/connection error surfacing as `\"fetch failed\"` maps\n * to `code: \"unknown\"` and does NOT count. 429 / 401 / 403 / 404 / `invalid_input` never count.\n *\n * Size it for transport flakiness as well as for Mem0 outages: with `threshold: 5`, five\n * consecutive `network`-shaped errors open the breaker exactly as five 500s would, and the\n * resulting error says `rate_limited`, which is not what caused it.\n *\n * A single success resets the counter to zero, so this is effectively \"consecutive counted\n * failures\" — 4 failures followed by a success followed by 4 more never trips a default breaker.\n */\n threshold?: number;\n /**\n * How long the breaker stays open, in milliseconds. Default `120000` (2 minutes).\n *\n * While open, every call fails immediately with `MemoryAdapterError(code: \"rate_limited\")`\n * without touching the network. There is no half-open probe: the breaker simply closes when the\n * cooldown elapses and the next call goes through for real.\n */\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. Call only for provider-down 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/**\n * Configuration accepted by the `mem0Memory(...)` factory.\n *\n * @public\n */\nexport interface Mem0AdapterOptions {\n /**\n * Mem0 API key. Genuinely required — `mem0ai` reads no `MEM0_API_KEY` environment variable, so\n * there is no fallback anywhere in the chain.\n *\n * The client is built lazily on the first `write` / `recall`, so a wrong key does not fail\n * `Agent.create`; it surfaces as `MemoryAdapterError(code: \"auth_failed\")` on the first call.\n */\n apiKey: string;\n /** Alternate Mem0 API host. Omit for Mem0 cloud, which is the vendor default. */\n host?: string;\n /** Mem0 organization to scope writes to. Forwarded only when set. */\n organizationId?: string;\n /** Mem0 project to scope writes to. Forwarded only when set. */\n projectId?: string;\n /**\n * Circuit-breaker tuning. Defaults: trip after 5 failures, 2-minute cooldown.\n *\n * The breaker is PER ADAPTER INSTANCE — one `mem0Memory(...)` call, one breaker. Two agents\n * built from two separate factory calls do not share it, so one agent tripping does not\n * protect the other.\n */\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 // The real mem0ai SDK does NOT attach `.status`/`.statusCode`/`.response.status` to its\n // thrown errors (verified against mem0ai@3.0.3's `createExceptionFromResponse`, which builds\n // `RateLimitError`/`AuthenticationError`/etc. carrying only `.errorCode` as a string like\n // `\"HTTP_429\"`). Without this fallback, every real vendor error fell through to `status ===\n // undefined` and was misclassified as `code: \"unknown\"` — 429s never got the EC-K rate-limit\n // exemption and 5xx never tripped the breaker. Caught by wire-contract.test.ts running the\n // real SDK; the old hand-written `vi.mock` fabricated `.status` on its thrown errors, which\n // is why this never failed a test.\n const errorCode = (err as { errorCode?: unknown })?.errorCode;\n const statusFromErrorCode =\n typeof errorCode === \"string\" && /^HTTP_(\\d{3})$/.test(errorCode)\n ? Number(errorCode.slice(5))\n : undefined;\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 statusFromErrorCode;\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","import { Plugin } from \"@theokit/sdk\";\n\nimport { Mem0Adapter, type Mem0AdapterOptions } from \"./adapter.js\";\n\nexport type { Mem0AdapterOptions } from \"./adapter.js\";\n\n/**\n * Wire Mem0 cloud as the agent's long-term memory.\n *\n * ```ts\n * const agent = await Agent.create({\n * model: { id: \"openai/gpt-4o-mini\" },\n * plugins: [mem0Memory({ apiKey: process.env.MEM0_API_KEY! })],\n * });\n * ```\n *\n * Needs `mem0ai@^3.0.0` — a REQUIRED peer dependency, not an optional one; without it the import\n * throws at load time. Cloud only: `MemoryClient` talks to Mem0's hosted API, and `mem0ai` has no\n * `MEM0_API_KEY` environment fallback, so {@link Mem0AdapterOptions.apiKey} must be supplied.\n *\n * What this adapter gives you that the others do not, and what to watch for:\n *\n * - **`history(id)` works** (`capabilities.history === true`) — it is the only adapter in the\n * ecosystem that exposes per-memory versioning, and it backs the extra `memory_history` tool\n * offered to the model.\n * - **`recall` is CROSS-SESSION on purpose.** Writes carry `run_id = ctx.sessionId`, but the\n * search filter is `user_id` alone, so a recall in session B returns memories written in\n * session A. If you need per-session isolation, use distinct `ctx.userId` values — `sessionId`\n * will not give it to you.\n * - **`recall` defaults to `k = 10`** with server-side rerank; `write` returns the id of the first\n * memory Mem0's server-side extraction produced, which need not be the text you sent.\n * - **`system` turns are rewritten.** Mem0 accepts only `user` / `assistant`, so a\n * `MemoryTurnMessage` with `role: \"system\"` is sent as a `user` turn prefixed with `[system] `.\n *\n * Trap — the circuit breaker reports itself as a RATE LIMIT. After\n * {@link Mem0AdapterOptions.breaker} trips, every call throws\n * `MemoryAdapterError(code: \"rate_limited\")` with a message naming the remaining cooldown, even\n * though the cause was a 5xx or a transport failure and no request was sent. Match on the message,\n * or on the fact that the failure is instantaneous, to tell the two apart.\n *\n * Errors are always `MemoryAdapterError` with `adapterId: \"mem0\"` and one of\n * `auth_failed` (401/403) | `rate_limited` (429 or breaker open) | `not_found` (404) |\n * `network` (5xx, or a status-less error whose message contains \"network\") | `invalid_input` |\n * `unknown` (everything else, including a transport error reported as `\"fetch failed\"`).\n * Both `network` shapes count toward {@link Mem0AdapterOptions.breaker}; `unknown` does not.\n *\n * @public\n */\nexport function mem0Memory(options: Mem0AdapterOptions): Plugin {\n return Plugin.create({\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 CHANGED
@@ -3,14 +3,43 @@ import { Plugin } from '@theokit/sdk';
3
3
  /**
4
4
  * In-memory circuit breaker for Mem0Adapter (T5.1, EC-K).
5
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).
6
+ * Trips after `threshold` consecutive failures that `Mem0Adapter#translateError`
7
+ * decides are provider-down signals: an HTTP 5xx, or a status-less error whose
8
+ * message contains "network". 429 / 401 / 403 / 404 / invalid_input do NOT count
9
+ * toward the threshold — rate limits are a caller-pace signal, not a
10
+ * provider-down signal (EC-K).
9
11
  *
10
12
  * @internal
11
13
  */
14
+ /**
15
+ * Tuning for the Mem0 adapter's circuit breaker, passed as `mem0Memory({ breaker })`.
16
+ *
17
+ * @public
18
+ */
12
19
  interface CircuitBreakerOptions {
20
+ /**
21
+ * Failures required to open the breaker. Default `5`.
22
+ *
23
+ * TWO kinds of failure count, not one: an HTTP 5xx, and a status-less error whose message
24
+ * contains the substring `network` (case-insensitive) — that substring match is the only way a
25
+ * transport failure is recognised, so a DNS/connection error surfacing as `"fetch failed"` maps
26
+ * to `code: "unknown"` and does NOT count. 429 / 401 / 403 / 404 / `invalid_input` never count.
27
+ *
28
+ * Size it for transport flakiness as well as for Mem0 outages: with `threshold: 5`, five
29
+ * consecutive `network`-shaped errors open the breaker exactly as five 500s would, and the
30
+ * resulting error says `rate_limited`, which is not what caused it.
31
+ *
32
+ * A single success resets the counter to zero, so this is effectively "consecutive counted
33
+ * failures" — 4 failures followed by a success followed by 4 more never trips a default breaker.
34
+ */
13
35
  threshold?: number;
36
+ /**
37
+ * How long the breaker stays open, in milliseconds. Default `120000` (2 minutes).
38
+ *
39
+ * While open, every call fails immediately with `MemoryAdapterError(code: "rate_limited")`
40
+ * without touching the network. There is no half-open probe: the breaker simply closes when the
41
+ * cooldown elapses and the next call goes through for real.
42
+ */
14
43
  cooldownMs?: number;
15
44
  }
16
45
 
@@ -26,19 +55,78 @@ interface CircuitBreakerOptions {
26
55
  * @public
27
56
  */
28
57
 
29
- /** Configuration accepted by the `mem0Memory(...)` factory. @public */
58
+ /**
59
+ * Configuration accepted by the `mem0Memory(...)` factory.
60
+ *
61
+ * @public
62
+ */
30
63
  interface Mem0AdapterOptions {
31
- /** Mem0 API key. Required. */
64
+ /**
65
+ * Mem0 API key. Genuinely required — `mem0ai` reads no `MEM0_API_KEY` environment variable, so
66
+ * there is no fallback anywhere in the chain.
67
+ *
68
+ * The client is built lazily on the first `write` / `recall`, so a wrong key does not fail
69
+ * `Agent.create`; it surfaces as `MemoryAdapterError(code: "auth_failed")` on the first call.
70
+ */
32
71
  apiKey: string;
33
- /** Override host (default mem0 cloud). */
72
+ /** Alternate Mem0 API host. Omit for Mem0 cloud, which is the vendor default. */
34
73
  host?: string;
74
+ /** Mem0 organization to scope writes to. Forwarded only when set. */
35
75
  organizationId?: string;
76
+ /** Mem0 project to scope writes to. Forwarded only when set. */
36
77
  projectId?: string;
37
- /** Circuit breaker tuning (EC-K). */
78
+ /**
79
+ * Circuit-breaker tuning. Defaults: trip after 5 failures, 2-minute cooldown.
80
+ *
81
+ * The breaker is PER ADAPTER INSTANCE — one `mem0Memory(...)` call, one breaker. Two agents
82
+ * built from two separate factory calls do not share it, so one agent tripping does not
83
+ * protect the other.
84
+ */
38
85
  breaker?: CircuitBreakerOptions;
39
86
  }
40
87
 
41
- /** Build a `Plugin { kind: "memory" }`. @public */
88
+ /**
89
+ * Wire Mem0 cloud as the agent's long-term memory.
90
+ *
91
+ * ```ts
92
+ * const agent = await Agent.create({
93
+ * model: { id: "openai/gpt-4o-mini" },
94
+ * plugins: [mem0Memory({ apiKey: process.env.MEM0_API_KEY! })],
95
+ * });
96
+ * ```
97
+ *
98
+ * Needs `mem0ai@^3.0.0` — a REQUIRED peer dependency, not an optional one; without it the import
99
+ * throws at load time. Cloud only: `MemoryClient` talks to Mem0's hosted API, and `mem0ai` has no
100
+ * `MEM0_API_KEY` environment fallback, so {@link Mem0AdapterOptions.apiKey} must be supplied.
101
+ *
102
+ * What this adapter gives you that the others do not, and what to watch for:
103
+ *
104
+ * - **`history(id)` works** (`capabilities.history === true`) — it is the only adapter in the
105
+ * ecosystem that exposes per-memory versioning, and it backs the extra `memory_history` tool
106
+ * offered to the model.
107
+ * - **`recall` is CROSS-SESSION on purpose.** Writes carry `run_id = ctx.sessionId`, but the
108
+ * search filter is `user_id` alone, so a recall in session B returns memories written in
109
+ * session A. If you need per-session isolation, use distinct `ctx.userId` values — `sessionId`
110
+ * will not give it to you.
111
+ * - **`recall` defaults to `k = 10`** with server-side rerank; `write` returns the id of the first
112
+ * memory Mem0's server-side extraction produced, which need not be the text you sent.
113
+ * - **`system` turns are rewritten.** Mem0 accepts only `user` / `assistant`, so a
114
+ * `MemoryTurnMessage` with `role: "system"` is sent as a `user` turn prefixed with `[system] `.
115
+ *
116
+ * Trap — the circuit breaker reports itself as a RATE LIMIT. After
117
+ * {@link Mem0AdapterOptions.breaker} trips, every call throws
118
+ * `MemoryAdapterError(code: "rate_limited")` with a message naming the remaining cooldown, even
119
+ * though the cause was a 5xx or a transport failure and no request was sent. Match on the message,
120
+ * or on the fact that the failure is instantaneous, to tell the two apart.
121
+ *
122
+ * Errors are always `MemoryAdapterError` with `adapterId: "mem0"` and one of
123
+ * `auth_failed` (401/403) | `rate_limited` (429 or breaker open) | `not_found` (404) |
124
+ * `network` (5xx, or a status-less error whose message contains "network") | `invalid_input` |
125
+ * `unknown` (everything else, including a transport error reported as `"fetch failed"`).
126
+ * Both `network` shapes count toward {@link Mem0AdapterOptions.breaker}; `unknown` does not.
127
+ *
128
+ * @public
129
+ */
42
130
  declare function mem0Memory(options: Mem0AdapterOptions): Plugin;
43
131
 
44
132
  export { type Mem0AdapterOptions, mem0Memory };
package/dist/index.d.ts CHANGED
@@ -3,14 +3,43 @@ import { Plugin } from '@theokit/sdk';
3
3
  /**
4
4
  * In-memory circuit breaker for Mem0Adapter (T5.1, EC-K).
5
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).
6
+ * Trips after `threshold` consecutive failures that `Mem0Adapter#translateError`
7
+ * decides are provider-down signals: an HTTP 5xx, or a status-less error whose
8
+ * message contains "network". 429 / 401 / 403 / 404 / invalid_input do NOT count
9
+ * toward the threshold — rate limits are a caller-pace signal, not a
10
+ * provider-down signal (EC-K).
9
11
  *
10
12
  * @internal
11
13
  */
14
+ /**
15
+ * Tuning for the Mem0 adapter's circuit breaker, passed as `mem0Memory({ breaker })`.
16
+ *
17
+ * @public
18
+ */
12
19
  interface CircuitBreakerOptions {
20
+ /**
21
+ * Failures required to open the breaker. Default `5`.
22
+ *
23
+ * TWO kinds of failure count, not one: an HTTP 5xx, and a status-less error whose message
24
+ * contains the substring `network` (case-insensitive) — that substring match is the only way a
25
+ * transport failure is recognised, so a DNS/connection error surfacing as `"fetch failed"` maps
26
+ * to `code: "unknown"` and does NOT count. 429 / 401 / 403 / 404 / `invalid_input` never count.
27
+ *
28
+ * Size it for transport flakiness as well as for Mem0 outages: with `threshold: 5`, five
29
+ * consecutive `network`-shaped errors open the breaker exactly as five 500s would, and the
30
+ * resulting error says `rate_limited`, which is not what caused it.
31
+ *
32
+ * A single success resets the counter to zero, so this is effectively "consecutive counted
33
+ * failures" — 4 failures followed by a success followed by 4 more never trips a default breaker.
34
+ */
13
35
  threshold?: number;
36
+ /**
37
+ * How long the breaker stays open, in milliseconds. Default `120000` (2 minutes).
38
+ *
39
+ * While open, every call fails immediately with `MemoryAdapterError(code: "rate_limited")`
40
+ * without touching the network. There is no half-open probe: the breaker simply closes when the
41
+ * cooldown elapses and the next call goes through for real.
42
+ */
14
43
  cooldownMs?: number;
15
44
  }
16
45
 
@@ -26,19 +55,78 @@ interface CircuitBreakerOptions {
26
55
  * @public
27
56
  */
28
57
 
29
- /** Configuration accepted by the `mem0Memory(...)` factory. @public */
58
+ /**
59
+ * Configuration accepted by the `mem0Memory(...)` factory.
60
+ *
61
+ * @public
62
+ */
30
63
  interface Mem0AdapterOptions {
31
- /** Mem0 API key. Required. */
64
+ /**
65
+ * Mem0 API key. Genuinely required — `mem0ai` reads no `MEM0_API_KEY` environment variable, so
66
+ * there is no fallback anywhere in the chain.
67
+ *
68
+ * The client is built lazily on the first `write` / `recall`, so a wrong key does not fail
69
+ * `Agent.create`; it surfaces as `MemoryAdapterError(code: "auth_failed")` on the first call.
70
+ */
32
71
  apiKey: string;
33
- /** Override host (default mem0 cloud). */
72
+ /** Alternate Mem0 API host. Omit for Mem0 cloud, which is the vendor default. */
34
73
  host?: string;
74
+ /** Mem0 organization to scope writes to. Forwarded only when set. */
35
75
  organizationId?: string;
76
+ /** Mem0 project to scope writes to. Forwarded only when set. */
36
77
  projectId?: string;
37
- /** Circuit breaker tuning (EC-K). */
78
+ /**
79
+ * Circuit-breaker tuning. Defaults: trip after 5 failures, 2-minute cooldown.
80
+ *
81
+ * The breaker is PER ADAPTER INSTANCE — one `mem0Memory(...)` call, one breaker. Two agents
82
+ * built from two separate factory calls do not share it, so one agent tripping does not
83
+ * protect the other.
84
+ */
38
85
  breaker?: CircuitBreakerOptions;
39
86
  }
40
87
 
41
- /** Build a `Plugin { kind: "memory" }`. @public */
88
+ /**
89
+ * Wire Mem0 cloud as the agent's long-term memory.
90
+ *
91
+ * ```ts
92
+ * const agent = await Agent.create({
93
+ * model: { id: "openai/gpt-4o-mini" },
94
+ * plugins: [mem0Memory({ apiKey: process.env.MEM0_API_KEY! })],
95
+ * });
96
+ * ```
97
+ *
98
+ * Needs `mem0ai@^3.0.0` — a REQUIRED peer dependency, not an optional one; without it the import
99
+ * throws at load time. Cloud only: `MemoryClient` talks to Mem0's hosted API, and `mem0ai` has no
100
+ * `MEM0_API_KEY` environment fallback, so {@link Mem0AdapterOptions.apiKey} must be supplied.
101
+ *
102
+ * What this adapter gives you that the others do not, and what to watch for:
103
+ *
104
+ * - **`history(id)` works** (`capabilities.history === true`) — it is the only adapter in the
105
+ * ecosystem that exposes per-memory versioning, and it backs the extra `memory_history` tool
106
+ * offered to the model.
107
+ * - **`recall` is CROSS-SESSION on purpose.** Writes carry `run_id = ctx.sessionId`, but the
108
+ * search filter is `user_id` alone, so a recall in session B returns memories written in
109
+ * session A. If you need per-session isolation, use distinct `ctx.userId` values — `sessionId`
110
+ * will not give it to you.
111
+ * - **`recall` defaults to `k = 10`** with server-side rerank; `write` returns the id of the first
112
+ * memory Mem0's server-side extraction produced, which need not be the text you sent.
113
+ * - **`system` turns are rewritten.** Mem0 accepts only `user` / `assistant`, so a
114
+ * `MemoryTurnMessage` with `role: "system"` is sent as a `user` turn prefixed with `[system] `.
115
+ *
116
+ * Trap — the circuit breaker reports itself as a RATE LIMIT. After
117
+ * {@link Mem0AdapterOptions.breaker} trips, every call throws
118
+ * `MemoryAdapterError(code: "rate_limited")` with a message naming the remaining cooldown, even
119
+ * though the cause was a 5xx or a transport failure and no request was sent. Match on the message,
120
+ * or on the fact that the failure is instantaneous, to tell the two apart.
121
+ *
122
+ * Errors are always `MemoryAdapterError` with `adapterId: "mem0"` and one of
123
+ * `auth_failed` (401/403) | `rate_limited` (429 or breaker open) | `not_found` (404) |
124
+ * `network` (5xx, or a status-less error whose message contains "network") | `invalid_input` |
125
+ * `unknown` (everything else, including a transport error reported as `"fetch failed"`).
126
+ * Both `network` shapes count toward {@link Mem0AdapterOptions.breaker}; `unknown` does not.
127
+ *
128
+ * @public
129
+ */
42
130
  declare function mem0Memory(options: Mem0AdapterOptions): Plugin;
43
131
 
44
132
  export { type Mem0AdapterOptions, mem0Memory };
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ var CircuitBreaker = class {
22
22
  );
23
23
  }
24
24
  }
25
- /** Increment failure counter. Trips when threshold reached. Only call for 5xx-class errors. */
25
+ /** Increment failure counter. Trips when threshold reached. Call only for provider-down errors. */
26
26
  recordFailure() {
27
27
  this.#failures += 1;
28
28
  if (this.#failures >= this.threshold) {
@@ -247,7 +247,9 @@ var Mem0Adapter = class {
247
247
  }
248
248
  return err;
249
249
  }
250
- const status = err?.status ?? err?.statusCode ?? err?.response?.status;
250
+ const errorCode = err?.errorCode;
251
+ const statusFromErrorCode = typeof errorCode === "string" && /^HTTP_(\d{3})$/.test(errorCode) ? Number(errorCode.slice(5)) : void 0;
252
+ const status = err?.status ?? err?.statusCode ?? err?.response?.status ?? statusFromErrorCode;
251
253
  const message = err?.message ?? String(err);
252
254
  if (status === 401 || status === 403) {
253
255
  return new MemoryAdapterError(`Mem0 auth failed (${op}): ${message}`, {
package/dist/index.js.map CHANGED
@@ -1 +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","import { Plugin } 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 Plugin.create({\n name: \"@theokit/memory-mem0\",\n version: \"0.1.0\",\n kind: \"memory\",\n createProvider: () => new Mem0Adapter(options),\n });\n}\n"]}
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 failures that `Mem0Adapter#translateError`\n * decides are provider-down signals: an HTTP 5xx, or a status-less error whose\n * message contains \"network\". 429 / 401 / 403 / 404 / invalid_input do NOT count\n * toward the threshold — rate limits are a caller-pace signal, not a\n * provider-down signal (EC-K).\n *\n * @internal\n */\n\nimport { MemoryAdapterError } from \"@theokit/sdk\";\n\nconst ADAPTER_ID = \"mem0\";\n\n/**\n * Tuning for the Mem0 adapter's circuit breaker, passed as `mem0Memory({ breaker })`.\n *\n * @public\n */\nexport interface CircuitBreakerOptions {\n /**\n * Failures required to open the breaker. Default `5`.\n *\n * TWO kinds of failure count, not one: an HTTP 5xx, and a status-less error whose message\n * contains the substring `network` (case-insensitive) — that substring match is the only way a\n * transport failure is recognised, so a DNS/connection error surfacing as `\"fetch failed\"` maps\n * to `code: \"unknown\"` and does NOT count. 429 / 401 / 403 / 404 / `invalid_input` never count.\n *\n * Size it for transport flakiness as well as for Mem0 outages: with `threshold: 5`, five\n * consecutive `network`-shaped errors open the breaker exactly as five 500s would, and the\n * resulting error says `rate_limited`, which is not what caused it.\n *\n * A single success resets the counter to zero, so this is effectively \"consecutive counted\n * failures\" — 4 failures followed by a success followed by 4 more never trips a default breaker.\n */\n threshold?: number;\n /**\n * How long the breaker stays open, in milliseconds. Default `120000` (2 minutes).\n *\n * While open, every call fails immediately with `MemoryAdapterError(code: \"rate_limited\")`\n * without touching the network. There is no half-open probe: the breaker simply closes when the\n * cooldown elapses and the next call goes through for real.\n */\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. Call only for provider-down 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/**\n * Configuration accepted by the `mem0Memory(...)` factory.\n *\n * @public\n */\nexport interface Mem0AdapterOptions {\n /**\n * Mem0 API key. Genuinely required — `mem0ai` reads no `MEM0_API_KEY` environment variable, so\n * there is no fallback anywhere in the chain.\n *\n * The client is built lazily on the first `write` / `recall`, so a wrong key does not fail\n * `Agent.create`; it surfaces as `MemoryAdapterError(code: \"auth_failed\")` on the first call.\n */\n apiKey: string;\n /** Alternate Mem0 API host. Omit for Mem0 cloud, which is the vendor default. */\n host?: string;\n /** Mem0 organization to scope writes to. Forwarded only when set. */\n organizationId?: string;\n /** Mem0 project to scope writes to. Forwarded only when set. */\n projectId?: string;\n /**\n * Circuit-breaker tuning. Defaults: trip after 5 failures, 2-minute cooldown.\n *\n * The breaker is PER ADAPTER INSTANCE — one `mem0Memory(...)` call, one breaker. Two agents\n * built from two separate factory calls do not share it, so one agent tripping does not\n * protect the other.\n */\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 // The real mem0ai SDK does NOT attach `.status`/`.statusCode`/`.response.status` to its\n // thrown errors (verified against mem0ai@3.0.3's `createExceptionFromResponse`, which builds\n // `RateLimitError`/`AuthenticationError`/etc. carrying only `.errorCode` as a string like\n // `\"HTTP_429\"`). Without this fallback, every real vendor error fell through to `status ===\n // undefined` and was misclassified as `code: \"unknown\"` — 429s never got the EC-K rate-limit\n // exemption and 5xx never tripped the breaker. Caught by wire-contract.test.ts running the\n // real SDK; the old hand-written `vi.mock` fabricated `.status` on its thrown errors, which\n // is why this never failed a test.\n const errorCode = (err as { errorCode?: unknown })?.errorCode;\n const statusFromErrorCode =\n typeof errorCode === \"string\" && /^HTTP_(\\d{3})$/.test(errorCode)\n ? Number(errorCode.slice(5))\n : undefined;\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 statusFromErrorCode;\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","import { Plugin } from \"@theokit/sdk\";\n\nimport { Mem0Adapter, type Mem0AdapterOptions } from \"./adapter.js\";\n\nexport type { Mem0AdapterOptions } from \"./adapter.js\";\n\n/**\n * Wire Mem0 cloud as the agent's long-term memory.\n *\n * ```ts\n * const agent = await Agent.create({\n * model: { id: \"openai/gpt-4o-mini\" },\n * plugins: [mem0Memory({ apiKey: process.env.MEM0_API_KEY! })],\n * });\n * ```\n *\n * Needs `mem0ai@^3.0.0` — a REQUIRED peer dependency, not an optional one; without it the import\n * throws at load time. Cloud only: `MemoryClient` talks to Mem0's hosted API, and `mem0ai` has no\n * `MEM0_API_KEY` environment fallback, so {@link Mem0AdapterOptions.apiKey} must be supplied.\n *\n * What this adapter gives you that the others do not, and what to watch for:\n *\n * - **`history(id)` works** (`capabilities.history === true`) — it is the only adapter in the\n * ecosystem that exposes per-memory versioning, and it backs the extra `memory_history` tool\n * offered to the model.\n * - **`recall` is CROSS-SESSION on purpose.** Writes carry `run_id = ctx.sessionId`, but the\n * search filter is `user_id` alone, so a recall in session B returns memories written in\n * session A. If you need per-session isolation, use distinct `ctx.userId` values — `sessionId`\n * will not give it to you.\n * - **`recall` defaults to `k = 10`** with server-side rerank; `write` returns the id of the first\n * memory Mem0's server-side extraction produced, which need not be the text you sent.\n * - **`system` turns are rewritten.** Mem0 accepts only `user` / `assistant`, so a\n * `MemoryTurnMessage` with `role: \"system\"` is sent as a `user` turn prefixed with `[system] `.\n *\n * Trap — the circuit breaker reports itself as a RATE LIMIT. After\n * {@link Mem0AdapterOptions.breaker} trips, every call throws\n * `MemoryAdapterError(code: \"rate_limited\")` with a message naming the remaining cooldown, even\n * though the cause was a 5xx or a transport failure and no request was sent. Match on the message,\n * or on the fact that the failure is instantaneous, to tell the two apart.\n *\n * Errors are always `MemoryAdapterError` with `adapterId: \"mem0\"` and one of\n * `auth_failed` (401/403) | `rate_limited` (429 or breaker open) | `not_found` (404) |\n * `network` (5xx, or a status-less error whose message contains \"network\") | `invalid_input` |\n * `unknown` (everything else, including a transport error reported as `\"fetch failed\"`).\n * Both `network` shapes count toward {@link Mem0AdapterOptions.breaker}; `unknown` does not.\n *\n * @public\n */\nexport function mem0Memory(options: Mem0AdapterOptions): Plugin {\n return Plugin.create({\n name: \"@theokit/memory-mem0\",\n version: \"0.1.0\",\n kind: \"memory\",\n createProvider: () => new Mem0Adapter(options),\n });\n}\n"]}
package/package.json CHANGED
@@ -1,9 +1,17 @@
1
1
  {
2
2
  "name": "@theokit/memory-mem0",
3
- "version": "3.0.2",
3
+ "version": "3.0.4-next.0",
4
4
  "description": "Mem0 cloud memory adapter for @theokit/sdk — wraps mem0ai MemoryClient with the MemoryAdapter contract (ADR D141).",
5
5
  "license": "Apache-2.0",
6
+ "homepage": "https://github.com/usetheokit/theokit-sdk#readme",
7
+ "bugs": "https://github.com/usetheokit/theokit-sdk/issues",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/usetheokit/theokit-sdk.git",
11
+ "directory": "packages/memory-mem0"
12
+ },
6
13
  "type": "module",
14
+ "sideEffects": false,
7
15
  "engines": {
8
16
  "node": ">=22.12.0"
9
17
  },
@@ -28,24 +36,23 @@
28
36
  "LICENSE",
29
37
  "CHANGELOG.md"
30
38
  ],
39
+ "publishConfig": {
40
+ "provenance": true,
41
+ "access": "public"
42
+ },
31
43
  "peerDependencies": {
32
44
  "mem0ai": "^3.0.0",
33
- "@theokit/sdk": "^4.43.0"
45
+ "@theokit/sdk": "^4.63.4-next.0"
34
46
  },
35
47
  "devDependencies": {
36
48
  "mem0ai": "^3.0.3",
37
49
  "tsup": "^8.5.0",
38
50
  "typescript": "^5.8.0",
39
51
  "vitest": "^4.1.8",
40
- "@theokit/sdk": "4.43.0"
41
- },
42
- "repository": {
43
- "type": "git",
44
- "url": "git+https://github.com/usetheodev/theokit-sdk.git",
45
- "directory": "packages/memory-mem0"
52
+ "@theokit/sdk": "4.63.4-next.0"
46
53
  },
47
54
  "scripts": {
48
- "build": "tsup",
55
+ "build": "tsup && node ../../tools/repair-dts-imports.mjs .",
49
56
  "typecheck": "tsc --noEmit",
50
57
  "test": "vitest run"
51
58
  }