@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.
Files changed (82) hide show
  1. package/README.md +89 -82
  2. package/dist/client/index.d.ts +30 -26
  3. package/dist/client/index.d.ts.map +1 -1
  4. package/dist/client/index.js +2 -2
  5. package/dist/client/index.js.map +1 -1
  6. package/dist/component/_generated/api.d.ts +25 -482
  7. package/dist/component/_generated/api.d.ts.map +1 -1
  8. package/dist/component/_generated/api.js +10 -1
  9. package/dist/component/_generated/api.js.map +1 -1
  10. package/dist/component/_generated/component.d.ts +380 -0
  11. package/dist/component/_generated/component.d.ts.map +1 -0
  12. package/dist/component/_generated/component.js +11 -0
  13. package/dist/component/_generated/component.js.map +1 -0
  14. package/dist/component/_generated/dataModel.d.ts +4 -18
  15. package/dist/component/_generated/dataModel.d.ts.map +1 -0
  16. package/dist/component/_generated/dataModel.js +11 -0
  17. package/dist/component/_generated/dataModel.js.map +1 -0
  18. package/dist/component/_generated/server.d.ts +10 -38
  19. package/dist/component/_generated/server.d.ts.map +1 -1
  20. package/dist/component/_generated/server.js +9 -5
  21. package/dist/component/_generated/server.js.map +1 -1
  22. package/dist/component/chunks.d.ts +5 -5
  23. package/dist/component/chunks.d.ts.map +1 -1
  24. package/dist/component/chunks.js +21 -51
  25. package/dist/component/chunks.js.map +1 -1
  26. package/dist/component/embeddings/tables.d.ts +4 -5
  27. package/dist/component/embeddings/tables.d.ts.map +1 -1
  28. package/dist/component/embeddings/tables.js.map +1 -1
  29. package/dist/component/entries.d.ts +6 -6
  30. package/dist/component/namespaces.d.ts +8 -8
  31. package/dist/component/namespaces.d.ts.map +1 -1
  32. package/dist/component/namespaces.js +2 -2
  33. package/dist/component/namespaces.js.map +1 -1
  34. package/dist/component/schema.d.ts +185 -224
  35. package/dist/component/schema.d.ts.map +1 -1
  36. package/dist/component/search.d.ts +4 -3
  37. package/dist/component/search.d.ts.map +1 -1
  38. package/dist/component/search.js +1 -1
  39. package/dist/component/search.js.map +1 -1
  40. package/dist/shared.d.ts +9 -4
  41. package/dist/shared.d.ts.map +1 -1
  42. package/dist/shared.js +1 -4
  43. package/dist/shared.js.map +1 -1
  44. package/package.json +72 -44
  45. package/src/client/defaultChunker.test.ts +1 -1
  46. package/src/client/defaultChunker.ts +7 -7
  47. package/src/client/fileUtils.ts +3 -3
  48. package/src/client/hybridRank.ts +1 -1
  49. package/src/client/index.test.ts +18 -18
  50. package/src/client/index.ts +104 -84
  51. package/src/client/setup.test.ts +2 -2
  52. package/src/component/_generated/api.ts +66 -0
  53. package/src/component/_generated/component.ts +442 -0
  54. package/src/component/_generated/{server.d.ts → server.ts} +33 -21
  55. package/src/component/chunks.test.ts +14 -14
  56. package/src/component/chunks.ts +59 -88
  57. package/src/component/embeddings/importance.test.ts +4 -4
  58. package/src/component/embeddings/importance.ts +1 -1
  59. package/src/component/embeddings/index.test.ts +3 -4
  60. package/src/component/embeddings/index.ts +6 -6
  61. package/src/component/embeddings/tables.ts +9 -8
  62. package/src/component/entries.test.ts +10 -10
  63. package/src/component/entries.ts +29 -29
  64. package/src/component/filters.ts +8 -8
  65. package/src/component/namespaces.ts +31 -34
  66. package/src/component/schema.ts +2 -2
  67. package/src/component/search.test.ts +5 -5
  68. package/src/component/search.ts +8 -9
  69. package/src/component/setup.test.ts +2 -8
  70. package/src/shared.ts +47 -45
  71. package/src/test.ts +20 -0
  72. package/dist/client/types.d.ts +0 -29
  73. package/dist/client/types.d.ts.map +0 -1
  74. package/dist/client/types.js +0 -2
  75. package/dist/client/types.js.map +0 -1
  76. package/dist/package.json +0 -3
  77. package/src/client/types.ts +0 -69
  78. package/src/component/_generated/api.d.ts +0 -507
  79. package/src/component/_generated/api.js +0 -23
  80. package/src/component/_generated/server.js +0 -90
  81. package/src/vitest.config.ts +0 -7
  82. /package/src/component/_generated/{dataModel.d.ts → dataModel.ts} +0 -0
@@ -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
- vOnCompleteArgs,
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: RAGComponent,
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: RunMutationCtx,
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: RunMutationCtx,
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: RunActionCtx,
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: RunActionCtx,
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: RunQueryCtx,
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: RunQueryCtx,
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: RunQueryCtx,
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: RunMutationCtx,
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: RunQueryCtx,
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: RunQueryCtx,
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: RunMutationCtx, args: { entryId: EntryId }) {
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(ctx: RunActionCtx, args: { entryId: EntryId }): Promise<void>;
732
+ async delete(
733
+ ctx: CtxWith<"runAction">,
734
+ args: { entryId: EntryId },
735
+ ): Promise<void>;
739
736
  /** @deprecated Use `deleteAsync` in mutations. */
740
- async delete(ctx: RunMutationCtx, args: { entryId: EntryId }): Promise<void>;
741
- async delete(ctx: RunActionCtx | RunMutationCtx, args: { entryId: EntryId }) {
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: RunMutationCtx,
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: RunActionCtx,
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: FunctionArgs<OnComplete<FitlerSchemas, EntryMetadata>>
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: { namespace: Namespace; entry: Entry<FitlerSchemas, EntryMetadata> }
840
- ) => AsyncIterable<InputChunk> | Promise<{ chunks: InputChunk[] }>
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<RAGComponent["chunks"]["insert"]>,
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
+ >;
@@ -8,7 +8,7 @@ import {
8
8
  type GenericSchema,
9
9
  type SchemaDefinition,
10
10
  } from "convex/server";
11
- import { type RAGComponent } from "./index.js";
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: RAGComponent;
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
+ };