@fastpaca/cria 1.7.0 → 1.7.2
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/README.md +47 -1
- package/dist/memory/chroma/index.d.ts +0 -2
- package/dist/memory/chroma/index.d.ts.map +1 -1
- package/dist/memory/chroma/index.js +30 -34
- package/dist/memory/chroma/index.js.map +1 -1
- package/dist/memory/postgres.d.ts.map +1 -1
- package/dist/memory/postgres.js +17 -22
- package/dist/memory/postgres.js.map +1 -1
- package/dist/memory/qdrant/index.d.ts +0 -1
- package/dist/memory/qdrant/index.d.ts.map +1 -1
- package/dist/memory/qdrant/index.js +25 -30
- package/dist/memory/qdrant/index.js.map +1 -1
- package/dist/memory/redis.d.ts.map +1 -1
- package/dist/memory/redis.js +20 -33
- package/dist/memory/redis.js.map +1 -1
- package/dist/memory/sqlite-vector.d.ts +89 -0
- package/dist/memory/sqlite-vector.d.ts.map +1 -0
- package/dist/memory/sqlite-vector.js +211 -0
- package/dist/memory/sqlite-vector.js.map +1 -0
- package/dist/memory/sqlite.d.ts +77 -0
- package/dist/memory/sqlite.d.ts.map +1 -0
- package/dist/memory/sqlite.js +119 -0
- package/dist/memory/sqlite.js.map +1 -0
- package/package.json +14 -1
package/README.md
CHANGED
|
@@ -302,6 +302,52 @@ const messages = await cria
|
|
|
302
302
|
|
|
303
303
|
</details>
|
|
304
304
|
|
|
305
|
+
<details>
|
|
306
|
+
<summary><strong>SQLite (conversation summaries)</strong></summary>
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
import { SqliteStore } from "@fastpaca/cria/memory/sqlite";
|
|
310
|
+
import type { StoredSummary } from "@fastpaca/cria";
|
|
311
|
+
|
|
312
|
+
const store = new SqliteStore<StoredSummary>({
|
|
313
|
+
filename: "cria.sqlite",
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const messages = await cria
|
|
317
|
+
.prompt(provider)
|
|
318
|
+
.system("You are a helpful assistant.")
|
|
319
|
+
.summary(conversation, { id: "conv-123", store, priority: 2 })
|
|
320
|
+
.last(conversation, { n: 20 })
|
|
321
|
+
.user(query)
|
|
322
|
+
.render({ budget: 128_000 });
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
</details>
|
|
326
|
+
|
|
327
|
+
<details>
|
|
328
|
+
<summary><strong>SQLite (vector search)</strong></summary>
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
import { z } from "zod";
|
|
332
|
+
import { SqliteVectorStore } from "@fastpaca/cria/memory/sqlite-vector";
|
|
333
|
+
|
|
334
|
+
const store = new SqliteVectorStore({
|
|
335
|
+
filename: "cria.sqlite",
|
|
336
|
+
dimensions: 1536,
|
|
337
|
+
embed: async (text) => await getEmbedding(text),
|
|
338
|
+
schema: z.string(),
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
const messages = await cria
|
|
342
|
+
.prompt(provider)
|
|
343
|
+
.system("You are a research assistant.")
|
|
344
|
+
.vectorSearch({ store, query, limit: 10 })
|
|
345
|
+
.user(query)
|
|
346
|
+
.render({ budget: 128_000 });
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
</details>
|
|
350
|
+
|
|
305
351
|
<details>
|
|
306
352
|
<summary><strong>Chroma (vector search)</strong></summary>
|
|
307
353
|
|
|
@@ -367,7 +413,7 @@ const messages = await cria
|
|
|
367
413
|
Prompt structures/messages (via a provider adapter). You pass the rendered output into your existing LLM SDK call.
|
|
368
414
|
|
|
369
415
|
**What works out of the box?**
|
|
370
|
-
Provider adapters for OpenAI (Chat Completions + Responses), Anthropic, and Vercel AI SDK; store adapters for Redis, Postgres, Chroma, and Qdrant.
|
|
416
|
+
Provider adapters for OpenAI (Chat Completions + Responses), Anthropic, and Vercel AI SDK; store adapters for Redis, SQLite, Postgres, Chroma, and Qdrant.
|
|
371
417
|
|
|
372
418
|
**How do I validate component swaps?**
|
|
373
419
|
Swap via adapters, diff the rendered prompt output, and run prompt eval/tests to catch drift.
|
|
@@ -49,11 +49,9 @@ export declare class ChromaStore<T = unknown> implements VectorMemory<T> {
|
|
|
49
49
|
private readonly collection;
|
|
50
50
|
private readonly embedFn;
|
|
51
51
|
constructor(options: ChromaStoreOptions);
|
|
52
|
-
private embed;
|
|
53
52
|
get(key: string): Promise<MemoryEntry<T> | null>;
|
|
54
53
|
set(key: string, data: T, metadata?: Record<string, unknown>): Promise<void>;
|
|
55
54
|
delete(key: string): Promise<boolean>;
|
|
56
55
|
search(query: string, options?: VectorSearchOptions): Promise<VectorSearchResult<T>[]>;
|
|
57
|
-
private buildSearchResults;
|
|
58
56
|
}
|
|
59
57
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/memory/chroma/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAA8B,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/memory/chroma/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAA8B,MAAM,UAAU,CAAC;AAEvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,mCAAmC;IACnC,UAAU,EAAE,UAAU,CAAC;IACvB,gDAAgD;IAChD,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAwDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,WAAW,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,YAAY,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;gBAEhC,OAAO,EAAE,kBAAkB;IAKjC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAgBhD,GAAG,CACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,EACP,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IA0BV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASrC,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;CAkDpC"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { IncludeEnum } from "chromadb";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
function parseDocument(document) {
|
|
7
|
-
if (!document) {
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const DocumentSchema = z
|
|
4
|
+
.preprocess((value) => {
|
|
5
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
8
6
|
throw new Error("ChromaStore: document is missing from entry");
|
|
9
7
|
}
|
|
8
|
+
return value;
|
|
9
|
+
}, z.string())
|
|
10
|
+
.transform((document) => {
|
|
10
11
|
try {
|
|
11
12
|
return JSON.parse(document);
|
|
12
13
|
}
|
|
@@ -14,7 +15,8 @@ function parseDocument(document) {
|
|
|
14
15
|
// Document was stored as a raw string (T is string)
|
|
15
16
|
return document;
|
|
16
17
|
}
|
|
17
|
-
}
|
|
18
|
+
});
|
|
19
|
+
const MetadataSchema = z.record(z.string(), z.unknown()).optional().nullable();
|
|
18
20
|
/**
|
|
19
21
|
* Convert L2 distance to a similarity score (0-1).
|
|
20
22
|
* Lower distance = higher similarity.
|
|
@@ -29,6 +31,20 @@ function extractTimestamp(metadata, field) {
|
|
|
29
31
|
const value = metadata?.[field];
|
|
30
32
|
return typeof value === "number" ? value : 0;
|
|
31
33
|
}
|
|
34
|
+
const ChromaEntrySchema = z
|
|
35
|
+
.object({
|
|
36
|
+
document: DocumentSchema,
|
|
37
|
+
metadata: MetadataSchema,
|
|
38
|
+
})
|
|
39
|
+
.transform((entry) => {
|
|
40
|
+
const metadata = entry.metadata ?? undefined;
|
|
41
|
+
return {
|
|
42
|
+
data: entry.document,
|
|
43
|
+
createdAt: extractTimestamp(metadata, "_createdAt"),
|
|
44
|
+
updatedAt: extractTimestamp(metadata, "_updatedAt"),
|
|
45
|
+
...(metadata && { metadata }),
|
|
46
|
+
};
|
|
47
|
+
});
|
|
32
48
|
/**
|
|
33
49
|
* VectorMemory implementation backed by ChromaDB.
|
|
34
50
|
*
|
|
@@ -67,16 +83,6 @@ export class ChromaStore {
|
|
|
67
83
|
this.collection = options.collection;
|
|
68
84
|
this.embedFn = options.embed;
|
|
69
85
|
}
|
|
70
|
-
async embed(text, context) {
|
|
71
|
-
try {
|
|
72
|
-
return await this.embedFn(text);
|
|
73
|
-
}
|
|
74
|
-
catch (error) {
|
|
75
|
-
throw new Error(`ChromaStore: embedding failed during ${context}`, {
|
|
76
|
-
cause: error,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
86
|
async get(key) {
|
|
81
87
|
const response = await this.collection.get({
|
|
82
88
|
ids: [key],
|
|
@@ -87,12 +93,7 @@ export class ChromaStore {
|
|
|
87
93
|
}
|
|
88
94
|
const document = response.documents?.[0];
|
|
89
95
|
const metadata = response.metadatas?.[0];
|
|
90
|
-
return {
|
|
91
|
-
data: parseDocument(document),
|
|
92
|
-
createdAt: extractTimestamp(metadata, "_createdAt"),
|
|
93
|
-
updatedAt: extractTimestamp(metadata, "_updatedAt"),
|
|
94
|
-
...(metadata && { metadata: metadata }),
|
|
95
|
-
};
|
|
96
|
+
return ChromaEntrySchema.parse({ document, metadata });
|
|
96
97
|
}
|
|
97
98
|
async set(key, data, metadata) {
|
|
98
99
|
const now = Date.now();
|
|
@@ -101,7 +102,7 @@ export class ChromaStore {
|
|
|
101
102
|
const createdAt = existing?.createdAt ?? now;
|
|
102
103
|
// Convert data to text for embedding and storage
|
|
103
104
|
const document = typeof data === "string" ? data : JSON.stringify(data);
|
|
104
|
-
const vector = await this.
|
|
105
|
+
const vector = await this.embedFn(document);
|
|
105
106
|
// Merge user metadata with timestamps
|
|
106
107
|
const chromaMetadata = {
|
|
107
108
|
...metadata,
|
|
@@ -126,7 +127,7 @@ export class ChromaStore {
|
|
|
126
127
|
async search(query, options) {
|
|
127
128
|
const limit = options?.limit ?? 10;
|
|
128
129
|
const threshold = options?.threshold;
|
|
129
|
-
const queryVector = await this.
|
|
130
|
+
const queryVector = await this.embedFn(query);
|
|
130
131
|
const response = await this.collection.query({
|
|
131
132
|
queryEmbeddings: [queryVector],
|
|
132
133
|
nResults: limit,
|
|
@@ -140,9 +141,6 @@ export class ChromaStore {
|
|
|
140
141
|
const documents = response.documents?.[0] ?? [];
|
|
141
142
|
const metadatas = response.metadatas?.[0] ?? [];
|
|
142
143
|
const distances = response.distances?.[0] ?? [];
|
|
143
|
-
return this.buildSearchResults(ids, documents, metadatas, distances, threshold);
|
|
144
|
-
}
|
|
145
|
-
buildSearchResults(ids, documents, metadatas, distances, threshold) {
|
|
146
144
|
const results = [];
|
|
147
145
|
for (let i = 0; i < ids.length; i++) {
|
|
148
146
|
const id = ids[i];
|
|
@@ -158,12 +156,10 @@ export class ChromaStore {
|
|
|
158
156
|
results.push({
|
|
159
157
|
key: id,
|
|
160
158
|
score,
|
|
161
|
-
entry: {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
...(metadata && { metadata: metadata }),
|
|
166
|
-
},
|
|
159
|
+
entry: ChromaEntrySchema.parse({
|
|
160
|
+
document: documents[i],
|
|
161
|
+
metadata,
|
|
162
|
+
}),
|
|
167
163
|
});
|
|
168
164
|
}
|
|
169
165
|
return results;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/memory/chroma/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,WAAW,EAAiB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/memory/chroma/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/memory/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/memory/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAGrC,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,aAAa,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,QAAQ,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAO;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;IAC1C,OAAO,CAAC,YAAY,CAAS;gBAEjB,OAAO,GAAE,oBAAyB;YAQhC,WAAW;IAkBnB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAiBhD,GAAG,CACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,EACP,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAyBV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW3C;;;OAGG;IACG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAG3B;AAGD,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/memory/postgres.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { Pool } from "pg";
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const KVRowSchema = z
|
|
4
|
+
.object({
|
|
5
|
+
key: z.string(),
|
|
6
|
+
data: z.unknown(),
|
|
7
|
+
created_at: z.coerce.date(),
|
|
8
|
+
updated_at: z.coerce.date(),
|
|
9
|
+
metadata: z.record(z.string(), z.unknown()).nullable(),
|
|
10
|
+
})
|
|
11
|
+
.transform((row) => ({
|
|
12
|
+
data: row.data,
|
|
13
|
+
createdAt: row.created_at.getTime(),
|
|
14
|
+
updatedAt: row.updated_at.getTime(),
|
|
15
|
+
...(row.metadata && { metadata: row.metadata }),
|
|
16
|
+
}));
|
|
16
17
|
/**
|
|
17
18
|
* Postgres-backed implementation of KVMemory.
|
|
18
19
|
*
|
|
@@ -55,8 +56,7 @@ export class PostgresStore {
|
|
|
55
56
|
tableCreated = false;
|
|
56
57
|
constructor(options = {}) {
|
|
57
58
|
const { tableName, autoCreateTable, ...poolConfig } = options;
|
|
58
|
-
|
|
59
|
-
this.tableName = sanitizedTableName;
|
|
59
|
+
this.tableName = tableName ?? "cria_kv_store";
|
|
60
60
|
this.pool = new Pool(poolConfig);
|
|
61
61
|
this.autoCreateTable = autoCreateTable ?? true;
|
|
62
62
|
}
|
|
@@ -82,12 +82,7 @@ export class PostgresStore {
|
|
|
82
82
|
if (row === undefined) {
|
|
83
83
|
return null;
|
|
84
84
|
}
|
|
85
|
-
return
|
|
86
|
-
data: row.data,
|
|
87
|
-
createdAt: new Date(row.created_at).getTime(),
|
|
88
|
-
updatedAt: new Date(row.updated_at).getTime(),
|
|
89
|
-
...(row.metadata && { metadata: row.metadata }),
|
|
90
|
-
};
|
|
85
|
+
return KVRowSchema.parse(row);
|
|
91
86
|
}
|
|
92
87
|
async set(key, data, metadata) {
|
|
93
88
|
await this.ensureTable();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/memory/postgres.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/memory/postgres.ts"],"names":[],"mappings":"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"}
|
|
@@ -55,7 +55,6 @@ export declare class QdrantStore<T = unknown> implements VectorMemory<T> {
|
|
|
55
55
|
private readonly embedFn;
|
|
56
56
|
private readonly vectorName;
|
|
57
57
|
constructor(options: QdrantStoreOptions);
|
|
58
|
-
private embed;
|
|
59
58
|
get(key: string): Promise<MemoryEntry<T> | null>;
|
|
60
59
|
set(key: string, data: T, metadata?: Record<string, unknown>): Promise<void>;
|
|
61
60
|
delete(key: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/memory/qdrant/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/memory/qdrant/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,WAAW,CAAC;AAEnB;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iCAAiC;IACjC,MAAM,EAAE,YAAY,CAAC;IACrB,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,KAAK,EAAE,iBAAiB,CAAC;IACzB,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAgBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,WAAW,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,YAAY,CAAC,CAAC,CAAC;IAC9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;gBAEpC,OAAO,EAAE,kBAAkB;IAOjC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAkBhD,GAAG,CACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,EACP,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IA0BV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYrC,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;CAiCpC"}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const QdrantPayloadSchema = z
|
|
3
|
+
.object({
|
|
4
|
+
data: z.unknown(),
|
|
5
|
+
createdAt: z.number(),
|
|
6
|
+
updatedAt: z.number(),
|
|
7
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
8
|
+
})
|
|
9
|
+
.transform((payload) => ({
|
|
10
|
+
data: payload.data,
|
|
11
|
+
createdAt: payload.createdAt,
|
|
12
|
+
updatedAt: payload.updatedAt,
|
|
13
|
+
...(payload.metadata && { metadata: payload.metadata }),
|
|
14
|
+
}));
|
|
12
15
|
/**
|
|
13
16
|
* VectorMemory implementation backed by Qdrant.
|
|
14
17
|
*
|
|
@@ -51,16 +54,6 @@ export class QdrantStore {
|
|
|
51
54
|
this.embedFn = options.embed;
|
|
52
55
|
this.vectorName = options.vectorName;
|
|
53
56
|
}
|
|
54
|
-
async embed(text, context) {
|
|
55
|
-
try {
|
|
56
|
-
return await this.embedFn(text);
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
throw new Error(`QdrantStore: embedding failed during ${context}`, {
|
|
60
|
-
cause: error,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
57
|
async get(key) {
|
|
65
58
|
const response = await this.client.retrieve(this.collectionName, {
|
|
66
59
|
ids: [key],
|
|
@@ -70,14 +63,16 @@ export class QdrantStore {
|
|
|
70
63
|
if (!point) {
|
|
71
64
|
return null;
|
|
72
65
|
}
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
if (!point.payload) {
|
|
67
|
+
throw new Error("QdrantStore: payload is missing from entry");
|
|
68
|
+
}
|
|
69
|
+
return QdrantPayloadSchema.parse(point.payload);
|
|
75
70
|
}
|
|
76
71
|
async set(key, data, metadata) {
|
|
77
72
|
const now = Date.now();
|
|
78
73
|
// Convert data to text for embedding
|
|
79
74
|
const textToEmbed = typeof data === "string" ? data : JSON.stringify(data);
|
|
80
|
-
const vector = await this.
|
|
75
|
+
const vector = await this.embedFn(textToEmbed);
|
|
81
76
|
const payload = {
|
|
82
77
|
data,
|
|
83
78
|
createdAt: now,
|
|
@@ -90,7 +85,7 @@ export class QdrantStore {
|
|
|
90
85
|
{
|
|
91
86
|
id: key,
|
|
92
87
|
vector: this.vectorName ? { [this.vectorName]: vector } : vector,
|
|
93
|
-
payload
|
|
88
|
+
payload,
|
|
94
89
|
},
|
|
95
90
|
],
|
|
96
91
|
});
|
|
@@ -109,7 +104,7 @@ export class QdrantStore {
|
|
|
109
104
|
async search(query, options) {
|
|
110
105
|
const limit = options?.limit ?? 10;
|
|
111
106
|
const threshold = options?.threshold;
|
|
112
|
-
const queryVector = await this.
|
|
107
|
+
const queryVector = await this.embedFn(query);
|
|
113
108
|
const response = await this.client.search(this.collectionName, {
|
|
114
109
|
vector: this.vectorName
|
|
115
110
|
? { name: this.vectorName, vector: queryVector }
|
|
@@ -120,14 +115,14 @@ export class QdrantStore {
|
|
|
120
115
|
});
|
|
121
116
|
const results = [];
|
|
122
117
|
for (const point of response) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
continue;
|
|
118
|
+
if (!point.payload) {
|
|
119
|
+
throw new Error("QdrantStore: payload is missing from entry");
|
|
126
120
|
}
|
|
121
|
+
const entry = QdrantPayloadSchema.parse(point.payload);
|
|
127
122
|
results.push({
|
|
128
123
|
key: String(point.id),
|
|
129
124
|
score: point.score,
|
|
130
|
-
entry
|
|
125
|
+
entry,
|
|
131
126
|
});
|
|
132
127
|
}
|
|
133
128
|
return results;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/memory/qdrant/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/memory/qdrant/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2BxB,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;IACjB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CACvD,CAAC;KACD,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACvB,IAAI,EAAE,OAAO,CAAC,IAAI;IAClB,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;CACxD,CAAC,CAAC,CAAC;AAEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,OAAO,WAAW;IACL,MAAM,CAAe;IACrB,cAAc,CAAS;IACvB,OAAO,CAAoB;IAC3B,UAAU,CAAqB;IAEhD,YAAY,OAA2B;QACrC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE;YAC/D,GAAG,EAAE,CAAC,GAAG,CAAC;YACV,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QAED,OAAO,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAmB,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAW,EACX,IAAO,EACP,QAAkC;QAElC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,qCAAqC;QACrC,MAAM,WAAW,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAE/C,MAAM,OAAO,GAAG;YACd,IAAI;YACJ,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;YACd,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,CAAC;SAC9B,CAAC;QAEF,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE;YAC5C,IAAI,EAAE,IAAI;YACV,MAAM,EAAE;gBACN;oBACE,EAAE,EAAE,GAAG;oBACP,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM;oBAChE,OAAO;iBACR;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE;YAC5C,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,CAAC,GAAG,CAAC;SACd,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAM,CACV,KAAa,EACb,OAA6B;QAE7B,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,CAAC;QAErC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAE9C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE;YAC7D,MAAM,EAAE,IAAI,CAAC,UAAU;gBACrB,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE;gBAChD,CAAC,CAAC,WAAW;YACf,KAAK;YACL,YAAY,EAAE,IAAI;YAClB,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;SAC/D,CAAC,CAAC;QAEH,MAAM,OAAO,GAA4B,EAAE,CAAC;QAE5C,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAChE,CAAC;YAED,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAmB,CAAC;YAEzE,OAAO,CAAC,IAAI,CAAC;gBACX,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,KAAK;aACN,CAAC,CAAC;QACL,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/memory/redis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/memory/redis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAyBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,UAAU,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,QAAQ,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;gBAEzB,OAAO,GAAE,iBAAsB;IAW3C,OAAO,CAAC,WAAW;IAIb,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAWhD,GAAG,CACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,EACP,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IA6BV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK3C;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAGlC;AAGD,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/memory/redis.js
CHANGED
|
@@ -1,30 +1,23 @@
|
|
|
1
1
|
import Redis from "ioredis";
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const StoredEntrySchema = z
|
|
4
|
+
.preprocess((value) => {
|
|
5
|
+
if (typeof value === "string") {
|
|
6
|
+
return JSON.parse(value);
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return {
|
|
22
|
-
data: data,
|
|
23
|
-
createdAt,
|
|
24
|
-
updatedAt,
|
|
25
|
-
...(metadata ? { metadata } : {}),
|
|
26
|
-
};
|
|
27
|
-
};
|
|
8
|
+
return value;
|
|
9
|
+
}, z.object({
|
|
10
|
+
data: z.unknown(),
|
|
11
|
+
createdAt: z.number(),
|
|
12
|
+
updatedAt: z.number(),
|
|
13
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
14
|
+
}))
|
|
15
|
+
.transform((entry) => ({
|
|
16
|
+
data: entry.data,
|
|
17
|
+
createdAt: entry.createdAt,
|
|
18
|
+
updatedAt: entry.updatedAt,
|
|
19
|
+
...(entry.metadata && { metadata: entry.metadata }),
|
|
20
|
+
}));
|
|
28
21
|
/**
|
|
29
22
|
* Redis-backed implementation of KVMemory.
|
|
30
23
|
*
|
|
@@ -80,13 +73,7 @@ export class RedisStore {
|
|
|
80
73
|
if (raw === null) {
|
|
81
74
|
return null;
|
|
82
75
|
}
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
data: stored.data,
|
|
86
|
-
createdAt: stored.createdAt,
|
|
87
|
-
updatedAt: stored.updatedAt,
|
|
88
|
-
...(stored.metadata && { metadata: stored.metadata }),
|
|
89
|
-
};
|
|
76
|
+
return StoredEntrySchema.parse(raw);
|
|
90
77
|
}
|
|
91
78
|
async set(key, data, metadata) {
|
|
92
79
|
const prefixedKey = this.prefixedKey(key);
|
|
@@ -95,7 +82,7 @@ export class RedisStore {
|
|
|
95
82
|
const existingRaw = await this.client.get(prefixedKey);
|
|
96
83
|
let createdAt = now;
|
|
97
84
|
if (existingRaw !== null) {
|
|
98
|
-
const existing =
|
|
85
|
+
const existing = StoredEntrySchema.parse(existingRaw);
|
|
99
86
|
createdAt = existing.createdAt;
|
|
100
87
|
}
|
|
101
88
|
const entry = {
|
package/dist/memory/redis.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/memory/redis.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/memory/redis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { MemoryEntry } from "./key-value";
|
|
3
|
+
import type { SqliteConnectionOptions, SqliteDatabase } from "./sqlite";
|
|
4
|
+
import type { VectorMemory, VectorSearchOptions, VectorSearchResult } from "./vector";
|
|
5
|
+
/**
|
|
6
|
+
* Function to generate embeddings for text.
|
|
7
|
+
*/
|
|
8
|
+
export type EmbeddingFunction = (text: string) => Promise<number[]>;
|
|
9
|
+
/**
|
|
10
|
+
* Configuration options for the SQLite vector store.
|
|
11
|
+
*/
|
|
12
|
+
export interface SqliteVectorStoreOptions<T = unknown> {
|
|
13
|
+
/**
|
|
14
|
+
* Database filename. Use ":memory:" for in-memory databases.
|
|
15
|
+
* @default ":memory:"
|
|
16
|
+
*/
|
|
17
|
+
filename?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Options passed to the libSQL client.
|
|
20
|
+
*/
|
|
21
|
+
options?: SqliteConnectionOptions;
|
|
22
|
+
/**
|
|
23
|
+
* Provide an existing database client (overrides filename/options).
|
|
24
|
+
*/
|
|
25
|
+
database?: SqliteDatabase;
|
|
26
|
+
/**
|
|
27
|
+
* Table name for storing entries.
|
|
28
|
+
* The table will be created automatically if it doesn't exist.
|
|
29
|
+
* @default "cria_vector_store"
|
|
30
|
+
*/
|
|
31
|
+
tableName?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Vector dimensionality (must match embedding length).
|
|
34
|
+
*/
|
|
35
|
+
dimensions: number;
|
|
36
|
+
/**
|
|
37
|
+
* Function to generate embeddings from text.
|
|
38
|
+
*/
|
|
39
|
+
embed: EmbeddingFunction;
|
|
40
|
+
/**
|
|
41
|
+
* Schema for validating stored data.
|
|
42
|
+
*/
|
|
43
|
+
schema: z.ZodType<T>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* SQLite-backed implementation of VectorMemory.
|
|
47
|
+
*
|
|
48
|
+
* Uses libSQL vector columns and vector indexes for DB-side similarity search.
|
|
49
|
+
*
|
|
50
|
+
* @template T - The type of data to store
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import { z } from "zod";
|
|
55
|
+
* import { SqliteVectorStore } from "@fastpaca/cria/memory/sqlite-vector";
|
|
56
|
+
*
|
|
57
|
+
* const store = new SqliteVectorStore<string>({
|
|
58
|
+
* filename: "cria.sqlite",
|
|
59
|
+
* dimensions: 1536,
|
|
60
|
+
* embed: async (text) => getEmbedding(text),
|
|
61
|
+
* schema: z.string(),
|
|
62
|
+
* });
|
|
63
|
+
*
|
|
64
|
+
* const results = await store.search("What is RAG?", { limit: 5 });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare class SqliteVectorStore<T = unknown> implements VectorMemory<T> {
|
|
68
|
+
private readonly db;
|
|
69
|
+
private readonly tableName;
|
|
70
|
+
private readonly embedFn;
|
|
71
|
+
private readonly dimensions;
|
|
72
|
+
private readonly schema;
|
|
73
|
+
private readonly embeddingSchema;
|
|
74
|
+
private tableCreated;
|
|
75
|
+
private indexCreated;
|
|
76
|
+
constructor(options: SqliteVectorStoreOptions<T>);
|
|
77
|
+
private ensureTable;
|
|
78
|
+
private ensureIndex;
|
|
79
|
+
get(key: string): Promise<MemoryEntry<T> | null>;
|
|
80
|
+
set(key: string, data: T, metadata?: Record<string, unknown>): Promise<void>;
|
|
81
|
+
delete(key: string): Promise<boolean>;
|
|
82
|
+
search(query: string, options?: VectorSearchOptions): Promise<VectorSearchResult<T>[]>;
|
|
83
|
+
/**
|
|
84
|
+
* Close the database connection.
|
|
85
|
+
* Call this when you're done using the store to clean up resources.
|
|
86
|
+
*/
|
|
87
|
+
close(): void;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=sqlite-vector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-vector.d.ts","sourceRoot":"","sources":["../../src/memory/sqlite-vector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACxE,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,wBAAwB,CAAC,CAAC,GAAG,OAAO;IACnD;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,KAAK,EAAE,iBAAiB,CAAC;IACzB;;OAEG;IACH,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CACtB;AAWD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,iBAAiB,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,YAAY,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAiB;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsB;IACtD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAS;gBAEjB,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC;YAwBlC,WAAW;YAmBX,WAAW;IAenB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IA4BhD,GAAG,CACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,EACP,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAuCV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWrC,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IAsEnC;;;OAGG;IACH,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { createClient } from "@libsql/client";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const metadataSchema = z.object({}).catchall(z.unknown());
|
|
4
|
+
const sqliteRowSchema = z.object({
|
|
5
|
+
key: z.string(),
|
|
6
|
+
data: z.string(),
|
|
7
|
+
created_at: z.number(),
|
|
8
|
+
updated_at: z.number(),
|
|
9
|
+
metadata: z.string().nullable(),
|
|
10
|
+
});
|
|
11
|
+
/**
|
|
12
|
+
* SQLite-backed implementation of VectorMemory.
|
|
13
|
+
*
|
|
14
|
+
* Uses libSQL vector columns and vector indexes for DB-side similarity search.
|
|
15
|
+
*
|
|
16
|
+
* @template T - The type of data to store
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { z } from "zod";
|
|
21
|
+
* import { SqliteVectorStore } from "@fastpaca/cria/memory/sqlite-vector";
|
|
22
|
+
*
|
|
23
|
+
* const store = new SqliteVectorStore<string>({
|
|
24
|
+
* filename: "cria.sqlite",
|
|
25
|
+
* dimensions: 1536,
|
|
26
|
+
* embed: async (text) => getEmbedding(text),
|
|
27
|
+
* schema: z.string(),
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* const results = await store.search("What is RAG?", { limit: 5 });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export class SqliteVectorStore {
|
|
34
|
+
db;
|
|
35
|
+
tableName;
|
|
36
|
+
embedFn;
|
|
37
|
+
dimensions;
|
|
38
|
+
schema;
|
|
39
|
+
embeddingSchema;
|
|
40
|
+
tableCreated = false;
|
|
41
|
+
indexCreated = false;
|
|
42
|
+
constructor(options) {
|
|
43
|
+
const { filename = ":memory:", options: dbOptions, database, tableName = "cria_vector_store", dimensions, embed, schema, } = options;
|
|
44
|
+
this.db =
|
|
45
|
+
database ??
|
|
46
|
+
createClient({
|
|
47
|
+
url: filename === ":memory:" ? ":memory:" : `file:${filename}`,
|
|
48
|
+
...dbOptions,
|
|
49
|
+
});
|
|
50
|
+
this.tableName = tableName;
|
|
51
|
+
this.embedFn = embed;
|
|
52
|
+
this.dimensions = dimensions;
|
|
53
|
+
this.schema = schema;
|
|
54
|
+
this.embeddingSchema = z.array(z.number()).length(dimensions);
|
|
55
|
+
}
|
|
56
|
+
async ensureTable() {
|
|
57
|
+
if (this.tableCreated) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
await this.db.execute(`
|
|
61
|
+
CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
62
|
+
key TEXT PRIMARY KEY,
|
|
63
|
+
data TEXT NOT NULL,
|
|
64
|
+
embedding F32_BLOB(${this.dimensions}) NOT NULL,
|
|
65
|
+
created_at INTEGER NOT NULL,
|
|
66
|
+
updated_at INTEGER NOT NULL,
|
|
67
|
+
metadata TEXT
|
|
68
|
+
)
|
|
69
|
+
`);
|
|
70
|
+
this.tableCreated = true;
|
|
71
|
+
}
|
|
72
|
+
async ensureIndex() {
|
|
73
|
+
if (this.indexCreated) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
await this.db.execute(`
|
|
77
|
+
CREATE INDEX IF NOT EXISTS ${this.tableName}_vector_idx
|
|
78
|
+
ON ${this.tableName} (
|
|
79
|
+
libsql_vector_idx(embedding, 'metric=cosine')
|
|
80
|
+
)
|
|
81
|
+
`);
|
|
82
|
+
this.indexCreated = true;
|
|
83
|
+
}
|
|
84
|
+
async get(key) {
|
|
85
|
+
await this.ensureTable();
|
|
86
|
+
const result = await this.db.execute({
|
|
87
|
+
sql: `SELECT key, data, created_at, updated_at, metadata FROM ${this.tableName} WHERE key = ?`,
|
|
88
|
+
args: [key],
|
|
89
|
+
});
|
|
90
|
+
const row = result.rows[0];
|
|
91
|
+
if (!row) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const parsedRow = sqliteRowSchema.parse(row);
|
|
95
|
+
const data = this.schema.parse(JSON.parse(parsedRow.data));
|
|
96
|
+
const metadata = parsedRow.metadata === null
|
|
97
|
+
? undefined
|
|
98
|
+
: metadataSchema.parse(JSON.parse(parsedRow.metadata));
|
|
99
|
+
return {
|
|
100
|
+
data,
|
|
101
|
+
createdAt: parsedRow.created_at,
|
|
102
|
+
updatedAt: parsedRow.updated_at,
|
|
103
|
+
...(metadata && { metadata }),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async set(key, data, metadata) {
|
|
107
|
+
await this.ensureTable();
|
|
108
|
+
await this.ensureIndex();
|
|
109
|
+
const now = Date.now();
|
|
110
|
+
const parsedData = this.schema.parse(data);
|
|
111
|
+
const serializedData = JSON.stringify(parsedData);
|
|
112
|
+
const serializedMetadata = metadata === undefined
|
|
113
|
+
? null
|
|
114
|
+
: JSON.stringify(metadataSchema.parse(metadata));
|
|
115
|
+
const textToEmbed = typeof parsedData === "string" ? parsedData : serializedData;
|
|
116
|
+
const embedding = this.embeddingSchema.parse(await this.embedFn(textToEmbed));
|
|
117
|
+
await this.db.execute({
|
|
118
|
+
sql: `
|
|
119
|
+
INSERT INTO ${this.tableName} (key, data, embedding, created_at, updated_at, metadata)
|
|
120
|
+
VALUES (?, ?, vector32(?), ?, ?, ?)
|
|
121
|
+
ON CONFLICT(key) DO UPDATE SET
|
|
122
|
+
data = excluded.data,
|
|
123
|
+
embedding = excluded.embedding,
|
|
124
|
+
updated_at = excluded.updated_at,
|
|
125
|
+
metadata = excluded.metadata
|
|
126
|
+
`,
|
|
127
|
+
args: [
|
|
128
|
+
key,
|
|
129
|
+
serializedData,
|
|
130
|
+
JSON.stringify(embedding),
|
|
131
|
+
now,
|
|
132
|
+
now,
|
|
133
|
+
serializedMetadata,
|
|
134
|
+
],
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
async delete(key) {
|
|
138
|
+
await this.ensureTable();
|
|
139
|
+
const result = await this.db.execute({
|
|
140
|
+
sql: `DELETE FROM ${this.tableName} WHERE key = ?`,
|
|
141
|
+
args: [key],
|
|
142
|
+
});
|
|
143
|
+
return result.rowsAffected > 0;
|
|
144
|
+
}
|
|
145
|
+
async search(query, options) {
|
|
146
|
+
await this.ensureTable();
|
|
147
|
+
await this.ensureIndex();
|
|
148
|
+
const limit = Math.max(0, Math.trunc(options?.limit ?? 10));
|
|
149
|
+
const threshold = options?.threshold;
|
|
150
|
+
const queryVector = this.embeddingSchema.parse(await this.embedFn(query));
|
|
151
|
+
const serializedQuery = JSON.stringify(queryVector);
|
|
152
|
+
const result = await this.db.execute({
|
|
153
|
+
sql: `
|
|
154
|
+
SELECT
|
|
155
|
+
t.key,
|
|
156
|
+
t.data,
|
|
157
|
+
t.created_at,
|
|
158
|
+
t.updated_at,
|
|
159
|
+
t.metadata,
|
|
160
|
+
vector_distance_cos(t.embedding, vector32(?)) AS distance
|
|
161
|
+
FROM vector_top_k(
|
|
162
|
+
?,
|
|
163
|
+
vector32(?),
|
|
164
|
+
CAST(? AS INTEGER)
|
|
165
|
+
) AS i
|
|
166
|
+
JOIN ${this.tableName} AS t ON t.rowid = i.id
|
|
167
|
+
ORDER BY distance ASC
|
|
168
|
+
`,
|
|
169
|
+
args: [
|
|
170
|
+
serializedQuery,
|
|
171
|
+
`${this.tableName}_vector_idx`,
|
|
172
|
+
serializedQuery,
|
|
173
|
+
limit,
|
|
174
|
+
],
|
|
175
|
+
});
|
|
176
|
+
const results = [];
|
|
177
|
+
const searchRowSchema = sqliteRowSchema.extend({
|
|
178
|
+
distance: z.number(),
|
|
179
|
+
});
|
|
180
|
+
for (const row of result.rows) {
|
|
181
|
+
const parsedRow = searchRowSchema.parse(row);
|
|
182
|
+
const score = Math.max(0, Math.min(1, 1 - parsedRow.distance / 2));
|
|
183
|
+
if (threshold !== undefined && score < threshold) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
const data = this.schema.parse(JSON.parse(parsedRow.data));
|
|
187
|
+
const metadata = parsedRow.metadata === null
|
|
188
|
+
? undefined
|
|
189
|
+
: metadataSchema.parse(JSON.parse(parsedRow.metadata));
|
|
190
|
+
results.push({
|
|
191
|
+
key: parsedRow.key,
|
|
192
|
+
score,
|
|
193
|
+
entry: {
|
|
194
|
+
data,
|
|
195
|
+
createdAt: parsedRow.created_at,
|
|
196
|
+
updatedAt: parsedRow.updated_at,
|
|
197
|
+
...(metadata && { metadata }),
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return results;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Close the database connection.
|
|
205
|
+
* Call this when you're done using the store to clean up resources.
|
|
206
|
+
*/
|
|
207
|
+
close() {
|
|
208
|
+
this.db.close();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=sqlite-vector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-vector.js","sourceRoot":"","sources":["../../src/memory/sqlite-vector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type Client, type Config } from "@libsql/client";
|
|
2
|
+
import type { KVMemory, MemoryEntry } from "./key-value";
|
|
3
|
+
/**
|
|
4
|
+
* Connection options for a libSQL database.
|
|
5
|
+
*/
|
|
6
|
+
export type SqliteConnectionOptions = Omit<Config, "url">;
|
|
7
|
+
/**
|
|
8
|
+
* libSQL Client instance used by the store.
|
|
9
|
+
*/
|
|
10
|
+
export type SqliteDatabase = Client;
|
|
11
|
+
/**
|
|
12
|
+
* Configuration options for the SQLite store.
|
|
13
|
+
*/
|
|
14
|
+
export interface SqliteStoreOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Database filename. Use ":memory:" for in-memory databases.
|
|
17
|
+
* @default ":memory:"
|
|
18
|
+
*/
|
|
19
|
+
filename?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Options passed to the libSQL client.
|
|
22
|
+
*/
|
|
23
|
+
options?: SqliteConnectionOptions;
|
|
24
|
+
/**
|
|
25
|
+
* Provide an existing database client (overrides filename/options).
|
|
26
|
+
*/
|
|
27
|
+
database?: SqliteDatabase;
|
|
28
|
+
/**
|
|
29
|
+
* Table name for storing entries.
|
|
30
|
+
* The table will be created automatically if it doesn't exist.
|
|
31
|
+
* @default "cria_kv_store"
|
|
32
|
+
*/
|
|
33
|
+
tableName?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Whether to create the table on first use if it doesn't exist.
|
|
36
|
+
* @default true
|
|
37
|
+
*/
|
|
38
|
+
autoCreateTable?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* SQLite-backed implementation of KVMemory.
|
|
42
|
+
*
|
|
43
|
+
* Plug-and-play adapter using libSQL. Just pass a filename or
|
|
44
|
+
* an existing database client.
|
|
45
|
+
*
|
|
46
|
+
* @template T - The type of data to store
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* import { SqliteStore } from "@fastpaca/cria/memory/sqlite";
|
|
51
|
+
*
|
|
52
|
+
* const store = new SqliteStore<{ content: string }>({
|
|
53
|
+
* filename: "cria.sqlite",
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* await store.set("key-1", { content: "Hello" });
|
|
57
|
+
* const entry = await store.get("key-1");
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare class SqliteStore<T = unknown> implements KVMemory<T> {
|
|
61
|
+
private readonly db;
|
|
62
|
+
private readonly tableName;
|
|
63
|
+
private readonly autoCreateTable;
|
|
64
|
+
private tableCreated;
|
|
65
|
+
constructor(options?: SqliteStoreOptions);
|
|
66
|
+
private ensureTable;
|
|
67
|
+
get(key: string): Promise<MemoryEntry<T> | null>;
|
|
68
|
+
set(key: string, data: T, metadata?: Record<string, unknown>): Promise<void>;
|
|
69
|
+
delete(key: string): Promise<boolean>;
|
|
70
|
+
/**
|
|
71
|
+
* Close the database connection.
|
|
72
|
+
* Call this when you're done using the store to clean up resources.
|
|
73
|
+
*/
|
|
74
|
+
close(): void;
|
|
75
|
+
}
|
|
76
|
+
export type { KVMemory, MemoryEntry } from "./key-value";
|
|
77
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/memory/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,EAAgB,MAAM,gBAAgB,CAAC;AAExE,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE1D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AA0BpC;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,WAAW,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,QAAQ,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAiB;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;IAC1C,OAAO,CAAC,YAAY,CAAS;gBAEjB,OAAO,GAAE,kBAAuB;YAmB9B,WAAW;IAkBnB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAgBhD,GAAG,CACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,EACP,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAqBV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW3C;;;OAGG;IACH,KAAK,IAAI,IAAI;CAGd;AAGD,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { createClient } from "@libsql/client";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const MetadataSchema = z.record(z.string(), z.unknown());
|
|
4
|
+
const SqliteRowSchema = z
|
|
5
|
+
.object({
|
|
6
|
+
key: z.string(),
|
|
7
|
+
data: z.string(),
|
|
8
|
+
created_at: z.coerce.number(),
|
|
9
|
+
updated_at: z.coerce.number(),
|
|
10
|
+
metadata: z.string().nullable(),
|
|
11
|
+
})
|
|
12
|
+
.transform((row) => {
|
|
13
|
+
const metadata = row.metadata === null
|
|
14
|
+
? undefined
|
|
15
|
+
: MetadataSchema.parse(JSON.parse(row.metadata));
|
|
16
|
+
return {
|
|
17
|
+
data: JSON.parse(row.data),
|
|
18
|
+
createdAt: row.created_at,
|
|
19
|
+
updatedAt: row.updated_at,
|
|
20
|
+
...(metadata && { metadata }),
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* SQLite-backed implementation of KVMemory.
|
|
25
|
+
*
|
|
26
|
+
* Plug-and-play adapter using libSQL. Just pass a filename or
|
|
27
|
+
* an existing database client.
|
|
28
|
+
*
|
|
29
|
+
* @template T - The type of data to store
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* import { SqliteStore } from "@fastpaca/cria/memory/sqlite";
|
|
34
|
+
*
|
|
35
|
+
* const store = new SqliteStore<{ content: string }>({
|
|
36
|
+
* filename: "cria.sqlite",
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* await store.set("key-1", { content: "Hello" });
|
|
40
|
+
* const entry = await store.get("key-1");
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export class SqliteStore {
|
|
44
|
+
db;
|
|
45
|
+
tableName;
|
|
46
|
+
autoCreateTable;
|
|
47
|
+
tableCreated = false;
|
|
48
|
+
constructor(options = {}) {
|
|
49
|
+
const { filename = ":memory:", options: dbOptions, database, tableName = "cria_kv_store", autoCreateTable = true, } = options;
|
|
50
|
+
this.db =
|
|
51
|
+
database ??
|
|
52
|
+
createClient({
|
|
53
|
+
url: filename === ":memory:" ? ":memory:" : `file:${filename}`,
|
|
54
|
+
...dbOptions,
|
|
55
|
+
});
|
|
56
|
+
this.tableName = tableName;
|
|
57
|
+
this.autoCreateTable = autoCreateTable;
|
|
58
|
+
}
|
|
59
|
+
async ensureTable() {
|
|
60
|
+
if (this.tableCreated || !this.autoCreateTable) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
await this.db.execute(`
|
|
64
|
+
CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
65
|
+
key TEXT PRIMARY KEY,
|
|
66
|
+
data TEXT NOT NULL,
|
|
67
|
+
created_at INTEGER NOT NULL,
|
|
68
|
+
updated_at INTEGER NOT NULL,
|
|
69
|
+
metadata TEXT
|
|
70
|
+
)
|
|
71
|
+
`);
|
|
72
|
+
this.tableCreated = true;
|
|
73
|
+
}
|
|
74
|
+
async get(key) {
|
|
75
|
+
await this.ensureTable();
|
|
76
|
+
const result = await this.db.execute({
|
|
77
|
+
sql: `SELECT key, data, created_at, updated_at, metadata FROM ${this.tableName} WHERE key = ?`,
|
|
78
|
+
args: [key],
|
|
79
|
+
});
|
|
80
|
+
const row = result.rows[0];
|
|
81
|
+
if (row === undefined) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return SqliteRowSchema.parse(row);
|
|
85
|
+
}
|
|
86
|
+
async set(key, data, metadata) {
|
|
87
|
+
await this.ensureTable();
|
|
88
|
+
const now = Date.now();
|
|
89
|
+
const serializedData = JSON.stringify(data);
|
|
90
|
+
const serializedMetadata = metadata !== undefined ? JSON.stringify(metadata) : null;
|
|
91
|
+
await this.db.execute({
|
|
92
|
+
sql: `
|
|
93
|
+
INSERT INTO ${this.tableName} (key, data, created_at, updated_at, metadata)
|
|
94
|
+
VALUES (?, ?, ?, ?, ?)
|
|
95
|
+
ON CONFLICT(key) DO UPDATE SET
|
|
96
|
+
data = excluded.data,
|
|
97
|
+
updated_at = excluded.updated_at,
|
|
98
|
+
metadata = excluded.metadata
|
|
99
|
+
`,
|
|
100
|
+
args: [key, serializedData, now, now, serializedMetadata],
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async delete(key) {
|
|
104
|
+
await this.ensureTable();
|
|
105
|
+
const result = await this.db.execute({
|
|
106
|
+
sql: `DELETE FROM ${this.tableName} WHERE key = ?`,
|
|
107
|
+
args: [key],
|
|
108
|
+
});
|
|
109
|
+
return result.rowsAffected > 0;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Close the database connection.
|
|
113
|
+
* Call this when you're done using the store to clean up resources.
|
|
114
|
+
*/
|
|
115
|
+
close() {
|
|
116
|
+
this.db.close();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/memory/sqlite.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastpaca/cria",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "Lightweight, fast, and tiny LLM Context & Memory layout renderer to enforce token budgets in long running agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "seb@fastpaca.com",
|
|
@@ -41,6 +41,14 @@
|
|
|
41
41
|
"types": "./dist/memory/postgres.d.ts",
|
|
42
42
|
"import": "./dist/memory/postgres.js"
|
|
43
43
|
},
|
|
44
|
+
"./memory/sqlite": {
|
|
45
|
+
"types": "./dist/memory/sqlite.d.ts",
|
|
46
|
+
"import": "./dist/memory/sqlite.js"
|
|
47
|
+
},
|
|
48
|
+
"./memory/sqlite-vector": {
|
|
49
|
+
"types": "./dist/memory/sqlite-vector.d.ts",
|
|
50
|
+
"import": "./dist/memory/sqlite-vector.js"
|
|
51
|
+
},
|
|
44
52
|
"./memory/chroma": {
|
|
45
53
|
"types": "./dist/memory/chroma/index.d.ts",
|
|
46
54
|
"import": "./dist/memory/chroma/index.js"
|
|
@@ -56,6 +64,7 @@
|
|
|
56
64
|
},
|
|
57
65
|
"peerDependencies": {
|
|
58
66
|
"@anthropic-ai/sdk": "^0.20.0",
|
|
67
|
+
"@libsql/client": "^0.17.0",
|
|
59
68
|
"@qdrant/js-client-rest": "^1.0.0",
|
|
60
69
|
"ai": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0",
|
|
61
70
|
"chromadb": "^1.0.0 || ^2.0.0 || ^3.0.0",
|
|
@@ -67,6 +76,9 @@
|
|
|
67
76
|
"@anthropic-ai/sdk": {
|
|
68
77
|
"optional": true
|
|
69
78
|
},
|
|
79
|
+
"@libsql/client": {
|
|
80
|
+
"optional": true
|
|
81
|
+
},
|
|
70
82
|
"@qdrant/js-client-rest": {
|
|
71
83
|
"optional": true
|
|
72
84
|
},
|
|
@@ -109,6 +121,7 @@
|
|
|
109
121
|
"@qdrant/js-client-rest": "^1.16.2",
|
|
110
122
|
"@semantic-release/changelog": "^6.0.3",
|
|
111
123
|
"@semantic-release/git": "^10.0.1",
|
|
124
|
+
"@libsql/client": "^0.17.0",
|
|
112
125
|
"@types/node": "^25.0.10",
|
|
113
126
|
"@types/pg": "^8.16.0",
|
|
114
127
|
"ai": "^6.0.45",
|