@agentskit/memory 0.8.1 → 0.9.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/dist/chunk-G5S2A3MJ.js +48 -0
- package/dist/chunk-G5S2A3MJ.js.map +1 -0
- package/dist/index.cjs +206 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +105 -32
- package/dist/index.d.ts +105 -32
- package/dist/index.js +206 -90
- package/dist/index.js.map +1 -1
- package/dist/personalization.cjs +44 -0
- package/dist/personalization.cjs.map +1 -0
- package/dist/personalization.d.cts +32 -0
- package/dist/personalization.d.ts +32 -0
- package/dist/personalization.js +3 -0
- package/dist/personalization.js.map +1 -0
- package/package.json +15 -9
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/personalization.ts
|
|
9
|
+
function createInMemoryPersonalization() {
|
|
10
|
+
const profiles = /* @__PURE__ */ new Map();
|
|
11
|
+
return {
|
|
12
|
+
async get(subjectId) {
|
|
13
|
+
const hit = profiles.get(subjectId);
|
|
14
|
+
return hit ? { ...hit, traits: { ...hit.traits } } : null;
|
|
15
|
+
},
|
|
16
|
+
async set(profile) {
|
|
17
|
+
profiles.set(profile.subjectId, {
|
|
18
|
+
...profile,
|
|
19
|
+
traits: { ...profile.traits },
|
|
20
|
+
updatedAt: profile.updatedAt || (/* @__PURE__ */ new Date()).toISOString()
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
async merge(subjectId, traits) {
|
|
24
|
+
const existing = profiles.get(subjectId);
|
|
25
|
+
const next = {
|
|
26
|
+
subjectId,
|
|
27
|
+
traits: { ...existing?.traits ?? {}, ...traits },
|
|
28
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
29
|
+
};
|
|
30
|
+
profiles.set(subjectId, next);
|
|
31
|
+
return { ...next, traits: { ...next.traits } };
|
|
32
|
+
},
|
|
33
|
+
async delete(subjectId) {
|
|
34
|
+
profiles.delete(subjectId);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function renderProfileContext(profile) {
|
|
39
|
+
if (!profile || Object.keys(profile.traits).length === 0) return "";
|
|
40
|
+
const lines = Object.entries(profile.traits).filter(([, value]) => value !== void 0 && value !== null && value !== "").map(([key, value]) => `- ${key}: ${typeof value === "string" ? value : JSON.stringify(value)}`);
|
|
41
|
+
if (lines.length === 0) return "";
|
|
42
|
+
return `## User profile
|
|
43
|
+
${lines.join("\n")}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { __require, createInMemoryPersonalization, renderProfileContext };
|
|
47
|
+
//# sourceMappingURL=chunk-G5S2A3MJ.js.map
|
|
48
|
+
//# sourceMappingURL=chunk-G5S2A3MJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/personalization.ts"],"names":[],"mappings":";;;;;;;;AA0BO,SAAS,6BAAA,GAAsD;AACpE,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAoC;AAEzD,EAAA,OAAO;AAAA,IACL,MAAM,IAAI,SAAA,EAAW;AACnB,MAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA;AAClC,MAAA,OAAO,GAAA,GAAM,EAAE,GAAG,GAAA,EAAK,MAAA,EAAQ,EAAE,GAAG,GAAA,CAAI,MAAA,EAAO,EAAE,GAAI,IAAA;AAAA,IACvD,CAAA;AAAA,IACA,MAAM,IAAI,OAAA,EAAS;AACjB,MAAA,QAAA,CAAS,GAAA,CAAI,QAAQ,SAAA,EAAW;AAAA,QAC9B,GAAG,OAAA;AAAA,QACH,MAAA,EAAQ,EAAE,GAAG,OAAA,CAAQ,MAAA,EAAO;AAAA,QAC5B,WAAW,OAAA,CAAQ,SAAA,IAAA,iBAAa,IAAI,IAAA,IAAO,WAAA;AAAY,OACxD,CAAA;AAAA,IACH,CAAA;AAAA,IACA,MAAM,KAAA,CAAM,SAAA,EAAW,MAAA,EAAQ;AAC7B,MAAA,MAAM,QAAA,GAAW,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA;AACvC,MAAA,MAAM,IAAA,GAA+B;AAAA,QACnC,SAAA;AAAA,QACA,MAAA,EAAQ,EAAE,GAAI,QAAA,EAAU,UAAU,EAAC,EAAI,GAAG,MAAA,EAAO;AAAA,QACjD,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,OACpC;AACA,MAAA,QAAA,CAAS,GAAA,CAAI,WAAW,IAAI,CAAA;AAC5B,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,EAAE,GAAG,IAAA,CAAK,QAAO,EAAE;AAAA,IAC/C,CAAA;AAAA,IACA,MAAM,OAAO,SAAA,EAAW;AACtB,MAAA,QAAA,CAAS,OAAO,SAAS,CAAA;AAAA,IAC3B;AAAA,GACF;AACF;AAOO,SAAS,qBAAqB,OAAA,EAAgD;AACnF,EAAA,IAAI,CAAC,WAAW,MAAA,CAAO,IAAA,CAAK,QAAQ,MAAM,CAAA,CAAE,MAAA,KAAW,CAAA,EAAG,OAAO,EAAA;AACjE,EAAA,MAAM,QAAQ,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,MAAM,EACxC,MAAA,CAAO,CAAC,GAAG,KAAK,CAAA,KAAM,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,QAAQ,KAAA,KAAU,EAAE,CAAA,CAC3E,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM,KAAK,GAAG,CAAA,EAAA,EAAK,OAAO,KAAA,KAAU,WAAW,KAAA,GAAQ,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA,CAAE,CAAA;AACjG,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,EAAA;AAC/B,EAAA,OAAO,CAAA;AAAA,EAAoB,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAC7C","file":"chunk-G5S2A3MJ.js","sourcesContent":["/**\n * Personalization — a persisted profile per subject (user id,\n * account id, device). The agent reads it on every run to\n * condition responses; the runtime updates it when new facts\n * appear.\n */\n\nexport interface PersonalizationProfile {\n subjectId: string\n /** Human-editable notes, facts, preferences. */\n traits: Record<string, unknown>\n /** ISO timestamp of the latest update. */\n updatedAt: string\n}\n\nexport interface PersonalizationStore {\n get: (subjectId: string) => Promise<PersonalizationProfile | null>\n set: (profile: PersonalizationProfile) => Promise<void>\n merge: (subjectId: string, traits: Record<string, unknown>) => Promise<PersonalizationProfile>\n delete?: (subjectId: string) => Promise<void>\n}\n\n/**\n * In-memory personalization store — tests, single-process demos.\n * Bring your own for production (Postgres, Redis, DynamoDB).\n */\nexport function createInMemoryPersonalization(): PersonalizationStore {\n const profiles = new Map<string, PersonalizationProfile>()\n\n return {\n async get(subjectId) {\n const hit = profiles.get(subjectId)\n return hit ? { ...hit, traits: { ...hit.traits } } : null\n },\n async set(profile) {\n profiles.set(profile.subjectId, {\n ...profile,\n traits: { ...profile.traits },\n updatedAt: profile.updatedAt || new Date().toISOString(),\n })\n },\n async merge(subjectId, traits) {\n const existing = profiles.get(subjectId)\n const next: PersonalizationProfile = {\n subjectId,\n traits: { ...(existing?.traits ?? {}), ...traits },\n updatedAt: new Date().toISOString(),\n }\n profiles.set(subjectId, next)\n return { ...next, traits: { ...next.traits } }\n },\n async delete(subjectId) {\n profiles.delete(subjectId)\n },\n }\n}\n\n/**\n * Render a profile into a system-prompt fragment the runtime can\n * prepend. Kept intentionally short — full profile dumps bloat\n * context and leak unnecessary detail to the model.\n */\nexport function renderProfileContext(profile: PersonalizationProfile | null): string {\n if (!profile || Object.keys(profile.traits).length === 0) return ''\n const lines = Object.entries(profile.traits)\n .filter(([, value]) => value !== undefined && value !== null && value !== '')\n .map(([key, value]) => `- ${key}: ${typeof value === 'string' ? value : JSON.stringify(value)}`)\n if (lines.length === 0) return ''\n return `## User profile\\n${lines.join('\\n')}`\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var core = require('@agentskit/core');
|
|
4
|
+
var security = require('@agentskit/core/security');
|
|
4
5
|
|
|
5
6
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
6
7
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
@@ -21,7 +22,11 @@ function fileChatMemory(path) {
|
|
|
21
22
|
},
|
|
22
23
|
async save(messages) {
|
|
23
24
|
const fs = await import('fs/promises');
|
|
24
|
-
await fs.writeFile(
|
|
25
|
+
await fs.writeFile(
|
|
26
|
+
path,
|
|
27
|
+
JSON.stringify(core.serializeMessages(messages), null, 2),
|
|
28
|
+
{ encoding: "utf8", mode: 384 }
|
|
29
|
+
);
|
|
25
30
|
},
|
|
26
31
|
async clear() {
|
|
27
32
|
try {
|
|
@@ -49,7 +54,11 @@ async function openDatabase(path) {
|
|
|
49
54
|
const Database = mod.default ?? mod;
|
|
50
55
|
return new Database(path);
|
|
51
56
|
} catch {
|
|
52
|
-
throw new
|
|
57
|
+
throw new core.MemoryError({
|
|
58
|
+
code: core.ErrorCodes.AK_MEMORY_PEER_MISSING,
|
|
59
|
+
message: "Install better-sqlite3 to use sqliteChatMemory: npm install better-sqlite3",
|
|
60
|
+
hint: 'sqliteChatMemory uses the optional peer "better-sqlite3".'
|
|
61
|
+
});
|
|
53
62
|
}
|
|
54
63
|
}
|
|
55
64
|
function sqliteChatMemory(config) {
|
|
@@ -100,7 +109,11 @@ async function loadSdk() {
|
|
|
100
109
|
moduleId
|
|
101
110
|
);
|
|
102
111
|
} catch {
|
|
103
|
-
throw new
|
|
112
|
+
throw new core.MemoryError({
|
|
113
|
+
code: core.ErrorCodes.AK_MEMORY_PEER_MISSING,
|
|
114
|
+
message: "Install @libsql/client to use tursoChatMemory: npm install @libsql/client",
|
|
115
|
+
hint: 'tursoChatMemory uses the optional peer "@libsql/client".'
|
|
116
|
+
});
|
|
104
117
|
}
|
|
105
118
|
})();
|
|
106
119
|
}
|
|
@@ -161,14 +174,16 @@ function tursoChatMemory(config) {
|
|
|
161
174
|
}
|
|
162
175
|
};
|
|
163
176
|
}
|
|
164
|
-
|
|
165
|
-
// src/redis-client.ts
|
|
166
177
|
async function createRedisClientAdapter(url) {
|
|
167
178
|
let redis;
|
|
168
179
|
try {
|
|
169
180
|
redis = await import('redis');
|
|
170
181
|
} catch {
|
|
171
|
-
throw new
|
|
182
|
+
throw new core.MemoryError({
|
|
183
|
+
code: core.ErrorCodes.AK_MEMORY_PEER_MISSING,
|
|
184
|
+
message: "Install redis to use Redis memory backends: npm install redis",
|
|
185
|
+
hint: 'redisChatMemory and redisVectorMemory use the optional peer "redis".'
|
|
186
|
+
});
|
|
172
187
|
}
|
|
173
188
|
const client = redis.createClient({ url });
|
|
174
189
|
await client.connect();
|
|
@@ -187,7 +202,7 @@ async function createRedisClientAdapter(url) {
|
|
|
187
202
|
return await client.keys(pattern);
|
|
188
203
|
},
|
|
189
204
|
async disconnect() {
|
|
190
|
-
await client.
|
|
205
|
+
await client.close();
|
|
191
206
|
},
|
|
192
207
|
async call(command, ...args) {
|
|
193
208
|
return await client.sendCommand([command, ...args.map(String)]);
|
|
@@ -394,9 +409,11 @@ function requireVectra() {
|
|
|
394
409
|
try {
|
|
395
410
|
return __require("vectra");
|
|
396
411
|
} catch {
|
|
397
|
-
throw new
|
|
398
|
-
|
|
399
|
-
|
|
412
|
+
throw new core.MemoryError({
|
|
413
|
+
code: core.ErrorCodes.AK_MEMORY_PEER_MISSING,
|
|
414
|
+
message: "Install vectra to use fileVectorMemory: npm install vectra",
|
|
415
|
+
hint: 'fileVectorMemory uses the optional peer "vectra" for the on-disk index.'
|
|
416
|
+
});
|
|
400
417
|
}
|
|
401
418
|
}
|
|
402
419
|
function createVectraStore(dirPath) {
|
|
@@ -413,16 +430,23 @@ function createVectraStore(dirPath) {
|
|
|
413
430
|
return {
|
|
414
431
|
async upsert(docs) {
|
|
415
432
|
const idx = await getIndex();
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
433
|
+
await idx.beginUpdate();
|
|
434
|
+
try {
|
|
435
|
+
for (const doc of docs) {
|
|
436
|
+
await idx.insertItem({
|
|
437
|
+
vector: doc.vector,
|
|
438
|
+
metadata: { _id: doc.id, ...doc.metadata }
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
await idx.endUpdate();
|
|
442
|
+
} catch (err) {
|
|
443
|
+
idx.cancelUpdate();
|
|
444
|
+
throw err;
|
|
421
445
|
}
|
|
422
446
|
},
|
|
423
447
|
async query(vector, topK) {
|
|
424
448
|
const idx = await getIndex();
|
|
425
|
-
const results = await idx.queryItems(vector, topK);
|
|
449
|
+
const results = await idx.queryItems(vector, "", topK);
|
|
426
450
|
return results.map((r) => ({
|
|
427
451
|
id: String(r.item.metadata._id ?? ""),
|
|
428
452
|
score: r.score,
|
|
@@ -634,8 +658,6 @@ function pgvector(config) {
|
|
|
634
658
|
}
|
|
635
659
|
};
|
|
636
660
|
}
|
|
637
|
-
|
|
638
|
-
// src/vector/pinecone.ts
|
|
639
661
|
async function call(config, path, body) {
|
|
640
662
|
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
641
663
|
const response = await fetchImpl(`${config.indexUrl}${path}`, {
|
|
@@ -647,7 +669,13 @@ async function call(config, path, body) {
|
|
|
647
669
|
body: JSON.stringify(body)
|
|
648
670
|
});
|
|
649
671
|
const text = await response.text();
|
|
650
|
-
if (!response.ok)
|
|
672
|
+
if (!response.ok) {
|
|
673
|
+
throw new core.MemoryError({
|
|
674
|
+
code: core.ErrorCodes.AK_MEMORY_REMOTE_HTTP,
|
|
675
|
+
message: `pinecone ${response.status}: ${text.slice(0, 200)}`,
|
|
676
|
+
hint: `URL ${config.indexUrl}${path}. Check api-key + index URL/namespace.`
|
|
677
|
+
});
|
|
678
|
+
}
|
|
651
679
|
return text.length > 0 ? JSON.parse(text) : {};
|
|
652
680
|
}
|
|
653
681
|
function pinecone(config) {
|
|
@@ -687,8 +715,6 @@ function pinecone(config) {
|
|
|
687
715
|
}
|
|
688
716
|
};
|
|
689
717
|
}
|
|
690
|
-
|
|
691
|
-
// src/vector/qdrant.ts
|
|
692
718
|
async function call2(config, method, path, body) {
|
|
693
719
|
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
694
720
|
const response = await fetchImpl(`${config.url}${path}`, {
|
|
@@ -700,7 +726,13 @@ async function call2(config, method, path, body) {
|
|
|
700
726
|
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
701
727
|
});
|
|
702
728
|
const text = await response.text();
|
|
703
|
-
if (!response.ok)
|
|
729
|
+
if (!response.ok) {
|
|
730
|
+
throw new core.MemoryError({
|
|
731
|
+
code: core.ErrorCodes.AK_MEMORY_REMOTE_HTTP,
|
|
732
|
+
message: `qdrant ${response.status}: ${text.slice(0, 200)}`,
|
|
733
|
+
hint: `URL ${config.url}${path}. Check api-key + collection "${config.collection}".`
|
|
734
|
+
});
|
|
735
|
+
}
|
|
704
736
|
return text.length > 0 ? JSON.parse(text) : {};
|
|
705
737
|
}
|
|
706
738
|
function qdrant(config) {
|
|
@@ -739,8 +771,6 @@ function qdrant(config) {
|
|
|
739
771
|
}
|
|
740
772
|
};
|
|
741
773
|
}
|
|
742
|
-
|
|
743
|
-
// src/vector/chroma.ts
|
|
744
774
|
async function call3(config, method, path, body) {
|
|
745
775
|
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
746
776
|
const response = await fetchImpl(`${config.url}${path}`, {
|
|
@@ -749,7 +779,13 @@ async function call3(config, method, path, body) {
|
|
|
749
779
|
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
750
780
|
});
|
|
751
781
|
const text = await response.text();
|
|
752
|
-
if (!response.ok)
|
|
782
|
+
if (!response.ok) {
|
|
783
|
+
throw new core.MemoryError({
|
|
784
|
+
code: core.ErrorCodes.AK_MEMORY_REMOTE_HTTP,
|
|
785
|
+
message: `chroma ${response.status}: ${text.slice(0, 200)}`,
|
|
786
|
+
hint: `URL ${config.url}${path}. Check Chroma server health + collection name.`
|
|
787
|
+
});
|
|
788
|
+
}
|
|
753
789
|
return text.length > 0 ? JSON.parse(text) : {};
|
|
754
790
|
}
|
|
755
791
|
function chroma(config) {
|
|
@@ -788,8 +824,6 @@ function chroma(config) {
|
|
|
788
824
|
}
|
|
789
825
|
};
|
|
790
826
|
}
|
|
791
|
-
|
|
792
|
-
// src/vector/upstash.ts
|
|
793
827
|
async function call4(config, path, body) {
|
|
794
828
|
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
795
829
|
const response = await fetchImpl(`${config.url}${path}`, {
|
|
@@ -801,7 +835,13 @@ async function call4(config, path, body) {
|
|
|
801
835
|
body: JSON.stringify(body)
|
|
802
836
|
});
|
|
803
837
|
const text = await response.text();
|
|
804
|
-
if (!response.ok)
|
|
838
|
+
if (!response.ok) {
|
|
839
|
+
throw new core.MemoryError({
|
|
840
|
+
code: core.ErrorCodes.AK_MEMORY_REMOTE_HTTP,
|
|
841
|
+
message: `upstash-vector ${response.status}: ${text.slice(0, 200)}`,
|
|
842
|
+
hint: `URL ${config.url}${path}. Check token + index URL.`
|
|
843
|
+
});
|
|
844
|
+
}
|
|
805
845
|
return text.length > 0 ? JSON.parse(text) : {};
|
|
806
846
|
}
|
|
807
847
|
function upstashVector(config) {
|
|
@@ -836,8 +876,6 @@ function upstashVector(config) {
|
|
|
836
876
|
}
|
|
837
877
|
};
|
|
838
878
|
}
|
|
839
|
-
|
|
840
|
-
// src/vector/supabase.ts
|
|
841
879
|
var cachedSdk2 = null;
|
|
842
880
|
async function loadSdk2() {
|
|
843
881
|
if (!cachedSdk2) {
|
|
@@ -849,9 +887,11 @@ async function loadSdk2() {
|
|
|
849
887
|
moduleId
|
|
850
888
|
);
|
|
851
889
|
} catch {
|
|
852
|
-
throw new
|
|
853
|
-
|
|
854
|
-
|
|
890
|
+
throw new core.MemoryError({
|
|
891
|
+
code: core.ErrorCodes.AK_MEMORY_PEER_MISSING,
|
|
892
|
+
message: "Install @supabase/supabase-js to use supabaseVectorStore: npm install @supabase/supabase-js",
|
|
893
|
+
hint: 'supabaseVectorStore uses the optional peer "@supabase/supabase-js".'
|
|
894
|
+
});
|
|
855
895
|
}
|
|
856
896
|
})();
|
|
857
897
|
}
|
|
@@ -861,7 +901,13 @@ function buildRunner(client) {
|
|
|
861
901
|
return {
|
|
862
902
|
async query(sql, params) {
|
|
863
903
|
const result = await client.rpc("agentskit_execute_sql", { sql, params });
|
|
864
|
-
if (result.error)
|
|
904
|
+
if (result.error) {
|
|
905
|
+
throw new core.MemoryError({
|
|
906
|
+
code: core.ErrorCodes.AK_MEMORY_REMOTE_HTTP,
|
|
907
|
+
message: `supabase: ${result.error.message}`,
|
|
908
|
+
hint: "Check the agentskit_execute_sql RPC + service role key permissions."
|
|
909
|
+
});
|
|
910
|
+
}
|
|
865
911
|
return { rows: result.data ?? [] };
|
|
866
912
|
}
|
|
867
913
|
};
|
|
@@ -905,8 +951,6 @@ function supabaseVectorStore(config) {
|
|
|
905
951
|
}
|
|
906
952
|
};
|
|
907
953
|
}
|
|
908
|
-
|
|
909
|
-
// src/vector/weaviate.ts
|
|
910
954
|
async function call5(config, method, path, body) {
|
|
911
955
|
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
912
956
|
const response = await fetchImpl(`${config.url}${path}`, {
|
|
@@ -918,7 +962,13 @@ async function call5(config, method, path, body) {
|
|
|
918
962
|
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
919
963
|
});
|
|
920
964
|
const text = await response.text();
|
|
921
|
-
if (!response.ok)
|
|
965
|
+
if (!response.ok) {
|
|
966
|
+
throw new core.MemoryError({
|
|
967
|
+
code: core.ErrorCodes.AK_MEMORY_REMOTE_HTTP,
|
|
968
|
+
message: `weaviate ${response.status}: ${text.slice(0, 200)}`,
|
|
969
|
+
hint: `URL ${config.url}${path}. Check API key + class name "${config.className}".`
|
|
970
|
+
});
|
|
971
|
+
}
|
|
922
972
|
return text.length > 0 ? JSON.parse(text) : {};
|
|
923
973
|
}
|
|
924
974
|
function weaviateVectorStore(config) {
|
|
@@ -963,8 +1013,6 @@ function weaviateVectorStore(config) {
|
|
|
963
1013
|
}
|
|
964
1014
|
};
|
|
965
1015
|
}
|
|
966
|
-
|
|
967
|
-
// src/vector/milvus.ts
|
|
968
1016
|
async function call6(config, path, body) {
|
|
969
1017
|
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
970
1018
|
const response = await fetchImpl(`${config.url}${path}`, {
|
|
@@ -976,7 +1024,13 @@ async function call6(config, path, body) {
|
|
|
976
1024
|
body: JSON.stringify(body)
|
|
977
1025
|
});
|
|
978
1026
|
const text = await response.text();
|
|
979
|
-
if (!response.ok)
|
|
1027
|
+
if (!response.ok) {
|
|
1028
|
+
throw new core.MemoryError({
|
|
1029
|
+
code: core.ErrorCodes.AK_MEMORY_REMOTE_HTTP,
|
|
1030
|
+
message: `milvus ${response.status}: ${text.slice(0, 200)}`,
|
|
1031
|
+
hint: `URL ${config.url}${path}. Check token + collection "${config.collection}".`
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
980
1034
|
return text.length > 0 ? JSON.parse(text) : {};
|
|
981
1035
|
}
|
|
982
1036
|
function milvusVectorStore(config) {
|
|
@@ -1066,8 +1120,6 @@ function mongoAtlasVectorStore(config) {
|
|
|
1066
1120
|
}
|
|
1067
1121
|
};
|
|
1068
1122
|
}
|
|
1069
|
-
|
|
1070
|
-
// src/encrypted.ts
|
|
1071
1123
|
function toBase64(bytes) {
|
|
1072
1124
|
if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
|
|
1073
1125
|
let binary = "";
|
|
@@ -1085,14 +1137,24 @@ async function resolveKey(subtle, material) {
|
|
|
1085
1137
|
if ("type" in material && material.type === "secret") return material;
|
|
1086
1138
|
const raw = material;
|
|
1087
1139
|
if (raw.byteLength !== 32) {
|
|
1088
|
-
throw new
|
|
1140
|
+
throw new core.ConfigError({
|
|
1141
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1142
|
+
message: `createEncryptedMemory: key must be 32 bytes (got ${raw.byteLength})`,
|
|
1143
|
+
hint: "Generate a 32-byte key, e.g. crypto.getRandomValues(new Uint8Array(32))."
|
|
1144
|
+
});
|
|
1089
1145
|
}
|
|
1090
1146
|
return subtle.importKey("raw", raw, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
|
|
1091
1147
|
}
|
|
1092
1148
|
async function createEncryptedMemory(options) {
|
|
1093
1149
|
const subtle = options.subtle ?? globalThis.crypto?.subtle;
|
|
1094
1150
|
const random = options.getRandomValues ?? ((v) => globalThis.crypto.getRandomValues(v));
|
|
1095
|
-
if (!subtle)
|
|
1151
|
+
if (!subtle) {
|
|
1152
|
+
throw new core.MemoryError({
|
|
1153
|
+
code: core.ErrorCodes.AK_MEMORY_LOAD_FAILED,
|
|
1154
|
+
message: "createEncryptedMemory: SubtleCrypto not available",
|
|
1155
|
+
hint: "Run on Node \u2265 20 / a modern browser, or pass options.subtle explicitly."
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1096
1158
|
const key = await resolveKey(subtle, options.key);
|
|
1097
1159
|
const aad = options.aad;
|
|
1098
1160
|
const encrypt = async (plain) => {
|
|
@@ -1209,6 +1271,102 @@ function createHierarchicalMemory(options) {
|
|
|
1209
1271
|
};
|
|
1210
1272
|
}
|
|
1211
1273
|
|
|
1274
|
+
// src/forget.ts
|
|
1275
|
+
function isForgettable(value) {
|
|
1276
|
+
return !!value && typeof value === "object" && "forgetSubject" in value && typeof value.forgetSubject === "function";
|
|
1277
|
+
}
|
|
1278
|
+
async function hash(input) {
|
|
1279
|
+
const encoded = new TextEncoder().encode(input);
|
|
1280
|
+
const digest = await crypto.subtle.digest("SHA-256", encoded);
|
|
1281
|
+
return Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1282
|
+
}
|
|
1283
|
+
async function forgetSubject(memories, subjectId) {
|
|
1284
|
+
const reports = [];
|
|
1285
|
+
for (const memory of memories) {
|
|
1286
|
+
if (!isForgettable(memory)) continue;
|
|
1287
|
+
reports.push(await memory.forgetSubject(subjectId));
|
|
1288
|
+
}
|
|
1289
|
+
const totalDeleted = reports.reduce((sum, r) => sum + r.deletedCount, 0);
|
|
1290
|
+
const evidenceHash = await hash(
|
|
1291
|
+
JSON.stringify({ subjectId, reports: reports.map((r) => ({ b: r.backend, n: r.deletedCount, at: r.at })) })
|
|
1292
|
+
);
|
|
1293
|
+
return { subjectId, reports, totalDeleted, evidenceHash };
|
|
1294
|
+
}
|
|
1295
|
+
function makeForgettable(memory, options) {
|
|
1296
|
+
return Object.assign(memory, {
|
|
1297
|
+
__agentskitBackend: options.backend,
|
|
1298
|
+
forgetSubject: async (subjectId) => {
|
|
1299
|
+
const ids = await options.listIds(subjectId);
|
|
1300
|
+
const failures = [];
|
|
1301
|
+
try {
|
|
1302
|
+
await options.deleteIds(ids);
|
|
1303
|
+
} catch (err) {
|
|
1304
|
+
for (const id of ids) failures.push({ id, reason: err.message });
|
|
1305
|
+
}
|
|
1306
|
+
return {
|
|
1307
|
+
backend: options.backend,
|
|
1308
|
+
deletedCount: ids.length - failures.length,
|
|
1309
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1310
|
+
failures: failures.length ? failures : void 0
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
async function transform(input, opts) {
|
|
1316
|
+
if (opts.mode === "tokenize") {
|
|
1317
|
+
if (!opts.vault) {
|
|
1318
|
+
throw new core.ConfigError({
|
|
1319
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1320
|
+
message: 'wrapMemoryWithRedaction: vault is required when mode is "tokenize"'
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
if (!opts.allowedRoles) {
|
|
1324
|
+
throw new core.ConfigError({
|
|
1325
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1326
|
+
message: 'wrapMemoryWithRedaction: allowedRoles is required when mode is "tokenize"'
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
const result = await security.tokenize(input, {
|
|
1330
|
+
rules: opts.rules,
|
|
1331
|
+
vault: opts.vault,
|
|
1332
|
+
allowedRoles: opts.allowedRoles,
|
|
1333
|
+
audit: opts.audit
|
|
1334
|
+
});
|
|
1335
|
+
return result.value;
|
|
1336
|
+
}
|
|
1337
|
+
return security.createPIIRedactor({ rules: opts.rules }).redact(input).value;
|
|
1338
|
+
}
|
|
1339
|
+
function wrapChatMemoryWithRedaction(inner, options) {
|
|
1340
|
+
return {
|
|
1341
|
+
load: () => inner.load(),
|
|
1342
|
+
save: async (messages) => {
|
|
1343
|
+
const redacted = await Promise.all(
|
|
1344
|
+
messages.map(async (m) => ({
|
|
1345
|
+
...m,
|
|
1346
|
+
content: await transform(m.content ?? "", options)
|
|
1347
|
+
}))
|
|
1348
|
+
);
|
|
1349
|
+
await inner.save(redacted);
|
|
1350
|
+
},
|
|
1351
|
+
clear: inner.clear ? () => inner.clear() : void 0
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
function wrapVectorMemoryWithRedaction(inner, options) {
|
|
1355
|
+
return {
|
|
1356
|
+
store: async (docs) => {
|
|
1357
|
+
const redacted = await Promise.all(
|
|
1358
|
+
docs.map(async (d) => ({
|
|
1359
|
+
...d,
|
|
1360
|
+
content: await transform(d.content, options)
|
|
1361
|
+
}))
|
|
1362
|
+
);
|
|
1363
|
+
await inner.store(redacted);
|
|
1364
|
+
},
|
|
1365
|
+
search: (embedding, opts) => inner.search(embedding, opts),
|
|
1366
|
+
delete: inner.delete ? (ids) => inner.delete(ids) : void 0
|
|
1367
|
+
};
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1212
1370
|
exports.chroma = chroma;
|
|
1213
1371
|
exports.createEncryptedMemory = createEncryptedMemory;
|
|
1214
1372
|
exports.createHierarchicalMemory = createHierarchicalMemory;
|
|
@@ -1216,6 +1374,8 @@ exports.createInMemoryGraph = createInMemoryGraph;
|
|
|
1216
1374
|
exports.createInMemoryPersonalization = createInMemoryPersonalization;
|
|
1217
1375
|
exports.fileChatMemory = fileChatMemory;
|
|
1218
1376
|
exports.fileVectorMemory = fileVectorMemory;
|
|
1377
|
+
exports.forgetSubject = forgetSubject;
|
|
1378
|
+
exports.makeForgettable = makeForgettable;
|
|
1219
1379
|
exports.matchesFilter = matchesFilter;
|
|
1220
1380
|
exports.milvusVectorStore = milvusVectorStore;
|
|
1221
1381
|
exports.mongoAtlasVectorStore = mongoAtlasVectorStore;
|
|
@@ -1230,5 +1390,7 @@ exports.supabaseVectorStore = supabaseVectorStore;
|
|
|
1230
1390
|
exports.tursoChatMemory = tursoChatMemory;
|
|
1231
1391
|
exports.upstashVector = upstashVector;
|
|
1232
1392
|
exports.weaviateVectorStore = weaviateVectorStore;
|
|
1393
|
+
exports.wrapChatMemoryWithRedaction = wrapChatMemoryWithRedaction;
|
|
1394
|
+
exports.wrapVectorMemoryWithRedaction = wrapVectorMemoryWithRedaction;
|
|
1233
1395
|
//# sourceMappingURL=index.cjs.map
|
|
1234
1396
|
//# sourceMappingURL=index.cjs.map
|