flexorch-sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -167,7 +167,7 @@ await client.connectors.get(id);
167
167
  await client.connectors.delete(id);
168
168
  ```
169
169
 
170
- Supported connector types: `"s3"`, `"gcs"`, `"azure_blob"`.
170
+ Supported connector types: `"s3"`. (`"gcs"` and `"azure_blob"` coming in a future release.)
171
171
 
172
172
  ---
173
173
 
@@ -7,7 +7,8 @@ var SUPPORTED_FORMATS = /* @__PURE__ */ new Set([
7
7
  "md",
8
8
  "xml",
9
9
  "xlsx",
10
- "rag"
10
+ "rag",
11
+ "hf"
11
12
  ]);
12
13
  var Dataset = class _Dataset {
13
14
  id;
@@ -62,6 +63,27 @@ var Dataset = class _Dataset {
62
63
  sizeBytes: Number(data["size_bytes"] ?? 0)
63
64
  };
64
65
  }
66
+ async chunks(opts = {}) {
67
+ const params = {};
68
+ if (opts.page !== void 0) params["page"] = String(opts.page);
69
+ if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
70
+ if (opts.qualityGrade !== void 0) params["quality_grade"] = opts.qualityGrade;
71
+ if (opts.piiMasked !== void 0) params["pii_masked"] = String(opts.piiMasked);
72
+ const data = await this._transport.get(`/datasets/${this.id}/chunks`, params) ?? {};
73
+ const raw = data["items"] ?? [];
74
+ return {
75
+ items: raw.map((item) => ({
76
+ chunkId: String(item["chunk_id"] ?? ""),
77
+ chunkIndex: Number(item["chunk_index"] ?? 0),
78
+ text: String(item["text"] ?? ""),
79
+ tokenCount: Number(item["token_count"] ?? 0),
80
+ metadata: item["metadata"] ?? {}
81
+ })),
82
+ total: Number(data["total"] ?? 0),
83
+ page: Number(data["page"] ?? 1),
84
+ pageSize: Number(data["page_size"] ?? 20)
85
+ };
86
+ }
65
87
  async index() {
66
88
  const data = await this._transport.post(`/datasets/${this.id}/index`) ?? {};
67
89
  return {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Dataset
3
- } from "./chunk-7JBTDKMH.js";
3
+ } from "./chunk-35RGZSFP.js";
4
4
  export {
5
5
  Dataset
6
6
  };
package/dist/index.cjs CHANGED
@@ -47,7 +47,8 @@ var init_dataset = __esm({
47
47
  "md",
48
48
  "xml",
49
49
  "xlsx",
50
- "rag"
50
+ "rag",
51
+ "hf"
51
52
  ]);
52
53
  Dataset = class _Dataset {
53
54
  id;
@@ -102,6 +103,27 @@ var init_dataset = __esm({
102
103
  sizeBytes: Number(data["size_bytes"] ?? 0)
103
104
  };
104
105
  }
106
+ async chunks(opts = {}) {
107
+ const params = {};
108
+ if (opts.page !== void 0) params["page"] = String(opts.page);
109
+ if (opts.pageSize !== void 0) params["page_size"] = String(opts.pageSize);
110
+ if (opts.qualityGrade !== void 0) params["quality_grade"] = opts.qualityGrade;
111
+ if (opts.piiMasked !== void 0) params["pii_masked"] = String(opts.piiMasked);
112
+ const data = await this._transport.get(`/datasets/${this.id}/chunks`, params) ?? {};
113
+ const raw = data["items"] ?? [];
114
+ return {
115
+ items: raw.map((item) => ({
116
+ chunkId: String(item["chunk_id"] ?? ""),
117
+ chunkIndex: Number(item["chunk_index"] ?? 0),
118
+ text: String(item["text"] ?? ""),
119
+ tokenCount: Number(item["token_count"] ?? 0),
120
+ metadata: item["metadata"] ?? {}
121
+ })),
122
+ total: Number(data["total"] ?? 0),
123
+ page: Number(data["page"] ?? 1),
124
+ pageSize: Number(data["page_size"] ?? 20)
125
+ };
126
+ }
105
127
  async index() {
106
128
  const data = await this._transport.post(`/datasets/${this.id}/index`) ?? {};
107
129
  return {
@@ -132,11 +154,14 @@ __export(index_exports, {
132
154
  Dataset: () => Dataset,
133
155
  FlexOrchClient: () => FlexOrchClient,
134
156
  FlexOrchError: () => FlexOrchError,
157
+ FlexOrchReader: () => FlexOrchReader,
158
+ FlexOrchRetriever: () => FlexOrchRetriever,
135
159
  Job: () => Job,
136
160
  JobFailedError: () => JobFailedError,
137
161
  JobTimeoutError: () => JobTimeoutError,
138
162
  NotFoundError: () => NotFoundError,
139
163
  QuotaError: () => QuotaError,
164
+ RAGDocument: () => RAGDocument,
140
165
  RateLimitError: () => RateLimitError,
141
166
  SearchResult: () => SearchResult,
142
167
  ServerError: () => ServerError,
@@ -679,7 +704,8 @@ var FlexOrchClient = class {
679
704
  async search(query, opts = {}) {
680
705
  const body = {
681
706
  query,
682
- top_k: opts.topK ?? 10
707
+ top_k: opts.topK ?? 10,
708
+ mode: opts.mode ?? "auto"
683
709
  };
684
710
  if (opts.filters) {
685
711
  const f = opts.filters;
@@ -701,7 +727,184 @@ var FlexOrchClient = class {
701
727
 
702
728
  // src/index.ts
703
729
  init_dataset();
704
- var version = "0.1.0";
730
+
731
+ // src/rag.ts
732
+ var GRADE_ORDER = { A: 0, B: 1, C: 2, D: 3 };
733
+ function gradeAndAbove(threshold) {
734
+ const t = GRADE_ORDER[threshold.toUpperCase()] ?? 3;
735
+ return Object.entries(GRADE_ORDER).filter(([, rank]) => rank <= t).map(([g]) => g);
736
+ }
737
+ var RAGDocument = class {
738
+ /** Chunk text — LangChain-style attribute name. */
739
+ pageContent;
740
+ metadata;
741
+ constructor(pageContent, metadata = {}) {
742
+ this.pageContent = pageContent;
743
+ this.metadata = metadata;
744
+ }
745
+ /** LlamaIndex-style alias for pageContent. */
746
+ get text() {
747
+ return this.pageContent;
748
+ }
749
+ toString() {
750
+ const snippet = this.pageContent.slice(0, 60).replace(/\n/g, " ");
751
+ return `RAGDocument(text="${snippet}", metadata=${JSON.stringify(this.metadata)})`;
752
+ }
753
+ };
754
+ var FlexOrchRetriever = class {
755
+ _client;
756
+ _qualityThreshold;
757
+ _piiMasked;
758
+ _topK;
759
+ _documentType;
760
+ _language;
761
+ _mode;
762
+ /**
763
+ * LangChain-compatible retriever backed by FlexOrch's /v1/search endpoint.
764
+ *
765
+ * Works without LangChain installed — invoke() returns RAGDocument objects
766
+ * that are duck-type compatible with langchain_core.documents.Document.
767
+ *
768
+ * @example
769
+ * ```ts
770
+ * const client = new FlexOrchClient("dfx_xxx");
771
+ * const retriever = new FlexOrchRetriever(client, { qualityThreshold: "B", piiMasked: true });
772
+ *
773
+ * // standalone
774
+ * const docs = await retriever.invoke("payment terms");
775
+ *
776
+ * // LangChain chain (TypeScript)
777
+ * import { RetrievalQAChain } from "langchain/chains";
778
+ * const chain = RetrievalQAChain.fromLLM(llm, retriever);
779
+ * ```
780
+ */
781
+ constructor(client, opts = {}) {
782
+ const threshold = (opts.qualityThreshold ?? "B").toUpperCase();
783
+ if (!(threshold in GRADE_ORDER)) {
784
+ throw new Error(`qualityThreshold must be A, B, C, or D \u2014 got "${opts.qualityThreshold}"`);
785
+ }
786
+ this._client = client;
787
+ this._qualityThreshold = threshold;
788
+ this._piiMasked = opts.piiMasked;
789
+ this._topK = opts.topK ?? 5;
790
+ this._documentType = opts.documentType;
791
+ this._language = opts.language;
792
+ this._mode = opts.mode ?? "auto";
793
+ }
794
+ /**
795
+ * Retrieve the most relevant chunks for a query.
796
+ *
797
+ * Requests 2× topK results from the API then filters client-side by quality
798
+ * threshold, returning at most topK final documents.
799
+ */
800
+ async invoke(query) {
801
+ const filters = {};
802
+ if (this._piiMasked !== void 0) filters.piiMasked = this._piiMasked;
803
+ if (this._documentType) filters.documentType = this._documentType;
804
+ if (this._language) filters.language = this._language;
805
+ const raw = await this._client.search(query, {
806
+ topK: Math.min(this._topK * 2, 50),
807
+ mode: this._mode,
808
+ filters: Object.keys(filters).length > 0 ? filters : void 0
809
+ });
810
+ const allowedGrades = new Set(gradeAndAbove(this._qualityThreshold));
811
+ const docs = [];
812
+ for (const r of raw) {
813
+ const grade = String(r.metadata["quality_grade"] ?? "D");
814
+ if (!allowedGrades.has(grade)) continue;
815
+ docs.push(
816
+ new RAGDocument(r.text, {
817
+ chunkId: r.chunkId,
818
+ datasetId: r.datasetId,
819
+ score: r.score,
820
+ qualityGrade: grade,
821
+ piiMasked: r.metadata["pii_masked"],
822
+ docType: r.metadata["doc_type"],
823
+ language: r.metadata["language"]
824
+ })
825
+ );
826
+ if (docs.length >= this._topK) break;
827
+ }
828
+ return docs;
829
+ }
830
+ /** LangChain BaseRetriever compatibility shim. */
831
+ async getRelevantDocuments(query) {
832
+ return this.invoke(query);
833
+ }
834
+ toString() {
835
+ return `FlexOrchRetriever(qualityThreshold="${this._qualityThreshold}", topK=${this._topK}, mode="${this._mode}")`;
836
+ }
837
+ };
838
+ var FlexOrchReader = class {
839
+ _client;
840
+ /**
841
+ * LlamaIndex-compatible reader backed by FlexOrch's chunk API.
842
+ *
843
+ * Paginates through all RAG chunks of a processed, indexed dataset.
844
+ * Returns RAGDocument objects duck-type compatible with llama_index Document.
845
+ *
846
+ * @example
847
+ * ```ts
848
+ * const reader = new FlexOrchReader(new FlexOrchClient("dfx_xxx"));
849
+ * const docs = await reader.loadData("42", { minQuality: "B" });
850
+ * ```
851
+ */
852
+ constructor(client) {
853
+ this._client = client;
854
+ }
855
+ /**
856
+ * Load all qualifying chunks from a dataset, paginating automatically.
857
+ *
858
+ * @param datasetId ID of the indexed dataset.
859
+ * @param opts Filtering and pagination options.
860
+ */
861
+ async loadData(datasetId, opts = {}) {
862
+ const minQuality = (opts.minQuality ?? "B").toUpperCase();
863
+ if (!(minQuality in GRADE_ORDER)) {
864
+ throw new Error(`minQuality must be A, B, C, or D \u2014 got "${opts.minQuality}"`);
865
+ }
866
+ const gradeFilter = gradeAndAbove(minQuality).join(",");
867
+ const pageSize = opts.pageSize ?? 100;
868
+ const allDocs = [];
869
+ let page = 1;
870
+ while (true) {
871
+ const params = {
872
+ page: String(page),
873
+ page_size: String(pageSize),
874
+ quality_grade: gradeFilter
875
+ };
876
+ if (opts.piiMaskedOnly) params["pii_masked"] = "true";
877
+ const data = await this._client._transport.get(`/datasets/${datasetId}/chunks`, params) ?? {};
878
+ const items = data["items"] ?? [];
879
+ const total = Number(data["total"] ?? 0);
880
+ for (const item of items) {
881
+ const meta = item["metadata"] ?? {};
882
+ allDocs.push(
883
+ new RAGDocument(String(item["text"] ?? ""), {
884
+ chunkId: item["chunk_id"],
885
+ chunkIndex: item["chunk_index"],
886
+ datasetId: String(datasetId),
887
+ docType: meta["doc_type"],
888
+ language: meta["language"],
889
+ qualityGrade: meta["quality_grade"],
890
+ qualityScore: meta["quality_score"],
891
+ piiMasked: meta["pii_masked"],
892
+ source: meta["source_filename"]
893
+ })
894
+ );
895
+ }
896
+ if (allDocs.length >= total || items.length < pageSize) break;
897
+ page++;
898
+ }
899
+ return allDocs;
900
+ }
901
+ toString() {
902
+ return "FlexOrchReader()";
903
+ }
904
+ };
905
+
906
+ // src/index.ts
907
+ var version = "0.2.0";
705
908
  // Annotate the CommonJS export names for ESM import in node:
706
909
  0 && (module.exports = {
707
910
  AuthError,
@@ -709,11 +912,14 @@ var version = "0.1.0";
709
912
  Dataset,
710
913
  FlexOrchClient,
711
914
  FlexOrchError,
915
+ FlexOrchReader,
916
+ FlexOrchRetriever,
712
917
  Job,
713
918
  JobFailedError,
714
919
  JobTimeoutError,
715
920
  NotFoundError,
716
921
  QuotaError,
922
+ RAGDocument,
717
923
  RateLimitError,
718
924
  SearchResult,
719
925
  ServerError,
package/dist/index.d.cts CHANGED
@@ -15,7 +15,7 @@ declare class Transport {
15
15
  delete(path: string): Promise<unknown>;
16
16
  }
17
17
 
18
- type ExportFormat = "json" | "jsonl" | "csv" | "parquet" | "md" | "xml" | "xlsx" | "rag";
18
+ type ExportFormat = "json" | "jsonl" | "csv" | "parquet" | "md" | "xml" | "xlsx" | "rag" | "hf";
19
19
  declare class Dataset {
20
20
  readonly id: string;
21
21
  readonly name: string;
@@ -41,6 +41,23 @@ declare class Dataset {
41
41
  s3Key: string;
42
42
  sizeBytes: number;
43
43
  }>;
44
+ chunks(opts?: {
45
+ page?: number;
46
+ pageSize?: number;
47
+ qualityGrade?: string;
48
+ piiMasked?: boolean;
49
+ }): Promise<{
50
+ items: Array<{
51
+ chunkId: string;
52
+ chunkIndex: number;
53
+ text: string;
54
+ tokenCount: number;
55
+ metadata: Record<string, unknown>;
56
+ }>;
57
+ total: number;
58
+ page: number;
59
+ pageSize: number;
60
+ }>;
44
61
  index(): Promise<{
45
62
  status: string;
46
63
  message: string;
@@ -232,6 +249,7 @@ declare class FlexOrchClient {
232
249
  }): Promise<Job[]>;
233
250
  search(query: string, opts?: {
234
251
  topK?: number;
252
+ mode?: string;
235
253
  filters?: SearchFilters;
236
254
  }): Promise<SearchResult[]>;
237
255
  toString(): string;
@@ -274,6 +292,113 @@ declare class JobTimeoutError extends FlexOrchError {
274
292
  constructor(jobId: string, timeout: number);
275
293
  }
276
294
 
277
- declare const version = "0.1.0";
295
+ /**
296
+ * RAG helpers for the FlexOrch SDK.
297
+ *
298
+ * FlexOrchRetriever — LangChain-compatible retriever backed by /v1/search.
299
+ * FlexOrchReader — LlamaIndex-compatible reader backed by /v1/datasets/{id}/chunks.
300
+ *
301
+ * Both classes work without LangChain or LlamaIndex installed.
302
+ * RAGDocument is duck-type compatible with:
303
+ * - langchain_core.documents.Document (pageContent + metadata)
304
+ * - llama_index.core.schema.Document (.text + metadata)
305
+ */
306
+
307
+ declare class RAGDocument {
308
+ /** Chunk text — LangChain-style attribute name. */
309
+ readonly pageContent: string;
310
+ readonly metadata: Record<string, unknown>;
311
+ constructor(pageContent: string, metadata?: Record<string, unknown>);
312
+ /** LlamaIndex-style alias for pageContent. */
313
+ get text(): string;
314
+ toString(): string;
315
+ }
316
+ interface RetrieverOptions {
317
+ /** Minimum quality grade to return (A/B/C/D). Default: "B". */
318
+ qualityThreshold?: string;
319
+ /** When set, only include chunks where PII was (true) or wasn't (false) masked. */
320
+ piiMasked?: boolean;
321
+ /** Number of results to return. Default: 5. */
322
+ topK?: number;
323
+ /** Filter by document type (e.g. "invoice"). */
324
+ documentType?: string;
325
+ /** Filter by language code (e.g. "en", "tr"). */
326
+ language?: string;
327
+ /** Search mode: "auto" | "semantic" | "hybrid" | "structured". Default: "auto". */
328
+ mode?: string;
329
+ }
330
+ declare class FlexOrchRetriever {
331
+ private readonly _client;
332
+ private readonly _qualityThreshold;
333
+ private readonly _piiMasked;
334
+ private readonly _topK;
335
+ private readonly _documentType;
336
+ private readonly _language;
337
+ private readonly _mode;
338
+ /**
339
+ * LangChain-compatible retriever backed by FlexOrch's /v1/search endpoint.
340
+ *
341
+ * Works without LangChain installed — invoke() returns RAGDocument objects
342
+ * that are duck-type compatible with langchain_core.documents.Document.
343
+ *
344
+ * @example
345
+ * ```ts
346
+ * const client = new FlexOrchClient("dfx_xxx");
347
+ * const retriever = new FlexOrchRetriever(client, { qualityThreshold: "B", piiMasked: true });
348
+ *
349
+ * // standalone
350
+ * const docs = await retriever.invoke("payment terms");
351
+ *
352
+ * // LangChain chain (TypeScript)
353
+ * import { RetrievalQAChain } from "langchain/chains";
354
+ * const chain = RetrievalQAChain.fromLLM(llm, retriever);
355
+ * ```
356
+ */
357
+ constructor(client: FlexOrchClient, opts?: RetrieverOptions);
358
+ /**
359
+ * Retrieve the most relevant chunks for a query.
360
+ *
361
+ * Requests 2× topK results from the API then filters client-side by quality
362
+ * threshold, returning at most topK final documents.
363
+ */
364
+ invoke(query: string): Promise<RAGDocument[]>;
365
+ /** LangChain BaseRetriever compatibility shim. */
366
+ getRelevantDocuments(query: string): Promise<RAGDocument[]>;
367
+ toString(): string;
368
+ }
369
+ interface ReaderLoadOptions {
370
+ /** Minimum quality grade to include (A/B/C/D). Default: "B". */
371
+ minQuality?: string;
372
+ /** When true, include only chunks where PII was masked. Default: false. */
373
+ piiMaskedOnly?: boolean;
374
+ /** Chunks per page (max 100). Default: 100. */
375
+ pageSize?: number;
376
+ }
377
+ declare class FlexOrchReader {
378
+ private readonly _client;
379
+ /**
380
+ * LlamaIndex-compatible reader backed by FlexOrch's chunk API.
381
+ *
382
+ * Paginates through all RAG chunks of a processed, indexed dataset.
383
+ * Returns RAGDocument objects duck-type compatible with llama_index Document.
384
+ *
385
+ * @example
386
+ * ```ts
387
+ * const reader = new FlexOrchReader(new FlexOrchClient("dfx_xxx"));
388
+ * const docs = await reader.loadData("42", { minQuality: "B" });
389
+ * ```
390
+ */
391
+ constructor(client: FlexOrchClient);
392
+ /**
393
+ * Load all qualifying chunks from a dataset, paginating automatically.
394
+ *
395
+ * @param datasetId ID of the indexed dataset.
396
+ * @param opts Filtering and pagination options.
397
+ */
398
+ loadData(datasetId: string | number, opts?: ReaderLoadOptions): Promise<RAGDocument[]>;
399
+ toString(): string;
400
+ }
401
+
402
+ declare const version = "0.2.0";
278
403
 
279
- export { AuthError, Connector, type ConnectorTestResult, type ConnectorType, Dataset, type ExportFormat, FlexOrchClient, type FlexOrchClientOptions, FlexOrchError, Job, JobFailedError, JobTimeoutError, NotFoundError, QuotaError, RateLimitError, type S3ConnectorConfig, type SearchFilters, SearchResult, ServerError, type UsageSnapshot, ValidationError, type Webhook, type WebhookEvent, version };
404
+ export { AuthError, Connector, type ConnectorTestResult, type ConnectorType, Dataset, type ExportFormat, FlexOrchClient, type FlexOrchClientOptions, FlexOrchError, FlexOrchReader, FlexOrchRetriever, Job, JobFailedError, JobTimeoutError, NotFoundError, QuotaError, RAGDocument, RateLimitError, type ReaderLoadOptions, type RetrieverOptions, type S3ConnectorConfig, type SearchFilters, SearchResult, ServerError, type UsageSnapshot, ValidationError, type Webhook, type WebhookEvent, version };
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@ declare class Transport {
15
15
  delete(path: string): Promise<unknown>;
16
16
  }
17
17
 
18
- type ExportFormat = "json" | "jsonl" | "csv" | "parquet" | "md" | "xml" | "xlsx" | "rag";
18
+ type ExportFormat = "json" | "jsonl" | "csv" | "parquet" | "md" | "xml" | "xlsx" | "rag" | "hf";
19
19
  declare class Dataset {
20
20
  readonly id: string;
21
21
  readonly name: string;
@@ -41,6 +41,23 @@ declare class Dataset {
41
41
  s3Key: string;
42
42
  sizeBytes: number;
43
43
  }>;
44
+ chunks(opts?: {
45
+ page?: number;
46
+ pageSize?: number;
47
+ qualityGrade?: string;
48
+ piiMasked?: boolean;
49
+ }): Promise<{
50
+ items: Array<{
51
+ chunkId: string;
52
+ chunkIndex: number;
53
+ text: string;
54
+ tokenCount: number;
55
+ metadata: Record<string, unknown>;
56
+ }>;
57
+ total: number;
58
+ page: number;
59
+ pageSize: number;
60
+ }>;
44
61
  index(): Promise<{
45
62
  status: string;
46
63
  message: string;
@@ -232,6 +249,7 @@ declare class FlexOrchClient {
232
249
  }): Promise<Job[]>;
233
250
  search(query: string, opts?: {
234
251
  topK?: number;
252
+ mode?: string;
235
253
  filters?: SearchFilters;
236
254
  }): Promise<SearchResult[]>;
237
255
  toString(): string;
@@ -274,6 +292,113 @@ declare class JobTimeoutError extends FlexOrchError {
274
292
  constructor(jobId: string, timeout: number);
275
293
  }
276
294
 
277
- declare const version = "0.1.0";
295
+ /**
296
+ * RAG helpers for the FlexOrch SDK.
297
+ *
298
+ * FlexOrchRetriever — LangChain-compatible retriever backed by /v1/search.
299
+ * FlexOrchReader — LlamaIndex-compatible reader backed by /v1/datasets/{id}/chunks.
300
+ *
301
+ * Both classes work without LangChain or LlamaIndex installed.
302
+ * RAGDocument is duck-type compatible with:
303
+ * - langchain_core.documents.Document (pageContent + metadata)
304
+ * - llama_index.core.schema.Document (.text + metadata)
305
+ */
306
+
307
+ declare class RAGDocument {
308
+ /** Chunk text — LangChain-style attribute name. */
309
+ readonly pageContent: string;
310
+ readonly metadata: Record<string, unknown>;
311
+ constructor(pageContent: string, metadata?: Record<string, unknown>);
312
+ /** LlamaIndex-style alias for pageContent. */
313
+ get text(): string;
314
+ toString(): string;
315
+ }
316
+ interface RetrieverOptions {
317
+ /** Minimum quality grade to return (A/B/C/D). Default: "B". */
318
+ qualityThreshold?: string;
319
+ /** When set, only include chunks where PII was (true) or wasn't (false) masked. */
320
+ piiMasked?: boolean;
321
+ /** Number of results to return. Default: 5. */
322
+ topK?: number;
323
+ /** Filter by document type (e.g. "invoice"). */
324
+ documentType?: string;
325
+ /** Filter by language code (e.g. "en", "tr"). */
326
+ language?: string;
327
+ /** Search mode: "auto" | "semantic" | "hybrid" | "structured". Default: "auto". */
328
+ mode?: string;
329
+ }
330
+ declare class FlexOrchRetriever {
331
+ private readonly _client;
332
+ private readonly _qualityThreshold;
333
+ private readonly _piiMasked;
334
+ private readonly _topK;
335
+ private readonly _documentType;
336
+ private readonly _language;
337
+ private readonly _mode;
338
+ /**
339
+ * LangChain-compatible retriever backed by FlexOrch's /v1/search endpoint.
340
+ *
341
+ * Works without LangChain installed — invoke() returns RAGDocument objects
342
+ * that are duck-type compatible with langchain_core.documents.Document.
343
+ *
344
+ * @example
345
+ * ```ts
346
+ * const client = new FlexOrchClient("dfx_xxx");
347
+ * const retriever = new FlexOrchRetriever(client, { qualityThreshold: "B", piiMasked: true });
348
+ *
349
+ * // standalone
350
+ * const docs = await retriever.invoke("payment terms");
351
+ *
352
+ * // LangChain chain (TypeScript)
353
+ * import { RetrievalQAChain } from "langchain/chains";
354
+ * const chain = RetrievalQAChain.fromLLM(llm, retriever);
355
+ * ```
356
+ */
357
+ constructor(client: FlexOrchClient, opts?: RetrieverOptions);
358
+ /**
359
+ * Retrieve the most relevant chunks for a query.
360
+ *
361
+ * Requests 2× topK results from the API then filters client-side by quality
362
+ * threshold, returning at most topK final documents.
363
+ */
364
+ invoke(query: string): Promise<RAGDocument[]>;
365
+ /** LangChain BaseRetriever compatibility shim. */
366
+ getRelevantDocuments(query: string): Promise<RAGDocument[]>;
367
+ toString(): string;
368
+ }
369
+ interface ReaderLoadOptions {
370
+ /** Minimum quality grade to include (A/B/C/D). Default: "B". */
371
+ minQuality?: string;
372
+ /** When true, include only chunks where PII was masked. Default: false. */
373
+ piiMaskedOnly?: boolean;
374
+ /** Chunks per page (max 100). Default: 100. */
375
+ pageSize?: number;
376
+ }
377
+ declare class FlexOrchReader {
378
+ private readonly _client;
379
+ /**
380
+ * LlamaIndex-compatible reader backed by FlexOrch's chunk API.
381
+ *
382
+ * Paginates through all RAG chunks of a processed, indexed dataset.
383
+ * Returns RAGDocument objects duck-type compatible with llama_index Document.
384
+ *
385
+ * @example
386
+ * ```ts
387
+ * const reader = new FlexOrchReader(new FlexOrchClient("dfx_xxx"));
388
+ * const docs = await reader.loadData("42", { minQuality: "B" });
389
+ * ```
390
+ */
391
+ constructor(client: FlexOrchClient);
392
+ /**
393
+ * Load all qualifying chunks from a dataset, paginating automatically.
394
+ *
395
+ * @param datasetId ID of the indexed dataset.
396
+ * @param opts Filtering and pagination options.
397
+ */
398
+ loadData(datasetId: string | number, opts?: ReaderLoadOptions): Promise<RAGDocument[]>;
399
+ toString(): string;
400
+ }
401
+
402
+ declare const version = "0.2.0";
278
403
 
279
- export { AuthError, Connector, type ConnectorTestResult, type ConnectorType, Dataset, type ExportFormat, FlexOrchClient, type FlexOrchClientOptions, FlexOrchError, Job, JobFailedError, JobTimeoutError, NotFoundError, QuotaError, RateLimitError, type S3ConnectorConfig, type SearchFilters, SearchResult, ServerError, type UsageSnapshot, ValidationError, type Webhook, type WebhookEvent, version };
404
+ export { AuthError, Connector, type ConnectorTestResult, type ConnectorType, Dataset, type ExportFormat, FlexOrchClient, type FlexOrchClientOptions, FlexOrchError, FlexOrchReader, FlexOrchRetriever, Job, JobFailedError, JobTimeoutError, NotFoundError, QuotaError, RAGDocument, RateLimitError, type ReaderLoadOptions, type RetrieverOptions, type S3ConnectorConfig, type SearchFilters, SearchResult, ServerError, type UsageSnapshot, ValidationError, type Webhook, type WebhookEvent, version };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Dataset
3
- } from "./chunk-7JBTDKMH.js";
3
+ } from "./chunk-35RGZSFP.js";
4
4
 
5
5
  // src/errors.ts
6
6
  var FlexOrchError = class extends Error {
@@ -251,7 +251,7 @@ var Job = class _Job {
251
251
  });
252
252
  const items = data["items"] ?? [];
253
253
  if (items.length === 0) return null;
254
- const { Dataset: Dataset2 } = await import("./dataset-IS63EK2G.js");
254
+ const { Dataset: Dataset2 } = await import("./dataset-PP755LIW.js");
255
255
  return Dataset2.fromDict(items[0], this._transport);
256
256
  }
257
257
  toString() {
@@ -535,7 +535,8 @@ var FlexOrchClient = class {
535
535
  async search(query, opts = {}) {
536
536
  const body = {
537
537
  query,
538
- top_k: opts.topK ?? 10
538
+ top_k: opts.topK ?? 10,
539
+ mode: opts.mode ?? "auto"
539
540
  };
540
541
  if (opts.filters) {
541
542
  const f = opts.filters;
@@ -555,19 +556,197 @@ var FlexOrchClient = class {
555
556
  }
556
557
  };
557
558
 
559
+ // src/rag.ts
560
+ var GRADE_ORDER = { A: 0, B: 1, C: 2, D: 3 };
561
+ function gradeAndAbove(threshold) {
562
+ const t = GRADE_ORDER[threshold.toUpperCase()] ?? 3;
563
+ return Object.entries(GRADE_ORDER).filter(([, rank]) => rank <= t).map(([g]) => g);
564
+ }
565
+ var RAGDocument = class {
566
+ /** Chunk text — LangChain-style attribute name. */
567
+ pageContent;
568
+ metadata;
569
+ constructor(pageContent, metadata = {}) {
570
+ this.pageContent = pageContent;
571
+ this.metadata = metadata;
572
+ }
573
+ /** LlamaIndex-style alias for pageContent. */
574
+ get text() {
575
+ return this.pageContent;
576
+ }
577
+ toString() {
578
+ const snippet = this.pageContent.slice(0, 60).replace(/\n/g, " ");
579
+ return `RAGDocument(text="${snippet}", metadata=${JSON.stringify(this.metadata)})`;
580
+ }
581
+ };
582
+ var FlexOrchRetriever = class {
583
+ _client;
584
+ _qualityThreshold;
585
+ _piiMasked;
586
+ _topK;
587
+ _documentType;
588
+ _language;
589
+ _mode;
590
+ /**
591
+ * LangChain-compatible retriever backed by FlexOrch's /v1/search endpoint.
592
+ *
593
+ * Works without LangChain installed — invoke() returns RAGDocument objects
594
+ * that are duck-type compatible with langchain_core.documents.Document.
595
+ *
596
+ * @example
597
+ * ```ts
598
+ * const client = new FlexOrchClient("dfx_xxx");
599
+ * const retriever = new FlexOrchRetriever(client, { qualityThreshold: "B", piiMasked: true });
600
+ *
601
+ * // standalone
602
+ * const docs = await retriever.invoke("payment terms");
603
+ *
604
+ * // LangChain chain (TypeScript)
605
+ * import { RetrievalQAChain } from "langchain/chains";
606
+ * const chain = RetrievalQAChain.fromLLM(llm, retriever);
607
+ * ```
608
+ */
609
+ constructor(client, opts = {}) {
610
+ const threshold = (opts.qualityThreshold ?? "B").toUpperCase();
611
+ if (!(threshold in GRADE_ORDER)) {
612
+ throw new Error(`qualityThreshold must be A, B, C, or D \u2014 got "${opts.qualityThreshold}"`);
613
+ }
614
+ this._client = client;
615
+ this._qualityThreshold = threshold;
616
+ this._piiMasked = opts.piiMasked;
617
+ this._topK = opts.topK ?? 5;
618
+ this._documentType = opts.documentType;
619
+ this._language = opts.language;
620
+ this._mode = opts.mode ?? "auto";
621
+ }
622
+ /**
623
+ * Retrieve the most relevant chunks for a query.
624
+ *
625
+ * Requests 2× topK results from the API then filters client-side by quality
626
+ * threshold, returning at most topK final documents.
627
+ */
628
+ async invoke(query) {
629
+ const filters = {};
630
+ if (this._piiMasked !== void 0) filters.piiMasked = this._piiMasked;
631
+ if (this._documentType) filters.documentType = this._documentType;
632
+ if (this._language) filters.language = this._language;
633
+ const raw = await this._client.search(query, {
634
+ topK: Math.min(this._topK * 2, 50),
635
+ mode: this._mode,
636
+ filters: Object.keys(filters).length > 0 ? filters : void 0
637
+ });
638
+ const allowedGrades = new Set(gradeAndAbove(this._qualityThreshold));
639
+ const docs = [];
640
+ for (const r of raw) {
641
+ const grade = String(r.metadata["quality_grade"] ?? "D");
642
+ if (!allowedGrades.has(grade)) continue;
643
+ docs.push(
644
+ new RAGDocument(r.text, {
645
+ chunkId: r.chunkId,
646
+ datasetId: r.datasetId,
647
+ score: r.score,
648
+ qualityGrade: grade,
649
+ piiMasked: r.metadata["pii_masked"],
650
+ docType: r.metadata["doc_type"],
651
+ language: r.metadata["language"]
652
+ })
653
+ );
654
+ if (docs.length >= this._topK) break;
655
+ }
656
+ return docs;
657
+ }
658
+ /** LangChain BaseRetriever compatibility shim. */
659
+ async getRelevantDocuments(query) {
660
+ return this.invoke(query);
661
+ }
662
+ toString() {
663
+ return `FlexOrchRetriever(qualityThreshold="${this._qualityThreshold}", topK=${this._topK}, mode="${this._mode}")`;
664
+ }
665
+ };
666
+ var FlexOrchReader = class {
667
+ _client;
668
+ /**
669
+ * LlamaIndex-compatible reader backed by FlexOrch's chunk API.
670
+ *
671
+ * Paginates through all RAG chunks of a processed, indexed dataset.
672
+ * Returns RAGDocument objects duck-type compatible with llama_index Document.
673
+ *
674
+ * @example
675
+ * ```ts
676
+ * const reader = new FlexOrchReader(new FlexOrchClient("dfx_xxx"));
677
+ * const docs = await reader.loadData("42", { minQuality: "B" });
678
+ * ```
679
+ */
680
+ constructor(client) {
681
+ this._client = client;
682
+ }
683
+ /**
684
+ * Load all qualifying chunks from a dataset, paginating automatically.
685
+ *
686
+ * @param datasetId ID of the indexed dataset.
687
+ * @param opts Filtering and pagination options.
688
+ */
689
+ async loadData(datasetId, opts = {}) {
690
+ const minQuality = (opts.minQuality ?? "B").toUpperCase();
691
+ if (!(minQuality in GRADE_ORDER)) {
692
+ throw new Error(`minQuality must be A, B, C, or D \u2014 got "${opts.minQuality}"`);
693
+ }
694
+ const gradeFilter = gradeAndAbove(minQuality).join(",");
695
+ const pageSize = opts.pageSize ?? 100;
696
+ const allDocs = [];
697
+ let page = 1;
698
+ while (true) {
699
+ const params = {
700
+ page: String(page),
701
+ page_size: String(pageSize),
702
+ quality_grade: gradeFilter
703
+ };
704
+ if (opts.piiMaskedOnly) params["pii_masked"] = "true";
705
+ const data = await this._client._transport.get(`/datasets/${datasetId}/chunks`, params) ?? {};
706
+ const items = data["items"] ?? [];
707
+ const total = Number(data["total"] ?? 0);
708
+ for (const item of items) {
709
+ const meta = item["metadata"] ?? {};
710
+ allDocs.push(
711
+ new RAGDocument(String(item["text"] ?? ""), {
712
+ chunkId: item["chunk_id"],
713
+ chunkIndex: item["chunk_index"],
714
+ datasetId: String(datasetId),
715
+ docType: meta["doc_type"],
716
+ language: meta["language"],
717
+ qualityGrade: meta["quality_grade"],
718
+ qualityScore: meta["quality_score"],
719
+ piiMasked: meta["pii_masked"],
720
+ source: meta["source_filename"]
721
+ })
722
+ );
723
+ }
724
+ if (allDocs.length >= total || items.length < pageSize) break;
725
+ page++;
726
+ }
727
+ return allDocs;
728
+ }
729
+ toString() {
730
+ return "FlexOrchReader()";
731
+ }
732
+ };
733
+
558
734
  // src/index.ts
559
- var version = "0.1.0";
735
+ var version = "0.2.0";
560
736
  export {
561
737
  AuthError,
562
738
  Connector,
563
739
  Dataset,
564
740
  FlexOrchClient,
565
741
  FlexOrchError,
742
+ FlexOrchReader,
743
+ FlexOrchRetriever,
566
744
  Job,
567
745
  JobFailedError,
568
746
  JobTimeoutError,
569
747
  NotFoundError,
570
748
  QuotaError,
749
+ RAGDocument,
571
750
  RateLimitError,
572
751
  SearchResult,
573
752
  ServerError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flexorch-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "TypeScript/JavaScript SDK for the FlexOrch API — process documents, build LLM-ready datasets",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",