@agentskit/memory 0.8.3 → 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 +120 -8
- 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 +119 -53
- 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 {
|
|
@@ -197,7 +202,7 @@ async function createRedisClientAdapter(url) {
|
|
|
197
202
|
return await client.keys(pattern);
|
|
198
203
|
},
|
|
199
204
|
async disconnect() {
|
|
200
|
-
await client.
|
|
205
|
+
await client.close();
|
|
201
206
|
},
|
|
202
207
|
async call(command, ...args) {
|
|
203
208
|
return await client.sendCommand([command, ...args.map(String)]);
|
|
@@ -425,16 +430,23 @@ function createVectraStore(dirPath) {
|
|
|
425
430
|
return {
|
|
426
431
|
async upsert(docs) {
|
|
427
432
|
const idx = await getIndex();
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
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;
|
|
433
445
|
}
|
|
434
446
|
},
|
|
435
447
|
async query(vector, topK) {
|
|
436
448
|
const idx = await getIndex();
|
|
437
|
-
const results = await idx.queryItems(vector, topK);
|
|
449
|
+
const results = await idx.queryItems(vector, "", topK);
|
|
438
450
|
return results.map((r) => ({
|
|
439
451
|
id: String(r.item.metadata._id ?? ""),
|
|
440
452
|
score: r.score,
|
|
@@ -1259,6 +1271,102 @@ function createHierarchicalMemory(options) {
|
|
|
1259
1271
|
};
|
|
1260
1272
|
}
|
|
1261
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
|
+
|
|
1262
1370
|
exports.chroma = chroma;
|
|
1263
1371
|
exports.createEncryptedMemory = createEncryptedMemory;
|
|
1264
1372
|
exports.createHierarchicalMemory = createHierarchicalMemory;
|
|
@@ -1266,6 +1374,8 @@ exports.createInMemoryGraph = createInMemoryGraph;
|
|
|
1266
1374
|
exports.createInMemoryPersonalization = createInMemoryPersonalization;
|
|
1267
1375
|
exports.fileChatMemory = fileChatMemory;
|
|
1268
1376
|
exports.fileVectorMemory = fileVectorMemory;
|
|
1377
|
+
exports.forgetSubject = forgetSubject;
|
|
1378
|
+
exports.makeForgettable = makeForgettable;
|
|
1269
1379
|
exports.matchesFilter = matchesFilter;
|
|
1270
1380
|
exports.milvusVectorStore = milvusVectorStore;
|
|
1271
1381
|
exports.mongoAtlasVectorStore = mongoAtlasVectorStore;
|
|
@@ -1280,5 +1390,7 @@ exports.supabaseVectorStore = supabaseVectorStore;
|
|
|
1280
1390
|
exports.tursoChatMemory = tursoChatMemory;
|
|
1281
1391
|
exports.upstashVector = upstashVector;
|
|
1282
1392
|
exports.weaviateVectorStore = weaviateVectorStore;
|
|
1393
|
+
exports.wrapChatMemoryWithRedaction = wrapChatMemoryWithRedaction;
|
|
1394
|
+
exports.wrapVectorMemoryWithRedaction = wrapVectorMemoryWithRedaction;
|
|
1283
1395
|
//# sourceMappingURL=index.cjs.map
|
|
1284
1396
|
//# sourceMappingURL=index.cjs.map
|