@convex-dev/rag 0.5.4 → 0.6.1
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 +89 -82
- package/dist/client/index.d.ts +30 -26
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -2
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +25 -482
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js +10 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +380 -0
- package/dist/component/_generated/component.d.ts.map +1 -0
- package/dist/component/_generated/component.js +11 -0
- package/dist/component/_generated/component.js.map +1 -0
- package/dist/component/_generated/dataModel.d.ts +4 -18
- package/dist/component/_generated/dataModel.d.ts.map +1 -0
- package/dist/component/_generated/dataModel.js +11 -0
- package/dist/component/_generated/dataModel.js.map +1 -0
- package/dist/component/_generated/server.d.ts +10 -38
- package/dist/component/_generated/server.d.ts.map +1 -1
- package/dist/component/_generated/server.js +9 -5
- package/dist/component/_generated/server.js.map +1 -1
- package/dist/component/chunks.d.ts +5 -5
- package/dist/component/chunks.d.ts.map +1 -1
- package/dist/component/chunks.js +21 -51
- package/dist/component/chunks.js.map +1 -1
- package/dist/component/embeddings/tables.d.ts +4 -5
- package/dist/component/embeddings/tables.d.ts.map +1 -1
- package/dist/component/embeddings/tables.js.map +1 -1
- package/dist/component/entries.d.ts +6 -6
- package/dist/component/namespaces.d.ts +8 -8
- package/dist/component/namespaces.d.ts.map +1 -1
- package/dist/component/namespaces.js +2 -2
- package/dist/component/namespaces.js.map +1 -1
- package/dist/component/schema.d.ts +185 -224
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/search.d.ts +4 -3
- package/dist/component/search.d.ts.map +1 -1
- package/dist/component/search.js +1 -1
- package/dist/component/search.js.map +1 -1
- package/dist/shared.d.ts +9 -4
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +1 -4
- package/dist/shared.js.map +1 -1
- package/package.json +72 -44
- package/src/client/defaultChunker.test.ts +1 -1
- package/src/client/defaultChunker.ts +7 -7
- package/src/client/fileUtils.ts +3 -3
- package/src/client/hybridRank.ts +1 -1
- package/src/client/index.test.ts +18 -18
- package/src/client/index.ts +104 -84
- package/src/client/setup.test.ts +2 -2
- package/src/component/_generated/api.ts +66 -0
- package/src/component/_generated/component.ts +442 -0
- package/src/component/_generated/{server.d.ts → server.ts} +33 -21
- package/src/component/chunks.test.ts +14 -14
- package/src/component/chunks.ts +59 -88
- package/src/component/embeddings/importance.test.ts +4 -4
- package/src/component/embeddings/importance.ts +1 -1
- package/src/component/embeddings/index.test.ts +3 -4
- package/src/component/embeddings/index.ts +6 -6
- package/src/component/embeddings/tables.ts +9 -8
- package/src/component/entries.test.ts +10 -10
- package/src/component/entries.ts +29 -29
- package/src/component/filters.ts +8 -8
- package/src/component/namespaces.ts +31 -34
- package/src/component/schema.ts +2 -2
- package/src/component/search.test.ts +5 -5
- package/src/component/search.ts +8 -9
- package/src/component/setup.test.ts +2 -8
- package/src/shared.ts +47 -45
- package/src/test.ts +20 -0
- package/dist/client/types.d.ts +0 -29
- package/dist/client/types.d.ts.map +0 -1
- package/dist/client/types.js +0 -2
- package/dist/client/types.js.map +0 -1
- package/dist/package.json +0 -3
- package/src/client/types.ts +0 -69
- package/src/component/_generated/api.d.ts +0 -507
- package/src/component/_generated/api.js +0 -23
- package/src/component/_generated/server.js +0 -90
- package/src/vitest.config.ts +0 -7
- /package/src/component/_generated/{dataModel.d.ts → dataModel.ts} +0 -0
package/src/client/index.ts
CHANGED
|
@@ -2,13 +2,14 @@ import {
|
|
|
2
2
|
embed,
|
|
3
3
|
embedMany,
|
|
4
4
|
generateText,
|
|
5
|
-
type ModelMessage,
|
|
6
5
|
type EmbeddingModel,
|
|
7
6
|
type EmbeddingModelUsage,
|
|
7
|
+
type ModelMessage,
|
|
8
8
|
} from "ai";
|
|
9
9
|
import { assert } from "convex-helpers";
|
|
10
10
|
import {
|
|
11
11
|
createFunctionHandle,
|
|
12
|
+
FunctionReference,
|
|
12
13
|
internalActionGeneric,
|
|
13
14
|
internalMutationGeneric,
|
|
14
15
|
type FunctionArgs,
|
|
@@ -23,36 +24,30 @@ import {
|
|
|
23
24
|
type RegisteredMutation,
|
|
24
25
|
} from "convex/server";
|
|
25
26
|
import { type Value } from "convex/values";
|
|
27
|
+
import { ComponentApi } from "../component/_generated/component.js";
|
|
28
|
+
import type { NamedFilter } from "../component/filters.js";
|
|
26
29
|
import {
|
|
27
30
|
CHUNK_BATCH_SIZE,
|
|
28
31
|
filterNamesContain,
|
|
32
|
+
OnCompleteArgs,
|
|
29
33
|
vChunkerArgs,
|
|
30
34
|
vEntryId,
|
|
31
35
|
vNamespaceId,
|
|
32
36
|
vOnCompleteArgs,
|
|
33
37
|
type Chunk,
|
|
38
|
+
type ChunkerAction,
|
|
34
39
|
type CreateChunkArgs,
|
|
35
40
|
type Entry,
|
|
36
41
|
type EntryFilter,
|
|
37
42
|
type EntryId,
|
|
38
43
|
type Namespace,
|
|
39
44
|
type NamespaceId,
|
|
45
|
+
type OnComplete,
|
|
46
|
+
type OnCompleteNamespace,
|
|
40
47
|
type SearchEntry,
|
|
41
48
|
type SearchResult,
|
|
42
49
|
type Status,
|
|
43
50
|
} from "../shared.js";
|
|
44
|
-
import {
|
|
45
|
-
type RAGComponent,
|
|
46
|
-
type RunActionCtx,
|
|
47
|
-
type RunMutationCtx,
|
|
48
|
-
type RunQueryCtx,
|
|
49
|
-
} from "./types.js";
|
|
50
|
-
import {
|
|
51
|
-
type ChunkerAction,
|
|
52
|
-
type OnComplete,
|
|
53
|
-
type OnCompleteNamespace,
|
|
54
|
-
} from "../shared.js";
|
|
55
|
-
import type { NamedFilter } from "../component/filters.js";
|
|
56
51
|
import { defaultChunker } from "./defaultChunker.js";
|
|
57
52
|
|
|
58
53
|
export { hybridRank } from "./hybridRank.js";
|
|
@@ -61,7 +56,6 @@ export type {
|
|
|
61
56
|
ChunkerAction,
|
|
62
57
|
Entry,
|
|
63
58
|
EntryId,
|
|
64
|
-
RAGComponent,
|
|
65
59
|
NamespaceId,
|
|
66
60
|
OnComplete,
|
|
67
61
|
OnCompleteNamespace,
|
|
@@ -71,18 +65,18 @@ export type {
|
|
|
71
65
|
};
|
|
72
66
|
|
|
73
67
|
export {
|
|
74
|
-
type VEntry,
|
|
75
|
-
type VSearchEntry,
|
|
76
|
-
type EntryFilter,
|
|
77
68
|
vEntry,
|
|
69
|
+
vOnCompleteArgs,
|
|
78
70
|
vSearchEntry,
|
|
79
71
|
vSearchResult,
|
|
80
|
-
|
|
72
|
+
type EntryFilter,
|
|
73
|
+
type VEntry,
|
|
74
|
+
type VSearchEntry,
|
|
81
75
|
} from "../shared.js";
|
|
82
76
|
export {
|
|
83
77
|
contentHashFromArrayBuffer,
|
|
84
|
-
guessMimeTypeFromExtension,
|
|
85
78
|
guessMimeTypeFromContents,
|
|
79
|
+
guessMimeTypeFromExtension,
|
|
86
80
|
} from "./fileUtils.js";
|
|
87
81
|
|
|
88
82
|
const DEFAULT_SEARCH_LIMIT = 10;
|
|
@@ -115,12 +109,12 @@ export class RAG<
|
|
|
115
109
|
* and then entry results will have the metadata type `{ source: "website" }`.
|
|
116
110
|
*/
|
|
117
111
|
constructor(
|
|
118
|
-
public component:
|
|
112
|
+
public component: ComponentApi,
|
|
119
113
|
public options: {
|
|
120
114
|
embeddingDimension: number;
|
|
121
115
|
textEmbeddingModel: EmbeddingModel<string>;
|
|
122
116
|
filterNames?: FilterNames<FitlerSchemas>;
|
|
123
|
-
}
|
|
117
|
+
},
|
|
124
118
|
) {}
|
|
125
119
|
|
|
126
120
|
/**
|
|
@@ -134,7 +128,7 @@ export class RAG<
|
|
|
134
128
|
* The filterValues you provide can be used later to search for it.
|
|
135
129
|
*/
|
|
136
130
|
async add(
|
|
137
|
-
ctx:
|
|
131
|
+
ctx: CtxWith<"runMutation">,
|
|
138
132
|
args: NamespaceSelection &
|
|
139
133
|
EntryArgs<FitlerSchemas, EntryMetadata> &
|
|
140
134
|
(
|
|
@@ -158,7 +152,7 @@ export class RAG<
|
|
|
158
152
|
/** @deprecated You cannot specify both chunks and text currently. */
|
|
159
153
|
chunks?: undefined;
|
|
160
154
|
}
|
|
161
|
-
)
|
|
155
|
+
),
|
|
162
156
|
): Promise<{
|
|
163
157
|
entryId: EntryId;
|
|
164
158
|
status: Status;
|
|
@@ -185,7 +179,7 @@ export class RAG<
|
|
|
185
179
|
if (Array.isArray(chunks) && chunks.length < CHUNK_BATCH_SIZE) {
|
|
186
180
|
const result = await createChunkArgsBatch(
|
|
187
181
|
this.options.textEmbeddingModel,
|
|
188
|
-
chunks
|
|
182
|
+
chunks,
|
|
189
183
|
);
|
|
190
184
|
allChunks = result.chunks;
|
|
191
185
|
totalUsage.tokens += result.usage.tokens;
|
|
@@ -208,7 +202,7 @@ export class RAG<
|
|
|
208
202
|
},
|
|
209
203
|
onComplete,
|
|
210
204
|
allChunks,
|
|
211
|
-
}
|
|
205
|
+
},
|
|
212
206
|
);
|
|
213
207
|
if (status === "ready") {
|
|
214
208
|
return {
|
|
@@ -230,7 +224,7 @@ export class RAG<
|
|
|
230
224
|
for await (const batch of batchIterator(chunks, CHUNK_BATCH_SIZE)) {
|
|
231
225
|
const result = await createChunkArgsBatch(
|
|
232
226
|
this.options.textEmbeddingModel,
|
|
233
|
-
batch
|
|
227
|
+
batch,
|
|
234
228
|
);
|
|
235
229
|
totalUsage.tokens += result.usage.tokens;
|
|
236
230
|
const { status } = await ctx.runMutation(this.component.chunks.insert, {
|
|
@@ -250,7 +244,7 @@ export class RAG<
|
|
|
250
244
|
while (true) {
|
|
251
245
|
const { status, nextStartOrder } = await ctx.runMutation(
|
|
252
246
|
this.component.chunks.replaceChunksPage,
|
|
253
|
-
{ entryId, startOrder }
|
|
247
|
+
{ entryId, startOrder },
|
|
254
248
|
);
|
|
255
249
|
if (status === "ready") {
|
|
256
250
|
break;
|
|
@@ -268,7 +262,7 @@ export class RAG<
|
|
|
268
262
|
}
|
|
269
263
|
const promoted = await ctx.runMutation(
|
|
270
264
|
this.component.entries.promoteToReady,
|
|
271
|
-
{ entryId }
|
|
265
|
+
{ entryId },
|
|
272
266
|
);
|
|
273
267
|
return {
|
|
274
268
|
entryId: entryId as EntryId,
|
|
@@ -306,7 +300,7 @@ export class RAG<
|
|
|
306
300
|
* ```
|
|
307
301
|
*/
|
|
308
302
|
async addAsync(
|
|
309
|
-
ctx:
|
|
303
|
+
ctx: CtxWith<"runMutation">,
|
|
310
304
|
args: NamespaceSelection &
|
|
311
305
|
EntryArgs<FitlerSchemas, EntryMetadata> & {
|
|
312
306
|
/**
|
|
@@ -324,7 +318,7 @@ export class RAG<
|
|
|
324
318
|
* });
|
|
325
319
|
*/
|
|
326
320
|
chunkerAction: ChunkerAction;
|
|
327
|
-
}
|
|
321
|
+
},
|
|
328
322
|
): Promise<{ entryId: EntryId; status: "ready" | "pending" }> {
|
|
329
323
|
let namespaceId: NamespaceId;
|
|
330
324
|
if ("namespaceId" in args) {
|
|
@@ -358,7 +352,7 @@ export class RAG<
|
|
|
358
352
|
},
|
|
359
353
|
onComplete,
|
|
360
354
|
chunker,
|
|
361
|
-
}
|
|
355
|
+
},
|
|
362
356
|
);
|
|
363
357
|
return { entryId: entryId as EntryId, status };
|
|
364
358
|
}
|
|
@@ -369,7 +363,7 @@ export class RAG<
|
|
|
369
363
|
* parameters to filter and constrain the results.
|
|
370
364
|
*/
|
|
371
365
|
async search(
|
|
372
|
-
ctx:
|
|
366
|
+
ctx: CtxWith<"runAction">,
|
|
373
367
|
args: {
|
|
374
368
|
/**
|
|
375
369
|
* The namespace to search in. e.g. a userId if entries are per-user.
|
|
@@ -381,7 +375,7 @@ export class RAG<
|
|
|
381
375
|
* The query to search for. Optional if embedding is provided.
|
|
382
376
|
*/
|
|
383
377
|
query: string | Array<number>;
|
|
384
|
-
} & SearchOptions<FitlerSchemas
|
|
378
|
+
} & SearchOptions<FitlerSchemas>,
|
|
385
379
|
): Promise<{
|
|
386
380
|
results: SearchResult[];
|
|
387
381
|
text: string;
|
|
@@ -415,7 +409,7 @@ export class RAG<
|
|
|
415
409
|
limit,
|
|
416
410
|
vectorScoreThreshold,
|
|
417
411
|
chunkContext,
|
|
418
|
-
}
|
|
412
|
+
},
|
|
419
413
|
);
|
|
420
414
|
const entriesWithTexts = entries.map((e) => {
|
|
421
415
|
const ranges = results
|
|
@@ -458,7 +452,7 @@ export class RAG<
|
|
|
458
452
|
* extra context / conversation history.
|
|
459
453
|
*/
|
|
460
454
|
async generateText(
|
|
461
|
-
ctx:
|
|
455
|
+
ctx: CtxWith<"runAction">,
|
|
462
456
|
args: {
|
|
463
457
|
/**
|
|
464
458
|
* The search options to use for context search, including the namespace.
|
|
@@ -485,7 +479,7 @@ export class RAG<
|
|
|
485
479
|
* to the prompt, in which case it will precede the prompt.
|
|
486
480
|
*/
|
|
487
481
|
messages?: ModelMessage[];
|
|
488
|
-
} & Parameters<typeof generateText>[0]
|
|
482
|
+
} & Parameters<typeof generateText>[0],
|
|
489
483
|
): Promise<
|
|
490
484
|
Awaited<ReturnType<typeof generateText>> & {
|
|
491
485
|
context: {
|
|
@@ -530,7 +524,7 @@ export class RAG<
|
|
|
530
524
|
.map((e) =>
|
|
531
525
|
e.title
|
|
532
526
|
? `<document title="${e.title}">${e.text}</document>`
|
|
533
|
-
: `<document>${e.text}</document
|
|
527
|
+
: `<document>${e.text}</document>`,
|
|
534
528
|
)
|
|
535
529
|
.join("\n");
|
|
536
530
|
contextFooter = "</context>";
|
|
@@ -576,12 +570,12 @@ export class RAG<
|
|
|
576
570
|
* List all entries in a namespace.
|
|
577
571
|
*/
|
|
578
572
|
async list(
|
|
579
|
-
ctx:
|
|
573
|
+
ctx: CtxWith<"runQuery">,
|
|
580
574
|
args: {
|
|
581
575
|
namespaceId?: NamespaceId;
|
|
582
576
|
order?: "desc" | "asc";
|
|
583
577
|
status?: Status;
|
|
584
|
-
} & ({ paginationOpts: PaginationOptions } | { limit: number })
|
|
578
|
+
} & ({ paginationOpts: PaginationOptions } | { limit: number }),
|
|
585
579
|
): Promise<PaginationResult<Entry<FitlerSchemas, EntryMetadata>>> {
|
|
586
580
|
const paginationOpts =
|
|
587
581
|
"paginationOpts" in args
|
|
@@ -600,10 +594,10 @@ export class RAG<
|
|
|
600
594
|
* Get entry metadata by its id.
|
|
601
595
|
*/
|
|
602
596
|
async getEntry(
|
|
603
|
-
ctx:
|
|
597
|
+
ctx: CtxWith<"runQuery">,
|
|
604
598
|
args: {
|
|
605
599
|
entryId: EntryId;
|
|
606
|
-
}
|
|
600
|
+
},
|
|
607
601
|
): Promise<Entry<FitlerSchemas, EntryMetadata> | null> {
|
|
608
602
|
const entry = await ctx.runQuery(this.component.entries.get, {
|
|
609
603
|
entryId: args.entryId,
|
|
@@ -617,13 +611,13 @@ export class RAG<
|
|
|
617
611
|
* when updating content.
|
|
618
612
|
*/
|
|
619
613
|
async findEntryByContentHash(
|
|
620
|
-
ctx:
|
|
614
|
+
ctx: CtxWith<"runQuery">,
|
|
621
615
|
args: {
|
|
622
616
|
namespace: string;
|
|
623
617
|
key: string;
|
|
624
618
|
/** The hash of the entry contents to try to match. */
|
|
625
619
|
contentHash: string;
|
|
626
|
-
}
|
|
620
|
+
},
|
|
627
621
|
): Promise<Entry<FitlerSchemas, EntryMetadata> | null> {
|
|
628
622
|
const entry = await ctx.runQuery(this.component.entries.findByContentHash, {
|
|
629
623
|
namespace: args.namespace,
|
|
@@ -641,7 +635,7 @@ export class RAG<
|
|
|
641
635
|
* filterNames of the RAG instance. If it doesn't exist, it will be created.
|
|
642
636
|
*/
|
|
643
637
|
async getOrCreateNamespace(
|
|
644
|
-
ctx:
|
|
638
|
+
ctx: CtxWith<"runMutation">,
|
|
645
639
|
args: {
|
|
646
640
|
/**
|
|
647
641
|
* The namespace to get or create. e.g. a userId if entries are per-user.
|
|
@@ -657,7 +651,7 @@ export class RAG<
|
|
|
657
651
|
* along the way.
|
|
658
652
|
*/
|
|
659
653
|
onComplete?: OnCompleteNamespace;
|
|
660
|
-
}
|
|
654
|
+
},
|
|
661
655
|
): Promise<{
|
|
662
656
|
namespaceId: NamespaceId;
|
|
663
657
|
status: "pending" | "ready";
|
|
@@ -667,7 +661,7 @@ export class RAG<
|
|
|
667
661
|
: undefined;
|
|
668
662
|
assert(
|
|
669
663
|
!onComplete || args.status === "pending",
|
|
670
|
-
"You can only supply an onComplete handler for pending namespaces"
|
|
664
|
+
"You can only supply an onComplete handler for pending namespaces",
|
|
671
665
|
);
|
|
672
666
|
const { namespaceId, status } = await ctx.runMutation(
|
|
673
667
|
this.component.namespaces.getOrCreate,
|
|
@@ -678,7 +672,7 @@ export class RAG<
|
|
|
678
672
|
modelId: getModelId(this.options.textEmbeddingModel),
|
|
679
673
|
dimension: this.options.embeddingDimension,
|
|
680
674
|
filterNames: this.options.filterNames ?? [],
|
|
681
|
-
}
|
|
675
|
+
},
|
|
682
676
|
);
|
|
683
677
|
return { namespaceId: namespaceId as NamespaceId, status };
|
|
684
678
|
}
|
|
@@ -688,10 +682,10 @@ export class RAG<
|
|
|
688
682
|
* filterNames of the RAG instance. If it doesn't exist, it will return null.
|
|
689
683
|
*/
|
|
690
684
|
async getNamespace(
|
|
691
|
-
ctx:
|
|
685
|
+
ctx: CtxWith<"runQuery">,
|
|
692
686
|
args: {
|
|
693
687
|
namespace: string;
|
|
694
|
-
}
|
|
688
|
+
},
|
|
695
689
|
): Promise<Namespace | null> {
|
|
696
690
|
return ctx.runQuery(this.component.namespaces.get, {
|
|
697
691
|
namespace: args.namespace,
|
|
@@ -705,12 +699,12 @@ export class RAG<
|
|
|
705
699
|
* List all chunks for an entry, paginated.
|
|
706
700
|
*/
|
|
707
701
|
async listChunks(
|
|
708
|
-
ctx:
|
|
702
|
+
ctx: CtxWith<"runQuery">,
|
|
709
703
|
args: {
|
|
710
704
|
paginationOpts: PaginationOptions;
|
|
711
705
|
entryId: EntryId;
|
|
712
706
|
order?: "desc" | "asc";
|
|
713
|
-
}
|
|
707
|
+
},
|
|
714
708
|
): Promise<PaginationResult<Chunk>> {
|
|
715
709
|
return ctx.runQuery(this.component.chunks.list, {
|
|
716
710
|
entryId: args.entryId,
|
|
@@ -722,7 +716,7 @@ export class RAG<
|
|
|
722
716
|
/**
|
|
723
717
|
* Delete an entry and all its chunks in the background using a workpool.
|
|
724
718
|
*/
|
|
725
|
-
async deleteAsync(ctx:
|
|
719
|
+
async deleteAsync(ctx: CtxWith<"runMutation">, args: { entryId: EntryId }) {
|
|
726
720
|
await ctx.runMutation(this.component.entries.deleteAsync, {
|
|
727
721
|
entryId: args.entryId,
|
|
728
722
|
startOrder: 0,
|
|
@@ -735,17 +729,26 @@ export class RAG<
|
|
|
735
729
|
* you're likely running this in a mutation.
|
|
736
730
|
* Use `deleteAsync` or run `delete` in an action.
|
|
737
731
|
*/
|
|
738
|
-
async delete(
|
|
732
|
+
async delete(
|
|
733
|
+
ctx: CtxWith<"runAction">,
|
|
734
|
+
args: { entryId: EntryId },
|
|
735
|
+
): Promise<void>;
|
|
739
736
|
/** @deprecated Use `deleteAsync` in mutations. */
|
|
740
|
-
async delete(
|
|
741
|
-
|
|
737
|
+
async delete(
|
|
738
|
+
ctx: CtxWith<"runMutation">,
|
|
739
|
+
args: { entryId: EntryId },
|
|
740
|
+
): Promise<void>;
|
|
741
|
+
async delete(
|
|
742
|
+
ctx: CtxWith<"runMutation"> | CtxWith<"runAction">,
|
|
743
|
+
args: { entryId: EntryId },
|
|
744
|
+
) {
|
|
742
745
|
if ("runAction" in ctx) {
|
|
743
746
|
await ctx.runAction(this.component.entries.deleteSync, {
|
|
744
747
|
entryId: args.entryId,
|
|
745
748
|
});
|
|
746
749
|
} else {
|
|
747
750
|
console.warn(
|
|
748
|
-
"You are running `rag.delete` in a mutation. This is deprecated. Use `rag.deleteAsync` from mutations, or `rag.delete` in actions."
|
|
751
|
+
"You are running `rag.delete` in a mutation. This is deprecated. Use `rag.deleteAsync` from mutations, or `rag.delete` in actions.",
|
|
749
752
|
);
|
|
750
753
|
await ctx.runMutation(this.component.entries.deleteAsync, {
|
|
751
754
|
entryId: args.entryId,
|
|
@@ -758,8 +761,8 @@ export class RAG<
|
|
|
758
761
|
* Delete all entries with a given key (asynchrounously).
|
|
759
762
|
*/
|
|
760
763
|
async deleteByKeyAsync(
|
|
761
|
-
ctx:
|
|
762
|
-
args: { namespaceId: NamespaceId; key: string; beforeVersion?: number }
|
|
764
|
+
ctx: CtxWith<"runMutation">,
|
|
765
|
+
args: { namespaceId: NamespaceId; key: string; beforeVersion?: number },
|
|
763
766
|
) {
|
|
764
767
|
await ctx.runMutation(this.component.entries.deleteByKeyAsync, {
|
|
765
768
|
namespaceId: args.namespaceId,
|
|
@@ -775,8 +778,8 @@ export class RAG<
|
|
|
775
778
|
* Use `deleteByKeyAsync` or run `delete` in an action.
|
|
776
779
|
*/
|
|
777
780
|
async deleteByKey(
|
|
778
|
-
ctx:
|
|
779
|
-
args: { namespaceId: NamespaceId; key: string; beforeVersion?: number }
|
|
781
|
+
ctx: CtxWith<"runAction">,
|
|
782
|
+
args: { namespaceId: NamespaceId; key: string; beforeVersion?: number },
|
|
780
783
|
) {
|
|
781
784
|
await ctx.runAction(this.component.entries.deleteByKeySync, args);
|
|
782
785
|
}
|
|
@@ -802,13 +805,9 @@ export class RAG<
|
|
|
802
805
|
defineOnComplete<DataModel extends GenericDataModel>(
|
|
803
806
|
fn: (
|
|
804
807
|
ctx: GenericMutationCtx<DataModel>,
|
|
805
|
-
args:
|
|
806
|
-
) => Promise<void
|
|
807
|
-
): RegisteredMutation<
|
|
808
|
-
"internal",
|
|
809
|
-
FunctionArgs<OnComplete<FitlerSchemas, EntryMetadata>>,
|
|
810
|
-
null
|
|
811
|
-
> {
|
|
808
|
+
args: OnCompleteArgs<FitlerSchemas, EntryMetadata>,
|
|
809
|
+
) => Promise<void>,
|
|
810
|
+
): RegisteredMutation<"internal", FunctionArgs<OnComplete>, null> {
|
|
812
811
|
return internalMutationGeneric({
|
|
813
812
|
args: vOnCompleteArgs,
|
|
814
813
|
handler: fn,
|
|
@@ -836,8 +835,11 @@ export class RAG<
|
|
|
836
835
|
defineChunkerAction<DataModel extends GenericDataModel>(
|
|
837
836
|
fn: (
|
|
838
837
|
ctx: GenericActionCtx<DataModel>,
|
|
839
|
-
args: {
|
|
840
|
-
|
|
838
|
+
args: {
|
|
839
|
+
namespace: Namespace;
|
|
840
|
+
entry: Entry<FitlerSchemas, EntryMetadata>;
|
|
841
|
+
},
|
|
842
|
+
) => AsyncIterable<InputChunk> | Promise<{ chunks: InputChunk[] }>,
|
|
841
843
|
): RegisteredAction<
|
|
842
844
|
"internal",
|
|
843
845
|
FunctionArgs<ChunkerAction>,
|
|
@@ -851,26 +853,26 @@ export class RAG<
|
|
|
851
853
|
if (namespace.modelId !== modelId) {
|
|
852
854
|
console.error(
|
|
853
855
|
`You are using a different embedding model ${modelId} for asynchronously ` +
|
|
854
|
-
`generating chunks than the one provided when it was started: ${namespace.modelId}
|
|
856
|
+
`generating chunks than the one provided when it was started: ${namespace.modelId}`,
|
|
855
857
|
);
|
|
856
858
|
return;
|
|
857
859
|
}
|
|
858
860
|
if (namespace.dimension !== this.options.embeddingDimension) {
|
|
859
861
|
console.error(
|
|
860
862
|
`You are using a different embedding dimension ${this.options.embeddingDimension} for asynchronously ` +
|
|
861
|
-
`generating chunks than the one provided when it was started: ${namespace.dimension}
|
|
863
|
+
`generating chunks than the one provided when it was started: ${namespace.dimension}`,
|
|
862
864
|
);
|
|
863
865
|
return;
|
|
864
866
|
}
|
|
865
867
|
if (
|
|
866
868
|
!filterNamesContain(
|
|
867
869
|
namespace.filterNames,
|
|
868
|
-
this.options.filterNames ?? []
|
|
870
|
+
this.options.filterNames ?? [],
|
|
869
871
|
)
|
|
870
872
|
) {
|
|
871
873
|
console.error(
|
|
872
874
|
`You are using a different filters (${this.options.filterNames?.join(", ")}) for asynchronously ` +
|
|
873
|
-
`generating chunks than the one provided when it was started: ${namespace.filterNames.join(", ")}
|
|
875
|
+
`generating chunks than the one provided when it was started: ${namespace.filterNames.join(", ")}`,
|
|
874
876
|
);
|
|
875
877
|
return;
|
|
876
878
|
}
|
|
@@ -892,23 +894,23 @@ export class RAG<
|
|
|
892
894
|
let batchOrder = 0;
|
|
893
895
|
for await (const batch of batchIterator(
|
|
894
896
|
chunkIterator,
|
|
895
|
-
CHUNK_BATCH_SIZE
|
|
897
|
+
CHUNK_BATCH_SIZE,
|
|
896
898
|
)) {
|
|
897
899
|
const result = await createChunkArgsBatch(
|
|
898
900
|
this.options.textEmbeddingModel,
|
|
899
|
-
batch
|
|
901
|
+
batch,
|
|
900
902
|
);
|
|
901
903
|
await ctx.runMutation(
|
|
902
904
|
args.insertChunks as FunctionHandle<
|
|
903
905
|
"mutation",
|
|
904
|
-
FunctionArgs<
|
|
906
|
+
FunctionArgs<ComponentApi["chunks"]["insert"]>,
|
|
905
907
|
null
|
|
906
908
|
>,
|
|
907
909
|
{
|
|
908
910
|
entryId: entry.entryId,
|
|
909
911
|
startOrder: batchOrder,
|
|
910
912
|
chunks: result.chunks,
|
|
911
|
-
}
|
|
913
|
+
},
|
|
912
914
|
);
|
|
913
915
|
batchOrder += result.chunks.length;
|
|
914
916
|
}
|
|
@@ -919,7 +921,7 @@ export class RAG<
|
|
|
919
921
|
|
|
920
922
|
async function* batchIterator<T>(
|
|
921
923
|
iterator: Iterable<T> | AsyncIterable<T>,
|
|
922
|
-
batchSize: number
|
|
924
|
+
batchSize: number,
|
|
923
925
|
): AsyncIterable<T[]> {
|
|
924
926
|
let batch: T[] = [];
|
|
925
927
|
for await (const item of iterator) {
|
|
@@ -936,21 +938,21 @@ async function* batchIterator<T>(
|
|
|
936
938
|
|
|
937
939
|
function validateAddFilterValues(
|
|
938
940
|
filterValues: NamedFilter[] | undefined,
|
|
939
|
-
filterNames: string[] | undefined
|
|
941
|
+
filterNames: string[] | undefined,
|
|
940
942
|
) {
|
|
941
943
|
if (!filterValues) {
|
|
942
944
|
return;
|
|
943
945
|
}
|
|
944
946
|
if (!filterNames) {
|
|
945
947
|
throw new Error(
|
|
946
|
-
"You must provide filter names to RAG to add entries with filters."
|
|
948
|
+
"You must provide filter names to RAG to add entries with filters.",
|
|
947
949
|
);
|
|
948
950
|
}
|
|
949
951
|
const seen = new Set<string>();
|
|
950
952
|
for (const filterValue of filterValues) {
|
|
951
953
|
if (seen.has(filterValue.name)) {
|
|
952
954
|
throw new Error(
|
|
953
|
-
`You cannot provide the same filter name twice: ${filterValue.name}
|
|
955
|
+
`You cannot provide the same filter name twice: ${filterValue.name}.`,
|
|
954
956
|
);
|
|
955
957
|
}
|
|
956
958
|
seen.add(filterValue.name);
|
|
@@ -958,7 +960,7 @@ function validateAddFilterValues(
|
|
|
958
960
|
for (const filterName of filterNames) {
|
|
959
961
|
if (!seen.has(filterName)) {
|
|
960
962
|
throw new Error(
|
|
961
|
-
`Filter name ${filterName} is not valid (one of ${filterNames.join(", ")})
|
|
963
|
+
`Filter name ${filterName} is not valid (one of ${filterNames.join(", ")}).`,
|
|
962
964
|
);
|
|
963
965
|
}
|
|
964
966
|
}
|
|
@@ -974,7 +976,7 @@ function makeBatches<T>(items: T[], batchSize: number): T[][] {
|
|
|
974
976
|
|
|
975
977
|
async function createChunkArgsBatch(
|
|
976
978
|
embedModel: EmbeddingModel<string>,
|
|
977
|
-
chunks: InputChunk[]
|
|
979
|
+
chunks: InputChunk[],
|
|
978
980
|
): Promise<{ chunks: CreateChunkArgs[]; usage: EmbeddingModelUsage }> {
|
|
979
981
|
const argsMaybeMissingEmbeddings: (Omit<CreateChunkArgs, "embedding"> & {
|
|
980
982
|
embedding?: number[];
|
|
@@ -1006,7 +1008,7 @@ async function createChunkArgsBatch(
|
|
|
1006
1008
|
: {
|
|
1007
1009
|
text: arg.content.text,
|
|
1008
1010
|
index,
|
|
1009
|
-
}
|
|
1011
|
+
},
|
|
1010
1012
|
)
|
|
1011
1013
|
.filter((b) => b !== null);
|
|
1012
1014
|
const totalUsage: EmbeddingModelUsage = { tokens: 0 };
|
|
@@ -1216,3 +1218,21 @@ export function getProviderName(embeddingModel: ModelOrMetadata): string {
|
|
|
1216
1218
|
}
|
|
1217
1219
|
return embeddingModel.provider;
|
|
1218
1220
|
}
|
|
1221
|
+
|
|
1222
|
+
type CtxWith<T extends "runQuery" | "runMutation" | "runAction"> = Pick<
|
|
1223
|
+
{
|
|
1224
|
+
runQuery: <Query extends FunctionReference<"query", "internal">>(
|
|
1225
|
+
query: Query,
|
|
1226
|
+
args: FunctionArgs<Query>,
|
|
1227
|
+
) => Promise<FunctionReturnType<Query>>;
|
|
1228
|
+
runMutation: <Mutation extends FunctionReference<"mutation", "internal">>(
|
|
1229
|
+
mutation: Mutation,
|
|
1230
|
+
args: FunctionArgs<Mutation>,
|
|
1231
|
+
) => Promise<FunctionReturnType<Mutation>>;
|
|
1232
|
+
runAction: <Action extends FunctionReference<"action", "internal">>(
|
|
1233
|
+
action: Action,
|
|
1234
|
+
args: FunctionArgs<Action>,
|
|
1235
|
+
) => Promise<FunctionReturnType<Action>>;
|
|
1236
|
+
},
|
|
1237
|
+
T
|
|
1238
|
+
>;
|
package/src/client/setup.test.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type GenericSchema,
|
|
9
9
|
type SchemaDefinition,
|
|
10
10
|
} from "convex/server";
|
|
11
|
-
import { type
|
|
11
|
+
import { type ComponentApi } from "../component/_generated/component.js";
|
|
12
12
|
import { componentsGeneric } from "convex/server";
|
|
13
13
|
import componentSchema from "../component/schema.js";
|
|
14
14
|
export { componentSchema };
|
|
@@ -22,7 +22,7 @@ export function initConvexTest<
|
|
|
22
22
|
return t;
|
|
23
23
|
}
|
|
24
24
|
export const components = componentsGeneric() as unknown as {
|
|
25
|
-
rag:
|
|
25
|
+
rag: ComponentApi;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
test("setup", () => {});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/**
|
|
3
|
+
* Generated `api` utility.
|
|
4
|
+
*
|
|
5
|
+
* THIS CODE IS AUTOMATICALLY GENERATED.
|
|
6
|
+
*
|
|
7
|
+
* To regenerate, run `npx convex dev`.
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type * as chunks from "../chunks.js";
|
|
12
|
+
import type * as embeddings_importance from "../embeddings/importance.js";
|
|
13
|
+
import type * as embeddings_index from "../embeddings/index.js";
|
|
14
|
+
import type * as embeddings_tables from "../embeddings/tables.js";
|
|
15
|
+
import type * as entries from "../entries.js";
|
|
16
|
+
import type * as filters from "../filters.js";
|
|
17
|
+
import type * as namespaces from "../namespaces.js";
|
|
18
|
+
import type * as search from "../search.js";
|
|
19
|
+
|
|
20
|
+
import type {
|
|
21
|
+
ApiFromModules,
|
|
22
|
+
FilterApi,
|
|
23
|
+
FunctionReference,
|
|
24
|
+
} from "convex/server";
|
|
25
|
+
import { anyApi, componentsGeneric } from "convex/server";
|
|
26
|
+
|
|
27
|
+
const fullApi: ApiFromModules<{
|
|
28
|
+
chunks: typeof chunks;
|
|
29
|
+
"embeddings/importance": typeof embeddings_importance;
|
|
30
|
+
"embeddings/index": typeof embeddings_index;
|
|
31
|
+
"embeddings/tables": typeof embeddings_tables;
|
|
32
|
+
entries: typeof entries;
|
|
33
|
+
filters: typeof filters;
|
|
34
|
+
namespaces: typeof namespaces;
|
|
35
|
+
search: typeof search;
|
|
36
|
+
}> = anyApi as any;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A utility for referencing Convex functions in your app's public API.
|
|
40
|
+
*
|
|
41
|
+
* Usage:
|
|
42
|
+
* ```js
|
|
43
|
+
* const myFunctionReference = api.myModule.myFunction;
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export const api: FilterApi<
|
|
47
|
+
typeof fullApi,
|
|
48
|
+
FunctionReference<any, "public">
|
|
49
|
+
> = anyApi as any;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* A utility for referencing Convex functions in your app's internal API.
|
|
53
|
+
*
|
|
54
|
+
* Usage:
|
|
55
|
+
* ```js
|
|
56
|
+
* const myFunctionReference = internal.myModule.myFunction;
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export const internal: FilterApi<
|
|
60
|
+
typeof fullApi,
|
|
61
|
+
FunctionReference<any, "internal">
|
|
62
|
+
> = anyApi as any;
|
|
63
|
+
|
|
64
|
+
export const components = componentsGeneric() as unknown as {
|
|
65
|
+
workpool: import("@convex-dev/workpool/_generated/component.js").ComponentApi<"workpool">;
|
|
66
|
+
};
|