@theokit/memory-supermemory 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +82 -0
- package/dist/index.cjs +251 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +55 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.js +245 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @theokit/sdk@1.3.0
|
|
9
|
+
|
|
10
|
+
## 1.0.0
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
- @theokit/sdk@1.2.0
|
|
16
|
+
|
|
17
|
+
## 0.1.0
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Initial release. Implements the `MemoryAdapter` contract (ADR D141) over
|
|
22
|
+
the `supermemory@^4.21.0` SDK. Exposes:
|
|
23
|
+
- `supermemoryMemory(options)` plugin factory.
|
|
24
|
+
- `MemoryAdapter.write` → `documents.add` with translated containerTags.
|
|
25
|
+
- `MemoryAdapter.recall` → `search.memories` with rerank=true.
|
|
26
|
+
- `MemoryAdapter.delete` → `documents.delete` with EC-B prefix validation.
|
|
27
|
+
- LLM-callable tool schemas (`memory_write`, `memory_recall`).
|
|
28
|
+
- EC-C identifier sanitizer (`^[a-zA-Z0-9_-]+$`) for every containerTag
|
|
29
|
+
component — prevents silent cross-bucket leak from `:`/whitespace in
|
|
30
|
+
userId/agentId/tenantId/tags.
|
|
31
|
+
- Typed error translation: 401/403 → `auth_failed`, 429 → `rate_limited`,
|
|
32
|
+
404 → `not_found`, network → `network`.
|
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @theokit/memory-supermemory
|
|
2
|
+
|
|
3
|
+
Supermemory memory adapter for [`@theokit/sdk`](../sdk).
|
|
4
|
+
|
|
5
|
+
Wraps [`supermemory@^4`](https://www.npmjs.com/package/supermemory) (zero-dep,
|
|
6
|
+
MIT-licensed, native fetch) with the `MemoryAdapter` contract from ADR D141.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pnpm add @theokit/memory-supermemory supermemory
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { Agent } from "@theokit/sdk";
|
|
18
|
+
import { supermemoryMemory } from "@theokit/memory-supermemory";
|
|
19
|
+
|
|
20
|
+
const agent = await Agent.create({
|
|
21
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
22
|
+
model: { id: "openai/gpt-4o-mini" },
|
|
23
|
+
local: {},
|
|
24
|
+
plugins: [supermemoryMemory({ apiKey: process.env.SUPERMEMORY_API_KEY! })],
|
|
25
|
+
memoryContext: { userId: "demo" },
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Direct API
|
|
29
|
+
await agent.memory.write("User likes Brazilian jazz", { userId: "demo" });
|
|
30
|
+
const facts = await agent.memory.recall("music preferences", { userId: "demo" });
|
|
31
|
+
|
|
32
|
+
// LLM-driven via tool schemas (registered automatically when toolSchemas: true)
|
|
33
|
+
await agent.send("What music does the user enjoy?");
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Options
|
|
37
|
+
|
|
38
|
+
| Field | Type | Default | Description |
|
|
39
|
+
|---|---|---|---|
|
|
40
|
+
| `apiKey` | `string` | — | Supermemory API key. Required. |
|
|
41
|
+
| `baseUrl` | `string` | Supermemory cloud | Override for self-hosted deployments. |
|
|
42
|
+
| `containerTagPrefix` | `string` | `"theokit"` | Prefix for every container tag. Useful for test isolation. |
|
|
43
|
+
|
|
44
|
+
## Container tag scheme
|
|
45
|
+
|
|
46
|
+
Every memory write is tagged with:
|
|
47
|
+
|
|
48
|
+
- `${prefix}:user:${userId}` (always)
|
|
49
|
+
- `${prefix}:agent:${agentId}` (when set)
|
|
50
|
+
- `${prefix}:tenant:${tenantId}` (when set)
|
|
51
|
+
- `${prefix}:tag:${tag}` (one per entry in `ctx.tags`)
|
|
52
|
+
|
|
53
|
+
Each component is sanitized against `^[a-zA-Z0-9_-]+$` (EC-C) — values
|
|
54
|
+
containing `:` or whitespace throw `MemoryAdapterError(code: "invalid_input")`
|
|
55
|
+
at the boundary, before any HTTP call.
|
|
56
|
+
|
|
57
|
+
## Multi-tenant accumulation (EC-S)
|
|
58
|
+
|
|
59
|
+
Calling `agent.memory.write` writes durable data to Supermemory tied to
|
|
60
|
+
the supplied `userId`. In bot/CI scenarios where the same `userId` is
|
|
61
|
+
reused across runs, set a unique `containerTagPrefix` per test:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
supermemoryMemory({
|
|
65
|
+
apiKey,
|
|
66
|
+
containerTagPrefix: `theokit-test-${Date.now()}`,
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Failure modes
|
|
71
|
+
|
|
72
|
+
| HTTP status | Maps to | `isRetryable` |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| 401 / 403 | `MemoryAdapterError(code: "auth_failed")` | false |
|
|
75
|
+
| 429 | `MemoryAdapterError(code: "rate_limited")` | true |
|
|
76
|
+
| 404 | `MemoryAdapterError(code: "not_found")` | false |
|
|
77
|
+
| Network/timeout | `MemoryAdapterError(code: "network")` | true |
|
|
78
|
+
| Other | `MemoryAdapterError(code: "unknown")` | false |
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
Apache-2.0. See [LICENSE](./LICENSE).
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sdk = require('@theokit/sdk');
|
|
4
|
+
var SupermemoryClient = require('supermemory');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var SupermemoryClient__default = /*#__PURE__*/_interopDefault(SupermemoryClient);
|
|
9
|
+
|
|
10
|
+
// src/index.ts
|
|
11
|
+
var SAFE_IDENT = /^[a-zA-Z0-9_-]+$/;
|
|
12
|
+
var ADAPTER_ID = "supermemory";
|
|
13
|
+
function sanitizeIdentifier(value, fieldName) {
|
|
14
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
15
|
+
throw new sdk.MemoryAdapterError(`Supermemory adapter: ${fieldName} must be a non-empty string`, {
|
|
16
|
+
adapterId: ADAPTER_ID,
|
|
17
|
+
code: "invalid_input"
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (!SAFE_IDENT.test(value)) {
|
|
21
|
+
throw new sdk.MemoryAdapterError(
|
|
22
|
+
`Supermemory adapter: ${fieldName} "${value}" contains invalid characters (allowed: a-zA-Z0-9_-)`,
|
|
23
|
+
{ adapterId: ADAPTER_ID, code: "invalid_input" }
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
function buildContainerTags(ctx, prefix) {
|
|
29
|
+
const safePrefix = sanitizeIdentifier(prefix, "prefix");
|
|
30
|
+
const tags = [`${safePrefix}:user:${sanitizeIdentifier(ctx.userId, "userId")}`];
|
|
31
|
+
if (ctx.agentId !== void 0) {
|
|
32
|
+
tags.push(`${safePrefix}:agent:${sanitizeIdentifier(ctx.agentId, "agentId")}`);
|
|
33
|
+
}
|
|
34
|
+
if (ctx.tenantId !== void 0) {
|
|
35
|
+
tags.push(`${safePrefix}:tenant:${sanitizeIdentifier(ctx.tenantId, "tenantId")}`);
|
|
36
|
+
}
|
|
37
|
+
if (ctx.tags !== void 0) {
|
|
38
|
+
for (const t of ctx.tags) {
|
|
39
|
+
tags.push(`${safePrefix}:tag:${sanitizeIdentifier(t, "tag")}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return tags;
|
|
43
|
+
}
|
|
44
|
+
function primaryContainerTag(ctx, prefix) {
|
|
45
|
+
const safePrefix = sanitizeIdentifier(prefix, "prefix");
|
|
46
|
+
return `${safePrefix}:user:${sanitizeIdentifier(ctx.userId, "userId")}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/adapter.ts
|
|
50
|
+
var ADAPTER_ID2 = "supermemory";
|
|
51
|
+
var CAPS = {
|
|
52
|
+
history: false,
|
|
53
|
+
sessions: false,
|
|
54
|
+
tenancy: true,
|
|
55
|
+
reasoning: false,
|
|
56
|
+
toolSchemas: true,
|
|
57
|
+
prefetch: false
|
|
58
|
+
};
|
|
59
|
+
var SupermemoryAdapter = class {
|
|
60
|
+
id = ADAPTER_ID2;
|
|
61
|
+
capabilities = CAPS;
|
|
62
|
+
#opts;
|
|
63
|
+
#client;
|
|
64
|
+
constructor(opts) {
|
|
65
|
+
this.#opts = opts;
|
|
66
|
+
}
|
|
67
|
+
isAvailable() {
|
|
68
|
+
return typeof this.#opts.apiKey === "string" && this.#opts.apiKey.length > 0;
|
|
69
|
+
}
|
|
70
|
+
async initialize() {
|
|
71
|
+
}
|
|
72
|
+
async write(content, ctx) {
|
|
73
|
+
const text = this.#renderContent(content);
|
|
74
|
+
if (text.length === 0) {
|
|
75
|
+
throw new sdk.MemoryAdapterError("write: empty content", {
|
|
76
|
+
adapterId: ADAPTER_ID2,
|
|
77
|
+
code: "invalid_input"
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
const containerTags = buildContainerTags(ctx, this.#prefix());
|
|
81
|
+
try {
|
|
82
|
+
const resp = await this.#sdk().documents.add({
|
|
83
|
+
content: text,
|
|
84
|
+
containerTags,
|
|
85
|
+
...ctx.metadata !== void 0 ? { metadata: ctx.metadata } : {}
|
|
86
|
+
});
|
|
87
|
+
return sdk.mkMemoryId(ADAPTER_ID2, resp.id);
|
|
88
|
+
} catch (err) {
|
|
89
|
+
throw this.#translateError(err, "write");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async recall(query, ctx, k = 10) {
|
|
93
|
+
if (k <= 0) return [];
|
|
94
|
+
const containerTag = primaryContainerTag(ctx, this.#prefix());
|
|
95
|
+
try {
|
|
96
|
+
const resp = await this.#sdk().search.memories({
|
|
97
|
+
q: query,
|
|
98
|
+
containerTag,
|
|
99
|
+
limit: k,
|
|
100
|
+
rerank: true
|
|
101
|
+
});
|
|
102
|
+
const results = resp.results ?? [];
|
|
103
|
+
return results.map(this.#mapResult);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
throw this.#translateError(err, "recall");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async delete(id) {
|
|
109
|
+
const rawId = sdk.extractRawId(id, ADAPTER_ID2);
|
|
110
|
+
try {
|
|
111
|
+
await this.#sdk().documents.delete(rawId);
|
|
112
|
+
} catch (err) {
|
|
113
|
+
throw this.#translateError(err, "delete");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
getToolSchemas() {
|
|
117
|
+
return [
|
|
118
|
+
{
|
|
119
|
+
name: "memory_write",
|
|
120
|
+
description: "Persist a fact about the user or context to Supermemory long-term memory. Returns the stored memory ID.",
|
|
121
|
+
parameters: {
|
|
122
|
+
type: "object",
|
|
123
|
+
properties: {
|
|
124
|
+
content: { type: "string", description: "Fact text to persist verbatim." }
|
|
125
|
+
},
|
|
126
|
+
required: ["content"]
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "memory_recall",
|
|
131
|
+
description: "Retrieve up to k semantically relevant facts from Supermemory long-term memory. Returns an array of {id, content, score, createdAt} objects.",
|
|
132
|
+
parameters: {
|
|
133
|
+
type: "object",
|
|
134
|
+
properties: {
|
|
135
|
+
query: { type: "string", description: "Free-text query to search memory." },
|
|
136
|
+
k: {
|
|
137
|
+
type: "integer",
|
|
138
|
+
minimum: 1,
|
|
139
|
+
maximum: 50,
|
|
140
|
+
description: "Max results (default 10)."
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
required: ["query"]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
async handleToolCall(name, args, ctx) {
|
|
149
|
+
if (name === "memory_write") {
|
|
150
|
+
const content = String(args.content ?? "");
|
|
151
|
+
const id = await this.write(content, ctx);
|
|
152
|
+
return JSON.stringify({ ok: true, id });
|
|
153
|
+
}
|
|
154
|
+
if (name === "memory_recall") {
|
|
155
|
+
const query = String(args.query ?? "");
|
|
156
|
+
const k = typeof args.k === "number" ? args.k : 10;
|
|
157
|
+
const facts = await this.recall(query, ctx, k);
|
|
158
|
+
return JSON.stringify({ ok: true, facts });
|
|
159
|
+
}
|
|
160
|
+
throw new sdk.MemoryAdapterError(`Unknown tool name: ${name}`, {
|
|
161
|
+
adapterId: ADAPTER_ID2,
|
|
162
|
+
code: "invalid_input"
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
async shutdown() {
|
|
166
|
+
this.#client = void 0;
|
|
167
|
+
}
|
|
168
|
+
// ── helpers ────────────────────────────────────────────────────────
|
|
169
|
+
#prefix() {
|
|
170
|
+
return this.#opts.containerTagPrefix ?? "theokit";
|
|
171
|
+
}
|
|
172
|
+
#renderContent(content) {
|
|
173
|
+
if (typeof content === "string") return content.trim();
|
|
174
|
+
return content.map((m) => `${m.role}: ${m.content}`).join("\n").trim();
|
|
175
|
+
}
|
|
176
|
+
#mapResult = (r) => {
|
|
177
|
+
const obj = r ?? {};
|
|
178
|
+
const memory = obj.memory ?? obj;
|
|
179
|
+
const rawId = String(memory.id ?? obj.id ?? "");
|
|
180
|
+
const content = String(memory.content ?? memory.text ?? obj.content ?? "");
|
|
181
|
+
const score = typeof obj.score === "number" ? obj.score : void 0;
|
|
182
|
+
const createdAt = typeof memory.createdAt === "string" ? memory.createdAt : void 0;
|
|
183
|
+
return {
|
|
184
|
+
id: sdk.mkMemoryId(ADAPTER_ID2, rawId),
|
|
185
|
+
content,
|
|
186
|
+
...score !== void 0 ? { score } : {},
|
|
187
|
+
...createdAt !== void 0 ? { createdAt } : {}
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
#sdk() {
|
|
191
|
+
if (this.#client === void 0) {
|
|
192
|
+
this.#client = new SupermemoryClient__default.default({
|
|
193
|
+
apiKey: this.#opts.apiKey,
|
|
194
|
+
...this.#opts.baseUrl !== void 0 ? { baseURL: this.#opts.baseUrl } : {}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return this.#client;
|
|
198
|
+
}
|
|
199
|
+
#translateError(err, op) {
|
|
200
|
+
if (err instanceof sdk.MemoryAdapterError) return err;
|
|
201
|
+
const status = err?.status ?? err?.statusCode;
|
|
202
|
+
const message = err?.message ?? String(err);
|
|
203
|
+
if (status === 401 || status === 403) {
|
|
204
|
+
return new sdk.MemoryAdapterError(`Supermemory auth failed (${op}): ${message}`, {
|
|
205
|
+
adapterId: ADAPTER_ID2,
|
|
206
|
+
code: "auth_failed",
|
|
207
|
+
cause: err
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
if (status === 429) {
|
|
211
|
+
return new sdk.MemoryAdapterError(`Supermemory rate limited (${op}): ${message}`, {
|
|
212
|
+
adapterId: ADAPTER_ID2,
|
|
213
|
+
code: "rate_limited",
|
|
214
|
+
cause: err
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
if (status === 404) {
|
|
218
|
+
return new sdk.MemoryAdapterError(`Supermemory not found (${op}): ${message}`, {
|
|
219
|
+
adapterId: ADAPTER_ID2,
|
|
220
|
+
code: "not_found",
|
|
221
|
+
cause: err
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
if (status === void 0 && message.toLowerCase().includes("network")) {
|
|
225
|
+
return new sdk.MemoryAdapterError(`Supermemory network error (${op}): ${message}`, {
|
|
226
|
+
adapterId: ADAPTER_ID2,
|
|
227
|
+
code: "network",
|
|
228
|
+
cause: err
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
return new sdk.MemoryAdapterError(`Supermemory error (${op}): ${message}`, {
|
|
232
|
+
adapterId: ADAPTER_ID2,
|
|
233
|
+
code: "unknown",
|
|
234
|
+
cause: err
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// src/index.ts
|
|
240
|
+
function supermemoryMemory(options) {
|
|
241
|
+
return sdk.definePlugin({
|
|
242
|
+
name: "@theokit/memory-supermemory",
|
|
243
|
+
version: "0.1.0",
|
|
244
|
+
kind: "memory",
|
|
245
|
+
createProvider: () => new SupermemoryAdapter(options)
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
exports.supermemoryMemory = supermemoryMemory;
|
|
250
|
+
//# sourceMappingURL=index.cjs.map
|
|
251
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/translate.ts","../src/adapter.ts","../src/index.ts"],"names":["MemoryAdapterError","ADAPTER_ID","mkMemoryId","extractRawId","SupermemoryClient","definePlugin"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * `MemoryContext` → Supermemory containerTags translation (T3.2).\n *\n * EC-C fix: every component runs through a strict identifier sanitizer\n * (regex `^[a-zA-Z0-9_-]+$`) before being joined with `:`. Rejects with\n * `MemoryAdapterError(code: \"invalid_input\")` on invalid input, so a\n * value like `userId: \"user:123\"` cannot silently land in a different\n * bucket via tag mis-parsing.\n *\n * @internal\n */\n\nimport type { MemoryContext } from \"@theokit/sdk\";\nimport { MemoryAdapterError } from \"@theokit/sdk\";\n\nconst SAFE_IDENT = /^[a-zA-Z0-9_-]+$/;\nconst ADAPTER_ID = \"supermemory\";\n\nexport function sanitizeIdentifier(value: string, fieldName: string): string {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new MemoryAdapterError(`Supermemory adapter: ${fieldName} must be a non-empty string`, {\n adapterId: ADAPTER_ID,\n code: \"invalid_input\",\n });\n }\n if (!SAFE_IDENT.test(value)) {\n throw new MemoryAdapterError(\n `Supermemory adapter: ${fieldName} \"${value}\" contains invalid characters (allowed: a-zA-Z0-9_-)`,\n { adapterId: ADAPTER_ID, code: \"invalid_input\" },\n );\n }\n return value;\n}\n\n/**\n * Build the array of containerTags for `documents.add`. Each component\n * is sanitized; collisions across tag namespaces (user/agent/tenant/tag)\n * are intentional — Supermemory treats containerTags as a set.\n *\n * @internal\n */\nexport function buildContainerTags(ctx: MemoryContext, prefix: string): string[] {\n const safePrefix = sanitizeIdentifier(prefix, \"prefix\");\n const tags: string[] = [`${safePrefix}:user:${sanitizeIdentifier(ctx.userId, \"userId\")}`];\n if (ctx.agentId !== undefined) {\n tags.push(`${safePrefix}:agent:${sanitizeIdentifier(ctx.agentId, \"agentId\")}`);\n }\n if (ctx.tenantId !== undefined) {\n tags.push(`${safePrefix}:tenant:${sanitizeIdentifier(ctx.tenantId, \"tenantId\")}`);\n }\n if (ctx.tags !== undefined) {\n for (const t of ctx.tags) {\n tags.push(`${safePrefix}:tag:${sanitizeIdentifier(t, \"tag\")}`);\n }\n }\n return tags;\n}\n\n/**\n * Pick the primary containerTag for `search.memories` (which takes a\n * single string, not an array). The user tag is canonical.\n *\n * @internal\n */\nexport function primaryContainerTag(ctx: MemoryContext, prefix: string): string {\n const safePrefix = sanitizeIdentifier(prefix, \"prefix\");\n return `${safePrefix}:user:${sanitizeIdentifier(ctx.userId, \"userId\")}`;\n}\n","/**\n * SupermemoryAdapter — `@theokit-memory-supermemory` core (T3.2, ADR D141).\n *\n * Wraps `supermemory` SDK v4. Implements `MemoryAdapter` so the SDK's\n * `pre_user_send` / `post_assistant_reply` hooks (D145) and\n * `agent.memory.*` direct API (D142) work end-to-end against Supermemory's\n * managed memory + RAG service.\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 MemoryToolSchema,\n type MemoryTurnMessage,\n mkMemoryId,\n} from \"@theokit/sdk\";\nimport type Supermemory from \"supermemory\";\nimport SupermemoryClient from \"supermemory\";\n\nimport { buildContainerTags, primaryContainerTag } from \"./translate.js\";\n\n/** Configuration accepted by the `supermemoryMemory(...)` factory. @public */\nexport interface SupermemoryAdapterOptions {\n /** Supermemory API key. Falls back to `SUPERMEMORY_API_KEY`. */\n apiKey: string;\n /** Base URL override for self-hosted Supermemory deployments. */\n baseUrl?: string;\n /** Prefix for every containerTag (default `\"theokit\"`). Useful for test isolation (EC-S). */\n containerTagPrefix?: string;\n}\n\nconst ADAPTER_ID = \"supermemory\";\n\nconst CAPS: MemoryAdapterCapabilities = {\n history: false,\n sessions: false,\n tenancy: true,\n reasoning: false,\n toolSchemas: true,\n prefetch: false,\n};\n\n/**\n * SDK-internal adapter class. Construct via `supermemoryMemory(...)`\n * factory from `./index.ts`, not directly.\n *\n * @internal\n */\nexport class SupermemoryAdapter implements MemoryAdapter {\n readonly id = ADAPTER_ID;\n readonly capabilities = CAPS;\n readonly #opts: SupermemoryAdapterOptions;\n #client?: Supermemory;\n\n constructor(opts: SupermemoryAdapterOptions) {\n this.#opts = opts;\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: defer the actual client construction until first call.\n // initialize() is idempotent — see EC-3 / EC-I.\n }\n\n async write(content: string | MemoryTurnMessage[], ctx: MemoryContext): Promise<MemoryId> {\n const text = this.#renderContent(content);\n if (text.length === 0) {\n throw new MemoryAdapterError(\"write: empty content\", {\n adapterId: ADAPTER_ID,\n code: \"invalid_input\",\n });\n }\n const containerTags = buildContainerTags(ctx, this.#prefix());\n try {\n const resp = await this.#sdk().documents.add({\n content: text,\n containerTags,\n ...(ctx.metadata !== undefined ? { metadata: ctx.metadata as Record<string, string> } : {}),\n });\n return mkMemoryId(ADAPTER_ID, resp.id);\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 const containerTag = primaryContainerTag(ctx, this.#prefix());\n try {\n const resp = await this.#sdk().search.memories({\n q: query,\n containerTag,\n limit: k,\n rerank: true,\n });\n const results = resp.results ?? [];\n return results.map(this.#mapResult);\n } catch (err) {\n throw this.#translateError(err, \"recall\");\n }\n }\n\n async delete(id: MemoryId): Promise<void> {\n const rawId = extractRawId(id, ADAPTER_ID);\n try {\n await this.#sdk().documents.delete(rawId);\n } catch (err) {\n throw this.#translateError(err, \"delete\");\n }\n }\n\n getToolSchemas(): MemoryToolSchema[] {\n return [\n {\n name: \"memory_write\",\n description:\n \"Persist a fact about the user or context to Supermemory long-term memory. \" +\n \"Returns the stored memory ID.\",\n parameters: {\n type: \"object\",\n properties: {\n content: { type: \"string\", description: \"Fact text to persist verbatim.\" },\n },\n required: [\"content\"],\n },\n },\n {\n name: \"memory_recall\",\n description:\n \"Retrieve up to k semantically relevant facts from Supermemory long-term memory. \" +\n \"Returns an array of {id, content, score, createdAt} objects.\",\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Free-text query to search memory.\" },\n k: {\n type: \"integer\",\n minimum: 1,\n maximum: 50,\n description: \"Max results (default 10).\",\n },\n },\n required: [\"query\"],\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 content = String(args.content ?? \"\");\n const id = await this.write(content, ctx);\n return JSON.stringify({ ok: true, id });\n }\n if (name === \"memory_recall\") {\n const query = String(args.query ?? \"\");\n const k = typeof args.k === \"number\" ? args.k : 10;\n const facts = await this.recall(query, ctx, k);\n return JSON.stringify({ ok: true, facts });\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 // ── helpers ────────────────────────────────────────────────────────\n\n #prefix(): string {\n return this.#opts.containerTagPrefix ?? \"theokit\";\n }\n\n #renderContent(content: string | MemoryTurnMessage[]): string {\n if (typeof content === \"string\") return content.trim();\n return content\n .map((m) => `${m.role}: ${m.content}`)\n .join(\"\\n\")\n .trim();\n }\n\n #mapResult = (r: unknown): MemoryFact => {\n const obj = (r as Record<string, unknown>) ?? {};\n // SDK shape: { memory?: { id, content, ... }, score, ... } or chunk shape.\n const memory = (obj.memory as Record<string, unknown> | undefined) ?? obj;\n const rawId = String(memory.id ?? obj.id ?? \"\");\n const content = String(memory.content ?? memory.text ?? obj.content ?? \"\");\n const score = typeof obj.score === \"number\" ? obj.score : undefined;\n const createdAt = typeof memory.createdAt === \"string\" ? memory.createdAt : undefined;\n return {\n id: mkMemoryId(ADAPTER_ID, rawId),\n content,\n ...(score !== undefined ? { score } : {}),\n ...(createdAt !== undefined ? { createdAt } : {}),\n };\n };\n\n #sdk(): Supermemory {\n if (this.#client === undefined) {\n this.#client = new SupermemoryClient({\n apiKey: this.#opts.apiKey,\n ...(this.#opts.baseUrl !== undefined ? { baseURL: this.#opts.baseUrl } : {}),\n });\n }\n return this.#client;\n }\n\n #translateError(err: unknown, op: string): MemoryAdapterError {\n if (err instanceof MemoryAdapterError) return err;\n const status =\n (err as { status?: number; statusCode?: number })?.status ??\n (err as { statusCode?: number })?.statusCode;\n const message = (err as Error)?.message ?? String(err);\n if (status === 401 || status === 403) {\n return new MemoryAdapterError(`Supermemory auth failed (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"auth_failed\",\n cause: err,\n });\n }\n if (status === 429) {\n return new MemoryAdapterError(`Supermemory 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(`Supermemory not found (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"not_found\",\n cause: err,\n });\n }\n if (status === undefined && message.toLowerCase().includes(\"network\")) {\n return new MemoryAdapterError(`Supermemory network error (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"network\",\n cause: err,\n });\n }\n return new MemoryAdapterError(`Supermemory error (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"unknown\",\n cause: err,\n });\n }\n}\n","/**\n * `@theokit/memory-supermemory` — Supermemory memory adapter for @theokit/sdk.\n *\n * Usage:\n *\n * ```ts\n * import { Agent } from \"@theokit/sdk\";\n * import { supermemoryMemory } from \"@theokit/memory-supermemory\";\n *\n * const agent = await Agent.create({\n * apiKey: process.env.OPENROUTER_API_KEY,\n * model: { id: \"openai/gpt-4o-mini\" },\n * local: {},\n * plugins: [supermemoryMemory({ apiKey: process.env.SUPERMEMORY_API_KEY! })],\n * memoryContext: { userId: \"demo\" },\n * });\n *\n * await agent.memory.write(\"User likes Brazilian jazz\", { userId: \"demo\" });\n * const facts = await agent.memory.recall(\"music preferences\", { userId: \"demo\" });\n * ```\n *\n * @public\n */\n\nimport type { Plugin } from \"@theokit/sdk\";\nimport { definePlugin } from \"@theokit/sdk\";\n\nimport { SupermemoryAdapter, type SupermemoryAdapterOptions } from \"./adapter.js\";\n\nexport type { SupermemoryAdapterOptions } from \"./adapter.js\";\n\n/**\n * Build a `Plugin { kind: \"memory\" }` ready to pass to\n * `Agent.create({ plugins: [...] })`.\n *\n * @public\n */\nexport function supermemoryMemory(options: SupermemoryAdapterOptions): Plugin {\n return definePlugin({\n name: \"@theokit/memory-supermemory\",\n version: \"0.1.0\",\n kind: \"memory\",\n createProvider: () => new SupermemoryAdapter(options),\n });\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Plugin } from '@theokit/sdk';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SupermemoryAdapter — `@theokit-memory-supermemory` core (T3.2, ADR D141).
|
|
5
|
+
*
|
|
6
|
+
* Wraps `supermemory` SDK v4. Implements `MemoryAdapter` so the SDK's
|
|
7
|
+
* `pre_user_send` / `post_assistant_reply` hooks (D145) and
|
|
8
|
+
* `agent.memory.*` direct API (D142) work end-to-end against Supermemory's
|
|
9
|
+
* managed memory + RAG service.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
/** Configuration accepted by the `supermemoryMemory(...)` factory. @public */
|
|
14
|
+
interface SupermemoryAdapterOptions {
|
|
15
|
+
/** Supermemory API key. Falls back to `SUPERMEMORY_API_KEY`. */
|
|
16
|
+
apiKey: string;
|
|
17
|
+
/** Base URL override for self-hosted Supermemory deployments. */
|
|
18
|
+
baseUrl?: string;
|
|
19
|
+
/** Prefix for every containerTag (default `"theokit"`). Useful for test isolation (EC-S). */
|
|
20
|
+
containerTagPrefix?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* `@theokit/memory-supermemory` — Supermemory memory adapter for @theokit/sdk.
|
|
25
|
+
*
|
|
26
|
+
* Usage:
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { Agent } from "@theokit/sdk";
|
|
30
|
+
* import { supermemoryMemory } from "@theokit/memory-supermemory";
|
|
31
|
+
*
|
|
32
|
+
* const agent = await Agent.create({
|
|
33
|
+
* apiKey: process.env.OPENROUTER_API_KEY,
|
|
34
|
+
* model: { id: "openai/gpt-4o-mini" },
|
|
35
|
+
* local: {},
|
|
36
|
+
* plugins: [supermemoryMemory({ apiKey: process.env.SUPERMEMORY_API_KEY! })],
|
|
37
|
+
* memoryContext: { userId: "demo" },
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* await agent.memory.write("User likes Brazilian jazz", { userId: "demo" });
|
|
41
|
+
* const facts = await agent.memory.recall("music preferences", { userId: "demo" });
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Build a `Plugin { kind: "memory" }` ready to pass to
|
|
49
|
+
* `Agent.create({ plugins: [...] })`.
|
|
50
|
+
*
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
declare function supermemoryMemory(options: SupermemoryAdapterOptions): Plugin;
|
|
54
|
+
|
|
55
|
+
export { type SupermemoryAdapterOptions, supermemoryMemory };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Plugin } from '@theokit/sdk';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SupermemoryAdapter — `@theokit-memory-supermemory` core (T3.2, ADR D141).
|
|
5
|
+
*
|
|
6
|
+
* Wraps `supermemory` SDK v4. Implements `MemoryAdapter` so the SDK's
|
|
7
|
+
* `pre_user_send` / `post_assistant_reply` hooks (D145) and
|
|
8
|
+
* `agent.memory.*` direct API (D142) work end-to-end against Supermemory's
|
|
9
|
+
* managed memory + RAG service.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
/** Configuration accepted by the `supermemoryMemory(...)` factory. @public */
|
|
14
|
+
interface SupermemoryAdapterOptions {
|
|
15
|
+
/** Supermemory API key. Falls back to `SUPERMEMORY_API_KEY`. */
|
|
16
|
+
apiKey: string;
|
|
17
|
+
/** Base URL override for self-hosted Supermemory deployments. */
|
|
18
|
+
baseUrl?: string;
|
|
19
|
+
/** Prefix for every containerTag (default `"theokit"`). Useful for test isolation (EC-S). */
|
|
20
|
+
containerTagPrefix?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* `@theokit/memory-supermemory` — Supermemory memory adapter for @theokit/sdk.
|
|
25
|
+
*
|
|
26
|
+
* Usage:
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { Agent } from "@theokit/sdk";
|
|
30
|
+
* import { supermemoryMemory } from "@theokit/memory-supermemory";
|
|
31
|
+
*
|
|
32
|
+
* const agent = await Agent.create({
|
|
33
|
+
* apiKey: process.env.OPENROUTER_API_KEY,
|
|
34
|
+
* model: { id: "openai/gpt-4o-mini" },
|
|
35
|
+
* local: {},
|
|
36
|
+
* plugins: [supermemoryMemory({ apiKey: process.env.SUPERMEMORY_API_KEY! })],
|
|
37
|
+
* memoryContext: { userId: "demo" },
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* await agent.memory.write("User likes Brazilian jazz", { userId: "demo" });
|
|
41
|
+
* const facts = await agent.memory.recall("music preferences", { userId: "demo" });
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Build a `Plugin { kind: "memory" }` ready to pass to
|
|
49
|
+
* `Agent.create({ plugins: [...] })`.
|
|
50
|
+
*
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
declare function supermemoryMemory(options: SupermemoryAdapterOptions): Plugin;
|
|
54
|
+
|
|
55
|
+
export { type SupermemoryAdapterOptions, supermemoryMemory };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { definePlugin, MemoryAdapterError, mkMemoryId, extractRawId } from '@theokit/sdk';
|
|
2
|
+
import SupermemoryClient from 'supermemory';
|
|
3
|
+
|
|
4
|
+
// src/index.ts
|
|
5
|
+
var SAFE_IDENT = /^[a-zA-Z0-9_-]+$/;
|
|
6
|
+
var ADAPTER_ID = "supermemory";
|
|
7
|
+
function sanitizeIdentifier(value, fieldName) {
|
|
8
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
9
|
+
throw new MemoryAdapterError(`Supermemory adapter: ${fieldName} must be a non-empty string`, {
|
|
10
|
+
adapterId: ADAPTER_ID,
|
|
11
|
+
code: "invalid_input"
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
if (!SAFE_IDENT.test(value)) {
|
|
15
|
+
throw new MemoryAdapterError(
|
|
16
|
+
`Supermemory adapter: ${fieldName} "${value}" contains invalid characters (allowed: a-zA-Z0-9_-)`,
|
|
17
|
+
{ adapterId: ADAPTER_ID, code: "invalid_input" }
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
function buildContainerTags(ctx, prefix) {
|
|
23
|
+
const safePrefix = sanitizeIdentifier(prefix, "prefix");
|
|
24
|
+
const tags = [`${safePrefix}:user:${sanitizeIdentifier(ctx.userId, "userId")}`];
|
|
25
|
+
if (ctx.agentId !== void 0) {
|
|
26
|
+
tags.push(`${safePrefix}:agent:${sanitizeIdentifier(ctx.agentId, "agentId")}`);
|
|
27
|
+
}
|
|
28
|
+
if (ctx.tenantId !== void 0) {
|
|
29
|
+
tags.push(`${safePrefix}:tenant:${sanitizeIdentifier(ctx.tenantId, "tenantId")}`);
|
|
30
|
+
}
|
|
31
|
+
if (ctx.tags !== void 0) {
|
|
32
|
+
for (const t of ctx.tags) {
|
|
33
|
+
tags.push(`${safePrefix}:tag:${sanitizeIdentifier(t, "tag")}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return tags;
|
|
37
|
+
}
|
|
38
|
+
function primaryContainerTag(ctx, prefix) {
|
|
39
|
+
const safePrefix = sanitizeIdentifier(prefix, "prefix");
|
|
40
|
+
return `${safePrefix}:user:${sanitizeIdentifier(ctx.userId, "userId")}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/adapter.ts
|
|
44
|
+
var ADAPTER_ID2 = "supermemory";
|
|
45
|
+
var CAPS = {
|
|
46
|
+
history: false,
|
|
47
|
+
sessions: false,
|
|
48
|
+
tenancy: true,
|
|
49
|
+
reasoning: false,
|
|
50
|
+
toolSchemas: true,
|
|
51
|
+
prefetch: false
|
|
52
|
+
};
|
|
53
|
+
var SupermemoryAdapter = class {
|
|
54
|
+
id = ADAPTER_ID2;
|
|
55
|
+
capabilities = CAPS;
|
|
56
|
+
#opts;
|
|
57
|
+
#client;
|
|
58
|
+
constructor(opts) {
|
|
59
|
+
this.#opts = opts;
|
|
60
|
+
}
|
|
61
|
+
isAvailable() {
|
|
62
|
+
return typeof this.#opts.apiKey === "string" && this.#opts.apiKey.length > 0;
|
|
63
|
+
}
|
|
64
|
+
async initialize() {
|
|
65
|
+
}
|
|
66
|
+
async write(content, ctx) {
|
|
67
|
+
const text = this.#renderContent(content);
|
|
68
|
+
if (text.length === 0) {
|
|
69
|
+
throw new MemoryAdapterError("write: empty content", {
|
|
70
|
+
adapterId: ADAPTER_ID2,
|
|
71
|
+
code: "invalid_input"
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
const containerTags = buildContainerTags(ctx, this.#prefix());
|
|
75
|
+
try {
|
|
76
|
+
const resp = await this.#sdk().documents.add({
|
|
77
|
+
content: text,
|
|
78
|
+
containerTags,
|
|
79
|
+
...ctx.metadata !== void 0 ? { metadata: ctx.metadata } : {}
|
|
80
|
+
});
|
|
81
|
+
return mkMemoryId(ADAPTER_ID2, resp.id);
|
|
82
|
+
} catch (err) {
|
|
83
|
+
throw this.#translateError(err, "write");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async recall(query, ctx, k = 10) {
|
|
87
|
+
if (k <= 0) return [];
|
|
88
|
+
const containerTag = primaryContainerTag(ctx, this.#prefix());
|
|
89
|
+
try {
|
|
90
|
+
const resp = await this.#sdk().search.memories({
|
|
91
|
+
q: query,
|
|
92
|
+
containerTag,
|
|
93
|
+
limit: k,
|
|
94
|
+
rerank: true
|
|
95
|
+
});
|
|
96
|
+
const results = resp.results ?? [];
|
|
97
|
+
return results.map(this.#mapResult);
|
|
98
|
+
} catch (err) {
|
|
99
|
+
throw this.#translateError(err, "recall");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async delete(id) {
|
|
103
|
+
const rawId = extractRawId(id, ADAPTER_ID2);
|
|
104
|
+
try {
|
|
105
|
+
await this.#sdk().documents.delete(rawId);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
throw this.#translateError(err, "delete");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
getToolSchemas() {
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
name: "memory_write",
|
|
114
|
+
description: "Persist a fact about the user or context to Supermemory long-term memory. Returns the stored memory ID.",
|
|
115
|
+
parameters: {
|
|
116
|
+
type: "object",
|
|
117
|
+
properties: {
|
|
118
|
+
content: { type: "string", description: "Fact text to persist verbatim." }
|
|
119
|
+
},
|
|
120
|
+
required: ["content"]
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "memory_recall",
|
|
125
|
+
description: "Retrieve up to k semantically relevant facts from Supermemory long-term memory. Returns an array of {id, content, score, createdAt} objects.",
|
|
126
|
+
parameters: {
|
|
127
|
+
type: "object",
|
|
128
|
+
properties: {
|
|
129
|
+
query: { type: "string", description: "Free-text query to search memory." },
|
|
130
|
+
k: {
|
|
131
|
+
type: "integer",
|
|
132
|
+
minimum: 1,
|
|
133
|
+
maximum: 50,
|
|
134
|
+
description: "Max results (default 10)."
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
required: ["query"]
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
async handleToolCall(name, args, ctx) {
|
|
143
|
+
if (name === "memory_write") {
|
|
144
|
+
const content = String(args.content ?? "");
|
|
145
|
+
const id = await this.write(content, ctx);
|
|
146
|
+
return JSON.stringify({ ok: true, id });
|
|
147
|
+
}
|
|
148
|
+
if (name === "memory_recall") {
|
|
149
|
+
const query = String(args.query ?? "");
|
|
150
|
+
const k = typeof args.k === "number" ? args.k : 10;
|
|
151
|
+
const facts = await this.recall(query, ctx, k);
|
|
152
|
+
return JSON.stringify({ ok: true, facts });
|
|
153
|
+
}
|
|
154
|
+
throw new MemoryAdapterError(`Unknown tool name: ${name}`, {
|
|
155
|
+
adapterId: ADAPTER_ID2,
|
|
156
|
+
code: "invalid_input"
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
async shutdown() {
|
|
160
|
+
this.#client = void 0;
|
|
161
|
+
}
|
|
162
|
+
// ── helpers ────────────────────────────────────────────────────────
|
|
163
|
+
#prefix() {
|
|
164
|
+
return this.#opts.containerTagPrefix ?? "theokit";
|
|
165
|
+
}
|
|
166
|
+
#renderContent(content) {
|
|
167
|
+
if (typeof content === "string") return content.trim();
|
|
168
|
+
return content.map((m) => `${m.role}: ${m.content}`).join("\n").trim();
|
|
169
|
+
}
|
|
170
|
+
#mapResult = (r) => {
|
|
171
|
+
const obj = r ?? {};
|
|
172
|
+
const memory = obj.memory ?? obj;
|
|
173
|
+
const rawId = String(memory.id ?? obj.id ?? "");
|
|
174
|
+
const content = String(memory.content ?? memory.text ?? obj.content ?? "");
|
|
175
|
+
const score = typeof obj.score === "number" ? obj.score : void 0;
|
|
176
|
+
const createdAt = typeof memory.createdAt === "string" ? memory.createdAt : void 0;
|
|
177
|
+
return {
|
|
178
|
+
id: mkMemoryId(ADAPTER_ID2, rawId),
|
|
179
|
+
content,
|
|
180
|
+
...score !== void 0 ? { score } : {},
|
|
181
|
+
...createdAt !== void 0 ? { createdAt } : {}
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
#sdk() {
|
|
185
|
+
if (this.#client === void 0) {
|
|
186
|
+
this.#client = new SupermemoryClient({
|
|
187
|
+
apiKey: this.#opts.apiKey,
|
|
188
|
+
...this.#opts.baseUrl !== void 0 ? { baseURL: this.#opts.baseUrl } : {}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return this.#client;
|
|
192
|
+
}
|
|
193
|
+
#translateError(err, op) {
|
|
194
|
+
if (err instanceof MemoryAdapterError) return err;
|
|
195
|
+
const status = err?.status ?? err?.statusCode;
|
|
196
|
+
const message = err?.message ?? String(err);
|
|
197
|
+
if (status === 401 || status === 403) {
|
|
198
|
+
return new MemoryAdapterError(`Supermemory auth failed (${op}): ${message}`, {
|
|
199
|
+
adapterId: ADAPTER_ID2,
|
|
200
|
+
code: "auth_failed",
|
|
201
|
+
cause: err
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
if (status === 429) {
|
|
205
|
+
return new MemoryAdapterError(`Supermemory rate limited (${op}): ${message}`, {
|
|
206
|
+
adapterId: ADAPTER_ID2,
|
|
207
|
+
code: "rate_limited",
|
|
208
|
+
cause: err
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
if (status === 404) {
|
|
212
|
+
return new MemoryAdapterError(`Supermemory not found (${op}): ${message}`, {
|
|
213
|
+
adapterId: ADAPTER_ID2,
|
|
214
|
+
code: "not_found",
|
|
215
|
+
cause: err
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
if (status === void 0 && message.toLowerCase().includes("network")) {
|
|
219
|
+
return new MemoryAdapterError(`Supermemory network error (${op}): ${message}`, {
|
|
220
|
+
adapterId: ADAPTER_ID2,
|
|
221
|
+
code: "network",
|
|
222
|
+
cause: err
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return new MemoryAdapterError(`Supermemory error (${op}): ${message}`, {
|
|
226
|
+
adapterId: ADAPTER_ID2,
|
|
227
|
+
code: "unknown",
|
|
228
|
+
cause: err
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// src/index.ts
|
|
234
|
+
function supermemoryMemory(options) {
|
|
235
|
+
return definePlugin({
|
|
236
|
+
name: "@theokit/memory-supermemory",
|
|
237
|
+
version: "0.1.0",
|
|
238
|
+
kind: "memory",
|
|
239
|
+
createProvider: () => new SupermemoryAdapter(options)
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export { supermemoryMemory };
|
|
244
|
+
//# sourceMappingURL=index.js.map
|
|
245
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/translate.ts","../src/adapter.ts","../src/index.ts"],"names":["ADAPTER_ID","MemoryAdapterError"],"mappings":";;;;AAeA,IAAM,UAAA,GAAa,kBAAA;AACnB,IAAM,UAAA,GAAa,aAAA;AAEZ,SAAS,kBAAA,CAAmB,OAAe,SAAA,EAA2B;AAC3E,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,WAAW,CAAA,EAAG;AACnD,IAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,qBAAA,EAAwB,SAAS,CAAA,2BAAA,CAAA,EAA+B;AAAA,MAC3F,SAAA,EAAW,UAAA;AAAA,MACX,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACA,EAAA,IAAI,CAAC,UAAA,CAAW,IAAA,CAAK,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,CAAA,qBAAA,EAAwB,SAAS,CAAA,EAAA,EAAK,KAAK,CAAA,oDAAA,CAAA;AAAA,MAC3C,EAAE,SAAA,EAAW,UAAA,EAAY,IAAA,EAAM,eAAA;AAAgB,KACjD;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AASO,SAAS,kBAAA,CAAmB,KAAoB,MAAA,EAA0B;AAC/E,EAAA,MAAM,UAAA,GAAa,kBAAA,CAAmB,MAAA,EAAQ,QAAQ,CAAA;AACtD,EAAA,MAAM,IAAA,GAAiB,CAAC,CAAA,EAAG,UAAU,CAAA,MAAA,EAAS,mBAAmB,GAAA,CAAI,MAAA,EAAQ,QAAQ,CAAC,CAAA,CAAE,CAAA;AACxF,EAAA,IAAI,GAAA,CAAI,YAAY,MAAA,EAAW;AAC7B,IAAA,IAAA,CAAK,IAAA,CAAK,GAAG,UAAU,CAAA,OAAA,EAAU,mBAAmB,GAAA,CAAI,OAAA,EAAS,SAAS,CAAC,CAAA,CAAE,CAAA;AAAA,EAC/E;AACA,EAAA,IAAI,GAAA,CAAI,aAAa,MAAA,EAAW;AAC9B,IAAA,IAAA,CAAK,IAAA,CAAK,GAAG,UAAU,CAAA,QAAA,EAAW,mBAAmB,GAAA,CAAI,QAAA,EAAU,UAAU,CAAC,CAAA,CAAE,CAAA;AAAA,EAClF;AACA,EAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAW;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,IAAA,EAAM;AACxB,MAAA,IAAA,CAAK,IAAA,CAAK,GAAG,UAAU,CAAA,KAAA,EAAQ,mBAAmB,CAAA,EAAG,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,IAC/D;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAQO,SAAS,mBAAA,CAAoB,KAAoB,MAAA,EAAwB;AAC9E,EAAA,MAAM,UAAA,GAAa,kBAAA,CAAmB,MAAA,EAAQ,QAAQ,CAAA;AACtD,EAAA,OAAO,GAAG,UAAU,CAAA,MAAA,EAAS,mBAAmB,GAAA,CAAI,MAAA,EAAQ,QAAQ,CAAC,CAAA,CAAA;AACvE;;;AC7BA,IAAMA,WAAAA,GAAa,aAAA;AAEnB,IAAM,IAAA,GAAkC;AAAA,EACtC,OAAA,EAAS,KAAA;AAAA,EACT,QAAA,EAAU,KAAA;AAAA,EACV,OAAA,EAAS,IAAA;AAAA,EACT,SAAA,EAAW,KAAA;AAAA,EACX,WAAA,EAAa,IAAA;AAAA,EACb,QAAA,EAAU;AACZ,CAAA;AAQO,IAAM,qBAAN,MAAkD;AAAA,EAC9C,EAAA,GAAKA,WAAAA;AAAA,EACL,YAAA,GAAe,IAAA;AAAA,EACf,KAAA;AAAA,EACT,OAAA;AAAA,EAEA,YAAY,IAAA,EAAiC;AAC3C,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,EACf;AAAA,EAEA,WAAA,GAAuB;AACrB,IAAA,OAAO,OAAO,KAAK,KAAA,CAAM,MAAA,KAAW,YAAY,IAAA,CAAK,KAAA,CAAM,OAAO,MAAA,GAAS,CAAA;AAAA,EAC7E;AAAA,EAEA,MAAM,UAAA,GAA4B;AAAA,EAGlC;AAAA,EAEA,MAAM,KAAA,CAAM,OAAA,EAAuC,GAAA,EAAuC;AACxF,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,cAAA,CAAe,OAAO,CAAA;AACxC,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,MAAM,IAAIC,mBAAmB,sBAAA,EAAwB;AAAA,QACnD,SAAA,EAAWD,WAAAA;AAAA,QACX,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH;AACA,IAAA,MAAM,aAAA,GAAgB,kBAAA,CAAmB,GAAA,EAAK,IAAA,CAAK,SAAS,CAAA;AAC5D,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,MAAM,IAAA,CAAK,IAAA,EAAK,CAAE,UAAU,GAAA,CAAI;AAAA,QAC3C,OAAA,EAAS,IAAA;AAAA,QACT,aAAA;AAAA,QACA,GAAI,IAAI,QAAA,KAAa,KAAA,CAAA,GAAY,EAAE,QAAA,EAAU,GAAA,CAAI,QAAA,EAAmC,GAAI;AAAC,OAC1F,CAAA;AACD,MAAA,OAAO,UAAA,CAAWA,WAAAA,EAAY,IAAA,CAAK,EAAE,CAAA;AAAA,IACvC,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,IAAA,CAAK,eAAA,CAAgB,GAAA,EAAK,OAAO,CAAA;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAM,MAAA,CAAO,KAAA,EAAe,GAAA,EAAoB,IAAI,EAAA,EAA2B;AAC7E,IAAA,IAAI,CAAA,IAAK,CAAA,EAAG,OAAO,EAAC;AACpB,IAAA,MAAM,YAAA,GAAe,mBAAA,CAAoB,GAAA,EAAK,IAAA,CAAK,SAAS,CAAA;AAC5D,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,MAAM,IAAA,CAAK,IAAA,EAAK,CAAE,OAAO,QAAA,CAAS;AAAA,QAC7C,CAAA,EAAG,KAAA;AAAA,QACH,YAAA;AAAA,QACA,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,IAAW,EAAC;AACjC,MAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,UAAU,CAAA;AAAA,IACpC,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,IAAA,CAAK,eAAA,CAAgB,GAAA,EAAK,QAAQ,CAAA;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,EAAA,EAA6B;AACxC,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,EAAA,EAAIA,WAAU,CAAA;AACzC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,IAAA,EAAK,CAAE,SAAA,CAAU,OAAO,KAAK,CAAA;AAAA,IAC1C,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,IAAA,CAAK,eAAA,CAAgB,GAAA,EAAK,QAAQ,CAAA;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,cAAA,GAAqC;AACnC,IAAA,OAAO;AAAA,MACL;AAAA,QACE,IAAA,EAAM,cAAA;AAAA,QACN,WAAA,EACE,yGAAA;AAAA,QAEF,UAAA,EAAY;AAAA,UACV,IAAA,EAAM,QAAA;AAAA,UACN,UAAA,EAAY;AAAA,YACV,OAAA,EAAS,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,gCAAA;AAAiC,WAC3E;AAAA,UACA,QAAA,EAAU,CAAC,SAAS;AAAA;AACtB,OACF;AAAA,MACA;AAAA,QACE,IAAA,EAAM,eAAA;AAAA,QACN,WAAA,EACE,8IAAA;AAAA,QAEF,UAAA,EAAY;AAAA,UACV,IAAA,EAAM,QAAA;AAAA,UACN,UAAA,EAAY;AAAA,YACV,KAAA,EAAO,EAAE,IAAA,EAAM,QAAA,EAAU,aAAa,mCAAA,EAAoC;AAAA,YAC1E,CAAA,EAAG;AAAA,cACD,IAAA,EAAM,SAAA;AAAA,cACN,OAAA,EAAS,CAAA;AAAA,cACT,OAAA,EAAS,EAAA;AAAA,cACT,WAAA,EAAa;AAAA;AACf,WACF;AAAA,UACA,QAAA,EAAU,CAAC,OAAO;AAAA;AACpB;AACF,KACF;AAAA,EACF;AAAA,EAEA,MAAM,cAAA,CACJ,IAAA,EACA,IAAA,EACA,GAAA,EACiB;AACjB,IAAA,IAAI,SAAS,cAAA,EAAgB;AAC3B,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,OAAA,IAAW,EAAE,CAAA;AACzC,MAAA,MAAM,EAAA,GAAK,MAAM,IAAA,CAAK,KAAA,CAAM,SAAS,GAAG,CAAA;AACxC,MAAA,OAAO,KAAK,SAAA,CAAU,EAAE,EAAA,EAAI,IAAA,EAAM,IAAI,CAAA;AAAA,IACxC;AACA,IAAA,IAAI,SAAS,eAAA,EAAiB;AAC5B,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,KAAA,IAAS,EAAE,CAAA;AACrC,MAAA,MAAM,IAAI,OAAO,IAAA,CAAK,CAAA,KAAM,QAAA,GAAW,KAAK,CAAA,GAAI,EAAA;AAChD,MAAA,MAAM,QAAQ,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,KAAK,CAAC,CAAA;AAC7C,MAAA,OAAO,KAAK,SAAA,CAAU,EAAE,EAAA,EAAI,IAAA,EAAM,OAAO,CAAA;AAAA,IAC3C;AACA,IAAA,MAAM,IAAIC,kBAAAA,CAAmB,CAAA,mBAAA,EAAsB,IAAI,CAAA,CAAA,EAAI;AAAA,MACzD,SAAA,EAAWD,WAAAA;AAAA,MACX,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,QAAA,GAA0B;AAC9B,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA;AAAA,EACjB;AAAA;AAAA,EAIA,OAAA,GAAkB;AAChB,IAAA,OAAO,IAAA,CAAK,MAAM,kBAAA,IAAsB,SAAA;AAAA,EAC1C;AAAA,EAEA,eAAe,OAAA,EAA+C;AAC5D,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,QAAQ,IAAA,EAAK;AACrD,IAAA,OAAO,OAAA,CACJ,GAAA,CAAI,CAAC,CAAA,KAAM,GAAG,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA,CACpC,IAAA,CAAK,IAAI,EACT,IAAA,EAAK;AAAA,EACV;AAAA,EAEA,UAAA,GAAa,CAAC,CAAA,KAA2B;AACvC,IAAA,MAAM,GAAA,GAAO,KAAiC,EAAC;AAE/C,IAAA,MAAM,MAAA,GAAU,IAAI,MAAA,IAAkD,GAAA;AACtE,IAAA,MAAM,QAAQ,MAAA,CAAO,MAAA,CAAO,EAAA,IAAM,GAAA,CAAI,MAAM,EAAE,CAAA;AAC9C,IAAA,MAAM,OAAA,GAAU,OAAO,MAAA,CAAO,OAAA,IAAW,OAAO,IAAA,IAAQ,GAAA,CAAI,WAAW,EAAE,CAAA;AACzE,IAAA,MAAM,QAAQ,OAAO,GAAA,CAAI,KAAA,KAAU,QAAA,GAAW,IAAI,KAAA,GAAQ,MAAA;AAC1D,IAAA,MAAM,YAAY,OAAO,MAAA,CAAO,SAAA,KAAc,QAAA,GAAW,OAAO,SAAA,GAAY,MAAA;AAC5E,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,UAAA,CAAWA,WAAAA,EAAY,KAAK,CAAA;AAAA,MAChC,OAAA;AAAA,MACA,GAAI,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,KAAU,EAAC;AAAA,MACvC,GAAI,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,KAAc;AAAC,KACjD;AAAA,EACF,CAAA;AAAA,EAEA,IAAA,GAAoB;AAClB,IAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAW;AAC9B,MAAA,IAAA,CAAK,OAAA,GAAU,IAAI,iBAAA,CAAkB;AAAA,QACnC,MAAA,EAAQ,KAAK,KAAA,CAAM,MAAA;AAAA,QACnB,GAAI,IAAA,CAAK,KAAA,CAAM,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,IAAA,CAAK,KAAA,CAAM,OAAA,EAAQ,GAAI;AAAC,OAC3E,CAAA;AAAA,IACH;AACA,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA,EAEA,eAAA,CAAgB,KAAc,EAAA,EAAgC;AAC5D,IAAA,IAAI,GAAA,YAAeC,oBAAoB,OAAO,GAAA;AAC9C,IAAA,MAAM,MAAA,GACH,GAAA,EAAkD,MAAA,IAClD,GAAA,EAAiC,UAAA;AACpC,IAAA,MAAM,OAAA,GAAW,GAAA,EAAe,OAAA,IAAW,MAAA,CAAO,GAAG,CAAA;AACrD,IAAA,IAAI,MAAA,KAAW,GAAA,IAAO,MAAA,KAAW,GAAA,EAAK;AACpC,MAAA,OAAO,IAAIA,kBAAAA,CAAmB,CAAA,yBAAA,EAA4B,EAAE,CAAA,GAAA,EAAM,OAAO,CAAA,CAAA,EAAI;AAAA,QAC3E,SAAA,EAAWD,WAAAA;AAAA,QACX,IAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,IACH;AACA,IAAA,IAAI,WAAW,GAAA,EAAK;AAClB,MAAA,OAAO,IAAIC,kBAAAA,CAAmB,CAAA,0BAAA,EAA6B,EAAE,CAAA,GAAA,EAAM,OAAO,CAAA,CAAA,EAAI;AAAA,QAC5E,SAAA,EAAWD,WAAAA;AAAA,QACX,IAAA,EAAM,cAAA;AAAA,QACN,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,IACH;AACA,IAAA,IAAI,WAAW,GAAA,EAAK;AAClB,MAAA,OAAO,IAAIC,kBAAAA,CAAmB,CAAA,uBAAA,EAA0B,EAAE,CAAA,GAAA,EAAM,OAAO,CAAA,CAAA,EAAI;AAAA,QACzE,SAAA,EAAWD,WAAAA;AAAA,QACX,IAAA,EAAM,WAAA;AAAA,QACN,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,IACH;AACA,IAAA,IAAI,WAAW,MAAA,IAAa,OAAA,CAAQ,aAAY,CAAE,QAAA,CAAS,SAAS,CAAA,EAAG;AACrE,MAAA,OAAO,IAAIC,kBAAAA,CAAmB,CAAA,2BAAA,EAA8B,EAAE,CAAA,GAAA,EAAM,OAAO,CAAA,CAAA,EAAI;AAAA,QAC7E,SAAA,EAAWD,WAAAA;AAAA,QACX,IAAA,EAAM,SAAA;AAAA,QACN,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,IACH;AACA,IAAA,OAAO,IAAIC,kBAAAA,CAAmB,CAAA,mBAAA,EAAsB,EAAE,CAAA,GAAA,EAAM,OAAO,CAAA,CAAA,EAAI;AAAA,MACrE,SAAA,EAAWD,WAAAA;AAAA,MACX,IAAA,EAAM,SAAA;AAAA,MACN,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AACF,CAAA;;;ACnOO,SAAS,kBAAkB,OAAA,EAA4C;AAC5E,EAAA,OAAO,YAAA,CAAa;AAAA,IAClB,IAAA,EAAM,6BAAA;AAAA,IACN,OAAA,EAAS,OAAA;AAAA,IACT,IAAA,EAAM,QAAA;AAAA,IACN,cAAA,EAAgB,MAAM,IAAI,kBAAA,CAAmB,OAAO;AAAA,GACrD,CAAA;AACH","file":"index.js","sourcesContent":["/**\n * `MemoryContext` → Supermemory containerTags translation (T3.2).\n *\n * EC-C fix: every component runs through a strict identifier sanitizer\n * (regex `^[a-zA-Z0-9_-]+$`) before being joined with `:`. Rejects with\n * `MemoryAdapterError(code: \"invalid_input\")` on invalid input, so a\n * value like `userId: \"user:123\"` cannot silently land in a different\n * bucket via tag mis-parsing.\n *\n * @internal\n */\n\nimport type { MemoryContext } from \"@theokit/sdk\";\nimport { MemoryAdapterError } from \"@theokit/sdk\";\n\nconst SAFE_IDENT = /^[a-zA-Z0-9_-]+$/;\nconst ADAPTER_ID = \"supermemory\";\n\nexport function sanitizeIdentifier(value: string, fieldName: string): string {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new MemoryAdapterError(`Supermemory adapter: ${fieldName} must be a non-empty string`, {\n adapterId: ADAPTER_ID,\n code: \"invalid_input\",\n });\n }\n if (!SAFE_IDENT.test(value)) {\n throw new MemoryAdapterError(\n `Supermemory adapter: ${fieldName} \"${value}\" contains invalid characters (allowed: a-zA-Z0-9_-)`,\n { adapterId: ADAPTER_ID, code: \"invalid_input\" },\n );\n }\n return value;\n}\n\n/**\n * Build the array of containerTags for `documents.add`. Each component\n * is sanitized; collisions across tag namespaces (user/agent/tenant/tag)\n * are intentional — Supermemory treats containerTags as a set.\n *\n * @internal\n */\nexport function buildContainerTags(ctx: MemoryContext, prefix: string): string[] {\n const safePrefix = sanitizeIdentifier(prefix, \"prefix\");\n const tags: string[] = [`${safePrefix}:user:${sanitizeIdentifier(ctx.userId, \"userId\")}`];\n if (ctx.agentId !== undefined) {\n tags.push(`${safePrefix}:agent:${sanitizeIdentifier(ctx.agentId, \"agentId\")}`);\n }\n if (ctx.tenantId !== undefined) {\n tags.push(`${safePrefix}:tenant:${sanitizeIdentifier(ctx.tenantId, \"tenantId\")}`);\n }\n if (ctx.tags !== undefined) {\n for (const t of ctx.tags) {\n tags.push(`${safePrefix}:tag:${sanitizeIdentifier(t, \"tag\")}`);\n }\n }\n return tags;\n}\n\n/**\n * Pick the primary containerTag for `search.memories` (which takes a\n * single string, not an array). The user tag is canonical.\n *\n * @internal\n */\nexport function primaryContainerTag(ctx: MemoryContext, prefix: string): string {\n const safePrefix = sanitizeIdentifier(prefix, \"prefix\");\n return `${safePrefix}:user:${sanitizeIdentifier(ctx.userId, \"userId\")}`;\n}\n","/**\n * SupermemoryAdapter — `@theokit-memory-supermemory` core (T3.2, ADR D141).\n *\n * Wraps `supermemory` SDK v4. Implements `MemoryAdapter` so the SDK's\n * `pre_user_send` / `post_assistant_reply` hooks (D145) and\n * `agent.memory.*` direct API (D142) work end-to-end against Supermemory's\n * managed memory + RAG service.\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 MemoryToolSchema,\n type MemoryTurnMessage,\n mkMemoryId,\n} from \"@theokit/sdk\";\nimport type Supermemory from \"supermemory\";\nimport SupermemoryClient from \"supermemory\";\n\nimport { buildContainerTags, primaryContainerTag } from \"./translate.js\";\n\n/** Configuration accepted by the `supermemoryMemory(...)` factory. @public */\nexport interface SupermemoryAdapterOptions {\n /** Supermemory API key. Falls back to `SUPERMEMORY_API_KEY`. */\n apiKey: string;\n /** Base URL override for self-hosted Supermemory deployments. */\n baseUrl?: string;\n /** Prefix for every containerTag (default `\"theokit\"`). Useful for test isolation (EC-S). */\n containerTagPrefix?: string;\n}\n\nconst ADAPTER_ID = \"supermemory\";\n\nconst CAPS: MemoryAdapterCapabilities = {\n history: false,\n sessions: false,\n tenancy: true,\n reasoning: false,\n toolSchemas: true,\n prefetch: false,\n};\n\n/**\n * SDK-internal adapter class. Construct via `supermemoryMemory(...)`\n * factory from `./index.ts`, not directly.\n *\n * @internal\n */\nexport class SupermemoryAdapter implements MemoryAdapter {\n readonly id = ADAPTER_ID;\n readonly capabilities = CAPS;\n readonly #opts: SupermemoryAdapterOptions;\n #client?: Supermemory;\n\n constructor(opts: SupermemoryAdapterOptions) {\n this.#opts = opts;\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: defer the actual client construction until first call.\n // initialize() is idempotent — see EC-3 / EC-I.\n }\n\n async write(content: string | MemoryTurnMessage[], ctx: MemoryContext): Promise<MemoryId> {\n const text = this.#renderContent(content);\n if (text.length === 0) {\n throw new MemoryAdapterError(\"write: empty content\", {\n adapterId: ADAPTER_ID,\n code: \"invalid_input\",\n });\n }\n const containerTags = buildContainerTags(ctx, this.#prefix());\n try {\n const resp = await this.#sdk().documents.add({\n content: text,\n containerTags,\n ...(ctx.metadata !== undefined ? { metadata: ctx.metadata as Record<string, string> } : {}),\n });\n return mkMemoryId(ADAPTER_ID, resp.id);\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 const containerTag = primaryContainerTag(ctx, this.#prefix());\n try {\n const resp = await this.#sdk().search.memories({\n q: query,\n containerTag,\n limit: k,\n rerank: true,\n });\n const results = resp.results ?? [];\n return results.map(this.#mapResult);\n } catch (err) {\n throw this.#translateError(err, \"recall\");\n }\n }\n\n async delete(id: MemoryId): Promise<void> {\n const rawId = extractRawId(id, ADAPTER_ID);\n try {\n await this.#sdk().documents.delete(rawId);\n } catch (err) {\n throw this.#translateError(err, \"delete\");\n }\n }\n\n getToolSchemas(): MemoryToolSchema[] {\n return [\n {\n name: \"memory_write\",\n description:\n \"Persist a fact about the user or context to Supermemory long-term memory. \" +\n \"Returns the stored memory ID.\",\n parameters: {\n type: \"object\",\n properties: {\n content: { type: \"string\", description: \"Fact text to persist verbatim.\" },\n },\n required: [\"content\"],\n },\n },\n {\n name: \"memory_recall\",\n description:\n \"Retrieve up to k semantically relevant facts from Supermemory long-term memory. \" +\n \"Returns an array of {id, content, score, createdAt} objects.\",\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Free-text query to search memory.\" },\n k: {\n type: \"integer\",\n minimum: 1,\n maximum: 50,\n description: \"Max results (default 10).\",\n },\n },\n required: [\"query\"],\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 content = String(args.content ?? \"\");\n const id = await this.write(content, ctx);\n return JSON.stringify({ ok: true, id });\n }\n if (name === \"memory_recall\") {\n const query = String(args.query ?? \"\");\n const k = typeof args.k === \"number\" ? args.k : 10;\n const facts = await this.recall(query, ctx, k);\n return JSON.stringify({ ok: true, facts });\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 // ── helpers ────────────────────────────────────────────────────────\n\n #prefix(): string {\n return this.#opts.containerTagPrefix ?? \"theokit\";\n }\n\n #renderContent(content: string | MemoryTurnMessage[]): string {\n if (typeof content === \"string\") return content.trim();\n return content\n .map((m) => `${m.role}: ${m.content}`)\n .join(\"\\n\")\n .trim();\n }\n\n #mapResult = (r: unknown): MemoryFact => {\n const obj = (r as Record<string, unknown>) ?? {};\n // SDK shape: { memory?: { id, content, ... }, score, ... } or chunk shape.\n const memory = (obj.memory as Record<string, unknown> | undefined) ?? obj;\n const rawId = String(memory.id ?? obj.id ?? \"\");\n const content = String(memory.content ?? memory.text ?? obj.content ?? \"\");\n const score = typeof obj.score === \"number\" ? obj.score : undefined;\n const createdAt = typeof memory.createdAt === \"string\" ? memory.createdAt : undefined;\n return {\n id: mkMemoryId(ADAPTER_ID, rawId),\n content,\n ...(score !== undefined ? { score } : {}),\n ...(createdAt !== undefined ? { createdAt } : {}),\n };\n };\n\n #sdk(): Supermemory {\n if (this.#client === undefined) {\n this.#client = new SupermemoryClient({\n apiKey: this.#opts.apiKey,\n ...(this.#opts.baseUrl !== undefined ? { baseURL: this.#opts.baseUrl } : {}),\n });\n }\n return this.#client;\n }\n\n #translateError(err: unknown, op: string): MemoryAdapterError {\n if (err instanceof MemoryAdapterError) return err;\n const status =\n (err as { status?: number; statusCode?: number })?.status ??\n (err as { statusCode?: number })?.statusCode;\n const message = (err as Error)?.message ?? String(err);\n if (status === 401 || status === 403) {\n return new MemoryAdapterError(`Supermemory auth failed (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"auth_failed\",\n cause: err,\n });\n }\n if (status === 429) {\n return new MemoryAdapterError(`Supermemory 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(`Supermemory not found (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"not_found\",\n cause: err,\n });\n }\n if (status === undefined && message.toLowerCase().includes(\"network\")) {\n return new MemoryAdapterError(`Supermemory network error (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"network\",\n cause: err,\n });\n }\n return new MemoryAdapterError(`Supermemory error (${op}): ${message}`, {\n adapterId: ADAPTER_ID,\n code: \"unknown\",\n cause: err,\n });\n }\n}\n","/**\n * `@theokit/memory-supermemory` — Supermemory memory adapter for @theokit/sdk.\n *\n * Usage:\n *\n * ```ts\n * import { Agent } from \"@theokit/sdk\";\n * import { supermemoryMemory } from \"@theokit/memory-supermemory\";\n *\n * const agent = await Agent.create({\n * apiKey: process.env.OPENROUTER_API_KEY,\n * model: { id: \"openai/gpt-4o-mini\" },\n * local: {},\n * plugins: [supermemoryMemory({ apiKey: process.env.SUPERMEMORY_API_KEY! })],\n * memoryContext: { userId: \"demo\" },\n * });\n *\n * await agent.memory.write(\"User likes Brazilian jazz\", { userId: \"demo\" });\n * const facts = await agent.memory.recall(\"music preferences\", { userId: \"demo\" });\n * ```\n *\n * @public\n */\n\nimport type { Plugin } from \"@theokit/sdk\";\nimport { definePlugin } from \"@theokit/sdk\";\n\nimport { SupermemoryAdapter, type SupermemoryAdapterOptions } from \"./adapter.js\";\n\nexport type { SupermemoryAdapterOptions } from \"./adapter.js\";\n\n/**\n * Build a `Plugin { kind: \"memory\" }` ready to pass to\n * `Agent.create({ plugins: [...] })`.\n *\n * @public\n */\nexport function supermemoryMemory(options: SupermemoryAdapterOptions): Plugin {\n return definePlugin({\n name: \"@theokit/memory-supermemory\",\n version: \"0.1.0\",\n kind: \"memory\",\n createProvider: () => new SupermemoryAdapter(options),\n });\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@theokit/memory-supermemory",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Supermemory memory adapter for @theokit/sdk — wraps supermemory@^4 with the MemoryAdapter contract (ADR D141).",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.12.0"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.cjs",
|
|
11
|
+
"module": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"require": {
|
|
20
|
+
"types": "./dist/index.d.cts",
|
|
21
|
+
"default": "./dist/index.cjs"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE",
|
|
29
|
+
"CHANGELOG.md"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"test": "vitest run"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"@theokit/sdk": "workspace:^",
|
|
38
|
+
"supermemory": "^4.21.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@theokit/sdk": "workspace:*",
|
|
42
|
+
"supermemory": "^4.21.1",
|
|
43
|
+
"tsup": "^8.5.0",
|
|
44
|
+
"typescript": "^5.8.0",
|
|
45
|
+
"vitest": "^3.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|