@agentskit/memory 0.6.1 → 0.8.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/index.cjs +349 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +107 -2
- package/dist/index.d.ts +107 -2
- package/dist/index.js +344 -7
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -89,6 +89,78 @@ function sqliteChatMemory(config) {
|
|
|
89
89
|
}
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
|
+
var cachedSdk = null;
|
|
93
|
+
async function loadSdk() {
|
|
94
|
+
if (!cachedSdk) {
|
|
95
|
+
cachedSdk = (async () => {
|
|
96
|
+
try {
|
|
97
|
+
const moduleId = "@libsql/client";
|
|
98
|
+
return await import(
|
|
99
|
+
/* @vite-ignore */
|
|
100
|
+
moduleId
|
|
101
|
+
);
|
|
102
|
+
} catch {
|
|
103
|
+
throw new Error("Install @libsql/client to use tursoChatMemory: npm install @libsql/client");
|
|
104
|
+
}
|
|
105
|
+
})();
|
|
106
|
+
}
|
|
107
|
+
return cachedSdk;
|
|
108
|
+
}
|
|
109
|
+
function encodeMessages2(messages) {
|
|
110
|
+
return JSON.stringify(core.serializeMessages(messages));
|
|
111
|
+
}
|
|
112
|
+
function decodeMessages2(json) {
|
|
113
|
+
if (!json) return [];
|
|
114
|
+
try {
|
|
115
|
+
return core.deserializeMessages(JSON.parse(json));
|
|
116
|
+
} catch {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function tursoChatMemory(config) {
|
|
121
|
+
const conversationId = config.conversationId ?? "default";
|
|
122
|
+
let clientPromise = null;
|
|
123
|
+
const getClient = async () => {
|
|
124
|
+
if (!clientPromise) {
|
|
125
|
+
clientPromise = (async () => {
|
|
126
|
+
const sdk = await loadSdk();
|
|
127
|
+
const client = sdk.createClient({ url: config.url, authToken: config.authToken });
|
|
128
|
+
await client.execute({
|
|
129
|
+
sql: "CREATE TABLE IF NOT EXISTS conversations (id TEXT PRIMARY KEY, messages TEXT NOT NULL)"
|
|
130
|
+
});
|
|
131
|
+
return client;
|
|
132
|
+
})();
|
|
133
|
+
}
|
|
134
|
+
return clientPromise;
|
|
135
|
+
};
|
|
136
|
+
return {
|
|
137
|
+
async load() {
|
|
138
|
+
const client = await getClient();
|
|
139
|
+
const result = await client.execute({
|
|
140
|
+
sql: "SELECT messages FROM conversations WHERE id = ?",
|
|
141
|
+
args: [conversationId]
|
|
142
|
+
});
|
|
143
|
+
const row = result.rows[0];
|
|
144
|
+
return decodeMessages2(row?.messages);
|
|
145
|
+
},
|
|
146
|
+
async save(messages) {
|
|
147
|
+
const client = await getClient();
|
|
148
|
+
const json = encodeMessages2(messages);
|
|
149
|
+
await client.execute({
|
|
150
|
+
sql: `INSERT INTO conversations (id, messages) VALUES (?, ?)
|
|
151
|
+
ON CONFLICT(id) DO UPDATE SET messages = excluded.messages`,
|
|
152
|
+
args: [conversationId, json]
|
|
153
|
+
});
|
|
154
|
+
},
|
|
155
|
+
async clear() {
|
|
156
|
+
const client = await getClient();
|
|
157
|
+
await client.execute({
|
|
158
|
+
sql: "DELETE FROM conversations WHERE id = ?",
|
|
159
|
+
args: [conversationId]
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
92
164
|
|
|
93
165
|
// src/redis-client.ts
|
|
94
166
|
async function createRedisClientAdapter(url) {
|
|
@@ -124,10 +196,10 @@ async function createRedisClientAdapter(url) {
|
|
|
124
196
|
}
|
|
125
197
|
|
|
126
198
|
// src/redis-chat.ts
|
|
127
|
-
function
|
|
199
|
+
function encodeMessages3(messages) {
|
|
128
200
|
return JSON.stringify(core.serializeMessages(messages));
|
|
129
201
|
}
|
|
130
|
-
function
|
|
202
|
+
function decodeMessages3(json) {
|
|
131
203
|
if (!json) return [];
|
|
132
204
|
try {
|
|
133
205
|
return core.deserializeMessages(JSON.parse(json));
|
|
@@ -149,11 +221,11 @@ function redisChatMemory(config) {
|
|
|
149
221
|
async load() {
|
|
150
222
|
const client = await getClient();
|
|
151
223
|
const json = await client.get(key);
|
|
152
|
-
return
|
|
224
|
+
return decodeMessages3(json);
|
|
153
225
|
},
|
|
154
226
|
async save(messages) {
|
|
155
227
|
const client = await getClient();
|
|
156
|
-
await client.set(key,
|
|
228
|
+
await client.set(key, encodeMessages3(messages));
|
|
157
229
|
},
|
|
158
230
|
async clear() {
|
|
159
231
|
const client = await getClient();
|
|
@@ -283,6 +355,40 @@ function redisVectorMemory(config) {
|
|
|
283
355
|
};
|
|
284
356
|
}
|
|
285
357
|
|
|
358
|
+
// src/vector/filter.ts
|
|
359
|
+
function isPrimitive(value) {
|
|
360
|
+
const t = typeof value;
|
|
361
|
+
return value === null || t === "string" || t === "number" || t === "boolean";
|
|
362
|
+
}
|
|
363
|
+
function evalOperator(actual, op) {
|
|
364
|
+
if ("$eq" in op) return actual === op.$eq;
|
|
365
|
+
if ("$ne" in op) return actual !== op.$ne;
|
|
366
|
+
if ("$in" in op) return op.$in.includes(actual);
|
|
367
|
+
if ("$nin" in op) return !op.$nin.includes(actual);
|
|
368
|
+
if ("$gt" in op) return actual > op.$gt;
|
|
369
|
+
if ("$gte" in op) return actual >= op.$gte;
|
|
370
|
+
if ("$lt" in op) return actual < op.$lt;
|
|
371
|
+
if ("$lte" in op) return actual <= op.$lte;
|
|
372
|
+
if ("$exists" in op) return actual !== void 0 === op.$exists;
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
function evalPredicate(actual, predicate) {
|
|
376
|
+
if (isPrimitive(predicate)) return actual === predicate;
|
|
377
|
+
return evalOperator(actual, predicate);
|
|
378
|
+
}
|
|
379
|
+
function matchesFilter(metadata, filter) {
|
|
380
|
+
if (!filter) return true;
|
|
381
|
+
const meta = metadata ?? {};
|
|
382
|
+
const compound = filter;
|
|
383
|
+
if (compound.$and) return compound.$and.every((f) => matchesFilter(meta, f));
|
|
384
|
+
if (compound.$or) return compound.$or.some((f) => matchesFilter(meta, f));
|
|
385
|
+
for (const [field, predicate] of Object.entries(filter)) {
|
|
386
|
+
if (field.startsWith("$")) continue;
|
|
387
|
+
if (!evalPredicate(meta[field], predicate)) return false;
|
|
388
|
+
}
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
|
|
286
392
|
// src/file-vector.ts
|
|
287
393
|
function requireVectra() {
|
|
288
394
|
try {
|
|
@@ -351,8 +457,9 @@ function fileVectorMemory(config) {
|
|
|
351
457
|
async search(embedding, options) {
|
|
352
458
|
const topK = options?.topK ?? 5;
|
|
353
459
|
const threshold = options?.threshold ?? 0;
|
|
354
|
-
const
|
|
355
|
-
|
|
460
|
+
const fetchK = options?.filter ? Math.max(topK * 4, 50) : topK;
|
|
461
|
+
const results = await store.query(embedding, fetchK);
|
|
462
|
+
return results.filter((r) => r.score >= threshold).filter((r) => matchesFilter(r.metadata, options?.filter)).slice(0, topK).map((r) => ({
|
|
356
463
|
id: r.id,
|
|
357
464
|
content: String(r.metadata.content ?? contentCache.get(r.id) ?? ""),
|
|
358
465
|
score: r.score,
|
|
@@ -730,6 +837,236 @@ function upstashVector(config) {
|
|
|
730
837
|
};
|
|
731
838
|
}
|
|
732
839
|
|
|
840
|
+
// src/vector/supabase.ts
|
|
841
|
+
var cachedSdk2 = null;
|
|
842
|
+
async function loadSdk2() {
|
|
843
|
+
if (!cachedSdk2) {
|
|
844
|
+
cachedSdk2 = (async () => {
|
|
845
|
+
try {
|
|
846
|
+
const moduleId = "@supabase/supabase-js";
|
|
847
|
+
return await import(
|
|
848
|
+
/* @vite-ignore */
|
|
849
|
+
moduleId
|
|
850
|
+
);
|
|
851
|
+
} catch {
|
|
852
|
+
throw new Error(
|
|
853
|
+
"Install @supabase/supabase-js to use supabaseVectorStore: npm install @supabase/supabase-js"
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
})();
|
|
857
|
+
}
|
|
858
|
+
return cachedSdk2;
|
|
859
|
+
}
|
|
860
|
+
function buildRunner(client) {
|
|
861
|
+
return {
|
|
862
|
+
async query(sql, params) {
|
|
863
|
+
const result = await client.rpc("agentskit_execute_sql", { sql, params });
|
|
864
|
+
if (result.error) throw new Error(`supabase: ${result.error.message}`);
|
|
865
|
+
return { rows: result.data ?? [] };
|
|
866
|
+
}
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
function supabaseVectorStore(config) {
|
|
870
|
+
let runnerPromise = null;
|
|
871
|
+
const getRunner = () => {
|
|
872
|
+
if (!runnerPromise) {
|
|
873
|
+
runnerPromise = (async () => {
|
|
874
|
+
const sdk = await loadSdk2();
|
|
875
|
+
const client = sdk.createClient(config.url, config.serviceRoleKey);
|
|
876
|
+
return buildRunner(client);
|
|
877
|
+
})();
|
|
878
|
+
}
|
|
879
|
+
return runnerPromise;
|
|
880
|
+
};
|
|
881
|
+
let backend = null;
|
|
882
|
+
const getBackend = async () => {
|
|
883
|
+
if (!backend) {
|
|
884
|
+
const runner = await getRunner();
|
|
885
|
+
backend = pgvector({
|
|
886
|
+
runner,
|
|
887
|
+
table: config.table,
|
|
888
|
+
topK: config.topK
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
return backend;
|
|
892
|
+
};
|
|
893
|
+
return {
|
|
894
|
+
async store(docs) {
|
|
895
|
+
const b = await getBackend();
|
|
896
|
+
return b.store(docs);
|
|
897
|
+
},
|
|
898
|
+
async search(embedding, options) {
|
|
899
|
+
const b = await getBackend();
|
|
900
|
+
return b.search(embedding, options);
|
|
901
|
+
},
|
|
902
|
+
async delete(ids) {
|
|
903
|
+
const b = await getBackend();
|
|
904
|
+
return b.delete?.(ids);
|
|
905
|
+
}
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// src/vector/weaviate.ts
|
|
910
|
+
async function call5(config, method, path, body) {
|
|
911
|
+
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
912
|
+
const response = await fetchImpl(`${config.url}${path}`, {
|
|
913
|
+
method,
|
|
914
|
+
headers: {
|
|
915
|
+
"content-type": "application/json",
|
|
916
|
+
...config.apiKey ? { authorization: `Bearer ${config.apiKey}` } : {}
|
|
917
|
+
},
|
|
918
|
+
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
919
|
+
});
|
|
920
|
+
const text = await response.text();
|
|
921
|
+
if (!response.ok) throw new Error(`weaviate ${response.status}: ${text.slice(0, 200)}`);
|
|
922
|
+
return text.length > 0 ? JSON.parse(text) : {};
|
|
923
|
+
}
|
|
924
|
+
function weaviateVectorStore(config) {
|
|
925
|
+
const defaultTopK = Math.max(1, config.topK ?? 10);
|
|
926
|
+
const className = config.className;
|
|
927
|
+
return {
|
|
928
|
+
async store(docs) {
|
|
929
|
+
if (docs.length === 0) return;
|
|
930
|
+
await call5(config, "POST", "/v1/batch/objects", {
|
|
931
|
+
objects: docs.map((d) => ({
|
|
932
|
+
class: className,
|
|
933
|
+
id: d.id,
|
|
934
|
+
properties: { content: d.content, ...d.metadata ?? {} },
|
|
935
|
+
vector: d.embedding
|
|
936
|
+
}))
|
|
937
|
+
});
|
|
938
|
+
},
|
|
939
|
+
async search(embedding, options = {}) {
|
|
940
|
+
const topK = options.topK ?? defaultTopK;
|
|
941
|
+
const threshold = options.threshold ?? 0;
|
|
942
|
+
const query = `{
|
|
943
|
+
Get {
|
|
944
|
+
${className}(nearVector: { vector: [${embedding.join(",")}] }, limit: ${topK}) {
|
|
945
|
+
content
|
|
946
|
+
_additional { id certainty }
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}`;
|
|
950
|
+
const result = await call5(config, "POST", "/v1/graphql", { query });
|
|
951
|
+
const rows = result.data?.Get?.[className] ?? [];
|
|
952
|
+
return rows.map((row) => ({
|
|
953
|
+
id: String(row._additional?.id ?? ""),
|
|
954
|
+
content: String(row.content ?? ""),
|
|
955
|
+
score: row._additional?.certainty ?? 0,
|
|
956
|
+
metadata: row
|
|
957
|
+
})).filter((r) => (r.score ?? 0) >= threshold);
|
|
958
|
+
},
|
|
959
|
+
async delete(ids) {
|
|
960
|
+
for (const id of ids) {
|
|
961
|
+
await call5(config, "DELETE", `/v1/objects/${className}/${id}`);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// src/vector/milvus.ts
|
|
968
|
+
async function call6(config, path, body) {
|
|
969
|
+
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
970
|
+
const response = await fetchImpl(`${config.url}${path}`, {
|
|
971
|
+
method: "POST",
|
|
972
|
+
headers: {
|
|
973
|
+
"content-type": "application/json",
|
|
974
|
+
...config.token ? { authorization: `Bearer ${config.token}` } : {}
|
|
975
|
+
},
|
|
976
|
+
body: JSON.stringify(body)
|
|
977
|
+
});
|
|
978
|
+
const text = await response.text();
|
|
979
|
+
if (!response.ok) throw new Error(`milvus ${response.status}: ${text.slice(0, 200)}`);
|
|
980
|
+
return text.length > 0 ? JSON.parse(text) : {};
|
|
981
|
+
}
|
|
982
|
+
function milvusVectorStore(config) {
|
|
983
|
+
const defaultTopK = Math.max(1, config.topK ?? 10);
|
|
984
|
+
const vectorField = config.vectorField ?? "vector";
|
|
985
|
+
return {
|
|
986
|
+
async store(docs) {
|
|
987
|
+
if (docs.length === 0) return;
|
|
988
|
+
await call6(config, "/v2/vectordb/entities/upsert", {
|
|
989
|
+
collectionName: config.collection,
|
|
990
|
+
data: docs.map((d) => ({
|
|
991
|
+
id: d.id,
|
|
992
|
+
[vectorField]: d.embedding,
|
|
993
|
+
content: d.content,
|
|
994
|
+
metadata: d.metadata ?? {}
|
|
995
|
+
}))
|
|
996
|
+
});
|
|
997
|
+
},
|
|
998
|
+
async search(embedding, options = {}) {
|
|
999
|
+
const topK = options.topK ?? defaultTopK;
|
|
1000
|
+
const threshold = options.threshold ?? 0;
|
|
1001
|
+
const result = await call6(config, "/v2/vectordb/entities/search", {
|
|
1002
|
+
collectionName: config.collection,
|
|
1003
|
+
data: [embedding],
|
|
1004
|
+
annsField: vectorField,
|
|
1005
|
+
limit: topK,
|
|
1006
|
+
outputFields: ["content", "metadata"]
|
|
1007
|
+
});
|
|
1008
|
+
return (result.data ?? []).map((m) => ({
|
|
1009
|
+
id: String(m.id),
|
|
1010
|
+
content: String(m.content ?? ""),
|
|
1011
|
+
score: 1 - m.distance,
|
|
1012
|
+
metadata: m.metadata
|
|
1013
|
+
})).filter((r) => (r.score ?? 0) >= threshold);
|
|
1014
|
+
},
|
|
1015
|
+
async delete(ids) {
|
|
1016
|
+
if (ids.length === 0) return;
|
|
1017
|
+
await call6(config, "/v2/vectordb/entities/delete", {
|
|
1018
|
+
collectionName: config.collection,
|
|
1019
|
+
filter: `id in [${ids.map((id) => `"${id}"`).join(",")}]`
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
// src/vector/mongo-atlas.ts
|
|
1026
|
+
function mongoAtlasVectorStore(config) {
|
|
1027
|
+
const defaultTopK = Math.max(1, config.topK ?? 10);
|
|
1028
|
+
const vectorField = config.vectorField ?? "embedding";
|
|
1029
|
+
return {
|
|
1030
|
+
async store(docs) {
|
|
1031
|
+
if (docs.length === 0) return;
|
|
1032
|
+
await config.collection.insertMany(docs.map((d) => ({
|
|
1033
|
+
_id: d.id,
|
|
1034
|
+
content: d.content,
|
|
1035
|
+
[vectorField]: d.embedding,
|
|
1036
|
+
metadata: d.metadata ?? {}
|
|
1037
|
+
})));
|
|
1038
|
+
},
|
|
1039
|
+
async search(embedding, options = {}) {
|
|
1040
|
+
const topK = options.topK ?? defaultTopK;
|
|
1041
|
+
const threshold = options.threshold ?? 0;
|
|
1042
|
+
const numCandidates = config.numCandidates ?? topK * 10;
|
|
1043
|
+
const cursor = config.collection.aggregate([
|
|
1044
|
+
{
|
|
1045
|
+
$vectorSearch: {
|
|
1046
|
+
index: config.indexName,
|
|
1047
|
+
path: vectorField,
|
|
1048
|
+
queryVector: embedding,
|
|
1049
|
+
numCandidates,
|
|
1050
|
+
limit: topK
|
|
1051
|
+
}
|
|
1052
|
+
},
|
|
1053
|
+
{ $project: { content: 1, metadata: 1, score: { $meta: "vectorSearchScore" } } }
|
|
1054
|
+
]);
|
|
1055
|
+
const rows = await cursor.toArray();
|
|
1056
|
+
return rows.map((row) => ({
|
|
1057
|
+
id: String(row._id),
|
|
1058
|
+
content: String(row.content ?? ""),
|
|
1059
|
+
score: row.score,
|
|
1060
|
+
metadata: row.metadata
|
|
1061
|
+
})).filter((r) => (r.score ?? 0) >= threshold);
|
|
1062
|
+
},
|
|
1063
|
+
async delete(ids) {
|
|
1064
|
+
if (ids.length === 0) return;
|
|
1065
|
+
await config.collection.deleteMany({ _id: { $in: ids } });
|
|
1066
|
+
}
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
|
|
733
1070
|
// src/encrypted.ts
|
|
734
1071
|
function toBase64(bytes) {
|
|
735
1072
|
if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
|
|
@@ -879,6 +1216,9 @@ exports.createInMemoryGraph = createInMemoryGraph;
|
|
|
879
1216
|
exports.createInMemoryPersonalization = createInMemoryPersonalization;
|
|
880
1217
|
exports.fileChatMemory = fileChatMemory;
|
|
881
1218
|
exports.fileVectorMemory = fileVectorMemory;
|
|
1219
|
+
exports.matchesFilter = matchesFilter;
|
|
1220
|
+
exports.milvusVectorStore = milvusVectorStore;
|
|
1221
|
+
exports.mongoAtlasVectorStore = mongoAtlasVectorStore;
|
|
882
1222
|
exports.pgvector = pgvector;
|
|
883
1223
|
exports.pinecone = pinecone;
|
|
884
1224
|
exports.qdrant = qdrant;
|
|
@@ -886,6 +1226,9 @@ exports.redisChatMemory = redisChatMemory;
|
|
|
886
1226
|
exports.redisVectorMemory = redisVectorMemory;
|
|
887
1227
|
exports.renderProfileContext = renderProfileContext;
|
|
888
1228
|
exports.sqliteChatMemory = sqliteChatMemory;
|
|
1229
|
+
exports.supabaseVectorStore = supabaseVectorStore;
|
|
1230
|
+
exports.tursoChatMemory = tursoChatMemory;
|
|
889
1231
|
exports.upstashVector = upstashVector;
|
|
1232
|
+
exports.weaviateVectorStore = weaviateVectorStore;
|
|
890
1233
|
//# sourceMappingURL=index.cjs.map
|
|
891
1234
|
//# sourceMappingURL=index.cjs.map
|