@dudousxd/nestjs-agent-rag 0.14.2 → 0.14.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -281,8 +281,8 @@ interface LexicalVectorStore extends VectorStore {
281
281
  /**
282
282
  * An **optional** capability: swap all of a document's chunks safely under concurrent calls, so two
283
283
  * writers can't leave a mix of versions behind. Postgres also makes the swap atomic for searches and
284
- * crashes; Redis can't, and only guarantees the end state. {@link replaceDocumentChunks} falls back to
285
- * `remove` plus `upsert` for the others.
284
+ * crashes, and so does Redis up to a size limit (see `RedisVectorStore.replaceDocument`).
285
+ * {@link replaceDocumentChunks} falls back to `remove` plus `upsert` for the others.
286
286
  */
287
287
  interface AtomicReplaceVectorStore extends VectorStore {
288
288
  replaceDocument(documentId: string, records: VectorRecord[]): Promise<void>;
@@ -417,9 +417,11 @@ declare class MemoryVectorStore implements AtomicReplaceVectorStore {
417
417
  */
418
418
  describeRetrieval(): RetrievalDescriptor;
419
419
  upsert(records: VectorRecord[]): Promise<void>;
420
- /** Replaces take turns per document. A `remove` during one isn't queued, and may be undone by it. */
420
+ /** A replace and a removal of one document take turns, in the order they were called. */
421
421
  replaceDocument(documentId: string, records: VectorRecord[]): Promise<void>;
422
422
  remove(documentId: string): Promise<void>;
423
+ private inTurn;
424
+ private deleteChunks;
423
425
  /**
424
426
  * Merge `patch` into every chunk of `documentId`, leaving `text` and `embedding` untouched. The
425
427
  * record is *replaced* rather than mutated: `upsert` stores the caller's own object, and patching
@@ -881,18 +883,28 @@ declare class RedisVectorStore implements LexicalVectorStore, AtomicReplaceVecto
881
883
  private reconcileSchema;
882
884
  private createIndex;
883
885
  upsert(records: VectorRecord[]): Promise<void>;
886
+ private chunkFields;
884
887
  /**
885
- * Replaces a document's chunks, one writer at a time per document. Redis can't swap them in one step
886
- * without scanning the keyspace inside a script, so a search may briefly see old and new chunks
887
- * together, but concurrent calls can't leave them mixed. The new chunks go in before the old ones
888
- * come out, so a crash leaves the document searchable and the next call repairs it.
888
+ * Replaces a document's chunks, one writer at a time per document. The swap is one script, so a search
889
+ * sees the old version or the new one, and a crash leaves the old one. The keys to drop are found
890
+ * first, under the lock, because a script can't scan the keyspace.
891
+ *
892
+ * A document past {@link SWAP_MAX_CHUNKS} would block Redis for too long that way. Its new chunks go in
893
+ * first and the old ones come out after, so a search may briefly see both, and a crash leaves the
894
+ * document searchable for the next call to repair.
889
895
  */
890
896
  replaceDocument(documentId: string, records: VectorRecord[]): Promise<void>;
897
+ private swapChunks;
898
+ private lockKey;
891
899
  /**
892
- * A lease, so a crashed writer can't block the document forever. It is renewed while the work runs,
893
- * which keeps a large document from outliving it.
900
+ * A lease on each document, so a crashed writer can't block one forever. They are renewed while the
901
+ * work runs, which keeps a large document from outliving them.
902
+ *
903
+ * Several documents are locked in sorted order, without duplicates. Every other caller either holds
904
+ * one lock or takes them in that same order, so no two calls can wait on each other.
894
905
  */
895
- private withDocumentLock;
906
+ private withDocumentLocks;
907
+ private acquireLock;
896
908
  /**
897
909
  * Single-document deletion, by `SCAN … MATCH`.
898
910
  *
@@ -993,6 +1005,9 @@ declare class RedisVectorStore implements LexicalVectorStore, AtomicReplaceVecto
993
1005
  *
994
1006
  * It deletes by key, exactly as `remove` does, so it is correct on chunks written by any version of
995
1007
  * this library — there is no field it needs the corpus to already carry.
1008
+ *
1009
+ * It holds every document's lock for the whole scan, so it waits for a `replaceDocument` in progress
1010
+ * and one can't start partway through. That adds two commands per document to the one scan.
996
1011
  */
997
1012
  removeMany(documentIds: string[]): Promise<void>;
998
1013
  /**
@@ -1018,6 +1033,10 @@ declare class RedisVectorStore implements LexicalVectorStore, AtomicReplaceVecto
1018
1033
  * from the index, so paging forward would skip their replacements. If a page comes back non-empty
1019
1034
  * but `DEL` reports nothing removed (keys expired between query and delete, or the index is stale),
1020
1035
  * the loop stops rather than spinning on results it can never consume.
1036
+ *
1037
+ * The documents aren't known until a page comes back, so each page locks the documents it touches, one
1038
+ * page at a time, and asks again with `INKEYS` once it holds them. A `replaceDocument` that finished in
1039
+ * between may have dropped those chunks, or rewritten them to no longer match.
1021
1040
  */
1022
1041
  removeWhere(filter: Record<string, unknown>): Promise<number>;
1023
1042
  /**
@@ -1714,9 +1733,10 @@ declare class RagIndex<Row, Scope extends RagScopeDefinition<Row>> {
1714
1733
  search(query: string, options: RagSearchOptions<Scope>): Promise<Passage[]>;
1715
1734
  /**
1716
1735
  * Replaces the row's chunks and returns how many were written. Embeddings come first: if the
1717
- * provider fails, the previous chunks are still there. The swap is one transaction on Postgres. Redis
1718
- * adds the new chunks before dropping the old, so a search can briefly see both. On a store without
1719
- * `replaceDocument`, a crash mid-swap loses the document until the next `index`.
1736
+ * provider fails, the previous chunks are still there. The swap is one transaction on Postgres and one
1737
+ * script on Redis, where a document too large for that adds the new chunks before dropping the old, so
1738
+ * a search can briefly see both. On a store without `replaceDocument`, a crash mid-swap loses the
1739
+ * document until the next `index`.
1720
1740
  */
1721
1741
  index(row: Row): Promise<number>;
1722
1742
  /** Takes the id itself once the row is gone. */
package/dist/index.d.ts CHANGED
@@ -281,8 +281,8 @@ interface LexicalVectorStore extends VectorStore {
281
281
  /**
282
282
  * An **optional** capability: swap all of a document's chunks safely under concurrent calls, so two
283
283
  * writers can't leave a mix of versions behind. Postgres also makes the swap atomic for searches and
284
- * crashes; Redis can't, and only guarantees the end state. {@link replaceDocumentChunks} falls back to
285
- * `remove` plus `upsert` for the others.
284
+ * crashes, and so does Redis up to a size limit (see `RedisVectorStore.replaceDocument`).
285
+ * {@link replaceDocumentChunks} falls back to `remove` plus `upsert` for the others.
286
286
  */
287
287
  interface AtomicReplaceVectorStore extends VectorStore {
288
288
  replaceDocument(documentId: string, records: VectorRecord[]): Promise<void>;
@@ -417,9 +417,11 @@ declare class MemoryVectorStore implements AtomicReplaceVectorStore {
417
417
  */
418
418
  describeRetrieval(): RetrievalDescriptor;
419
419
  upsert(records: VectorRecord[]): Promise<void>;
420
- /** Replaces take turns per document. A `remove` during one isn't queued, and may be undone by it. */
420
+ /** A replace and a removal of one document take turns, in the order they were called. */
421
421
  replaceDocument(documentId: string, records: VectorRecord[]): Promise<void>;
422
422
  remove(documentId: string): Promise<void>;
423
+ private inTurn;
424
+ private deleteChunks;
423
425
  /**
424
426
  * Merge `patch` into every chunk of `documentId`, leaving `text` and `embedding` untouched. The
425
427
  * record is *replaced* rather than mutated: `upsert` stores the caller's own object, and patching
@@ -881,18 +883,28 @@ declare class RedisVectorStore implements LexicalVectorStore, AtomicReplaceVecto
881
883
  private reconcileSchema;
882
884
  private createIndex;
883
885
  upsert(records: VectorRecord[]): Promise<void>;
886
+ private chunkFields;
884
887
  /**
885
- * Replaces a document's chunks, one writer at a time per document. Redis can't swap them in one step
886
- * without scanning the keyspace inside a script, so a search may briefly see old and new chunks
887
- * together, but concurrent calls can't leave them mixed. The new chunks go in before the old ones
888
- * come out, so a crash leaves the document searchable and the next call repairs it.
888
+ * Replaces a document's chunks, one writer at a time per document. The swap is one script, so a search
889
+ * sees the old version or the new one, and a crash leaves the old one. The keys to drop are found
890
+ * first, under the lock, because a script can't scan the keyspace.
891
+ *
892
+ * A document past {@link SWAP_MAX_CHUNKS} would block Redis for too long that way. Its new chunks go in
893
+ * first and the old ones come out after, so a search may briefly see both, and a crash leaves the
894
+ * document searchable for the next call to repair.
889
895
  */
890
896
  replaceDocument(documentId: string, records: VectorRecord[]): Promise<void>;
897
+ private swapChunks;
898
+ private lockKey;
891
899
  /**
892
- * A lease, so a crashed writer can't block the document forever. It is renewed while the work runs,
893
- * which keeps a large document from outliving it.
900
+ * A lease on each document, so a crashed writer can't block one forever. They are renewed while the
901
+ * work runs, which keeps a large document from outliving them.
902
+ *
903
+ * Several documents are locked in sorted order, without duplicates. Every other caller either holds
904
+ * one lock or takes them in that same order, so no two calls can wait on each other.
894
905
  */
895
- private withDocumentLock;
906
+ private withDocumentLocks;
907
+ private acquireLock;
896
908
  /**
897
909
  * Single-document deletion, by `SCAN … MATCH`.
898
910
  *
@@ -993,6 +1005,9 @@ declare class RedisVectorStore implements LexicalVectorStore, AtomicReplaceVecto
993
1005
  *
994
1006
  * It deletes by key, exactly as `remove` does, so it is correct on chunks written by any version of
995
1007
  * this library — there is no field it needs the corpus to already carry.
1008
+ *
1009
+ * It holds every document's lock for the whole scan, so it waits for a `replaceDocument` in progress
1010
+ * and one can't start partway through. That adds two commands per document to the one scan.
996
1011
  */
997
1012
  removeMany(documentIds: string[]): Promise<void>;
998
1013
  /**
@@ -1018,6 +1033,10 @@ declare class RedisVectorStore implements LexicalVectorStore, AtomicReplaceVecto
1018
1033
  * from the index, so paging forward would skip their replacements. If a page comes back non-empty
1019
1034
  * but `DEL` reports nothing removed (keys expired between query and delete, or the index is stale),
1020
1035
  * the loop stops rather than spinning on results it can never consume.
1036
+ *
1037
+ * The documents aren't known until a page comes back, so each page locks the documents it touches, one
1038
+ * page at a time, and asks again with `INKEYS` once it holds them. A `replaceDocument` that finished in
1039
+ * between may have dropped those chunks, or rewritten them to no longer match.
1021
1040
  */
1022
1041
  removeWhere(filter: Record<string, unknown>): Promise<number>;
1023
1042
  /**
@@ -1714,9 +1733,10 @@ declare class RagIndex<Row, Scope extends RagScopeDefinition<Row>> {
1714
1733
  search(query: string, options: RagSearchOptions<Scope>): Promise<Passage[]>;
1715
1734
  /**
1716
1735
  * Replaces the row's chunks and returns how many were written. Embeddings come first: if the
1717
- * provider fails, the previous chunks are still there. The swap is one transaction on Postgres. Redis
1718
- * adds the new chunks before dropping the old, so a search can briefly see both. On a store without
1719
- * `replaceDocument`, a crash mid-swap loses the document until the next `index`.
1736
+ * provider fails, the previous chunks are still there. The swap is one transaction on Postgres and one
1737
+ * script on Redis, where a document too large for that adds the new chunks before dropping the old, so
1738
+ * a search can briefly see both. On a store without `replaceDocument`, a crash mid-swap loses the
1739
+ * document until the next `index`.
1720
1740
  */
1721
1741
  index(row: Row): Promise<number>;
1722
1742
  /** Takes the id itself once the row is gone. */