@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.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChatMemory, VectorMemory, Message } from '@agentskit/core';
|
|
1
|
+
import { ChatMemory, VectorMemory, VectorFilter, Message } from '@agentskit/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* ChatMemory backed by a JSON file on disk. Node-only.
|
|
@@ -17,6 +17,22 @@ interface SqliteChatMemoryConfig {
|
|
|
17
17
|
}
|
|
18
18
|
declare function sqliteChatMemory(config: SqliteChatMemoryConfig): ChatMemory;
|
|
19
19
|
|
|
20
|
+
interface TursoChatMemoryConfig {
|
|
21
|
+
/** libSQL URL — file:..., libsql://..., or http://... */
|
|
22
|
+
url: string;
|
|
23
|
+
/** Auth token — required for hosted (libsql://) URLs. */
|
|
24
|
+
authToken?: string;
|
|
25
|
+
conversationId?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* libSQL / Turso-backed chat memory. Mirrors the `sqliteChatMemory` shape so
|
|
29
|
+
* code paths can swap between local SQLite and replicated libSQL by changing
|
|
30
|
+
* one import.
|
|
31
|
+
*
|
|
32
|
+
* `@libsql/client` is an optional peer dependency loaded lazily.
|
|
33
|
+
*/
|
|
34
|
+
declare function tursoChatMemory(config: TursoChatMemoryConfig): ChatMemory;
|
|
35
|
+
|
|
20
36
|
/**
|
|
21
37
|
* Internal Redis client adapter interface.
|
|
22
38
|
* Abstracts the underlying Redis library so it can be swapped
|
|
@@ -218,6 +234,95 @@ interface UpstashVectorConfig {
|
|
|
218
234
|
*/
|
|
219
235
|
declare function upstashVector(config: UpstashVectorConfig): VectorMemory;
|
|
220
236
|
|
|
237
|
+
interface SupabaseVectorStoreConfig {
|
|
238
|
+
/** Supabase project URL, e.g. `https://xyz.supabase.co`. */
|
|
239
|
+
url: string;
|
|
240
|
+
/** Service-role key (server-side only). */
|
|
241
|
+
serviceRoleKey: string;
|
|
242
|
+
/** Table name. Default `agentskit_vectors`. */
|
|
243
|
+
table?: string;
|
|
244
|
+
/** Default topK for search. Default 10. */
|
|
245
|
+
topK?: number;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Supabase-hosted pgvector. Wraps the existing `pgvector` adapter with a
|
|
249
|
+
* Supabase RPC runner so callers don't need to import a separate pg driver.
|
|
250
|
+
*
|
|
251
|
+
* Server-side setup (run once in Supabase SQL editor):
|
|
252
|
+
* create extension if not exists vector;
|
|
253
|
+
* create table agentskit_vectors (
|
|
254
|
+
* id text primary key, content text, embedding vector(1536),
|
|
255
|
+
* metadata jsonb
|
|
256
|
+
* );
|
|
257
|
+
* create or replace function agentskit_execute_sql(sql text, params jsonb)
|
|
258
|
+
* returns setof json language plpgsql security definer as $$
|
|
259
|
+
* begin
|
|
260
|
+
* return query execute sql using params;
|
|
261
|
+
* end;
|
|
262
|
+
* $$;
|
|
263
|
+
*
|
|
264
|
+
* `@supabase/supabase-js` is an optional peer dependency loaded lazily.
|
|
265
|
+
*/
|
|
266
|
+
declare function supabaseVectorStore(config: SupabaseVectorStoreConfig): VectorMemory;
|
|
267
|
+
|
|
268
|
+
interface WeaviateConfig {
|
|
269
|
+
/** Cluster URL, e.g. `https://my-cluster.weaviate.network`. */
|
|
270
|
+
url: string;
|
|
271
|
+
/** Optional API key (Weaviate Cloud Services). */
|
|
272
|
+
apiKey?: string;
|
|
273
|
+
/** Class name in the Weaviate schema. */
|
|
274
|
+
className: string;
|
|
275
|
+
topK?: number;
|
|
276
|
+
fetch?: typeof globalThis.fetch;
|
|
277
|
+
}
|
|
278
|
+
declare function weaviateVectorStore(config: WeaviateConfig): VectorMemory;
|
|
279
|
+
|
|
280
|
+
interface MilvusConfig {
|
|
281
|
+
/** Milvus REST endpoint, e.g. `https://in03-xxx.api.gcp-us-west1.zillizcloud.com`. */
|
|
282
|
+
url: string;
|
|
283
|
+
/** API key / Zilliz Cloud token (Bearer). */
|
|
284
|
+
token?: string;
|
|
285
|
+
collection: string;
|
|
286
|
+
/** Vector field name in the schema. Default `vector`. */
|
|
287
|
+
vectorField?: string;
|
|
288
|
+
topK?: number;
|
|
289
|
+
fetch?: typeof globalThis.fetch;
|
|
290
|
+
}
|
|
291
|
+
declare function milvusVectorStore(config: MilvusConfig): VectorMemory;
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* MongoDB Atlas Vector Search adapter. Caller injects a typed collection
|
|
295
|
+
* shape (drop-in for the official `mongodb` driver's `Collection` type) so
|
|
296
|
+
* we don't bundle a driver. Atlas' \`$vectorSearch\` aggregation runs
|
|
297
|
+
* server-side; we just translate \`store\` / \`search\` / \`delete\` to
|
|
298
|
+
* insertMany + aggregate + deleteMany.
|
|
299
|
+
*/
|
|
300
|
+
interface MongoCollectionLike {
|
|
301
|
+
insertMany(docs: Array<Record<string, unknown>>, options?: unknown): Promise<unknown>;
|
|
302
|
+
deleteMany(filter: Record<string, unknown>): Promise<unknown>;
|
|
303
|
+
aggregate<T = Record<string, unknown>>(pipeline: Array<Record<string, unknown>>): {
|
|
304
|
+
toArray(): Promise<T[]>;
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
interface MongoAtlasVectorConfig {
|
|
308
|
+
collection: MongoCollectionLike;
|
|
309
|
+
/** Atlas Search index name on the embedding field. */
|
|
310
|
+
indexName: string;
|
|
311
|
+
/** Field that holds the embedding vector. Default `embedding`. */
|
|
312
|
+
vectorField?: string;
|
|
313
|
+
/** numCandidates for $vectorSearch. Default `topK * 10`. */
|
|
314
|
+
numCandidates?: number;
|
|
315
|
+
topK?: number;
|
|
316
|
+
}
|
|
317
|
+
declare function mongoAtlasVectorStore(config: MongoAtlasVectorConfig): VectorMemory;
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Evaluate a `VectorFilter` against a metadata record. Used by in-memory /
|
|
321
|
+
* file-backed vector stores. Backends with native filter languages (pgvector,
|
|
322
|
+
* Pinecone, Qdrant, etc.) translate the filter to their own form instead.
|
|
323
|
+
*/
|
|
324
|
+
declare function matchesFilter(metadata: Record<string, unknown> | undefined, filter: VectorFilter | undefined): boolean;
|
|
325
|
+
|
|
221
326
|
/**
|
|
222
327
|
* Client-side encrypted ChatMemory wrapper. Keys never leave the
|
|
223
328
|
* caller — the backing store only ever sees an opaque
|
|
@@ -307,4 +412,4 @@ interface HierarchicalMemory extends ChatMemory {
|
|
|
307
412
|
*/
|
|
308
413
|
declare function createHierarchicalMemory(options: HierarchicalMemoryOptions): HierarchicalMemory;
|
|
309
414
|
|
|
310
|
-
export { type ChromaConfig, type EncryptedEnvelope, type EncryptedMemoryOptions, type FileVectorMemoryConfig, type GraphEdge, type GraphMemory, type GraphNode, type GraphQuery, type HierarchicalMemory, type HierarchicalMemoryOptions, type HierarchicalRecall, type PersonalizationProfile, type PersonalizationStore, type PgVectorConfig, type PgVectorRunner, type PineconeConfig, type QdrantConfig, type RedisChatMemoryConfig, type RedisClientAdapter, type RedisConnectionConfig, type RedisVectorMemoryConfig, type SqliteChatMemoryConfig, type UpstashVectorConfig, type VectorStore, type VectorStoreDocument, type VectorStoreResult, chroma, createEncryptedMemory, createHierarchicalMemory, createInMemoryGraph, createInMemoryPersonalization, fileChatMemory, fileVectorMemory, pgvector, pinecone, qdrant, redisChatMemory, redisVectorMemory, renderProfileContext, sqliteChatMemory, upstashVector };
|
|
415
|
+
export { type ChromaConfig, type EncryptedEnvelope, type EncryptedMemoryOptions, type FileVectorMemoryConfig, type GraphEdge, type GraphMemory, type GraphNode, type GraphQuery, type HierarchicalMemory, type HierarchicalMemoryOptions, type HierarchicalRecall, type MilvusConfig, type MongoAtlasVectorConfig, type MongoCollectionLike, type PersonalizationProfile, type PersonalizationStore, type PgVectorConfig, type PgVectorRunner, type PineconeConfig, type QdrantConfig, type RedisChatMemoryConfig, type RedisClientAdapter, type RedisConnectionConfig, type RedisVectorMemoryConfig, type SqliteChatMemoryConfig, type SupabaseVectorStoreConfig, type TursoChatMemoryConfig, type UpstashVectorConfig, type VectorStore, type VectorStoreDocument, type VectorStoreResult, type WeaviateConfig, chroma, createEncryptedMemory, createHierarchicalMemory, createInMemoryGraph, createInMemoryPersonalization, fileChatMemory, fileVectorMemory, matchesFilter, milvusVectorStore, mongoAtlasVectorStore, pgvector, pinecone, qdrant, redisChatMemory, redisVectorMemory, renderProfileContext, sqliteChatMemory, supabaseVectorStore, tursoChatMemory, upstashVector, weaviateVectorStore };
|
package/dist/index.js
CHANGED
|
@@ -87,6 +87,78 @@ function sqliteChatMemory(config) {
|
|
|
87
87
|
}
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
|
+
var cachedSdk = null;
|
|
91
|
+
async function loadSdk() {
|
|
92
|
+
if (!cachedSdk) {
|
|
93
|
+
cachedSdk = (async () => {
|
|
94
|
+
try {
|
|
95
|
+
const moduleId = "@libsql/client";
|
|
96
|
+
return await import(
|
|
97
|
+
/* @vite-ignore */
|
|
98
|
+
moduleId
|
|
99
|
+
);
|
|
100
|
+
} catch {
|
|
101
|
+
throw new Error("Install @libsql/client to use tursoChatMemory: npm install @libsql/client");
|
|
102
|
+
}
|
|
103
|
+
})();
|
|
104
|
+
}
|
|
105
|
+
return cachedSdk;
|
|
106
|
+
}
|
|
107
|
+
function encodeMessages2(messages) {
|
|
108
|
+
return JSON.stringify(serializeMessages(messages));
|
|
109
|
+
}
|
|
110
|
+
function decodeMessages2(json) {
|
|
111
|
+
if (!json) return [];
|
|
112
|
+
try {
|
|
113
|
+
return deserializeMessages(JSON.parse(json));
|
|
114
|
+
} catch {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function tursoChatMemory(config) {
|
|
119
|
+
const conversationId = config.conversationId ?? "default";
|
|
120
|
+
let clientPromise = null;
|
|
121
|
+
const getClient = async () => {
|
|
122
|
+
if (!clientPromise) {
|
|
123
|
+
clientPromise = (async () => {
|
|
124
|
+
const sdk = await loadSdk();
|
|
125
|
+
const client = sdk.createClient({ url: config.url, authToken: config.authToken });
|
|
126
|
+
await client.execute({
|
|
127
|
+
sql: "CREATE TABLE IF NOT EXISTS conversations (id TEXT PRIMARY KEY, messages TEXT NOT NULL)"
|
|
128
|
+
});
|
|
129
|
+
return client;
|
|
130
|
+
})();
|
|
131
|
+
}
|
|
132
|
+
return clientPromise;
|
|
133
|
+
};
|
|
134
|
+
return {
|
|
135
|
+
async load() {
|
|
136
|
+
const client = await getClient();
|
|
137
|
+
const result = await client.execute({
|
|
138
|
+
sql: "SELECT messages FROM conversations WHERE id = ?",
|
|
139
|
+
args: [conversationId]
|
|
140
|
+
});
|
|
141
|
+
const row = result.rows[0];
|
|
142
|
+
return decodeMessages2(row?.messages);
|
|
143
|
+
},
|
|
144
|
+
async save(messages) {
|
|
145
|
+
const client = await getClient();
|
|
146
|
+
const json = encodeMessages2(messages);
|
|
147
|
+
await client.execute({
|
|
148
|
+
sql: `INSERT INTO conversations (id, messages) VALUES (?, ?)
|
|
149
|
+
ON CONFLICT(id) DO UPDATE SET messages = excluded.messages`,
|
|
150
|
+
args: [conversationId, json]
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
async clear() {
|
|
154
|
+
const client = await getClient();
|
|
155
|
+
await client.execute({
|
|
156
|
+
sql: "DELETE FROM conversations WHERE id = ?",
|
|
157
|
+
args: [conversationId]
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
90
162
|
|
|
91
163
|
// src/redis-client.ts
|
|
92
164
|
async function createRedisClientAdapter(url) {
|
|
@@ -122,10 +194,10 @@ async function createRedisClientAdapter(url) {
|
|
|
122
194
|
}
|
|
123
195
|
|
|
124
196
|
// src/redis-chat.ts
|
|
125
|
-
function
|
|
197
|
+
function encodeMessages3(messages) {
|
|
126
198
|
return JSON.stringify(serializeMessages(messages));
|
|
127
199
|
}
|
|
128
|
-
function
|
|
200
|
+
function decodeMessages3(json) {
|
|
129
201
|
if (!json) return [];
|
|
130
202
|
try {
|
|
131
203
|
return deserializeMessages(JSON.parse(json));
|
|
@@ -147,11 +219,11 @@ function redisChatMemory(config) {
|
|
|
147
219
|
async load() {
|
|
148
220
|
const client = await getClient();
|
|
149
221
|
const json = await client.get(key);
|
|
150
|
-
return
|
|
222
|
+
return decodeMessages3(json);
|
|
151
223
|
},
|
|
152
224
|
async save(messages) {
|
|
153
225
|
const client = await getClient();
|
|
154
|
-
await client.set(key,
|
|
226
|
+
await client.set(key, encodeMessages3(messages));
|
|
155
227
|
},
|
|
156
228
|
async clear() {
|
|
157
229
|
const client = await getClient();
|
|
@@ -281,6 +353,40 @@ function redisVectorMemory(config) {
|
|
|
281
353
|
};
|
|
282
354
|
}
|
|
283
355
|
|
|
356
|
+
// src/vector/filter.ts
|
|
357
|
+
function isPrimitive(value) {
|
|
358
|
+
const t = typeof value;
|
|
359
|
+
return value === null || t === "string" || t === "number" || t === "boolean";
|
|
360
|
+
}
|
|
361
|
+
function evalOperator(actual, op) {
|
|
362
|
+
if ("$eq" in op) return actual === op.$eq;
|
|
363
|
+
if ("$ne" in op) return actual !== op.$ne;
|
|
364
|
+
if ("$in" in op) return op.$in.includes(actual);
|
|
365
|
+
if ("$nin" in op) return !op.$nin.includes(actual);
|
|
366
|
+
if ("$gt" in op) return actual > op.$gt;
|
|
367
|
+
if ("$gte" in op) return actual >= op.$gte;
|
|
368
|
+
if ("$lt" in op) return actual < op.$lt;
|
|
369
|
+
if ("$lte" in op) return actual <= op.$lte;
|
|
370
|
+
if ("$exists" in op) return actual !== void 0 === op.$exists;
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
function evalPredicate(actual, predicate) {
|
|
374
|
+
if (isPrimitive(predicate)) return actual === predicate;
|
|
375
|
+
return evalOperator(actual, predicate);
|
|
376
|
+
}
|
|
377
|
+
function matchesFilter(metadata, filter) {
|
|
378
|
+
if (!filter) return true;
|
|
379
|
+
const meta = metadata ?? {};
|
|
380
|
+
const compound = filter;
|
|
381
|
+
if (compound.$and) return compound.$and.every((f) => matchesFilter(meta, f));
|
|
382
|
+
if (compound.$or) return compound.$or.some((f) => matchesFilter(meta, f));
|
|
383
|
+
for (const [field, predicate] of Object.entries(filter)) {
|
|
384
|
+
if (field.startsWith("$")) continue;
|
|
385
|
+
if (!evalPredicate(meta[field], predicate)) return false;
|
|
386
|
+
}
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
389
|
+
|
|
284
390
|
// src/file-vector.ts
|
|
285
391
|
function requireVectra() {
|
|
286
392
|
try {
|
|
@@ -349,8 +455,9 @@ function fileVectorMemory(config) {
|
|
|
349
455
|
async search(embedding, options) {
|
|
350
456
|
const topK = options?.topK ?? 5;
|
|
351
457
|
const threshold = options?.threshold ?? 0;
|
|
352
|
-
const
|
|
353
|
-
|
|
458
|
+
const fetchK = options?.filter ? Math.max(topK * 4, 50) : topK;
|
|
459
|
+
const results = await store.query(embedding, fetchK);
|
|
460
|
+
return results.filter((r) => r.score >= threshold).filter((r) => matchesFilter(r.metadata, options?.filter)).slice(0, topK).map((r) => ({
|
|
354
461
|
id: r.id,
|
|
355
462
|
content: String(r.metadata.content ?? contentCache.get(r.id) ?? ""),
|
|
356
463
|
score: r.score,
|
|
@@ -728,6 +835,236 @@ function upstashVector(config) {
|
|
|
728
835
|
};
|
|
729
836
|
}
|
|
730
837
|
|
|
838
|
+
// src/vector/supabase.ts
|
|
839
|
+
var cachedSdk2 = null;
|
|
840
|
+
async function loadSdk2() {
|
|
841
|
+
if (!cachedSdk2) {
|
|
842
|
+
cachedSdk2 = (async () => {
|
|
843
|
+
try {
|
|
844
|
+
const moduleId = "@supabase/supabase-js";
|
|
845
|
+
return await import(
|
|
846
|
+
/* @vite-ignore */
|
|
847
|
+
moduleId
|
|
848
|
+
);
|
|
849
|
+
} catch {
|
|
850
|
+
throw new Error(
|
|
851
|
+
"Install @supabase/supabase-js to use supabaseVectorStore: npm install @supabase/supabase-js"
|
|
852
|
+
);
|
|
853
|
+
}
|
|
854
|
+
})();
|
|
855
|
+
}
|
|
856
|
+
return cachedSdk2;
|
|
857
|
+
}
|
|
858
|
+
function buildRunner(client) {
|
|
859
|
+
return {
|
|
860
|
+
async query(sql, params) {
|
|
861
|
+
const result = await client.rpc("agentskit_execute_sql", { sql, params });
|
|
862
|
+
if (result.error) throw new Error(`supabase: ${result.error.message}`);
|
|
863
|
+
return { rows: result.data ?? [] };
|
|
864
|
+
}
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
function supabaseVectorStore(config) {
|
|
868
|
+
let runnerPromise = null;
|
|
869
|
+
const getRunner = () => {
|
|
870
|
+
if (!runnerPromise) {
|
|
871
|
+
runnerPromise = (async () => {
|
|
872
|
+
const sdk = await loadSdk2();
|
|
873
|
+
const client = sdk.createClient(config.url, config.serviceRoleKey);
|
|
874
|
+
return buildRunner(client);
|
|
875
|
+
})();
|
|
876
|
+
}
|
|
877
|
+
return runnerPromise;
|
|
878
|
+
};
|
|
879
|
+
let backend = null;
|
|
880
|
+
const getBackend = async () => {
|
|
881
|
+
if (!backend) {
|
|
882
|
+
const runner = await getRunner();
|
|
883
|
+
backend = pgvector({
|
|
884
|
+
runner,
|
|
885
|
+
table: config.table,
|
|
886
|
+
topK: config.topK
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
return backend;
|
|
890
|
+
};
|
|
891
|
+
return {
|
|
892
|
+
async store(docs) {
|
|
893
|
+
const b = await getBackend();
|
|
894
|
+
return b.store(docs);
|
|
895
|
+
},
|
|
896
|
+
async search(embedding, options) {
|
|
897
|
+
const b = await getBackend();
|
|
898
|
+
return b.search(embedding, options);
|
|
899
|
+
},
|
|
900
|
+
async delete(ids) {
|
|
901
|
+
const b = await getBackend();
|
|
902
|
+
return b.delete?.(ids);
|
|
903
|
+
}
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
// src/vector/weaviate.ts
|
|
908
|
+
async function call5(config, method, path, body) {
|
|
909
|
+
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
910
|
+
const response = await fetchImpl(`${config.url}${path}`, {
|
|
911
|
+
method,
|
|
912
|
+
headers: {
|
|
913
|
+
"content-type": "application/json",
|
|
914
|
+
...config.apiKey ? { authorization: `Bearer ${config.apiKey}` } : {}
|
|
915
|
+
},
|
|
916
|
+
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
917
|
+
});
|
|
918
|
+
const text = await response.text();
|
|
919
|
+
if (!response.ok) throw new Error(`weaviate ${response.status}: ${text.slice(0, 200)}`);
|
|
920
|
+
return text.length > 0 ? JSON.parse(text) : {};
|
|
921
|
+
}
|
|
922
|
+
function weaviateVectorStore(config) {
|
|
923
|
+
const defaultTopK = Math.max(1, config.topK ?? 10);
|
|
924
|
+
const className = config.className;
|
|
925
|
+
return {
|
|
926
|
+
async store(docs) {
|
|
927
|
+
if (docs.length === 0) return;
|
|
928
|
+
await call5(config, "POST", "/v1/batch/objects", {
|
|
929
|
+
objects: docs.map((d) => ({
|
|
930
|
+
class: className,
|
|
931
|
+
id: d.id,
|
|
932
|
+
properties: { content: d.content, ...d.metadata ?? {} },
|
|
933
|
+
vector: d.embedding
|
|
934
|
+
}))
|
|
935
|
+
});
|
|
936
|
+
},
|
|
937
|
+
async search(embedding, options = {}) {
|
|
938
|
+
const topK = options.topK ?? defaultTopK;
|
|
939
|
+
const threshold = options.threshold ?? 0;
|
|
940
|
+
const query = `{
|
|
941
|
+
Get {
|
|
942
|
+
${className}(nearVector: { vector: [${embedding.join(",")}] }, limit: ${topK}) {
|
|
943
|
+
content
|
|
944
|
+
_additional { id certainty }
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}`;
|
|
948
|
+
const result = await call5(config, "POST", "/v1/graphql", { query });
|
|
949
|
+
const rows = result.data?.Get?.[className] ?? [];
|
|
950
|
+
return rows.map((row) => ({
|
|
951
|
+
id: String(row._additional?.id ?? ""),
|
|
952
|
+
content: String(row.content ?? ""),
|
|
953
|
+
score: row._additional?.certainty ?? 0,
|
|
954
|
+
metadata: row
|
|
955
|
+
})).filter((r) => (r.score ?? 0) >= threshold);
|
|
956
|
+
},
|
|
957
|
+
async delete(ids) {
|
|
958
|
+
for (const id of ids) {
|
|
959
|
+
await call5(config, "DELETE", `/v1/objects/${className}/${id}`);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
// src/vector/milvus.ts
|
|
966
|
+
async function call6(config, path, body) {
|
|
967
|
+
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
968
|
+
const response = await fetchImpl(`${config.url}${path}`, {
|
|
969
|
+
method: "POST",
|
|
970
|
+
headers: {
|
|
971
|
+
"content-type": "application/json",
|
|
972
|
+
...config.token ? { authorization: `Bearer ${config.token}` } : {}
|
|
973
|
+
},
|
|
974
|
+
body: JSON.stringify(body)
|
|
975
|
+
});
|
|
976
|
+
const text = await response.text();
|
|
977
|
+
if (!response.ok) throw new Error(`milvus ${response.status}: ${text.slice(0, 200)}`);
|
|
978
|
+
return text.length > 0 ? JSON.parse(text) : {};
|
|
979
|
+
}
|
|
980
|
+
function milvusVectorStore(config) {
|
|
981
|
+
const defaultTopK = Math.max(1, config.topK ?? 10);
|
|
982
|
+
const vectorField = config.vectorField ?? "vector";
|
|
983
|
+
return {
|
|
984
|
+
async store(docs) {
|
|
985
|
+
if (docs.length === 0) return;
|
|
986
|
+
await call6(config, "/v2/vectordb/entities/upsert", {
|
|
987
|
+
collectionName: config.collection,
|
|
988
|
+
data: docs.map((d) => ({
|
|
989
|
+
id: d.id,
|
|
990
|
+
[vectorField]: d.embedding,
|
|
991
|
+
content: d.content,
|
|
992
|
+
metadata: d.metadata ?? {}
|
|
993
|
+
}))
|
|
994
|
+
});
|
|
995
|
+
},
|
|
996
|
+
async search(embedding, options = {}) {
|
|
997
|
+
const topK = options.topK ?? defaultTopK;
|
|
998
|
+
const threshold = options.threshold ?? 0;
|
|
999
|
+
const result = await call6(config, "/v2/vectordb/entities/search", {
|
|
1000
|
+
collectionName: config.collection,
|
|
1001
|
+
data: [embedding],
|
|
1002
|
+
annsField: vectorField,
|
|
1003
|
+
limit: topK,
|
|
1004
|
+
outputFields: ["content", "metadata"]
|
|
1005
|
+
});
|
|
1006
|
+
return (result.data ?? []).map((m) => ({
|
|
1007
|
+
id: String(m.id),
|
|
1008
|
+
content: String(m.content ?? ""),
|
|
1009
|
+
score: 1 - m.distance,
|
|
1010
|
+
metadata: m.metadata
|
|
1011
|
+
})).filter((r) => (r.score ?? 0) >= threshold);
|
|
1012
|
+
},
|
|
1013
|
+
async delete(ids) {
|
|
1014
|
+
if (ids.length === 0) return;
|
|
1015
|
+
await call6(config, "/v2/vectordb/entities/delete", {
|
|
1016
|
+
collectionName: config.collection,
|
|
1017
|
+
filter: `id in [${ids.map((id) => `"${id}"`).join(",")}]`
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
// src/vector/mongo-atlas.ts
|
|
1024
|
+
function mongoAtlasVectorStore(config) {
|
|
1025
|
+
const defaultTopK = Math.max(1, config.topK ?? 10);
|
|
1026
|
+
const vectorField = config.vectorField ?? "embedding";
|
|
1027
|
+
return {
|
|
1028
|
+
async store(docs) {
|
|
1029
|
+
if (docs.length === 0) return;
|
|
1030
|
+
await config.collection.insertMany(docs.map((d) => ({
|
|
1031
|
+
_id: d.id,
|
|
1032
|
+
content: d.content,
|
|
1033
|
+
[vectorField]: d.embedding,
|
|
1034
|
+
metadata: d.metadata ?? {}
|
|
1035
|
+
})));
|
|
1036
|
+
},
|
|
1037
|
+
async search(embedding, options = {}) {
|
|
1038
|
+
const topK = options.topK ?? defaultTopK;
|
|
1039
|
+
const threshold = options.threshold ?? 0;
|
|
1040
|
+
const numCandidates = config.numCandidates ?? topK * 10;
|
|
1041
|
+
const cursor = config.collection.aggregate([
|
|
1042
|
+
{
|
|
1043
|
+
$vectorSearch: {
|
|
1044
|
+
index: config.indexName,
|
|
1045
|
+
path: vectorField,
|
|
1046
|
+
queryVector: embedding,
|
|
1047
|
+
numCandidates,
|
|
1048
|
+
limit: topK
|
|
1049
|
+
}
|
|
1050
|
+
},
|
|
1051
|
+
{ $project: { content: 1, metadata: 1, score: { $meta: "vectorSearchScore" } } }
|
|
1052
|
+
]);
|
|
1053
|
+
const rows = await cursor.toArray();
|
|
1054
|
+
return rows.map((row) => ({
|
|
1055
|
+
id: String(row._id),
|
|
1056
|
+
content: String(row.content ?? ""),
|
|
1057
|
+
score: row.score,
|
|
1058
|
+
metadata: row.metadata
|
|
1059
|
+
})).filter((r) => (r.score ?? 0) >= threshold);
|
|
1060
|
+
},
|
|
1061
|
+
async delete(ids) {
|
|
1062
|
+
if (ids.length === 0) return;
|
|
1063
|
+
await config.collection.deleteMany({ _id: { $in: ids } });
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
|
|
731
1068
|
// src/encrypted.ts
|
|
732
1069
|
function toBase64(bytes) {
|
|
733
1070
|
if (typeof Buffer !== "undefined") return Buffer.from(bytes).toString("base64");
|
|
@@ -870,6 +1207,6 @@ function createHierarchicalMemory(options) {
|
|
|
870
1207
|
};
|
|
871
1208
|
}
|
|
872
1209
|
|
|
873
|
-
export { chroma, createEncryptedMemory, createHierarchicalMemory, createInMemoryGraph, createInMemoryPersonalization, fileChatMemory, fileVectorMemory, pgvector, pinecone, qdrant, redisChatMemory, redisVectorMemory, renderProfileContext, sqliteChatMemory, upstashVector };
|
|
1210
|
+
export { chroma, createEncryptedMemory, createHierarchicalMemory, createInMemoryGraph, createInMemoryPersonalization, fileChatMemory, fileVectorMemory, matchesFilter, milvusVectorStore, mongoAtlasVectorStore, pgvector, pinecone, qdrant, redisChatMemory, redisVectorMemory, renderProfileContext, sqliteChatMemory, supabaseVectorStore, tursoChatMemory, upstashVector, weaviateVectorStore };
|
|
874
1211
|
//# sourceMappingURL=index.js.map
|
|
875
1212
|
//# sourceMappingURL=index.js.map
|