@retrivora-ai/rag-engine 2.3.0 → 2.3.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/dist/server.js CHANGED
@@ -165,7 +165,7 @@ var init_ConfigFetcher = __esm({
165
165
  * Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
166
166
  */
167
167
  static async fetchRemoteConfig(projectId, licenseKey) {
168
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
168
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
169
169
  const cacheKey = `${projectId}:${licenseKey || ""}`;
170
170
  const now = Date.now();
171
171
  const cached = this.cache.get(cacheKey);
@@ -191,7 +191,7 @@ var init_ConfigFetcher = __esm({
191
191
  });
192
192
  if (res.ok) {
193
193
  const data = await res.json();
194
- if ((data == null ? void 0 : data.success) && ((_a2 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a2.apiKey)) {
194
+ if ((data == null ? void 0 : data.success) && ((_a3 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a3.apiKey)) {
195
195
  const fetchedProjectId = data.projectId || projectId;
196
196
  const config = {
197
197
  projectId: fetchedProjectId,
@@ -227,9 +227,9 @@ var init_ConfigFetcher = __esm({
227
227
  }
228
228
  /** Convenience: fetch only vector DB config (backwards compat). */
229
229
  static async fetchRemoteVectorConfig(projectId, licenseKey) {
230
- var _a2;
230
+ var _a3;
231
231
  const config = await this.fetchRemoteConfig(projectId, licenseKey);
232
- return (_a2 = config == null ? void 0 : config.vectorDb) != null ? _a2 : null;
232
+ return (_a3 = config == null ? void 0 : config.vectorDb) != null ? _a3 : null;
233
233
  }
234
234
  };
235
235
  ConfigFetcher.cache = /* @__PURE__ */ new Map();
@@ -278,7 +278,7 @@ var init_PineconeProvider = __esm({
278
278
  static getHealthChecker() {
279
279
  return {
280
280
  async check(config) {
281
- var _a2, _b;
281
+ var _a3, _b;
282
282
  const opts = config.options || {};
283
283
  const indexName = config.indexName;
284
284
  const timestamp = Date.now();
@@ -286,7 +286,7 @@ var init_PineconeProvider = __esm({
286
286
  const { Pinecone: Pinecone2 } = await import("@pinecone-database/pinecone");
287
287
  const client = new Pinecone2({ apiKey: opts.apiKey });
288
288
  const indexes = await client.listIndexes();
289
- const indexNames = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
289
+ const indexNames = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
290
290
  if (!indexNames.includes(indexName)) {
291
291
  return {
292
292
  healthy: false,
@@ -313,7 +313,7 @@ var init_PineconeProvider = __esm({
313
313
  };
314
314
  }
315
315
  async initialize() {
316
- var _a2, _b;
316
+ var _a3, _b;
317
317
  if (this.client) return;
318
318
  let key = this.apiKey || process.env.PINECONE_API_KEY || "";
319
319
  if (!key) {
@@ -350,7 +350,7 @@ var init_PineconeProvider = __esm({
350
350
  this.client = new import_pinecone.Pinecone({ apiKey: key });
351
351
  try {
352
352
  const indexes = await this.client.listIndexes();
353
- const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
353
+ const names = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
354
354
  if (!names.includes(this.indexName)) {
355
355
  console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
356
356
  }
@@ -369,13 +369,13 @@ var init_PineconeProvider = __esm({
369
369
  return namespace ? idx.namespace(namespace) : idx.namespace("");
370
370
  }
371
371
  async upsert(doc, namespace) {
372
- var _a2;
372
+ var _a3;
373
373
  const targetIdx = await this.getActiveIndex(namespace);
374
374
  await targetIdx.upsert({
375
375
  records: [{
376
376
  id: String(doc.id),
377
377
  values: doc.vector,
378
- metadata: __spreadValues({ content: doc.content }, (_a2 = doc.metadata) != null ? _a2 : {})
378
+ metadata: __spreadValues({ content: doc.content }, (_a3 = doc.metadata) != null ? _a3 : {})
379
379
  }]
380
380
  });
381
381
  }
@@ -384,18 +384,18 @@ var init_PineconeProvider = __esm({
384
384
  const BATCH = 100;
385
385
  for (let i = 0; i < docs.length; i += BATCH) {
386
386
  const records = docs.slice(i, i + BATCH).map((d) => {
387
- var _a2;
387
+ var _a3;
388
388
  return {
389
389
  id: String(d.id),
390
390
  values: d.vector,
391
- metadata: __spreadValues({ content: d.content }, (_a2 = d.metadata) != null ? _a2 : {})
391
+ metadata: __spreadValues({ content: d.content }, (_a3 = d.metadata) != null ? _a3 : {})
392
392
  };
393
393
  });
394
394
  await targetIdx.upsert({ records });
395
395
  }
396
396
  }
397
397
  async query(vector, topK, namespace, filter) {
398
- var _a2;
398
+ var _a3;
399
399
  const targetIdx = await this.getActiveIndex(namespace);
400
400
  const pineconeFilter = this.sanitizeFilter(filter);
401
401
  const result = await targetIdx.query(__spreadValues({
@@ -403,11 +403,11 @@ var init_PineconeProvider = __esm({
403
403
  topK,
404
404
  includeMetadata: true
405
405
  }, Object.keys(pineconeFilter).length > 0 ? { filter: pineconeFilter } : {}));
406
- return ((_a2 = result.matches) != null ? _a2 : []).map((m) => {
407
- var _a3, _b;
406
+ return ((_a3 = result.matches) != null ? _a3 : []).map((m) => {
407
+ var _a4, _b;
408
408
  return {
409
409
  id: m.id,
410
- score: (_a3 = m.score) != null ? _a3 : 0,
410
+ score: (_a4 = m.score) != null ? _a4 : 0,
411
411
  content: ((_b = m.metadata) == null ? void 0 : _b.content) || "",
412
412
  metadata: m.metadata
413
413
  };
@@ -450,13 +450,13 @@ var init_PostgreSQLProvider = __esm({
450
450
  init_BaseVectorProvider();
451
451
  PostgreSQLProvider = class extends BaseVectorProvider {
452
452
  constructor(config) {
453
- var _a2;
453
+ var _a3;
454
454
  super(config);
455
455
  this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
456
456
  const opts = config.options;
457
457
  if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
458
458
  this.connectionString = opts.connectionString;
459
- this.dimensions = (_a2 = opts.dimensions) != null ? _a2 : 1536;
459
+ this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 1536;
460
460
  }
461
461
  static getValidator() {
462
462
  return {
@@ -537,7 +537,7 @@ var init_PostgreSQLProvider = __esm({
537
537
  }
538
538
  }
539
539
  async upsert(doc, namespace = "") {
540
- var _a2;
540
+ var _a3;
541
541
  const vectorLiteral = `[${doc.vector.join(",")}]`;
542
542
  await this.pool.query(
543
543
  `INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
@@ -547,7 +547,7 @@ var init_PostgreSQLProvider = __esm({
547
547
  content = EXCLUDED.content,
548
548
  metadata = EXCLUDED.metadata,
549
549
  embedding = EXCLUDED.embedding`,
550
- [doc.id, namespace, doc.content, JSON.stringify((_a2 = doc.metadata) != null ? _a2 : {}), vectorLiteral]
550
+ [doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), vectorLiteral]
551
551
  );
552
552
  }
553
553
  async batchUpsert(docs, namespace = "") {
@@ -560,9 +560,9 @@ var init_PostgreSQLProvider = __esm({
560
560
  const batch = docs.slice(i, i + BATCH_SIZE);
561
561
  const values = [];
562
562
  const valuePlaceholders = batch.map((doc, idx) => {
563
- var _a2;
563
+ var _a3;
564
564
  const offset = idx * 5;
565
- values.push(doc.id, namespace, doc.content, JSON.stringify((_a2 = doc.metadata) != null ? _a2 : {}), `[${doc.vector.join(",")}]`);
565
+ values.push(doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), `[${doc.vector.join(",")}]`);
566
566
  return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
567
567
  }).join(", ");
568
568
  const query = `
@@ -645,8 +645,8 @@ var init_PostgreSQLProvider = __esm({
645
645
 
646
646
  // src/utils/synonyms.ts
647
647
  function resolveMetadataValue(meta, uiKey) {
648
- var _a2;
649
- const synonyms = (_a2 = FIELD_SYNONYMS[uiKey]) != null ? _a2 : [];
648
+ var _a3;
649
+ const synonyms = (_a3 = FIELD_SYNONYMS[uiKey]) != null ? _a3 : [];
650
650
  const keys = Object.keys(meta);
651
651
  const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
652
652
  let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
@@ -733,14 +733,14 @@ var init_MultiTablePostgresProvider = __esm({
733
733
  init_synonyms();
734
734
  MultiTablePostgresProvider = class extends BaseVectorProvider {
735
735
  constructor(config) {
736
- var _a2, _b, _c;
736
+ var _a3, _b, _c;
737
737
  super(config);
738
738
  const opts = config.options || {};
739
739
  if (!opts.connectionString) {
740
740
  throw new Error("[MultiTablePostgresProvider] options.connectionString is required");
741
741
  }
742
742
  this.connectionString = opts.connectionString;
743
- this.dimensions = (_a2 = opts.dimensions) != null ? _a2 : 768;
743
+ this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 768;
744
744
  this.tables = [];
745
745
  const rawSearchFields = (_c = (_b = opts.searchFields) != null ? _b : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _c : ["name", "product_name", "productname", "title"];
746
746
  this.searchFields = typeof rawSearchFields === "string" ? rawSearchFields.split(",").map((f) => f.trim()).filter(Boolean) : rawSearchFields;
@@ -798,11 +798,11 @@ var init_MultiTablePostgresProvider = __esm({
798
798
  * Batch upsert documents by dynamically provisioning tables and columns based on CSV headers.
799
799
  */
800
800
  async batchUpsert(docs, namespace = "") {
801
- var _a2;
801
+ var _a3;
802
802
  if (docs.length === 0) return;
803
803
  const docsByFile = {};
804
804
  for (const doc of docs) {
805
- const fileName = ((_a2 = doc.metadata) == null ? void 0 : _a2.fileName) || this.uploadTable;
805
+ const fileName = ((_a3 = doc.metadata) == null ? void 0 : _a3.fileName) || this.uploadTable;
806
806
  if (!docsByFile[fileName]) docsByFile[fileName] = [];
807
807
  docsByFile[fileName].push(doc);
808
808
  }
@@ -855,11 +855,11 @@ var init_MultiTablePostgresProvider = __esm({
855
855
  const headerColumns = csvHeaders.map((h) => `"${h}"`).join(", ");
856
856
  const allColumns = `id, ${headerColumns ? headerColumns + ", " : ""}namespace, content, metadata, embedding`;
857
857
  const valuePlaceholders = batch.map((doc, idx) => {
858
- var _a3, _b;
858
+ var _a4, _b;
859
859
  const offset = idx * (5 + csvHeaders.length);
860
860
  values.push(doc.id);
861
861
  for (const h of csvHeaders) {
862
- values.push(String(((_a3 = doc.metadata) == null ? void 0 : _a3[h]) || ""));
862
+ values.push(String(((_a4 = doc.metadata) == null ? void 0 : _a4[h]) || ""));
863
863
  }
864
864
  values.push(namespace, doc.content, JSON.stringify((_b = doc.metadata) != null ? _b : {}), `[${doc.vector.join(",")}]`);
865
865
  const docPlaceholders = [];
@@ -898,7 +898,7 @@ var init_MultiTablePostgresProvider = __esm({
898
898
  * Query all configured tables and merge results, sorted by cosine similarity score.
899
899
  */
900
900
  async query(vector, topK, _namespace, _filter) {
901
- var _a2;
901
+ var _a3;
902
902
  if (!this.pool) {
903
903
  throw new Error("[MultiTablePostgresProvider] Provider not initialized. Call initialize() first.");
904
904
  }
@@ -929,11 +929,11 @@ var init_MultiTablePostgresProvider = __esm({
929
929
  const filterParams = [];
930
930
  if (metadataFilters && Object.keys(metadataFilters).length > 0) {
931
931
  const conditions = Object.entries(metadataFilters).map(([key, val]) => {
932
- var _a4;
932
+ var _a5;
933
933
  filterParams.push(String(val));
934
934
  const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
935
935
  const paramIdx = baseOffset + filterParams.length;
936
- const synonyms = (_a4 = FIELD_SYNONYMS[key]) != null ? _a4 : [];
936
+ const synonyms = (_a5 = FIELD_SYNONYMS[key]) != null ? _a5 : [];
937
937
  const keysToCheck = [key, ...synonyms];
938
938
  const coalesceExprs = keysToCheck.flatMap((k) => [
939
939
  `metadata->>'${k}'`,
@@ -1002,7 +1002,7 @@ var init_MultiTablePostgresProvider = __esm({
1002
1002
  }
1003
1003
  const tableResults = [];
1004
1004
  for (const row of result.rows) {
1005
- const _a3 = row, { hybrid_score, id } = _a3, rest = __objRest(_a3, ["hybrid_score", "id"]);
1005
+ const _a4 = row, { hybrid_score, id } = _a4, rest = __objRest(_a4, ["hybrid_score", "id"]);
1006
1006
  delete rest.embedding;
1007
1007
  delete rest.vector_score;
1008
1008
  delete rest.keyword_score;
@@ -1031,10 +1031,10 @@ var init_MultiTablePostgresProvider = __esm({
1031
1031
  }
1032
1032
  allResults.sort((a, b) => b.score - a.score);
1033
1033
  if (allResults.length === 0) return [];
1034
- const bestMatchTable = (_a2 = allResults[0].metadata) == null ? void 0 : _a2.source_table;
1034
+ const bestMatchTable = (_a3 = allResults[0].metadata) == null ? void 0 : _a3.source_table;
1035
1035
  const finalSorted = allResults.filter((res) => {
1036
- var _a3;
1037
- return ((_a3 = res.metadata) == null ? void 0 : _a3.source_table) === bestMatchTable;
1036
+ var _a4;
1037
+ return ((_a4 = res.metadata) == null ? void 0 : _a4.source_table) === bestMatchTable;
1038
1038
  });
1039
1039
  console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
1040
1040
  console.log(`[MultiTablePostgresProvider] Final top match from "${bestMatchTable}" with score ${finalSorted[0].score.toFixed(4)}`);
@@ -1439,14 +1439,14 @@ var init_QdrantProvider = __esm({
1439
1439
  * Samples points from the collection to discover available payload fields.
1440
1440
  */
1441
1441
  async discoverSchema() {
1442
- var _a2;
1442
+ var _a3;
1443
1443
  try {
1444
1444
  const { data } = await this.http.post(`/collections/${this.indexName}/points/scroll`, {
1445
1445
  limit: 20,
1446
1446
  with_payload: true,
1447
1447
  with_vector: false
1448
1448
  });
1449
- const points = ((_a2 = data.result) == null ? void 0 : _a2.points) || [];
1449
+ const points = ((_a3 = data.result) == null ? void 0 : _a3.points) || [];
1450
1450
  const keys = /* @__PURE__ */ new Set();
1451
1451
  for (const point of points) {
1452
1452
  const payload = point.payload || {};
@@ -1472,12 +1472,12 @@ var init_QdrantProvider = __esm({
1472
1472
  * Ensures the collection exists. Creates it if missing.
1473
1473
  */
1474
1474
  async ensureCollection() {
1475
- var _a2;
1475
+ var _a3;
1476
1476
  try {
1477
1477
  await this.http.get(`/collections/${this.indexName}`);
1478
1478
  console.log(`[QdrantProvider] \u2705 Collection "${this.indexName}" already exists.`);
1479
1479
  } catch (err) {
1480
- if (import_axios4.default.isAxiosError(err) && ((_a2 = err.response) == null ? void 0 : _a2.status) === 404) {
1480
+ if (import_axios4.default.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
1481
1481
  const opts = this.config.options;
1482
1482
  const dimensionsForCreate = opts.dimensions || 1536;
1483
1483
  console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
@@ -1497,7 +1497,7 @@ var init_QdrantProvider = __esm({
1497
1497
  * Ensures that a payload field has an index.
1498
1498
  */
1499
1499
  async ensureIndex(fieldName, schema = "keyword") {
1500
- var _a2;
1500
+ var _a3;
1501
1501
  let fullPath = fieldName;
1502
1502
  if (!this.isFlatPayload && !fieldName.includes(".") && fieldName !== "namespace" && fieldName !== this.contentField) {
1503
1503
  fullPath = `${this.metadataField}.${fieldName}`;
@@ -1510,7 +1510,7 @@ var init_QdrantProvider = __esm({
1510
1510
  console.log(`[QdrantProvider] \u2705 Ensured ${schema} index for "${fullPath}"`);
1511
1511
  } catch (err) {
1512
1512
  let status;
1513
- if (import_axios4.default.isAxiosError(err)) status = (_a2 = err.response) == null ? void 0 : _a2.status;
1513
+ if (import_axios4.default.isAxiosError(err)) status = (_a3 = err.response) == null ? void 0 : _a3.status;
1514
1514
  if (status === 409) return;
1515
1515
  console.warn(`[QdrantProvider] \u26A0\uFE0F Could not ensure index for "${fullPath}":`, err instanceof Error ? err.message : String(err));
1516
1516
  }
@@ -1539,7 +1539,7 @@ var init_QdrantProvider = __esm({
1539
1539
  await this.http.put(`/collections/${this.indexName}/points`, payload);
1540
1540
  }
1541
1541
  async query(vector, topK, namespace, _filter) {
1542
- var _a2;
1542
+ var _a3;
1543
1543
  const must = [];
1544
1544
  if (namespace) {
1545
1545
  must.push({ key: "namespace", match: { value: namespace } });
@@ -1561,7 +1561,7 @@ var init_QdrantProvider = __esm({
1561
1561
  limit: topK,
1562
1562
  with_payload: true,
1563
1563
  params: {
1564
- hnsw_ef: ((_a2 = this.config.options) == null ? void 0 : _a2.efSearch) || Math.max(topK * 20, 128),
1564
+ hnsw_ef: ((_a3 = this.config.options) == null ? void 0 : _a3.efSearch) || Math.max(topK * 20, 128),
1565
1565
  exact: false
1566
1566
  },
1567
1567
  filter: must.length > 0 ? { must } : void 0
@@ -1656,13 +1656,13 @@ var init_ChromaDBProvider = __esm({
1656
1656
  * Get or create the ChromaDB collection.
1657
1657
  */
1658
1658
  async initialize() {
1659
- var _a2;
1659
+ var _a3;
1660
1660
  try {
1661
1661
  const { data } = await this.http.get(`/api/v1/collections/${this.indexName}`);
1662
1662
  this.collectionId = data.id;
1663
1663
  console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
1664
1664
  } catch (err) {
1665
- if (import_axios5.default.isAxiosError(err) && ((_a2 = err.response) == null ? void 0 : _a2.status) === 404) {
1665
+ if (import_axios5.default.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
1666
1666
  console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
1667
1667
  const { data } = await this.http.post("/api/v1/collections", {
1668
1668
  name: this.indexName
@@ -1883,7 +1883,7 @@ var init_WeaviateProvider = __esm({
1883
1883
  await this.http.post("/v1/batch/objects", payload);
1884
1884
  }
1885
1885
  async query(vector, topK, namespace, _filter) {
1886
- var _a2, _b;
1886
+ var _a3, _b;
1887
1887
  const queryText = _filter == null ? void 0 : _filter.queryText;
1888
1888
  const sanitizedFilter = this.sanitizeFilter(_filter);
1889
1889
  const searchParams = queryText ? `hybrid: { query: ${JSON.stringify(queryText)}, alpha: 0.5 }` : `nearVector: { vector: ${JSON.stringify(vector)} }`;
@@ -1909,7 +1909,7 @@ var init_WeaviateProvider = __esm({
1909
1909
  `
1910
1910
  };
1911
1911
  const { data } = await this.http.post("/v1/graphql", graphqlQuery);
1912
- const results = ((_b = (_a2 = data.data) == null ? void 0 : _a2.Get) == null ? void 0 : _b[this.indexName]) || [];
1912
+ const results = ((_b = (_a3 = data.data) == null ? void 0 : _a3.Get) == null ? void 0 : _b[this.indexName]) || [];
1913
1913
  return results.map((res) => ({
1914
1914
  id: res["_additional"].id,
1915
1915
  score: 1 - res["_additional"].distance,
@@ -1992,21 +1992,21 @@ var init_UniversalVectorProvider = __esm({
1992
1992
  }
1993
1993
  }
1994
1994
  async initialize() {
1995
- var _a2;
1995
+ var _a3;
1996
1996
  this.http = import_axios8.default.create({
1997
1997
  baseURL: this.opts.baseUrl,
1998
1998
  headers: __spreadValues({
1999
1999
  "Content-Type": "application/json"
2000
2000
  }, this.opts.headers),
2001
- timeout: (_a2 = this.opts.timeout) != null ? _a2 : 3e4
2001
+ timeout: (_a3 = this.opts.timeout) != null ? _a3 : 3e4
2002
2002
  });
2003
2003
  if (!await this.ping()) {
2004
2004
  throw new Error(`[UniversalVectorProvider] Failed to connect to ${this.opts.baseUrl}`);
2005
2005
  }
2006
2006
  }
2007
2007
  async upsert(doc, namespace) {
2008
- var _a2, _b, _c;
2009
- const endpoint = (_a2 = this.opts.upsertEndpoint) != null ? _a2 : "/upsert";
2008
+ var _a3, _b, _c;
2009
+ const endpoint = (_a3 = this.opts.upsertEndpoint) != null ? _a3 : "/upsert";
2010
2010
  const template = (_b = this.opts.upsertTemplate) != null ? _b : JSON.stringify({
2011
2011
  id: "{{id}}",
2012
2012
  vector: "{{vector}}",
@@ -2039,8 +2039,8 @@ var init_UniversalVectorProvider = __esm({
2039
2039
  }
2040
2040
  }
2041
2041
  async query(vector, topK, namespace, filter) {
2042
- var _a2, _b;
2043
- const endpoint = (_a2 = this.opts.queryEndpoint) != null ? _a2 : "/query";
2042
+ var _a3, _b;
2043
+ const endpoint = (_a3 = this.opts.queryEndpoint) != null ? _a3 : "/query";
2044
2044
  const template = (_b = this.opts.queryTemplate) != null ? _b : JSON.stringify({
2045
2045
  vector: "{{vector}}",
2046
2046
  limit: "{{topK}}",
@@ -2066,9 +2066,9 @@ var init_UniversalVectorProvider = __esm({
2066
2066
  );
2067
2067
  }
2068
2068
  return results.map((item) => {
2069
- var _a3, _b2, _c, _d, _e, _f, _g2;
2069
+ var _a4, _b2, _c, _d, _e, _f, _g2;
2070
2070
  return {
2071
- id: item[(_a3 = this.opts.queryIdField) != null ? _a3 : "id"],
2071
+ id: item[(_a4 = this.opts.queryIdField) != null ? _a4 : "id"],
2072
2072
  score: (_c = item[(_b2 = this.opts.queryScoreField) != null ? _b2 : "score"]) != null ? _c : 0,
2073
2073
  content: (_e = item[(_d = this.opts.queryContentField) != null ? _d : "content"]) != null ? _e : "",
2074
2074
  metadata: (_g2 = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g2 : {}
@@ -2081,8 +2081,8 @@ var init_UniversalVectorProvider = __esm({
2081
2081
  }
2082
2082
  }
2083
2083
  async delete(id, namespace) {
2084
- var _a2, _b;
2085
- const endpoint = (_a2 = this.opts.deleteEndpoint) != null ? _a2 : "/delete";
2084
+ var _a3, _b;
2085
+ const endpoint = (_a3 = this.opts.deleteEndpoint) != null ? _a3 : "/delete";
2086
2086
  const template = (_b = this.opts.deleteTemplate) != null ? _b : JSON.stringify({
2087
2087
  id: "{{id}}",
2088
2088
  namespace: "{{namespace}}"
@@ -2100,8 +2100,8 @@ var init_UniversalVectorProvider = __esm({
2100
2100
  }
2101
2101
  }
2102
2102
  async deleteNamespace(namespace) {
2103
- var _a2;
2104
- const endpoint = (_a2 = this.opts.deleteNamespaceEndpoint) != null ? _a2 : "/delete-namespace";
2103
+ var _a3;
2104
+ const endpoint = (_a3 = this.opts.deleteNamespaceEndpoint) != null ? _a3 : "/delete-namespace";
2105
2105
  try {
2106
2106
  await this.http.post(endpoint, { namespace });
2107
2107
  } catch (error) {
@@ -2111,9 +2111,9 @@ var init_UniversalVectorProvider = __esm({
2111
2111
  }
2112
2112
  }
2113
2113
  async ping() {
2114
- var _a2;
2114
+ var _a3;
2115
2115
  try {
2116
- const endpoint = (_a2 = this.opts.pingEndpoint) != null ? _a2 : "/health";
2116
+ const endpoint = (_a3 = this.opts.pingEndpoint) != null ? _a3 : "/health";
2117
2117
  const response = await this.http.get(endpoint, { timeout: 5e3 });
2118
2118
  return response.status >= 200 && response.status < 300;
2119
2119
  } catch (e) {
@@ -2342,13 +2342,13 @@ var LicenseValidationError = class extends RetrivoraError {
2342
2342
  }
2343
2343
  };
2344
2344
  function wrapError(err, defaultCode, defaultMessage) {
2345
- var _a2;
2345
+ var _a3;
2346
2346
  if (err instanceof RetrivoraError) {
2347
2347
  return err;
2348
2348
  }
2349
2349
  const error = err;
2350
2350
  const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
2351
- const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((_a2 = error == null ? void 0 : error.response) == null ? void 0 : _a2.status);
2351
+ const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((_a3 = error == null ? void 0 : error.response) == null ? void 0 : _a3.status);
2352
2352
  const code = error == null ? void 0 : error.code;
2353
2353
  if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
2354
2354
  return new RateLimitException(message, err);
@@ -2630,8 +2630,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
2630
2630
 
2631
2631
  // src/config/serverConfig.ts
2632
2632
  function readString(env, name) {
2633
- var _a2;
2634
- const value = (_a2 = env[name]) == null ? void 0 : _a2.trim();
2633
+ var _a3;
2634
+ const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
2635
2635
  return value ? value : void 0;
2636
2636
  }
2637
2637
  function readNumber(env, name, fallback) {
@@ -2644,8 +2644,8 @@ function readNumber(env, name, fallback) {
2644
2644
  return parsed;
2645
2645
  }
2646
2646
  function readEnum(env, name, fallback, allowed) {
2647
- var _a2;
2648
- const value = (_a2 = readString(env, name)) != null ? _a2 : fallback;
2647
+ var _a3;
2648
+ const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
2649
2649
  if (allowed.includes(value)) {
2650
2650
  return value;
2651
2651
  }
@@ -2655,8 +2655,8 @@ function getRagConfig(baseConfig, env = process.env) {
2655
2655
  return getEnvConfig(env, baseConfig);
2656
2656
  }
2657
2657
  function getEnvConfig(env = process.env, base) {
2658
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb, _ob, _pb, _qb, _rb, _sb, _tb, _ub, _vb, _wb, _xb, _yb, _zb, _Ab, _Bb, _Cb, _Db, _Eb, _Fb, _Gb, _Hb, _Ib, _Jb, _Kb;
2659
- const licenseKey = (_d = (_c = (_b = (_a2 = readString(env, "RAG_LICENSE_KEY")) != null ? _a2 : readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _b : readString(env, "NEXT_PUBLIC_RETRIVORA_LICENSE_KEY")) != null ? _c : readString(env, "LICENSE_KEY")) != null ? _d : base == null ? void 0 : base.licenseKey;
2658
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb, _ob, _pb, _qb, _rb, _sb, _tb, _ub, _vb, _wb, _xb, _yb, _zb, _Ab, _Bb, _Cb, _Db, _Eb, _Fb, _Gb, _Hb, _Ib, _Jb, _Kb;
2659
+ const licenseKey = (_d = (_c = (_b = (_a3 = readString(env, "RAG_LICENSE_KEY")) != null ? _a3 : readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _b : readString(env, "NEXT_PUBLIC_RETRIVORA_LICENSE_KEY")) != null ? _c : readString(env, "LICENSE_KEY")) != null ? _d : base == null ? void 0 : base.licenseKey;
2660
2660
  const jwtProjectId = (() => {
2661
2661
  if (!licenseKey) return void 0;
2662
2662
  try {
@@ -2737,7 +2737,7 @@ function getEnvConfig(env = process.env, base) {
2737
2737
  rest: "default",
2738
2738
  custom: "default"
2739
2739
  };
2740
- const isFreeTier = (() => {
2740
+ const isFreeTier2 = (() => {
2741
2741
  if (!licenseKey) return true;
2742
2742
  try {
2743
2743
  const payload = LicenseVerifier.verify(licenseKey, projectId);
@@ -2748,13 +2748,13 @@ function getEnvConfig(env = process.env, base) {
2748
2748
  }
2749
2749
  })();
2750
2750
  const defaultGatewayUrl = (_ra = (_qa = readString(env, "LITELLM_BASE_URL")) != null ? _qa : readString(env, "LLM_BASE_URL")) != null ? _ra : "https://www.retrivora.com/api/v1";
2751
- const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
2751
+ const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
2752
2752
  const llmProvider = (_ua = (_ta = readEnum(env, "LLM_PROVIDER", defaultLlmProvider, LLM_PROVIDERS)) != null ? _ta : (_sa = base == null ? void 0 : base.llm) == null ? void 0 : _sa.provider) != null ? _ua : defaultLlmProvider;
2753
2753
  const llmBaseUrl = (_ya = (_xa = (_va = readString(env, "LITELLM_BASE_URL")) != null ? _va : readString(env, "LLM_BASE_URL")) != null ? _xa : (_wa = base == null ? void 0 : base.llm) == null ? void 0 : _wa.baseUrl) != null ? _ya : defaultGatewayUrl;
2754
- const llmModel = (_Ca = (_Aa = readString(env, "LLM_MODEL")) != null ? _Aa : (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.model) != null ? _Ca : isFreeTier ? "llama-3.1-8b-instant" : (_Ba = DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _Ba : "gpt-4o";
2754
+ const llmModel = (_Ca = (_Aa = readString(env, "LLM_MODEL")) != null ? _Aa : (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.model) != null ? _Ca : isFreeTier2 ? "llama-3.1-8b-instant" : (_Ba = DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _Ba : "gpt-4o";
2755
2755
  const llmApiKey = (_Ia = (_Ha = (_Fa = (_Ea = (_Da = llmApiKeyByProvider[llmProvider]) != null ? _Da : readString(env, "LLM_API_KEY")) != null ? _Ea : readString(env, "LITELLM_MASTER_KEY")) != null ? _Fa : readString(env, "LITELLM_API_KEY")) != null ? _Ha : (_Ga = base == null ? void 0 : base.llm) == null ? void 0 : _Ga.apiKey) != null ? _Ia : licenseKey;
2756
2756
  const llmProfile = (_Ma = (_La = readString(env, "LLM_UNIVERSAL_PROFILE")) != null ? _La : (_Ka = (_Ja = base == null ? void 0 : base.llm) == null ? void 0 : _Ja.options) == null ? void 0 : _Ka.profile) != null ? _Ma : "litellm";
2757
- const defaultEmbeddingProvider = isFreeTier ? "universal_rest" : "universal_rest";
2757
+ const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
2758
2758
  const embeddingProvider = (_Pa = (_Oa = readEnum(env, "EMBEDDING_PROVIDER", defaultEmbeddingProvider, EMBEDDING_PROVIDERS)) != null ? _Oa : (_Na = base == null ? void 0 : base.embedding) == null ? void 0 : _Na.provider) != null ? _Pa : defaultEmbeddingProvider;
2759
2759
  const embeddingBaseUrl = (_Ua = (_Ta = (_Ra = (_Qa = readString(env, "LITELLM_BASE_URL")) != null ? _Qa : readString(env, "EMBEDDING_BASE_URL")) != null ? _Ra : readString(env, "LLM_BASE_URL")) != null ? _Ta : (_Sa = base == null ? void 0 : base.embedding) == null ? void 0 : _Sa.baseUrl) != null ? _Ua : defaultGatewayUrl;
2760
2760
  const embeddingModel = (_Xa = (_Wa = readString(env, "EMBEDDING_MODEL")) != null ? _Wa : (_Va = base == null ? void 0 : base.embedding) == null ? void 0 : _Va.model) != null ? _Xa : "text-embedding-004";
@@ -2844,8 +2844,8 @@ function getEnvConfig(env = process.env, base) {
2844
2844
  }
2845
2845
  } : {}), {
2846
2846
  mcpServers: (() => {
2847
- var _a3;
2848
- const raw = (_a3 = readString(env, "MCP_SERVERS")) != null ? _a3 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
2847
+ var _a4;
2848
+ const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
2849
2849
  if (!raw) return void 0;
2850
2850
  try {
2851
2851
  return JSON.parse(raw);
@@ -2890,10 +2890,10 @@ var ConfigResolver = class {
2890
2890
  * fallback behavior.
2891
2891
  */
2892
2892
  static resolveUniversal(hostConfig, env = process.env) {
2893
- var _a2;
2893
+ var _a3;
2894
2894
  if (!hostConfig) return this.resolve(void 0, env);
2895
2895
  const normalized = __spreadProps(__spreadValues({}, hostConfig), {
2896
- vectorDb: (_a2 = hostConfig.vectorDb) != null ? _a2 : hostConfig.vectorDatabase,
2896
+ vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
2897
2897
  rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
2898
2898
  });
2899
2899
  return this.resolve(normalized, env);
@@ -2913,11 +2913,11 @@ var ConfigResolver = class {
2913
2913
  }
2914
2914
  }
2915
2915
  static mergeRetrievalWorkflow(rag, retrieval, workflow) {
2916
- var _a2, _b, _c, _d, _e, _f;
2916
+ var _a3, _b, _c, _d, _e, _f;
2917
2917
  if (!rag && !retrieval && !workflow) return void 0;
2918
2918
  const normalized = __spreadValues({}, rag != null ? rag : {});
2919
2919
  if (retrieval) {
2920
- normalized.topK = (_a2 = retrieval.topK) != null ? _a2 : normalized.topK;
2920
+ normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
2921
2921
  normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
2922
2922
  normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
2923
2923
  if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
@@ -3045,8 +3045,8 @@ var OpenAIProvider = class {
3045
3045
  };
3046
3046
  }
3047
3047
  async chat(messages, context, options) {
3048
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3049
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3048
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
3049
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3050
3050
  const systemMessage = {
3051
3051
  role: "system",
3052
3052
  content: buildSystemContent(basePrompt, context)
@@ -3070,8 +3070,8 @@ var OpenAIProvider = class {
3070
3070
  }
3071
3071
  chatStream(messages, context, options) {
3072
3072
  return __asyncGenerator(this, null, function* () {
3073
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3074
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3073
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3074
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3075
3075
  const systemMessage = {
3076
3076
  role: "system",
3077
3077
  content: buildSystemContent(basePrompt, context)
@@ -3118,8 +3118,8 @@ var OpenAIProvider = class {
3118
3118
  return results[0];
3119
3119
  }
3120
3120
  async batchEmbed(texts, options) {
3121
- var _a2, _b, _c, _d, _e;
3122
- const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a2 = this.embeddingConfig) == null ? void 0 : _a2.model) != null ? _c : "text-embedding-3-small";
3121
+ var _a3, _b, _c, _d, _e;
3122
+ const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _c : "text-embedding-3-small";
3123
3123
  const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
3124
3124
  const client = apiKey !== this.llmConfig.apiKey ? new import_openai.default({ apiKey }) : this.client;
3125
3125
  const response = await client.embeddings.create({ model, input: texts });
@@ -3196,8 +3196,8 @@ var AnthropicProvider = class {
3196
3196
  };
3197
3197
  }
3198
3198
  async chat(messages, context, options) {
3199
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3200
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
3199
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3200
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
3201
3201
  const system = buildSystemContent(basePrompt, context);
3202
3202
  const anthropicMessages = messages.map((m) => ({
3203
3203
  role: m.role === "assistant" ? "assistant" : "user",
@@ -3235,8 +3235,8 @@ var AnthropicProvider = class {
3235
3235
  }
3236
3236
  chatStream(messages, context, options) {
3237
3237
  return __asyncGenerator(this, null, function* () {
3238
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3239
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
3238
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3239
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
3240
3240
  const system = buildSystemContent(basePrompt, context);
3241
3241
  const anthropicMessages = messages.map((m) => ({
3242
3242
  role: m.role === "assistant" ? "assistant" : "user",
@@ -3320,8 +3320,8 @@ var AnthropicProvider = class {
3320
3320
  var import_axios = __toESM(require("axios"));
3321
3321
  var OllamaProvider = class {
3322
3322
  constructor(llmConfig, embeddingConfig) {
3323
- var _a2, _b, _c;
3324
- const rawBaseURL = ((_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434").replace(/\/+$/, "");
3323
+ var _a3, _b, _c;
3324
+ const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
3325
3325
  const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
3326
3326
  const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
3327
3327
  const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
@@ -3381,8 +3381,8 @@ var OllamaProvider = class {
3381
3381
  };
3382
3382
  }
3383
3383
  async chat(messages, context, options) {
3384
- var _a2, _b, _c, _d, _e, _f;
3385
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
3384
+ var _a3, _b, _c, _d, _e, _f;
3385
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
3386
3386
  const system = buildSystemContent(basePrompt, context);
3387
3387
  const { data } = await this.http.post("/api/chat", {
3388
3388
  model: this.llmConfig.model,
@@ -3400,8 +3400,8 @@ var OllamaProvider = class {
3400
3400
  }
3401
3401
  chatStream(messages, context, options) {
3402
3402
  return __asyncGenerator(this, null, function* () {
3403
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3404
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
3403
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3404
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
3405
3405
  const system = buildSystemContent(basePrompt, context);
3406
3406
  const response = yield new __await(this.http.post("/api/chat", {
3407
3407
  model: this.llmConfig.model,
@@ -3459,8 +3459,8 @@ var OllamaProvider = class {
3459
3459
  });
3460
3460
  }
3461
3461
  async embed(text, options) {
3462
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3463
- const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a2 = this.embeddingConfig) == null ? void 0 : _a2.model) != null ? _c : "nomic-embed-text";
3462
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3463
+ const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _c : "nomic-embed-text";
3464
3464
  const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
3465
3465
  const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? import_axios.default.create({ baseURL, timeout: 6e4 }) : this.http;
3466
3466
  let prompt = text;
@@ -3561,9 +3561,9 @@ var GeminiProvider = class {
3561
3561
  static getHealthChecker() {
3562
3562
  return {
3563
3563
  async check(config) {
3564
- var _a2, _b;
3564
+ var _a3, _b;
3565
3565
  const timestamp = Date.now();
3566
- const apiKey = (_b = (_a2 = config.apiKey) != null ? _a2 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
3566
+ const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
3567
3567
  const modelName = sanitizeModel(config.model);
3568
3568
  try {
3569
3569
  const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
@@ -3593,16 +3593,16 @@ var GeminiProvider = class {
3593
3593
  /** Resolve the embedding client — uses a separate client when the embedding
3594
3594
  * API key differs from the LLM API key. */
3595
3595
  get embeddingClient() {
3596
- var _a2;
3597
- if (((_a2 = this.embeddingConfig) == null ? void 0 : _a2.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3596
+ var _a3;
3597
+ if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3598
3598
  return buildClient(this.embeddingConfig.apiKey);
3599
3599
  }
3600
3600
  return this.client;
3601
3601
  }
3602
3602
  /** Resolve the embedding model to use, in order of specificity. */
3603
3603
  resolveEmbeddingModel(optionsModel) {
3604
- var _a2, _b;
3605
- return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a2 = this.embeddingConfig) == null ? void 0 : _a2.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3604
+ var _a3, _b;
3605
+ return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3606
3606
  }
3607
3607
  /**
3608
3608
  * Convert ChatMessage[] to the Gemini contents format.
@@ -3622,8 +3622,8 @@ var GeminiProvider = class {
3622
3622
  // ILLMProvider — chat
3623
3623
  // -------------------------------------------------------------------------
3624
3624
  async chat(messages, context, options) {
3625
- var _a2, _b, _c, _d, _e, _f;
3626
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3625
+ var _a3, _b, _c, _d, _e, _f;
3626
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3627
3627
  const model = this.client.getGenerativeModel({
3628
3628
  model: this.llmConfig.model,
3629
3629
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3640,8 +3640,8 @@ var GeminiProvider = class {
3640
3640
  }
3641
3641
  chatStream(messages, context, options) {
3642
3642
  return __asyncGenerator(this, null, function* () {
3643
- var _a2, _b, _c, _d, _e, _f;
3644
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3643
+ var _a3, _b, _c, _d, _e, _f;
3644
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3645
3645
  const model = this.client.getGenerativeModel({
3646
3646
  model: this.llmConfig.model,
3647
3647
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3676,11 +3676,11 @@ var GeminiProvider = class {
3676
3676
  // ILLMProvider — embeddings
3677
3677
  // -------------------------------------------------------------------------
3678
3678
  async embed(text, options) {
3679
- var _a2, _b;
3679
+ var _a3, _b;
3680
3680
  const content = applyPrefix(
3681
3681
  text,
3682
3682
  options == null ? void 0 : options.taskType,
3683
- (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3683
+ (_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
3684
3684
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3685
3685
  );
3686
3686
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
@@ -3697,7 +3697,7 @@ var GeminiProvider = class {
3697
3697
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
3698
3698
  const model = this.embeddingClient.getGenerativeModel({ model: modelName });
3699
3699
  const requests = texts.map((text) => {
3700
- var _a2, _b;
3700
+ var _a3, _b;
3701
3701
  return {
3702
3702
  content: {
3703
3703
  role: "user",
@@ -3705,7 +3705,7 @@ var GeminiProvider = class {
3705
3705
  text: applyPrefix(
3706
3706
  text,
3707
3707
  options == null ? void 0 : options.taskType,
3708
- (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3708
+ (_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
3709
3709
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3710
3710
  )
3711
3711
  }]
@@ -3722,8 +3722,8 @@ var GeminiProvider = class {
3722
3722
  throw err;
3723
3723
  });
3724
3724
  return response.embeddings.map((e) => {
3725
- var _a2;
3726
- return (_a2 = e.values) != null ? _a2 : [];
3725
+ var _a3;
3726
+ return (_a3 = e.values) != null ? _a3 : [];
3727
3727
  });
3728
3728
  }
3729
3729
  // -------------------------------------------------------------------------
@@ -3812,8 +3812,8 @@ var GroqProvider = class {
3812
3812
  };
3813
3813
  }
3814
3814
  async chat(messages, context, options) {
3815
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3816
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3815
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
3816
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3817
3817
  const systemMessage = {
3818
3818
  role: "system",
3819
3819
  content: buildSystemContent(basePrompt, context)
@@ -3837,8 +3837,8 @@ var GroqProvider = class {
3837
3837
  }
3838
3838
  chatStream(messages, context, options) {
3839
3839
  return __asyncGenerator(this, null, function* () {
3840
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3841
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3840
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3841
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3842
3842
  const systemMessage = {
3843
3843
  role: "system",
3844
3844
  content: buildSystemContent(basePrompt, context)
@@ -3972,8 +3972,8 @@ var QwenProvider = class {
3972
3972
  };
3973
3973
  }
3974
3974
  async chat(messages, context, options) {
3975
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3976
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3975
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
3976
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3977
3977
  const systemMessage = {
3978
3978
  role: "system",
3979
3979
  content: buildSystemContent(basePrompt, context)
@@ -3997,8 +3997,8 @@ var QwenProvider = class {
3997
3997
  }
3998
3998
  chatStream(messages, context, options) {
3999
3999
  return __asyncGenerator(this, null, function* () {
4000
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
4001
- const basePrompt = (_b = (_a2 = options == null ? void 0 : options.systemPrompt) != null ? _a2 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
4000
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
4001
+ const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
4002
4002
  const systemMessage = {
4003
4003
  role: "system",
4004
4004
  content: buildSystemContent(basePrompt, context)
@@ -4045,8 +4045,8 @@ var QwenProvider = class {
4045
4045
  return results[0];
4046
4046
  }
4047
4047
  async batchEmbed(texts, options) {
4048
- var _a2, _b, _c, _d, _e, _f;
4049
- const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a2 = this.embeddingConfig) == null ? void 0 : _a2.model) != null ? _c : "text-embedding-v1";
4048
+ var _a3, _b, _c, _d, _e, _f;
4049
+ const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _c : "text-embedding-v1";
4050
4050
  const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
4051
4051
  const client = apiKey !== this.llmConfig.apiKey ? new import_openai3.default({
4052
4052
  apiKey,
@@ -4146,9 +4146,9 @@ var VECTOR_PROFILES = {
4146
4146
 
4147
4147
  // src/llm/providers/UniversalLLMAdapter.ts
4148
4148
  function extractContent(obj) {
4149
- var _a2, _b, _c;
4149
+ var _a3, _b, _c;
4150
4150
  if (!obj || typeof obj !== "object") return void 0;
4151
- const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
4151
+ const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
4152
4152
  if (!choice) return void 0;
4153
4153
  if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
4154
4154
  if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
@@ -4158,10 +4158,10 @@ function extractContent(obj) {
4158
4158
  }
4159
4159
  var UniversalLLMAdapter = class {
4160
4160
  constructor(config) {
4161
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
4161
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
4162
4162
  this.model = config.model;
4163
4163
  const llmConfig = config;
4164
- const options = (_a2 = llmConfig.options) != null ? _a2 : {};
4164
+ const options = (_a3 = llmConfig.options) != null ? _a3 : {};
4165
4165
  let profile = {};
4166
4166
  if (typeof options.profile === "string") {
4167
4167
  profile = LLM_PROFILES[options.profile] || {};
@@ -4187,8 +4187,8 @@ var UniversalLLMAdapter = class {
4187
4187
  });
4188
4188
  }
4189
4189
  async chat(messages, context) {
4190
- var _a2, _b, _c, _d, _e;
4191
- const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4190
+ var _a3, _b, _c, _d, _e;
4191
+ const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
4192
4192
  const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
4193
4193
  role: m.role || "user",
4194
4194
  content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
@@ -4254,8 +4254,8 @@ ${context != null ? context : "None"}` },
4254
4254
  */
4255
4255
  chatStream(messages, context) {
4256
4256
  return __asyncGenerator(this, null, function* () {
4257
- var _a2, _b, _c, _d, _e, _f;
4258
- const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4257
+ var _a3, _b, _c, _d, _e, _f;
4258
+ const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
4259
4259
  const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
4260
4260
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
4261
4261
  const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
@@ -4381,8 +4381,8 @@ ${context != null ? context : "None"}` },
4381
4381
  });
4382
4382
  }
4383
4383
  async embed(text) {
4384
- var _a2, _b, _c, _d, _e;
4385
- const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
4384
+ var _a3, _b, _c, _d, _e;
4385
+ const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
4386
4386
  const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
4387
4387
  try {
4388
4388
  const { data: data2 } = await this.http.post(path2, payload);
@@ -4471,7 +4471,7 @@ var LLMFactory = class _LLMFactory {
4471
4471
  ];
4472
4472
  }
4473
4473
  static create(llmConfig, embeddingConfig) {
4474
- var _a2, _b, _c;
4474
+ var _a3, _b, _c;
4475
4475
  switch (llmConfig.provider) {
4476
4476
  case "openai":
4477
4477
  return new OpenAIProvider(llmConfig, embeddingConfig);
@@ -4490,7 +4490,7 @@ var LLMFactory = class _LLMFactory {
4490
4490
  case "custom":
4491
4491
  return new UniversalLLMAdapter(llmConfig);
4492
4492
  default: {
4493
- const providerName = String((_a2 = llmConfig.provider) != null ? _a2 : "").toLowerCase();
4493
+ const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
4494
4494
  const customFactory = customProviders.get(providerName);
4495
4495
  if (customFactory) {
4496
4496
  return customFactory(llmConfig);
@@ -4592,7 +4592,7 @@ var ProviderRegistry = class {
4592
4592
  return null;
4593
4593
  }
4594
4594
  static async loadVectorProviderClass(provider) {
4595
- var _a2;
4595
+ var _a3;
4596
4596
  if (this.vectorProviders[provider]) return this.vectorProviders[provider];
4597
4597
  switch (provider) {
4598
4598
  case "pinecone": {
@@ -4601,7 +4601,7 @@ var ProviderRegistry = class {
4601
4601
  }
4602
4602
  case "pgvector":
4603
4603
  case "postgresql": {
4604
- const postgresMode = ((_a2 = process.env.POSTGRES_MODE) != null ? _a2 : "multi").toLowerCase();
4604
+ const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
4605
4605
  if (postgresMode === "single") {
4606
4606
  const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
4607
4607
  return PostgreSQLProvider2;
@@ -4824,7 +4824,7 @@ var ConfigValidator = class {
4824
4824
  // package.json
4825
4825
  var package_default = {
4826
4826
  name: "@retrivora-ai/rag-engine",
4827
- version: "2.3.0",
4827
+ version: "2.3.1",
4828
4828
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
4829
4829
  author: "Abhinav Alkuchi",
4830
4830
  license: "UNLICENSED",
@@ -5129,8 +5129,8 @@ var Reranker = class {
5129
5129
  return matches.sort((a, b) => b.score - a.score).slice(0, limit);
5130
5130
  }
5131
5131
  const scoredMatches = matches.map((match) => {
5132
- var _a2;
5133
- const contentLower = ((_a2 = match == null ? void 0 : match.content) != null ? _a2 : "").toLowerCase();
5132
+ var _a3;
5133
+ const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
5134
5134
  let keywordScore = 0;
5135
5135
  keywords.forEach((keyword) => {
5136
5136
  if (contentLower.includes(keyword)) {
@@ -5152,8 +5152,8 @@ var Reranker = class {
5152
5152
 
5153
5153
  Documents:
5154
5154
  ${topN.map((m, i) => {
5155
- var _a2;
5156
- return `[${i}] ${((_a2 = m == null ? void 0 : m.content) != null ? _a2 : "").replace(/\n/g, " ")}`;
5155
+ var _a3;
5156
+ return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
5157
5157
  }).join("\n")}` }],
5158
5158
  "",
5159
5159
  {
@@ -5197,11 +5197,11 @@ var LlamaIndexIngestor = class {
5197
5197
  * than standard character-count splitting.
5198
5198
  */
5199
5199
  async chunk(text, options = {}) {
5200
- var _a2, _b;
5200
+ var _a3, _b;
5201
5201
  try {
5202
5202
  const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
5203
5203
  const splitter = new SentenceSplitter({
5204
- chunkSize: (_a2 = options.chunkSize) != null ? _a2 : 1e3,
5204
+ chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
5205
5205
  chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
5206
5206
  });
5207
5207
  const doc = new Document({ text, metadata: options.metadata || {} });
@@ -5310,7 +5310,7 @@ ${error instanceof Error ? error.message : String(error)}`
5310
5310
  * The agent returns `{ messages: [...] }` — the last message is the final answer.
5311
5311
  */
5312
5312
  async run(input, chatHistory = []) {
5313
- var _a2, _b, _c;
5313
+ var _a3, _b, _c;
5314
5314
  if (!this.agent) {
5315
5315
  throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
5316
5316
  }
@@ -5321,7 +5321,7 @@ ${error instanceof Error ? error.message : String(error)}`
5321
5321
  const response = await this.agent.invoke({
5322
5322
  messages: [...historyMessages, new HumanMessage(input)]
5323
5323
  });
5324
- const lastMessage = (_a2 = response == null ? void 0 : response.messages) == null ? void 0 : _a2.at(-1);
5324
+ const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
5325
5325
  if (lastMessage && typeof lastMessage.content === "string") {
5326
5326
  return lastMessage.content;
5327
5327
  }
@@ -5373,7 +5373,7 @@ var MCPClient = class {
5373
5373
  }
5374
5374
  }
5375
5375
  async connectStdio() {
5376
- var _a2;
5376
+ var _a3;
5377
5377
  const cmd = this.config.command;
5378
5378
  if (!cmd) {
5379
5379
  throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
@@ -5388,7 +5388,7 @@ var MCPClient = class {
5388
5388
  this.stdioBuffer += data.toString("utf-8");
5389
5389
  this.processStdioLines();
5390
5390
  });
5391
- (_a2 = this.childProcess.stderr) == null ? void 0 : _a2.on("data", (data) => {
5391
+ (_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
5392
5392
  console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
5393
5393
  });
5394
5394
  this.childProcess.on("close", (code) => {
@@ -5463,14 +5463,14 @@ var MCPClient = class {
5463
5463
  }
5464
5464
  }
5465
5465
  async sendNotification(method, params) {
5466
- var _a2;
5466
+ var _a3;
5467
5467
  const notification = {
5468
5468
  jsonrpc: "2.0",
5469
5469
  method,
5470
5470
  params
5471
5471
  };
5472
5472
  if (this.config.transport === "stdio") {
5473
- if ((_a2 = this.childProcess) == null ? void 0 : _a2.stdin) {
5473
+ if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
5474
5474
  this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
5475
5475
  }
5476
5476
  } else if (this.sseUrl) {
@@ -5548,11 +5548,11 @@ var MCPRegistry = class {
5548
5548
  // src/core/MultiAgentCoordinator.ts
5549
5549
  var MultiAgentCoordinator = class {
5550
5550
  constructor(options) {
5551
- var _a2;
5551
+ var _a3;
5552
5552
  this.llmProvider = options.llmProvider;
5553
5553
  this.mcpRegistry = options.mcpRegistry;
5554
5554
  this.documentSearch = options.documentSearch;
5555
- this.maxIterations = (_a2 = options.maxIterations) != null ? _a2 : 5;
5555
+ this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
5556
5556
  }
5557
5557
  /**
5558
5558
  * Run the multi-agent coordination loop synchronously and return the final response.
@@ -5604,8 +5604,8 @@ Available Tools:
5604
5604
 
5605
5605
  ${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
5606
5606
  ${mcpTools.map((mt) => {
5607
- var _a2;
5608
- return `- ${mt.tool.name}(${JSON.stringify(((_a2 = mt.tool.inputSchema) == null ? void 0 : _a2.properties) || {})}): ${mt.tool.description || "No description provided."}`;
5607
+ var _a3;
5608
+ return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
5609
5609
  }).join("\n")}
5610
5610
 
5611
5611
  Tool Calling Protocol:
@@ -5763,6 +5763,100 @@ ${toolResultText}`
5763
5763
  }
5764
5764
  };
5765
5765
 
5766
+ // src/core/CircuitBreaker.ts
5767
+ var CircuitBreaker = class {
5768
+ constructor(options = {}) {
5769
+ this.state = "closed";
5770
+ this.failureCount = 0;
5771
+ this.successCount = 0;
5772
+ this.lastFailureAt = 0;
5773
+ this.halfOpenCalls = 0;
5774
+ var _a3, _b, _c;
5775
+ this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
5776
+ this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
5777
+ this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
5778
+ }
5779
+ record(success) {
5780
+ const now = Date.now();
5781
+ if (success) {
5782
+ this.successCount++;
5783
+ if (this.state === "half-open") {
5784
+ this.state = "closed";
5785
+ this.failureCount = 0;
5786
+ this.halfOpenCalls = 0;
5787
+ this.successCount = 1;
5788
+ } else if (this.state === "closed") {
5789
+ if (this.successCount >= this.failureThreshold) {
5790
+ this.failureCount = Math.max(0, this.failureCount - 1);
5791
+ this.successCount = 0;
5792
+ }
5793
+ }
5794
+ } else {
5795
+ this.failureCount++;
5796
+ this.lastFailureAt = now;
5797
+ this.successCount = 0;
5798
+ if (this.state === "half-open") {
5799
+ this.state = "open";
5800
+ this.halfOpenCalls = 0;
5801
+ } else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
5802
+ this.state = "open";
5803
+ }
5804
+ }
5805
+ }
5806
+ canExecute() {
5807
+ const now = Date.now();
5808
+ if (this.state === "closed") {
5809
+ return true;
5810
+ }
5811
+ if (this.state === "open") {
5812
+ if (now - this.lastFailureAt >= this.resetTimeoutMs) {
5813
+ this.state = "half-open";
5814
+ this.halfOpenCalls = 0;
5815
+ return true;
5816
+ }
5817
+ return false;
5818
+ }
5819
+ if (this.state === "half-open") {
5820
+ return this.halfOpenCalls < this.halfOpenMaxCalls;
5821
+ }
5822
+ return true;
5823
+ }
5824
+ async wrap(fn) {
5825
+ if (!this.canExecute()) {
5826
+ const retryAfterSec = Math.ceil(
5827
+ Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
5828
+ );
5829
+ throw new Error(
5830
+ `Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
5831
+ );
5832
+ }
5833
+ if (this.state === "half-open") {
5834
+ this.halfOpenCalls++;
5835
+ }
5836
+ try {
5837
+ const result = await fn();
5838
+ this.record(true);
5839
+ return result;
5840
+ } catch (err) {
5841
+ this.record(false);
5842
+ throw err;
5843
+ }
5844
+ }
5845
+ getState() {
5846
+ return this.state;
5847
+ }
5848
+ getFailureCount() {
5849
+ return this.failureCount;
5850
+ }
5851
+ reset() {
5852
+ this.state = "closed";
5853
+ this.failureCount = 0;
5854
+ this.successCount = 0;
5855
+ this.lastFailureAt = 0;
5856
+ this.halfOpenCalls = 0;
5857
+ }
5858
+ };
5859
+
5766
5860
  // src/core/BatchProcessor.ts
5767
5861
  function isTransientError(error) {
5768
5862
  if (!(error instanceof Error)) return false;
@@ -5786,7 +5880,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
5786
5880
  function sleep(ms) {
5787
5881
  return new Promise((resolve) => setTimeout(resolve, ms));
5788
5882
  }
5789
- var BatchProcessor = class {
5883
+ var _BatchProcessor = class _BatchProcessor {
5884
+ /**
5885
+ * Execute a processor call through the circuit breaker.
5886
+ * Only transient failures count toward opening the circuit.
5887
+ */
5888
+ static async executeWithCircuitBreaker(processor) {
5889
+ if (!this.cb.canExecute()) {
5890
+ const retryAfterSec = Math.ceil(
5891
+ Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
5892
+ );
5893
+ throw new Error(
5894
+ `[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
5895
+ );
5896
+ }
5897
+ if (this.cb.state === "half-open") {
5898
+ this.cb.halfOpenCalls++;
5899
+ }
5900
+ try {
5901
+ const result = await processor();
5902
+ this.cb.record(true);
5903
+ return result;
5904
+ } catch (err) {
5905
+ if (isTransientError(err)) {
5906
+ this.cb.record(false);
5907
+ }
5908
+ throw err;
5909
+ }
5910
+ }
5790
5911
  /**
5791
5912
  * Processes an array of items in configurable batches with retry logic.
5792
5913
  *
@@ -5827,7 +5948,7 @@ var BatchProcessor = class {
5827
5948
  let lastError;
5828
5949
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
5829
5950
  try {
5830
- const result = await processor(batch);
5951
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
5831
5952
  results.push(result);
5832
5953
  success = true;
5833
5954
  break;
@@ -5885,7 +6006,7 @@ ${errorMessages}`
5885
6006
  let lastError;
5886
6007
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
5887
6008
  try {
5888
- const result = await processor(item);
6009
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
5889
6010
  results.push(result);
5890
6011
  success = true;
5891
6012
  break;
@@ -5958,7 +6079,7 @@ ${errorMessages}`
5958
6079
  }));
5959
6080
  const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
5960
6081
  try {
5961
- const result = await processor(item);
6082
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
5962
6083
  return { success: true, result, index: originalIndex };
5963
6084
  } catch (err) {
5964
6085
  const error = err instanceof Error ? err : new Error(String(err));
@@ -5986,6 +6107,12 @@ ${errorMessages}`
5986
6107
  return { results, errors, totalProcessed, totalFailed };
5987
6108
  }
5988
6109
  };
6110
+ _BatchProcessor.cb = new CircuitBreaker({
6111
+ failureThreshold: 5,
6112
+ resetTimeoutMs: 3e4,
6113
+ halfOpenMaxCalls: 1
6114
+ });
6115
+ var BatchProcessor = _BatchProcessor;
5989
6116
 
5990
6117
  // src/config/EmbeddingStrategy.ts
5991
6118
  var EmbeddingStrategy = /* @__PURE__ */ ((EmbeddingStrategy2) => {
@@ -6089,7 +6216,7 @@ var QueryProcessor = class {
6089
6216
  * @param validFields Optional list of known filterable fields to look for
6090
6217
  */
6091
6218
  static extractQueryFieldHints(question, validFields = []) {
6092
- var _a2, _b, _c, _d;
6219
+ var _a3, _b, _c, _d;
6093
6220
  if (!question.trim()) return [];
6094
6221
  const hints = /* @__PURE__ */ new Map();
6095
6222
  const addHint = (value, field) => {
@@ -6169,7 +6296,7 @@ var QueryProcessor = class {
6169
6296
  ];
6170
6297
  for (const p of universalPatterns) {
6171
6298
  for (const match of question.matchAll(p.regex)) {
6172
- const val = p.group ? (_a2 = match[p.group]) != null ? _a2 : match[0] : match[0];
6299
+ const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
6173
6300
  if (!val) continue;
6174
6301
  if (p.field) addHint(val, p.field);
6175
6302
  else addHint(val);
@@ -6393,11 +6520,11 @@ var LLMRouter = class {
6393
6520
  * When provided it is used directly as the 'default' role without re-constructing.
6394
6521
  */
6395
6522
  async initialize(prebuiltDefault) {
6396
- var _a2;
6523
+ var _a3;
6397
6524
  const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
6398
6525
  this.models.set("default", defaultModel);
6399
6526
  const envFastModel = process.env.FAST_LLM_MODEL;
6400
- const providerFastDefault = (_a2 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a2 : "";
6527
+ const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
6401
6528
  const fastModelName = envFastModel || providerFastDefault;
6402
6529
  if (fastModelName && fastModelName !== this.config.llm.model) {
6403
6530
  console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
@@ -6416,8 +6543,8 @@ var LLMRouter = class {
6416
6543
  * Falls back to 'default' if the requested role is not registered.
6417
6544
  */
6418
6545
  get(role) {
6419
- var _a2;
6420
- const provider = (_a2 = this.models.get(role)) != null ? _a2 : this.models.get("default");
6546
+ var _a3;
6547
+ const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
6421
6548
  if (!provider) {
6422
6549
  throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
6423
6550
  }
@@ -6503,8 +6630,8 @@ var IntentClassifier = class {
6503
6630
  numericFieldCount = numericKeys.size;
6504
6631
  categoricalFieldCount = catKeys.size;
6505
6632
  if (productKeyMatches >= 2 || docs.some((d) => {
6506
- var _a2, _b;
6507
- return ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").toLowerCase().includes("price") || ((_b = d == null ? void 0 : d.content) != null ? _b : "").toLowerCase().includes("brand");
6633
+ var _a3, _b;
6634
+ return ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").toLowerCase().includes("price") || ((_b = d == null ? void 0 : d.content) != null ? _b : "").toLowerCase().includes("brand");
6508
6635
  })) {
6509
6636
  isProductLike = true;
6510
6637
  }
@@ -6786,8 +6913,8 @@ var TextRendererStrategy = class {
6786
6913
  }
6787
6914
  const docs = Array.isArray(data) ? data : [];
6788
6915
  const text = docs.map((d) => {
6789
- var _a2;
6790
- return (_a2 = d == null ? void 0 : d.content) != null ? _a2 : "";
6916
+ var _a3;
6917
+ return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
6791
6918
  }).join("\n\n");
6792
6919
  return { type: "text", title, data: { content: text || "No detailed content available." } };
6793
6920
  }
@@ -6930,9 +7057,9 @@ var LRUDecisionCache = class {
6930
7057
  this.maxSize = maxSize;
6931
7058
  }
6932
7059
  generateKey(context) {
6933
- var _a2, _b;
7060
+ var _a3, _b;
6934
7061
  const q = (context.userQuery || "").toLowerCase().trim();
6935
- const docCount = (_b = (_a2 = context.retrievedDocuments) == null ? void 0 : _a2.length) != null ? _b : 0;
7062
+ const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
6936
7063
  return `${q}::docs:${docCount}`;
6937
7064
  }
6938
7065
  get(context) {
@@ -7041,7 +7168,7 @@ var UITransformer = class _UITransformer {
7041
7168
  * Prefer `analyzeAndDecide()` in production.
7042
7169
  */
7043
7170
  static transform(userQuery, retrievedData, config, trainedSchema, intent) {
7044
- var _a2, _b, _c;
7171
+ var _a3, _b, _c;
7045
7172
  if (!retrievedData || retrievedData.length === 0) {
7046
7173
  return this.createTextResponse("No data available", "No relevant data found for your query.");
7047
7174
  }
@@ -7061,7 +7188,7 @@ var UITransformer = class _UITransformer {
7061
7188
  return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
7062
7189
  }
7063
7190
  if (resolvedIntent.visualizationHint === "distribution") {
7064
- return (_a2 = this.transformToHistogram(profile, userQuery)) != null ? _a2 : this.transformToBarChart(filteredData, profile, userQuery);
7191
+ return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
7065
7192
  }
7066
7193
  if (resolvedIntent.visualizationHint === "correlation") {
7067
7194
  return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
@@ -7394,11 +7521,11 @@ ${schemaProfileText}` : ""}`;
7394
7521
  };
7395
7522
  }
7396
7523
  static transformToPieChart(data, profile, query = "") {
7397
- var _a2;
7524
+ var _a3;
7398
7525
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
7399
7526
  const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
7400
- var _a3;
7401
- return String((_a3 = record.fields[dimension.key]) != null ? _a3 : "");
7527
+ var _a4;
7528
+ return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
7402
7529
  }).filter(Boolean))) : this.detectCategories(data);
7403
7530
  if (categories.length === 0) return null;
7404
7531
  const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
@@ -7408,7 +7535,7 @@ ${schemaProfileText}` : ""}`;
7408
7535
  });
7409
7536
  return {
7410
7537
  type: "pie_chart",
7411
- title: `Distribution by ${(_a2 = dimension == null ? void 0 : dimension.label) != null ? _a2 : "Category"}`,
7538
+ title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
7412
7539
  description: `Showing breakdown across ${pieData.length} categories`,
7413
7540
  data: pieData
7414
7541
  };
@@ -7418,8 +7545,8 @@ ${schemaProfileText}` : ""}`;
7418
7545
  const valueField = profile.numericFields[0];
7419
7546
  const buckets = /* @__PURE__ */ new Map();
7420
7547
  profile.records.forEach((record) => {
7421
- var _a2, _b, _c;
7422
- const timestamp = String((_a2 = record.fields[dateField.key]) != null ? _a2 : "");
7548
+ var _a3, _b, _c;
7549
+ const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
7423
7550
  const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
7424
7551
  buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
7425
7552
  });
@@ -7432,23 +7559,23 @@ ${schemaProfileText}` : ""}`;
7432
7559
  };
7433
7560
  }
7434
7561
  static transformToBarChart(data, profile, query = "", horizontal = false) {
7435
- var _a2;
7562
+ var _a3;
7436
7563
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
7437
7564
  const measure = profile ? this.selectNumericField(profile, query) : void 0;
7438
7565
  const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
7439
7566
  const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
7440
7567
  const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
7441
- var _a3, _b, _c, _d, _e;
7568
+ var _a4, _b, _c, _d, _e;
7442
7569
  const meta = item.metadata || {};
7443
7570
  const label = String(
7444
- (_c = (_b = (_a3 = this.getDynamicVal(meta, "name")) != null ? _a3 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
7571
+ (_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
7445
7572
  );
7446
7573
  const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
7447
7574
  return { category: label, value: Number(value) };
7448
7575
  });
7449
7576
  return {
7450
7577
  type: horizontal ? "horizontal_bar" : "bar_chart",
7451
- title: dimension ? `${(_a2 = measure == null ? void 0 : measure.label) != null ? _a2 : "Count"} by ${dimension.label}` : "Comparison",
7578
+ title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
7452
7579
  description: `Showing ${fallbackData.length} comparable values`,
7453
7580
  data: fallbackData
7454
7581
  };
@@ -7483,11 +7610,11 @@ ${schemaProfileText}` : ""}`;
7483
7610
  if (fields.length < 2) return null;
7484
7611
  const [xField, yField] = fields;
7485
7612
  const points = profile.records.map((record) => {
7486
- var _a2;
7613
+ var _a3;
7487
7614
  const x = this.toFiniteNumber(record.fields[xField.key]);
7488
7615
  const y = this.toFiniteNumber(record.fields[yField.key]);
7489
7616
  if (x === null || y === null) return null;
7490
- return { x, y, label: String((_a2 = this.getRecordLabel(record)) != null ? _a2 : record.id) };
7617
+ return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
7491
7618
  }).filter((point) => point !== null).slice(0, 100);
7492
7619
  if (points.length === 0) return null;
7493
7620
  return {
@@ -7517,9 +7644,9 @@ ${schemaProfileText}` : ""}`;
7517
7644
  static transformToRadarChart(data) {
7518
7645
  const attributeMap = {};
7519
7646
  data.forEach((item) => {
7520
- var _a2, _b, _c;
7647
+ var _a3, _b, _c;
7521
7648
  const meta = item.metadata || {};
7522
- const seriesName = String((_c = (_b = (_a2 = meta.name) != null ? _a2 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
7649
+ const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
7523
7650
  Object.entries(meta).forEach(([key, val]) => {
7524
7651
  if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
7525
7652
  if (!attributeMap[key]) attributeMap[key] = {};
@@ -7535,8 +7662,8 @@ ${schemaProfileText}` : ""}`;
7535
7662
  title: "Product Comparison",
7536
7663
  description: `Comparing ${data.length} items across ${radarData.length} attributes`,
7537
7664
  data: radarData.length > 0 ? radarData : data.map((d) => {
7538
- var _a2;
7539
- return { attribute: ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").substring(0, 40) };
7665
+ var _a3;
7666
+ return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
7540
7667
  })
7541
7668
  };
7542
7669
  }
@@ -7555,8 +7682,8 @@ ${schemaProfileText}` : ""}`;
7555
7682
  return this.createTextResponse(
7556
7683
  "Retrieved Context",
7557
7684
  data.map((item) => {
7558
- var _a2;
7559
- return (_a2 = item == null ? void 0 : item.content) != null ? _a2 : "";
7685
+ var _a3;
7686
+ return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
7560
7687
  }).join("\n\n"),
7561
7688
  `Found ${data.length} relevant results`
7562
7689
  );
@@ -7607,11 +7734,11 @@ ${schemaProfileText}` : ""}`;
7607
7734
  return null;
7608
7735
  }
7609
7736
  static normalizeTransformation(payload) {
7610
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
7737
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
7611
7738
  if (!payload || typeof payload !== "object") return null;
7612
7739
  const p = payload;
7613
7740
  const type = this.normalizeVisualizationType(
7614
- String((_c = (_b = (_a2 = p.type) != null ? _a2 : p.view) != null ? _b : p.chartType) != null ? _c : "")
7741
+ String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
7615
7742
  );
7616
7743
  if (!type) return null;
7617
7744
  const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
@@ -7622,7 +7749,7 @@ ${schemaProfileText}` : ""}`;
7622
7749
  return this.validateTransformation(transformation) ? transformation : null;
7623
7750
  }
7624
7751
  static normalizeVisualizationType(type) {
7625
- var _a2;
7752
+ var _a3;
7626
7753
  const mapping = {
7627
7754
  pie: "pie_chart",
7628
7755
  pie_chart: "pie_chart",
@@ -7650,7 +7777,7 @@ ${schemaProfileText}` : ""}`;
7650
7777
  product_carousel: "product_carousel",
7651
7778
  carousel: "carousel"
7652
7779
  };
7653
- return (_a2 = mapping[type.toLowerCase()]) != null ? _a2 : null;
7780
+ return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
7654
7781
  }
7655
7782
  static validateTransformation(t) {
7656
7783
  const { type, data } = t;
@@ -7766,7 +7893,7 @@ ${schemaProfileText}` : ""}`;
7766
7893
  }
7767
7894
  static profileData(data) {
7768
7895
  const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
7769
- var _a2, _b;
7896
+ var _a3, _b;
7770
7897
  const fields2 = {};
7771
7898
  Object.entries(item.metadata || {}).forEach(([key, value]) => {
7772
7899
  const primitive = this.toPrimitive(value);
@@ -7775,7 +7902,7 @@ ${schemaProfileText}` : ""}`;
7775
7902
  if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
7776
7903
  return {
7777
7904
  id: item.id,
7778
- content: (_a2 = item.content) != null ? _a2 : "",
7905
+ content: (_a3 = item.content) != null ? _a3 : "",
7779
7906
  score: (_b = item.score) != null ? _b : 0,
7780
7907
  fields: fields2,
7781
7908
  source: item
@@ -7856,16 +7983,16 @@ ${schemaProfileText}` : ""}`;
7856
7983
  return null;
7857
7984
  }
7858
7985
  static selectDimensionField(profile, query) {
7859
- var _a2, _b;
7986
+ var _a3, _b;
7860
7987
  const productCategory = profile.categoricalFields.find(
7861
7988
  (field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
7862
7989
  );
7863
7990
  const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
7864
- return (_b = (_a2 = ranked[0]) != null ? _a2 : productCategory) != null ? _b : profile.categoricalFields[0];
7991
+ return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
7865
7992
  }
7866
7993
  static selectNumericField(profile, query) {
7867
- var _a2;
7868
- return (_a2 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a2 : profile.numericFields[0];
7994
+ var _a3;
7995
+ return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
7869
7996
  }
7870
7997
  static rankFieldsByQuery(fields, query) {
7871
7998
  const q = query.toLowerCase();
@@ -7894,8 +8021,8 @@ ${schemaProfileText}` : ""}`;
7894
8021
  static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
7895
8022
  const result = {};
7896
8023
  profile.records.forEach((record) => {
7897
- var _a2, _b, _c;
7898
- const category = String((_a2 = record.fields[dimensionKey]) != null ? _a2 : "Other").trim() || "Other";
8024
+ var _a3, _b, _c;
8025
+ const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
7899
8026
  const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
7900
8027
  result[category] = ((_c = result[category]) != null ? _c : 0) + value;
7901
8028
  });
@@ -7975,8 +8102,8 @@ ${schemaProfileText}` : ""}`;
7975
8102
  static aggregateByCategory(data, categories) {
7976
8103
  const result = Object.fromEntries(categories.map((c) => [c, 0]));
7977
8104
  data.forEach((item) => {
7978
- var _a2;
7979
- const cat = (_a2 = this.getProductCategory(item)) != null ? _a2 : "Other";
8105
+ var _a3;
8106
+ const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
7980
8107
  if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
7981
8108
  else result["Other"] = (result["Other"] || 0) + 1;
7982
8109
  });
@@ -7984,17 +8111,17 @@ ${schemaProfileText}` : ""}`;
7984
8111
  }
7985
8112
  static extractTimeSeriesData(data) {
7986
8113
  return data.map((item) => {
7987
- var _a2, _b, _c, _d, _e, _f;
8114
+ var _a3, _b, _c, _d, _e, _f;
7988
8115
  const meta = item.metadata || {};
7989
8116
  return {
7990
- timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
8117
+ timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
7991
8118
  value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
7992
8119
  label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
7993
8120
  };
7994
8121
  });
7995
8122
  }
7996
8123
  static extractNumericValue(meta) {
7997
- var _a2;
8124
+ var _a3;
7998
8125
  const preferredKeys = [
7999
8126
  "value",
8000
8127
  "count",
@@ -8009,7 +8136,7 @@ ${schemaProfileText}` : ""}`;
8009
8136
  "price"
8010
8137
  ];
8011
8138
  for (const key of preferredKeys) {
8012
- const raw = (_a2 = resolveMetadataValue(meta, key)) != null ? _a2 : meta[key];
8139
+ const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
8013
8140
  const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
8014
8141
  if (Number.isFinite(value)) return value;
8015
8142
  }
@@ -8104,8 +8231,8 @@ ${schemaProfileText}` : ""}`;
8104
8231
  }, query.includes(normalizedField) ? 3 : 0);
8105
8232
  }
8106
8233
  static resolveTableCellValue(item, column) {
8107
- var _a2, _b, _c;
8108
- if (column === "Content") return ((_a2 = item == null ? void 0 : item.content) != null ? _a2 : "").substring(0, 100);
8234
+ var _a3, _b, _c;
8235
+ if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
8109
8236
  const meta = item.metadata || {};
8110
8237
  const normalizedColumn = this.normalizeComparableField(column);
8111
8238
  const exactMetadata = Object.entries(meta).find(
@@ -8157,8 +8284,8 @@ ${schemaProfileText}` : ""}`;
8157
8284
  let inStock = 0;
8158
8285
  let outOfStock = 0;
8159
8286
  data.forEach((d) => {
8160
- var _a2, _b;
8161
- const cat = (_a2 = this.getProductCategory(d)) != null ? _a2 : "Other";
8287
+ var _a3, _b;
8288
+ const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
8162
8289
  if (cat === category) {
8163
8290
  const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
8164
8291
  if (this.determineStockStatus(d)) inStock += quantity;
@@ -8204,9 +8331,9 @@ ${schemaProfileText}` : ""}`;
8204
8331
  }
8205
8332
  // ─── Product Extraction ───────────────────────────────────────────────────
8206
8333
  static getDynamicVal(meta, uiKey, config, trainedSchema) {
8207
- var _a2;
8334
+ var _a3;
8208
8335
  if (!meta) return void 0;
8209
- const mapping = (_a2 = config == null ? void 0 : config.rag) == null ? void 0 : _a2.uiMapping;
8336
+ const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
8210
8337
  if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
8211
8338
  if (trainedSchema && typeof trainedSchema === "object") {
8212
8339
  const trainedKey = trainedSchema[uiKey];
@@ -8215,7 +8342,7 @@ ${schemaProfileText}` : ""}`;
8215
8342
  return resolveMetadataValue(meta, uiKey);
8216
8343
  }
8217
8344
  static extractProductInfo(item, config, trainedSchema) {
8218
- var _a2, _b;
8345
+ var _a3, _b;
8219
8346
  if (!item) return null;
8220
8347
  const meta = item.metadata || {};
8221
8348
  const content = item.content || "";
@@ -8223,7 +8350,7 @@ ${schemaProfileText}` : ""}`;
8223
8350
  const price = this.getDynamicVal(meta, "price", config, trainedSchema);
8224
8351
  const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
8225
8352
  const description = this.cleanProductDescription(
8226
- (_a2 = this.extractProductDescriptionFromContent(content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
8353
+ (_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
8227
8354
  );
8228
8355
  if (name || this.isProductData(item)) {
8229
8356
  let finalName = name ? String(name) : void 0;
@@ -8358,10 +8485,10 @@ RULES:
8358
8485
  }
8359
8486
  static buildContextSummary(sources, maxChars = 6e3) {
8360
8487
  const items = (sources || []).filter(Boolean).map((s, i) => {
8361
- var _a2, _b, _c, _d;
8488
+ var _a3, _b, _c, _d;
8362
8489
  return {
8363
8490
  index: i + 1,
8364
- content: (_b = (_a2 = s == null ? void 0 : s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
8491
+ content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
8365
8492
  metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
8366
8493
  score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
8367
8494
  };
@@ -8401,7 +8528,7 @@ var SchemaMapper = class {
8401
8528
  return promise;
8402
8529
  }
8403
8530
  static async _doTrain(llm, cacheKey, keys) {
8404
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8531
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8405
8532
  console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
8406
8533
  const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
8407
8534
  const messages = [
@@ -8417,7 +8544,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
8417
8544
  }
8418
8545
  ];
8419
8546
  try {
8420
- const baseUrl = (_a2 = llm == null ? void 0 : llm.baseUrl) != null ? _a2 : "";
8547
+ const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
8421
8548
  const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
8422
8549
  const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
8423
8550
  let responseText;
@@ -8592,9 +8719,9 @@ var Pipeline = class {
8592
8719
  this.initialised = false;
8593
8720
  /** Namespace-specific static cold context cache for CAG */
8594
8721
  this.coldContexts = /* @__PURE__ */ new Map();
8595
- var _a2, _b, _c, _d, _e;
8722
+ var _a3, _b, _c, _d, _e;
8596
8723
  this.chunker = new DocumentChunker(
8597
- (_b = (_a2 = config.rag) == null ? void 0 : _a2.chunkSize) != null ? _b : 1e3,
8724
+ (_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
8598
8725
  (_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
8599
8726
  );
8600
8727
  if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
@@ -8610,7 +8737,7 @@ var Pipeline = class {
8610
8737
  return this.initialised ? this.llmProvider : void 0;
8611
8738
  }
8612
8739
  async initialize() {
8613
- var _a2, _b, _c, _d;
8740
+ var _a3, _b, _c, _d;
8614
8741
  if (this.initialised) return;
8615
8742
  const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
8616
8743
 
@@ -8653,7 +8780,7 @@ var Pipeline = class {
8653
8780
  this.entityExtractor = new EntityExtractor(this.llmProvider);
8654
8781
  }
8655
8782
  await this.vectorDB.initialize();
8656
- if (((_a2 = this.config.rag) == null ? void 0 : _a2.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) {
8783
+ if (((_a3 = this.config.rag) == null ? void 0 : _a3.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) {
8657
8784
  this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
8658
8785
  this.multiAgentCoordinator = new MultiAgentCoordinator({
8659
8786
  llmProvider: this.llmProvider,
@@ -8671,8 +8798,8 @@ var Pipeline = class {
8671
8798
  this.initialised = true;
8672
8799
  }
8673
8800
  async loadColdContext(ns) {
8674
- var _a2, _b;
8675
- const cagConfig = (_a2 = this.config.rag) == null ? void 0 : _a2.cag;
8801
+ var _a3, _b;
8802
+ const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
8676
8803
  if (!cagConfig || !cagConfig.enabled) return;
8677
8804
  try {
8678
8805
  const coldNs = cagConfig.coldNamespace || ns;
@@ -8725,12 +8852,12 @@ ${m.content}`).join("\n\n---\n\n");
8725
8852
  }
8726
8853
  /** Step 1: Chunk the document content. */
8727
8854
  async prepareChunks(doc) {
8728
- var _a2, _b;
8855
+ var _a3, _b;
8729
8856
  if (this.llamaIngestor) {
8730
8857
  return this.llamaIngestor.chunk(doc.content, {
8731
8858
  docId: doc.docId,
8732
8859
  metadata: doc.metadata,
8733
- chunkSize: (_a2 = this.config.rag) == null ? void 0 : _a2.chunkSize,
8860
+ chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
8734
8861
  chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
8735
8862
  });
8736
8863
  }
@@ -8828,9 +8955,9 @@ ${m.content}`).join("\n\n---\n\n");
8828
8955
  return { reply, sources };
8829
8956
  }
8830
8957
  async ask(question, history = [], namespace) {
8831
- var _a2, _b;
8958
+ var _a3, _b;
8832
8959
  await this.initialize();
8833
- if ((((_a2 = this.config.rag) == null ? void 0 : _a2.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
8960
+ if ((((_a3 = this.config.rag) == null ? void 0 : _a3.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
8834
8961
  return await this.multiAgentCoordinator.run(question, history);
8835
8962
  }
8836
8963
  const stream = this.askStream(question, history, namespace);
@@ -8865,9 +8992,9 @@ ${m.content}`).join("\n\n---\n\n");
8865
8992
  }
8866
8993
  askStream(_0) {
8867
8994
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
8868
- var _a2, _b;
8995
+ var _a3, _b;
8869
8996
  yield new __await(this.initialize());
8870
- if ((((_a2 = this.config.rag) == null ? void 0 : _a2.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
8997
+ if ((((_a3 = this.config.rag) == null ? void 0 : _a3.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
8871
8998
  const stream2 = this.multiAgentCoordinator.runStream(question, history);
8872
8999
  try {
8873
9000
  for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
@@ -8916,10 +9043,10 @@ ${m.content}`).join("\n\n---\n\n");
8916
9043
  */
8917
9044
  askStreamInternal(_0) {
8918
9045
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
8919
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
9046
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
8920
9047
  yield new __await(this.initialize());
8921
9048
  const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
8922
- const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
9049
+ const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
8923
9050
  const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
8924
9051
  const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
8925
9052
  const requestStart = performance.now();
@@ -8968,8 +9095,8 @@ ${m.content}`).join("\n\n---\n\n");
8968
9095
  const rerankStart = performance.now();
8969
9096
  const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
8970
9097
  let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
8971
- var _a3;
8972
- return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
9098
+ var _a4;
9099
+ return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
8973
9100
  });
8974
9101
  const rerankLimit = Math.max(retrievalLimit, fullSources.length);
8975
9102
  const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
@@ -8982,13 +9109,13 @@ ${m.content}`).join("\n\n---\n\n");
8982
9109
  let context = promptSources.length ? `[SEARCH SUMMARY: Found ${totalCount} matching record(s) out of ${rawSources.length} total resources searched in database. Context includes top ${promptSources.length} relevant records]
8983
9110
 
8984
9111
  ` + promptSources.map((m, i) => {
8985
- var _a3;
9112
+ var _a4;
8986
9113
  return `[Source ${i + 1}]
8987
- ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
9114
+ ${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
8988
9115
  }).join("\n\n---\n\n") : "No relevant context found.";
8989
9116
  const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
8990
- var _a3, _b2;
8991
- return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
9117
+ var _a4, _b2;
9118
+ return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
8992
9119
  });
8993
9120
  if (graphData && graphData.nodes.length > 0) {
8994
9121
  const graphContext = graphData.nodes.map(
@@ -9016,10 +9143,10 @@ ${context}`;
9016
9143
  yield {
9017
9144
  reply: "",
9018
9145
  sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
9019
- var _a3, _b2, _c2;
9146
+ var _a4, _b2, _c2;
9020
9147
  return {
9021
9148
  id: s.id,
9022
- score: (_a3 = s.score) != null ? _a3 : 0,
9149
+ score: (_a4 = s.score) != null ? _a4 : 0,
9023
9150
  content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
9024
9151
  metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
9025
9152
  namespace: ns
@@ -9212,11 +9339,11 @@ ${context}`;
9212
9339
  systemPrompt,
9213
9340
  userPrompt: question + finalRestrictionSuffix,
9214
9341
  chunks: (sources || []).filter(Boolean).map((s) => {
9215
- var _a3, _b2;
9342
+ var _a4, _b2;
9216
9343
  return {
9217
9344
  id: s.id,
9218
9345
  score: s.score,
9219
- content: (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "",
9346
+ content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
9220
9347
  metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
9221
9348
  namespace: ns
9222
9349
  };
@@ -9235,7 +9362,7 @@ ${context}`;
9235
9362
  const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
9236
9363
  const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
9237
9364
  (async () => {
9238
- var _a3, _b2, _c2, _d2, _e2;
9365
+ var _a4, _b2, _c2, _d2, _e2;
9239
9366
  try {
9240
9367
  let finalTrace = trace;
9241
9368
  if (!awaitHallucination && runHallucination) {
@@ -9244,7 +9371,7 @@ ${context}`;
9244
9371
  finalTrace = buildTrace(backgroundScoreResult);
9245
9372
  }
9246
9373
  }
9247
- const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a3 = this.config.llm) == null ? void 0 : _a3.model) || "llama-3.1-8b-instant";
9374
+ const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
9248
9375
  const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
9249
9376
  const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
9250
9377
  const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
@@ -9298,7 +9425,7 @@ ${context}`;
9298
9425
  * Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
9299
9426
  */
9300
9427
  async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
9301
- var _a2;
9428
+ var _a3;
9302
9429
  if (!sources || sources.length === 0) {
9303
9430
  return UITransformer.transform(question, sources, this.config, cachedSchema);
9304
9431
  }
@@ -9311,7 +9438,7 @@ ${context}`;
9311
9438
  { visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
9312
9439
  );
9313
9440
  }
9314
- const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
9441
+ const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
9315
9442
  if (forceDeterministic || !enableLlmUiTransform) {
9316
9443
  return UITransformer.transform(question, sources, this.config, cachedSchema);
9317
9444
  }
@@ -9329,15 +9456,15 @@ ${context}`;
9329
9456
  const value = this.resolveNumericPredicateValue(source, predicate);
9330
9457
  return value !== null && this.matchesNumericPredicate(value, predicate);
9331
9458
  })).sort((a, b) => {
9332
- var _a2, _b;
9459
+ var _a3, _b;
9333
9460
  const primary = predicates[0];
9334
- const aValue = (_a2 = this.resolveNumericPredicateValue(a, primary)) != null ? _a2 : 0;
9461
+ const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
9335
9462
  const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
9336
9463
  return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
9337
9464
  });
9338
9465
  }
9339
9466
  resolveNumericPredicateValue(source, predicate) {
9340
- var _a2;
9467
+ var _a3;
9341
9468
  if (!source) return null;
9342
9469
  const meta = source.metadata || {};
9343
9470
  const field = predicate.field;
@@ -9350,7 +9477,7 @@ ${context}`;
9350
9477
  const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
9351
9478
  if (value !== null) return value;
9352
9479
  }
9353
- const contentValue = this.extractNumericValueFromContent((_a2 = source.content) != null ? _a2 : "", field);
9480
+ const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
9354
9481
  if (contentValue !== null) return contentValue;
9355
9482
  }
9356
9483
  for (const [key, value] of entries) {
@@ -9406,8 +9533,8 @@ ${context}`;
9406
9533
  return Number.isFinite(numeric) ? numeric : null;
9407
9534
  }
9408
9535
  async retrieve(query, options) {
9409
- var _a2, _b, _c, _d, _e, _f, _g2;
9410
- const ns = formatNamespace((_a2 = options.namespace) != null ? _a2 : this.config.projectId);
9536
+ var _a3, _b, _c, _d, _e, _f, _g2;
9537
+ const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
9411
9538
  const topK = (_b = options.topK) != null ? _b : 5;
9412
9539
  const cacheKey = `${ns}::${query}`;
9413
9540
  let queryVector = this.embeddingCache.get(cacheKey);
@@ -9452,11 +9579,11 @@ ${context}`;
9452
9579
  namespace: ns,
9453
9580
  count: resolvedSources.length,
9454
9581
  sample: resolvedSources.slice(0, 2).map((s) => {
9455
- var _a3;
9582
+ var _a4;
9456
9583
  return {
9457
9584
  id: s == null ? void 0 : s.id,
9458
9585
  score: s == null ? void 0 : s.score,
9459
- contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9586
+ contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
9460
9587
  metadata: s == null ? void 0 : s.metadata
9461
9588
  };
9462
9589
  })
@@ -9470,8 +9597,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
9470
9597
 
9471
9598
  History:
9472
9599
  ${(history || []).map((m) => {
9473
- var _a2;
9474
- return `${(m == null ? void 0 : m.role) || "user"}: ${(_a2 = m == null ? void 0 : m.content) != null ? _a2 : ""}`;
9600
+ var _a3;
9601
+ return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
9475
9602
  }).join("\n")}
9476
9603
 
9477
9604
  New Question: ${question}
@@ -9498,8 +9625,8 @@ Optimized Search Query:`;
9498
9625
  const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
9499
9626
  if (!sources || sources.length === 0) return [];
9500
9627
  const context = sources.map((s) => {
9501
- var _a2;
9502
- return (_a2 = s == null ? void 0 : s.content) != null ? _a2 : "";
9628
+ var _a3;
9629
+ return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
9503
9630
  }).join("\n\n---\n\n");
9504
9631
  const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
9505
9632
  Focus on questions that can be answered by the context.
@@ -9541,13 +9668,13 @@ var Retrivora = class {
9541
9668
  this.pipeline = new Pipeline(this.config);
9542
9669
  }
9543
9670
  async initialize() {
9544
- var _a2;
9671
+ var _a3;
9545
9672
  try {
9546
9673
  await ConfigValidator.validateAndThrow(this.config);
9547
9674
  LicenseVerifier.verify(
9548
9675
  this.config.licenseKey,
9549
9676
  this.config.projectId,
9550
- (_a2 = this.config.vectorDb) == null ? void 0 : _a2.provider
9677
+ (_a3 = this.config.vectorDb) == null ? void 0 : _a3.provider
9551
9678
  );
9552
9679
  await LicenseVerifier.verifyIP(this.config.licenseKey);
9553
9680
  } catch (err) {
@@ -9720,18 +9847,200 @@ var ProviderHealthCheck = class {
9720
9847
  }
9721
9848
  };
9722
9849
 
9850
+ // src/core/FreeTierLimitsGuard.ts
9851
+ var FREE_TIER_QUOTAS = {
9852
+ MAX_DOCUMENTS: 25,
9853
+ MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
9854
+ MAX_STORAGE_BYTES: 250 * 1024 * 1024,
9855
+ MAX_TRIAL_REQUEST_UNITS: 500,
9856
+ MAX_DAILY_REQUEST_UNITS: 50,
9857
+ TRIAL_DURATION_DAYS: 14,
9858
+ GRACE_PERIOD_DAYS: 2,
9859
+ MAX_RPM: 10,
9860
+ MAX_RPH: 100,
9861
+ MAX_RPD: 500,
9862
+ MAX_CONCURRENT_REQUESTS: 2,
9863
+ MAX_INPUT_TOKENS: 2e4,
9864
+ MAX_OUTPUT_TOKENS: 4e3,
9865
+ UPGRADE_REMINDER_DAYS: [7, 12, 14],
9866
+ MAX_USERS: 1,
9867
+ MAX_NAMESPACES: 1,
9868
+ MAX_PROJECTS: 1
9869
+ };
9870
+ var FreeTierLimitsGuard = class {
9871
+ static calculateTrialTimestamps(startedAt) {
9872
+ const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
9873
+ const trialStartedAtMs = startDate.getTime();
9874
+ const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
9875
+ const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
9876
+ return {
9877
+ trial_started_at: new Date(trialStartedAtMs).toISOString(),
9878
+ trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
9879
+ grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
9880
+ };
9881
+ }
9882
+ static calculateRequestUnits(operationType, options) {
9883
+ var _a3;
9884
+ const op = operationType.toLowerCase().trim();
9885
+ if (op.includes("suggestion") || op.includes("template") || op.includes("history") || op.includes("model") || op.includes("health") || op.includes("auth") || op.includes("license") || op.includes("usage") || op.includes("feedback") || op.includes("analytic")) {
9886
+ return 0;
9887
+ }
9888
+ if (op.includes("image")) {
9889
+ return 10;
9890
+ }
9891
+ if (op.includes("embedding")) {
9892
+ const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
9893
+ return Math.max(1, Math.ceil(chunks / 1e3));
9894
+ }
9895
+ return 1;
9896
+ }
9897
+ static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
9898
+ const timestamps = this.calculateTrialTimestamps(startedAt);
9899
+ const startMs = new Date(timestamps.trial_started_at).getTime();
9900
+ const expireMs = new Date(timestamps.trial_expires_at).getTime();
9901
+ const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
9902
+ const nowMs = nowServerTime.getTime();
9903
+ const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
9904
+ const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
9905
+ const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
9906
+ const isExpiredTime = nowMs > expireMs;
9907
+ const isPastGraceTime = nowMs > graceExpireMs;
9908
+ let status = "active";
9909
+ let reason;
9910
+ if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
9911
+ status = "expired";
9912
+ reason = "Trial period and grace period have expired. Upgrade your plan.";
9913
+ } else if (isExpiredTime || isConsumedUnits) {
9914
+ status = "grace_period";
9915
+ reason = isConsumedUnits ? "Total trial request quota (500 units) consumed. Grace period active (dashboard access only)." : "14-day trial period expired. 2-day grace period active (dashboard access only).";
9916
+ }
9917
+ let upgradeReminderDue;
9918
+ if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
9919
+ upgradeReminderDue = daysElapsed;
9920
+ }
9921
+ let usageReminderDue;
9922
+ const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
9923
+ if (usagePercent >= 100) {
9924
+ usageReminderDue = "100%";
9925
+ } else if (usagePercent >= 90) {
9926
+ usageReminderDue = "90%";
9927
+ } else if (usagePercent >= 80) {
9928
+ usageReminderDue = "80%";
9929
+ }
9930
+ return {
9931
+ status,
9932
+ daysElapsed,
9933
+ daysRemaining,
9934
+ isGracePeriod: status === "grace_period",
9935
+ isExpired: status === "expired",
9936
+ upgradeReminderDue,
9937
+ usageReminderDue,
9938
+ reason
9939
+ };
9940
+ }
9941
+ static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
9942
+ var _a3, _b;
9943
+ const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
9944
+ const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
9945
+ if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
9946
+ const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
9947
+ return {
9948
+ allowed: false,
9949
+ reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
9950
+ };
9951
+ }
9952
+ if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
9953
+ return {
9954
+ allowed: false,
9955
+ reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
9956
+ };
9957
+ }
9958
+ if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
9959
+ const mbUsed = (storage / (1024 * 1024)).toFixed(1);
9960
+ return {
9961
+ allowed: false,
9962
+ reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
9963
+ };
9964
+ }
9965
+ return { allowed: true };
9966
+ }
9967
+ static checkRequestAllowed(params) {
9968
+ var _a3, _b, _c;
9969
+ const op = (_a3 = params.operationType) != null ? _a3 : "chat";
9970
+ const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
9971
+ if (costUnits === 0) {
9972
+ return { allowed: true, costUnits: 0 };
9973
+ }
9974
+ if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
9975
+ return {
9976
+ allowed: false,
9977
+ reason: "Token limit exceeded. Upgrade your plan.",
9978
+ costUnits
9979
+ };
9980
+ }
9981
+ if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
9982
+ return {
9983
+ allowed: false,
9984
+ reason: "Token limit exceeded. Upgrade your plan.",
9985
+ costUnits
9986
+ };
9987
+ }
9988
+ if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
9989
+ return {
9990
+ allowed: false,
9991
+ reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
9992
+ costUnits
9993
+ };
9994
+ }
9995
+ const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
9996
+ const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
9997
+ if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
9998
+ return {
9999
+ allowed: false,
10000
+ reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
10001
+ costUnits
10002
+ };
10003
+ }
10004
+ if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
10005
+ return {
10006
+ allowed: false,
10007
+ reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
10008
+ costUnits
10009
+ };
10010
+ }
10011
+ const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
10012
+ if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
10013
+ return {
10014
+ allowed: false,
10015
+ reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
10016
+ costUnits
10017
+ };
10018
+ }
10019
+ return { allowed: true, costUnits };
10020
+ }
10021
+ static checkQueryAllowed(dailyQueriesCount = 0) {
10022
+ if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
10023
+ return {
10024
+ allowed: false,
10025
+ reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
10026
+ };
10027
+ }
10028
+ return { allowed: true };
10029
+ }
10030
+ };
10031
+
9723
10032
  // src/core/VectorPlugin.ts
9724
10033
  var VectorPlugin = class {
9725
10034
  constructor(hostConfig) {
9726
10035
  const resolvedConfig = ConfigResolver.resolve(hostConfig);
9727
10036
  this.config = resolvedConfig;
9728
10037
  this.validationPromise = (async () => {
9729
- var _a2;
10038
+ var _a3;
9730
10039
  await ConfigValidator.validateAndThrow(resolvedConfig);
9731
10040
  LicenseVerifier.verify(
9732
10041
  resolvedConfig.licenseKey,
9733
10042
  resolvedConfig.projectId,
9734
- (_a2 = resolvedConfig.vectorDb) == null ? void 0 : _a2.provider
10043
+ (_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
9735
10044
  );
9736
10045
  })();
9737
10046
  this.validationPromise.catch(() => {
@@ -9765,16 +10074,32 @@ var VectorPlugin = class {
9765
10074
  this.config.embedding
9766
10075
  );
9767
10076
  }
10077
+ estimateInputTokens(message, history = []) {
10078
+ const allContent = message.length + history.reduce((acc, m) => {
10079
+ var _a3, _b;
10080
+ return acc + (((_a3 = m == null ? void 0 : m.content) == null ? void 0 : _a3.length) || ((_b = m == null ? void 0 : m.text) == null ? void 0 : _b.length) || 0);
10081
+ }, 0);
10082
+ return Math.ceil(allContent / 4);
10083
+ }
9768
10084
  /**
9769
10085
  * Run a chat query.
9770
10086
  */
9771
10087
  async chat(message, history = [], namespace) {
10088
+ var _a3;
9772
10089
  try {
9773
10090
  await this.validationPromise;
9774
10091
  } catch (err) {
9775
10092
  throw wrapError(err, "CONFIGURATION_ERROR");
9776
10093
  }
9777
10094
  try {
10095
+ const inputTokens = this.estimateInputTokens(message, history);
10096
+ const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
10097
+ operationType: "chat",
10098
+ inputTokens
10099
+ });
10100
+ if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
10101
+ throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
10102
+ }
9778
10103
  return await this.pipeline.ask(message, history, namespace);
9779
10104
  } catch (err) {
9780
10105
  const msg = String(err);
@@ -9782,6 +10107,9 @@ var VectorPlugin = class {
9782
10107
  if (msg.includes("Embed") || msg.includes("embed")) {
9783
10108
  defaultCode = "EMBEDDING_FAILED";
9784
10109
  }
10110
+ if (msg.toLowerCase().includes("token limit")) {
10111
+ defaultCode = "RATE_LIMITED";
10112
+ }
9785
10113
  throw wrapError(err, defaultCode);
9786
10114
  }
9787
10115
  }
@@ -9790,12 +10118,21 @@ var VectorPlugin = class {
9790
10118
  */
9791
10119
  chatStream(_0) {
9792
10120
  return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
10121
+ var _a3;
9793
10122
  try {
9794
10123
  yield new __await(this.validationPromise);
9795
10124
  } catch (err) {
9796
10125
  throw wrapError(err, "CONFIGURATION_ERROR");
9797
10126
  }
9798
10127
  try {
10128
+ const inputTokens = this.estimateInputTokens(message, history);
10129
+ const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
10130
+ operationType: "chat_stream",
10131
+ inputTokens
10132
+ });
10133
+ if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
10134
+ throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
10135
+ }
9799
10136
  const stream = this.pipeline.askStream(message, history, namespace);
9800
10137
  try {
9801
10138
  for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
@@ -9818,6 +10155,9 @@ var VectorPlugin = class {
9818
10155
  if (msg.includes("Embed") || msg.includes("embed")) {
9819
10156
  defaultCode = "EMBEDDING_FAILED";
9820
10157
  }
10158
+ if (msg.toLowerCase().includes("token limit")) {
10159
+ defaultCode = "RATE_LIMITED";
10160
+ }
9821
10161
  throw wrapError(err, defaultCode);
9822
10162
  }
9823
10163
  });
@@ -9872,13 +10212,13 @@ var ConfigBuilder = class {
9872
10212
  * Configure the vector database provider
9873
10213
  */
9874
10214
  vectorDb(provider, options) {
9875
- var _a2;
10215
+ var _a3;
9876
10216
  if (provider === "auto") {
9877
10217
  this._vectorDb = this._autoDetectVectorDb();
9878
10218
  } else {
9879
10219
  this._vectorDb = {
9880
10220
  provider,
9881
- indexName: (_a2 = options == null ? void 0 : options.indexName) != null ? _a2 : "default",
10221
+ indexName: (_a3 = options == null ? void 0 : options.indexName) != null ? _a3 : "default",
9882
10222
  options: __spreadValues({}, options)
9883
10223
  };
9884
10224
  }
@@ -9888,7 +10228,7 @@ var ConfigBuilder = class {
9888
10228
  * Configure the LLM provider for chat
9889
10229
  */
9890
10230
  llm(provider, model, apiKey, options) {
9891
- var _a2, _b;
10231
+ var _a3, _b;
9892
10232
  if (provider === "auto") {
9893
10233
  this._llm = this._autoDetectLLM();
9894
10234
  } else {
@@ -9897,7 +10237,7 @@ var ConfigBuilder = class {
9897
10237
  model: model != null ? model : "default-model",
9898
10238
  apiKey,
9899
10239
  systemPrompt: options == null ? void 0 : options.systemPrompt,
9900
- maxTokens: (_a2 = options == null ? void 0 : options.maxTokens) != null ? _a2 : 1024,
10240
+ maxTokens: (_a3 = options == null ? void 0 : options.maxTokens) != null ? _a3 : 1024,
9901
10241
  temperature: (_b = options == null ? void 0 : options.temperature) != null ? _b : 0.7,
9902
10242
  baseUrl: options == null ? void 0 : options.baseUrl,
9903
10243
  options
@@ -9940,8 +10280,8 @@ var ConfigBuilder = class {
9940
10280
  * Set RAG-specific pipeline parameters
9941
10281
  */
9942
10282
  rag(options) {
9943
- var _a2;
9944
- this._rag = __spreadValues(__spreadValues({}, (_a2 = this._rag) != null ? _a2 : {}), options);
10283
+ var _a3;
10284
+ this._rag = __spreadValues(__spreadValues({}, (_a3 = this._rag) != null ? _a3 : {}), options);
9945
10285
  return this;
9946
10286
  }
9947
10287
  /**
@@ -9957,7 +10297,7 @@ var ConfigBuilder = class {
9957
10297
  * Throws if required fields (projectId, vectorDb, llm, embedding) are not set.
9958
10298
  */
9959
10299
  build() {
9960
- var _a2;
10300
+ var _a3;
9961
10301
  const missing = [];
9962
10302
  if (!this._projectId) missing.push('projectId (call .projectId("my-app"))');
9963
10303
  if (!this._vectorDb) missing.push('vectorDb (call .vectorDb("pinecone", { ... }))');
@@ -9969,7 +10309,7 @@ var ConfigBuilder = class {
9969
10309
  ${missing.join("\n ")}`
9970
10310
  );
9971
10311
  }
9972
- const ragConfig = (_a2 = this._rag) != null ? _a2 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
10312
+ const ragConfig = (_a3 = this._rag) != null ? _a3 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
9973
10313
  if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
9974
10314
  ragConfig.useGraphRetrieval = true;
9975
10315
  }
@@ -10065,8 +10405,8 @@ var DocumentParser = class {
10065
10405
  * Extract text from a File or Buffer based on its type.
10066
10406
  */
10067
10407
  static async parse(file, fileName, mimeType) {
10068
- var _a2;
10069
- const extension = ((_a2 = fileName.split(".").pop()) == null ? void 0 : _a2.toLowerCase()) || "";
10408
+ var _a3;
10409
+ const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
10070
10410
  if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
10071
10411
  return this.readAsText(file);
10072
10412
  }
@@ -10173,9 +10513,9 @@ var DatabaseStorage = class {
10173
10513
  this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
10174
10514
  this.historyFile = path.join(this.fallbackDir, "history.json");
10175
10515
  this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
10176
- var _a2, _b, _c, _d, _e;
10516
+ var _a3, _b, _c, _d, _e;
10177
10517
  this.config = config;
10178
- this.provider = ((_a2 = config.vectorDb) == null ? void 0 : _a2.provider) || "fs";
10518
+ this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
10179
10519
  const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
10180
10520
  const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
10181
10521
  this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
@@ -10210,16 +10550,16 @@ var DatabaseStorage = class {
10210
10550
  }
10211
10551
  }
10212
10552
  checkHistoryEnabled() {
10213
- var _a2, _b;
10553
+ var _a3, _b;
10214
10554
  this.checkPremiumSubscription();
10215
- if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.history) == null ? void 0 : _b.enabled) === false) {
10555
+ if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
10216
10556
  throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
10217
10557
  }
10218
10558
  }
10219
10559
  checkFeedbackEnabled() {
10220
- var _a2, _b;
10560
+ var _a3, _b;
10221
10561
  this.checkPremiumSubscription();
10222
- if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.feedback) == null ? void 0 : _b.enabled) === false) {
10562
+ if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
10223
10563
  throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
10224
10564
  }
10225
10565
  }
@@ -10386,8 +10726,11 @@ var DatabaseStorage = class {
10386
10726
  this.writeLocalFile(this.historyFile, history);
10387
10727
  }
10388
10728
  }
10389
- async getHistory(sessionId) {
10729
+ async getHistory(sessionId, projectIds) {
10390
10730
  this.checkHistoryEnabled();
10731
+ if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
10732
+ return [];
10733
+ }
10391
10734
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10392
10735
  const pool = await this.getPGPool();
10393
10736
  const res = await pool.query(
@@ -10417,8 +10760,11 @@ var DatabaseStorage = class {
10417
10760
  return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
10418
10761
  }
10419
10762
  }
10420
- async clearHistory(sessionId) {
10763
+ async clearHistory(sessionId, projectIds) {
10421
10764
  this.checkHistoryEnabled();
10765
+ if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
10766
+ return;
10767
+ }
10422
10768
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10423
10769
  const pool = await this.getPGPool();
10424
10770
  await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
@@ -10437,21 +10783,36 @@ var DatabaseStorage = class {
10437
10783
  this.writeLocalFile(this.feedbackFile, filteredFeedback);
10438
10784
  }
10439
10785
  }
10440
- async listSessions() {
10786
+ /**
10787
+ * Return true when `sessionId` falls into the allowed `projectIds` scope.
10788
+ * When `projectIds` is empty / undefined we allow the call (legacy behavior
10789
+ * for non-multi-tenant consumers). Session ids typically begin with the
10790
+ * project id they were created for, so we prefix-match as well as contains-match
10791
+ * to catch sharded / suffix-style ids used by some integrations.
10792
+ */
10793
+ sessionInScope(sessionId, projectIds) {
10794
+ if (!projectIds || projectIds.length === 0) return true;
10795
+ return projectIds.some(
10796
+ (pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
10797
+ );
10798
+ }
10799
+ async listSessions(projectIds) {
10441
10800
  this.checkHistoryEnabled();
10801
+ let raw = [];
10442
10802
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10443
10803
  const pool = await this.getPGPool();
10444
10804
  const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
10445
- return res.rows.map((r) => r.session_id);
10805
+ raw = res.rows.map((r) => r.session_id);
10446
10806
  } else if (this.provider === "mongodb") {
10447
10807
  await this.getMongoClient();
10448
10808
  const db = this.getMongoDb();
10449
- return db.collection(this.historyTableName).distinct("session_id");
10809
+ raw = await db.collection(this.historyTableName).distinct("session_id");
10450
10810
  } else {
10451
10811
  const history = this.readLocalFile(this.historyFile);
10452
- const sessions = new Set(history.map((h) => h.session_id));
10453
- return Array.from(sessions);
10812
+ raw = Array.from(new Set(history.map((h) => h.session_id)));
10454
10813
  }
10814
+ if (!projectIds || projectIds.length === 0) return raw;
10815
+ return raw.filter((sid) => this.sessionInScope(sid, projectIds));
10455
10816
  }
10456
10817
  // ─── Feedback Operations ──────────────────────────────────────────────────
10457
10818
  async saveFeedback(feedback) {
@@ -10504,8 +10865,9 @@ var DatabaseStorage = class {
10504
10865
  this.writeLocalFile(this.feedbackFile, list);
10505
10866
  }
10506
10867
  }
10507
- async getFeedback(messageId) {
10868
+ async getFeedback(messageId, projectIds) {
10508
10869
  this.checkFeedbackEnabled();
10870
+ let item = null;
10509
10871
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10510
10872
  const pool = await this.getPGPool();
10511
10873
  const res = await pool.query(
@@ -10514,28 +10876,34 @@ var DatabaseStorage = class {
10514
10876
  WHERE message_id = $1`,
10515
10877
  [messageId]
10516
10878
  );
10517
- return res.rows[0] || null;
10879
+ item = res.rows[0] || null;
10518
10880
  } else if (this.provider === "mongodb") {
10519
10881
  await this.getMongoClient();
10520
10882
  const db = this.getMongoDb();
10521
10883
  const col = db.collection(this.feedbackTableName);
10522
- const item = await col.findOne({ message_id: messageId });
10523
- if (!item) return null;
10524
- return {
10525
- id: item.id,
10526
- messageId: item.message_id,
10527
- sessionId: item.session_id,
10528
- rating: item.rating,
10529
- comment: item.comment,
10530
- createdAt: item.created_at
10531
- };
10884
+ const raw = await col.findOne({ message_id: messageId });
10885
+ if (raw) {
10886
+ item = {
10887
+ id: raw.id,
10888
+ messageId: raw.message_id,
10889
+ sessionId: raw.session_id,
10890
+ rating: raw.rating,
10891
+ comment: raw.comment,
10892
+ createdAt: raw.created_at
10893
+ };
10894
+ }
10532
10895
  } else {
10533
10896
  const list = this.readLocalFile(this.feedbackFile);
10534
- return list.find((f) => f.message_id === messageId) || null;
10897
+ item = list.find((f) => f.message_id === messageId) || null;
10535
10898
  }
10899
+ if (item && projectIds && projectIds.length > 0) {
10900
+ return this.sessionInScope(item.sessionId, projectIds) ? item : null;
10901
+ }
10902
+ return item;
10536
10903
  }
10537
- async listFeedback() {
10904
+ async listFeedback(projectIds) {
10538
10905
  this.checkFeedbackEnabled();
10906
+ let raw = [];
10539
10907
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10540
10908
  const pool = await this.getPGPool();
10541
10909
  const res = await pool.query(
@@ -10543,13 +10911,13 @@ var DatabaseStorage = class {
10543
10911
  FROM ${this.feedbackTableName}
10544
10912
  ORDER BY created_at DESC`
10545
10913
  );
10546
- return res.rows;
10914
+ raw = res.rows;
10547
10915
  } else if (this.provider === "mongodb") {
10548
10916
  await this.getMongoClient();
10549
10917
  const db = this.getMongoDb();
10550
10918
  const col = db.collection(this.feedbackTableName);
10551
10919
  const items = await col.find({}).sort({ created_at: -1 }).toArray();
10552
- return items.map((item) => ({
10920
+ raw = items.map((item) => ({
10553
10921
  id: item.id,
10554
10922
  messageId: item.message_id,
10555
10923
  sessionId: item.session_id,
@@ -10559,8 +10927,10 @@ var DatabaseStorage = class {
10559
10927
  }));
10560
10928
  } else {
10561
10929
  const list = this.readLocalFile(this.feedbackFile);
10562
- return [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
10930
+ raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
10563
10931
  }
10932
+ if (!projectIds || projectIds.length === 0) return raw;
10933
+ return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
10564
10934
  }
10565
10935
  async disconnect() {
10566
10936
  if (this.pgPool) {
@@ -10623,8 +10993,8 @@ var _g = global;
10623
10993
  var _a;
10624
10994
  var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
10625
10995
  function getRateLimitKey(req) {
10626
- var _a2, _b;
10627
- const ip = ((_b = (_a2 = req.headers.get("x-forwarded-for")) == null ? void 0 : _a2.split(",")[0]) == null ? void 0 : _b.trim()) || req.headers.get("x-real-ip") || "127.0.0.1";
10996
+ var _a3, _b;
10997
+ const ip = ((_b = (_a3 = req.headers.get("x-forwarded-for")) == null ? void 0 : _a3.split(",")[0]) == null ? void 0 : _b.trim()) || req.headers.get("x-real-ip") || "127.0.0.1";
10628
10998
  return `ip:${ip}`;
10629
10999
  }
10630
11000
  function checkRateLimit(req) {
@@ -10646,6 +11016,66 @@ function checkRateLimit(req) {
10646
11016
  }
10647
11017
  return null;
10648
11018
  }
11019
+ var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
11020
+ function isFreeTier(tier) {
11021
+ if (!tier) return true;
11022
+ return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
11023
+ }
11024
+ var _a2;
11025
+ var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
11026
+ function createPaymentRequiredResponse(reason, details) {
11027
+ const body = __spreadProps(__spreadValues({
11028
+ type: "https://retrivora.com/docs/errors/payment-required",
11029
+ title: "Payment Required",
11030
+ status: 402,
11031
+ detail: reason,
11032
+ code: "FREE_TIER_LIMIT_EXCEEDED",
11033
+ instance: void 0
11034
+ }, details != null ? details : {}), {
11035
+ quota: {
11036
+ maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
11037
+ maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
11038
+ maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
11039
+ maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
11040
+ upgradeUrl: "https://retrivora.com/pricing"
11041
+ }
11042
+ });
11043
+ return new Response(JSON.stringify(body), {
11044
+ status: 402,
11045
+ headers: {
11046
+ "Content-Type": "application/problem+json"
11047
+ }
11048
+ });
11049
+ }
11050
+ function resolveLicenseKey(req, config, bodyLicenseKey) {
11051
+ var _a3;
11052
+ return req.headers.get("x-license-key") || bodyLicenseKey || ((_a3 = req.headers.get("authorization")) == null ? void 0 : _a3.replace(/^Bearer\s+/i, "")) || config.licenseKey || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.RAG_LICENSE_KEY || "";
11053
+ }
11054
+ function enforceLicense(req, config, bodyLicenseKey) {
11055
+ const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
11056
+ const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
11057
+ const projectId = config.projectId || "my-rag-app";
11058
+ try {
11059
+ const payload = LicenseVerifier.verify(licenseKey, projectId);
11060
+ return { ok: true, payload };
11061
+ } catch (err) {
11062
+ const message = err instanceof Error ? err.message : "Missing or invalid RETRIVORA_LICENSE_KEY. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or contact your administrator.";
11063
+ const body = {
11064
+ error: {
11065
+ code: "LICENSE_REVOKED",
11066
+ message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
11067
+ },
11068
+ details: message
11069
+ };
11070
+ return {
11071
+ ok: false,
11072
+ response: new Response(JSON.stringify(body), {
11073
+ status: 403,
11074
+ headers: { "Content-Type": "application/json" }
11075
+ })
11076
+ };
11077
+ }
11078
+ }
10649
11079
  var MAX_MESSAGE_LENGTH = 8e3;
10650
11080
  function sanitizeInput(raw) {
10651
11081
  const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
@@ -10667,7 +11097,7 @@ function getOrCreatePlugin(configOrPlugin) {
10667
11097
  return _g[cacheKey];
10668
11098
  }
10669
11099
  function reportTelemetry(req, plugin, action, status, details, trace) {
10670
- var _a2, _b, _c, _d, _e, _f, _g2;
11100
+ var _a3, _b, _c, _d, _e, _f, _g2;
10671
11101
  try {
10672
11102
  const config = plugin.getConfig();
10673
11103
  const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
@@ -10682,7 +11112,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
10682
11112
  absoluteUrl = `${proto}://${host}${telemetryUrl}`;
10683
11113
  }
10684
11114
  const projectId = config.projectId || "default";
10685
- const model = (trace == null ? void 0 : trace.model) || ((_a2 = config.llm) == null ? void 0 : _a2.model) || ((_b = config.embedding) == null ? void 0 : _b.model) || "llama-3.1-8b-instant";
11115
+ const model = (trace == null ? void 0 : trace.model) || ((_a3 = config.llm) == null ? void 0 : _a3.model) || ((_b = config.embedding) == null ? void 0 : _b.model) || "llama-3.1-8b-instant";
10686
11116
  const provider = (trace == null ? void 0 : trace.provider) || ((_c = config.llm) == null ? void 0 : _c.provider) || ((_d = config.embedding) == null ? void 0 : _d.provider) || "groq";
10687
11117
  const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
10688
11118
  const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
@@ -10706,7 +11136,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
10706
11136
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
10707
11137
  details
10708
11138
  };
10709
- console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
10710
11139
  fetch(absoluteUrl, {
10711
11140
  method: "POST",
10712
11141
  headers: {
@@ -10764,14 +11193,39 @@ function createChatHandler(configOrPlugin, options) {
10764
11193
  const storage = new DatabaseStorage(plugin.getConfig());
10765
11194
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10766
11195
  return async function POST(req, context) {
10767
- var _a2, _b, _c, _d;
11196
+ var _a3, _b, _c, _d, _e, _f;
10768
11197
  const authResult = await checkAuth(req, onAuthorize);
10769
11198
  if (authResult) return authResult;
10770
11199
  const rateLimited = checkRateLimit(req);
10771
11200
  if (rateLimited) return rateLimited;
11201
+ const config = plugin.getConfig();
10772
11202
  try {
10773
11203
  const body = await req.json();
10774
11204
  const bodyObj = body != null ? body : {};
11205
+ const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
11206
+ if (!licenseCheck.ok) return licenseCheck.response;
11207
+ if (isFreeTier(licenseCheck.payload.tier)) {
11208
+ const estimatedInputTokens = Math.ceil(
11209
+ ((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
11210
+ var _a4, _b2;
11211
+ return a + (((_a4 = m == null ? void 0 : m.content) == null ? void 0 : _a4.length) || ((_b2 = m == null ? void 0 : m.text) == null ? void 0 : _b2.length) || 0);
11212
+ }, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.reduce((a, m) => {
11213
+ var _a4, _b2;
11214
+ return a + (((_a4 = m == null ? void 0 : m.content) == null ? void 0 : _a4.length) || ((_b2 = m == null ? void 0 : m.text) == null ? void 0 : _b2.length) || 0);
11215
+ }, 0)) || 0)) / 4
11216
+ );
11217
+ const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
11218
+ operationType: "chat",
11219
+ inputTokens: estimatedInputTokens,
11220
+ projectId: licenseCheck.payload.projectId
11221
+ });
11222
+ if (!chatCheck.allowed) {
11223
+ return createPaymentRequiredResponse(
11224
+ chatCheck.reason || "Free tier quota exceeded.",
11225
+ { tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
11226
+ );
11227
+ }
11228
+ }
10775
11229
  let rawMessage = bodyObj.message;
10776
11230
  if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
10777
11231
  const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
@@ -10803,7 +11257,7 @@ function createChatHandler(configOrPlugin, options) {
10803
11257
  uiTransformation: result.ui_transformation,
10804
11258
  trace: result.trace
10805
11259
  }).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
10806
- reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((_b = (_a2 = result.trace) == null ? void 0 : _a2.tokens) == null ? void 0 : _b.totalTokens) || 0}, Latency: ${((_d = (_c = result.trace) == null ? void 0 : _c.latency) == null ? void 0 : _d.totalMs) || 0}ms`, result.trace);
11260
+ reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((_d = (_c = result.trace) == null ? void 0 : _c.tokens) == null ? void 0 : _d.totalTokens) || 0}, Latency: ${((_f = (_e = result.trace) == null ? void 0 : _e.latency) == null ? void 0 : _f.totalMs) || 0}ms`, result.trace);
10807
11261
  return import_server.NextResponse.json(__spreadProps(__spreadValues({}, result), {
10808
11262
  messageId: assistantMsgId,
10809
11263
  userMessageId: userMsgId
@@ -10820,14 +11274,15 @@ function createStreamHandler(configOrPlugin, options) {
10820
11274
  const storage = new DatabaseStorage(plugin.getConfig());
10821
11275
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10822
11276
  return async function POST(req, context) {
10823
- var _a2;
11277
+ var _a3, _b, _c;
10824
11278
  const authResult = await checkAuth(req, onAuthorize);
10825
11279
  if (authResult) return authResult;
10826
11280
  const rateLimited = checkRateLimit(req);
10827
11281
  if (rateLimited) return rateLimited;
11282
+ const config = plugin.getConfig();
10828
11283
  let body;
10829
11284
  try {
10830
- if ((_a2 = req.headers.get("content-type")) == null ? void 0 : _a2.includes("multipart/form-data")) {
11285
+ if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
10831
11286
  const uploader = createUploadHandler(plugin, { onAuthorize });
10832
11287
  return uploader(req);
10833
11288
  }
@@ -10839,6 +11294,30 @@ function createStreamHandler(configOrPlugin, options) {
10839
11294
  });
10840
11295
  }
10841
11296
  const bodyObj = body != null ? body : {};
11297
+ const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
11298
+ if (!licenseCheck.ok) return licenseCheck.response;
11299
+ if (isFreeTier(licenseCheck.payload.tier)) {
11300
+ const estimatedInputTokens = Math.ceil(
11301
+ ((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
11302
+ var _a4, _b2;
11303
+ return a + (((_a4 = m == null ? void 0 : m.content) == null ? void 0 : _a4.length) || ((_b2 = m == null ? void 0 : m.text) == null ? void 0 : _b2.length) || 0);
11304
+ }, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.reduce((a, m) => {
11305
+ var _a4, _b2;
11306
+ return a + (((_a4 = m == null ? void 0 : m.content) == null ? void 0 : _a4.length) || ((_b2 = m == null ? void 0 : m.text) == null ? void 0 : _b2.length) || 0);
11307
+ }, 0)) || 0)) / 4
11308
+ );
11309
+ const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
11310
+ operationType: "chat_stream",
11311
+ inputTokens: estimatedInputTokens,
11312
+ projectId: licenseCheck.payload.projectId
11313
+ });
11314
+ if (!chatCheck.allowed) {
11315
+ return createPaymentRequiredResponse(
11316
+ chatCheck.reason || "Free tier quota exceeded.",
11317
+ { tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
11318
+ );
11319
+ }
11320
+ }
10842
11321
  let rawMessage = bodyObj.message;
10843
11322
  if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
10844
11323
  const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
@@ -10868,7 +11347,7 @@ function createStreamHandler(configOrPlugin, options) {
10868
11347
  let isActive = true;
10869
11348
  const stream = new ReadableStream({
10870
11349
  async start(controller) {
10871
- var _a3, _b, _c, _d, _e;
11350
+ var _a4, _b2, _c2, _d, _e;
10872
11351
  const enqueue = (text) => {
10873
11352
  if (!isActive) return;
10874
11353
  try {
@@ -10901,7 +11380,7 @@ function createStreamHandler(configOrPlugin, options) {
10901
11380
  let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
10902
11381
  if (sources.length > 0) {
10903
11382
  try {
10904
- uiTransformation = (_a3 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a3 : UITransformer.transform(message, sources, plugin.getConfig());
11383
+ uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
10905
11384
  if (uiTransformation) {
10906
11385
  enqueue(sseUIFrame(uiTransformation));
10907
11386
  }
@@ -10925,7 +11404,7 @@ function createStreamHandler(configOrPlugin, options) {
10925
11404
  uiTransformation,
10926
11405
  trace: responseChunk == null ? void 0 : responseChunk.trace
10927
11406
  }).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
10928
- reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((_c = (_b = responseChunk == null ? void 0 : responseChunk.trace) == null ? void 0 : _b.tokens) == null ? void 0 : _c.totalTokens) || 0}, Latency: ${((_e = (_d = responseChunk == null ? void 0 : responseChunk.trace) == null ? void 0 : _d.latency) == null ? void 0 : _e.totalMs) || 0}ms`, responseChunk == null ? void 0 : responseChunk.trace);
11407
+ reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((_c2 = (_b2 = responseChunk == null ? void 0 : responseChunk.trace) == null ? void 0 : _b2.tokens) == null ? void 0 : _c2.totalTokens) || 0}, Latency: ${((_e = (_d = responseChunk == null ? void 0 : responseChunk.trace) == null ? void 0 : _d.latency) == null ? void 0 : _e.totalMs) || 0}ms`, responseChunk == null ? void 0 : responseChunk.trace);
10929
11408
  }
10930
11409
  }
10931
11410
  } catch (temp) {
@@ -10975,12 +11454,36 @@ function createIngestHandler(configOrPlugin, options) {
10975
11454
  return async function POST(req, context) {
10976
11455
  const authResult = await checkAuth(req, onAuthorize);
10977
11456
  if (authResult) return authResult;
11457
+ const config = plugin.getConfig();
10978
11458
  try {
10979
11459
  const body = await req.json();
11460
+ const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
11461
+ if (!licenseCheck.ok) return licenseCheck.response;
10980
11462
  const { documents, namespace } = body;
10981
11463
  if (!Array.isArray(documents) || documents.length === 0) {
10982
11464
  return import_server.NextResponse.json({ error: "documents array is required" }, { status: 400 });
10983
11465
  }
11466
+ if (isFreeTier(licenseCheck.payload.tier)) {
11467
+ const totalIncomingBytes = documents.reduce(
11468
+ (sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
11469
+ 0
11470
+ );
11471
+ const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
11472
+ { documentCount: documents.length },
11473
+ totalIncomingBytes
11474
+ );
11475
+ if (!ingestCheck.allowed) {
11476
+ return createPaymentRequiredResponse(
11477
+ ingestCheck.reason || "Free tier ingestion limit reached.",
11478
+ {
11479
+ tier: licenseCheck.payload.tier,
11480
+ projectId: licenseCheck.payload.projectId,
11481
+ documents: documents.length,
11482
+ incomingBytes: totalIncomingBytes
11483
+ }
11484
+ );
11485
+ }
11486
+ }
10984
11487
  const results = await plugin.ingest(documents, namespace);
10985
11488
  reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
10986
11489
  return import_server.NextResponse.json({ results });
@@ -11017,7 +11520,7 @@ function createLicenseHandler(configOrPlugin, options) {
11017
11520
  const plugin = getOrCreatePlugin(configOrPlugin);
11018
11521
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11019
11522
  return async function POST(req) {
11020
- var _a2;
11523
+ var _a3;
11021
11524
  if (req) {
11022
11525
  const authResult = await checkAuth(req, onAuthorize);
11023
11526
  if (authResult) return authResult;
@@ -11025,7 +11528,7 @@ function createLicenseHandler(configOrPlugin, options) {
11025
11528
  try {
11026
11529
  const body = await req.json().catch(() => ({}));
11027
11530
  const config = plugin.getConfig();
11028
- const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((_a2 = req.headers.get("authorization")) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || config.licenseKey || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || "";
11531
+ const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((_a3 = req.headers.get("authorization")) == null ? void 0 : _a3.replace(/^Bearer\s+/i, "")) || config.licenseKey || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || "";
11029
11532
  const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
11030
11533
  const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
11031
11534
  const payload = LicenseVerifier.verify(licenseKey, projectId);
@@ -11060,6 +11563,9 @@ function createUploadHandler(configOrPlugin, options) {
11060
11563
  return async function POST(req, context) {
11061
11564
  const authResult = await checkAuth(req, onAuthorize);
11062
11565
  if (authResult) return authResult;
11566
+ const config = plugin.getConfig();
11567
+ const licenseCheck = enforceLicense(req, config);
11568
+ if (!licenseCheck.ok) return licenseCheck.response;
11063
11569
  try {
11064
11570
  const formData = await req.formData();
11065
11571
  const files = formData.getAll("files");
@@ -11069,6 +11575,26 @@ function createUploadHandler(configOrPlugin, options) {
11069
11575
  if (!files || files.length === 0) {
11070
11576
  return import_server.NextResponse.json({ error: "No files provided" }, { status: 400 });
11071
11577
  }
11578
+ if (isFreeTier(licenseCheck.payload.tier)) {
11579
+ const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
11580
+ const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
11581
+ { documentCount: files.length },
11582
+ totalUploadBytes
11583
+ );
11584
+ if (!uploadCheck.allowed) {
11585
+ return createPaymentRequiredResponse(
11586
+ uploadCheck.reason || "Free tier upload limit reached.",
11587
+ {
11588
+ tier: licenseCheck.payload.tier,
11589
+ projectId: licenseCheck.payload.projectId,
11590
+ fileCount: files.length,
11591
+ totalUploadBytes,
11592
+ maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
11593
+ maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
11594
+ }
11595
+ );
11596
+ }
11597
+ }
11072
11598
  const documents = [];
11073
11599
  for (const file of files) {
11074
11600
  const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
@@ -11178,13 +11704,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
11178
11704
  return async function handler(req) {
11179
11705
  const authResult = await checkAuth(req, onAuthorize);
11180
11706
  if (authResult) return authResult;
11707
+ const config = plugin.getConfig();
11708
+ const licenseCheck = enforceLicense(req, config);
11709
+ if (!licenseCheck.ok) return licenseCheck.response;
11181
11710
  try {
11182
11711
  let query = "";
11183
11712
  let namespace = void 0;
11713
+ let bodyLicenseKey = void 0;
11184
11714
  if (req.method === "POST") {
11185
11715
  const body = await req.json().catch(() => ({}));
11186
11716
  query = body.query || "";
11187
11717
  namespace = body.namespace;
11718
+ bodyLicenseKey = body.licenseKey;
11719
+ if (bodyLicenseKey) {
11720
+ const recheck = enforceLicense(req, config, bodyLicenseKey);
11721
+ if (!recheck.ok) return recheck.response;
11722
+ }
11188
11723
  } else {
11189
11724
  const url = new URL(req.url);
11190
11725
  query = url.searchParams.get("query") || "";
@@ -11207,14 +11742,16 @@ function createHistoryHandler(configOrPlugin, options) {
11207
11742
  const plugin = getOrCreatePlugin(configOrPlugin);
11208
11743
  const storage = new DatabaseStorage(plugin.getConfig());
11209
11744
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11745
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
11210
11746
  return async function handler(req) {
11211
11747
  const authResult = await checkAuth(req, onAuthorize);
11212
11748
  if (authResult) return authResult;
11749
+ const scope = onResolveScope ? await onResolveScope(req) : void 0;
11213
11750
  const url = new URL(req.url);
11214
11751
  const sessionId = url.searchParams.get("sessionId") || "default";
11215
11752
  if (req.method === "GET") {
11216
11753
  try {
11217
- const history = await storage.getHistory(sessionId);
11754
+ const history = await storage.getHistory(sessionId, scope);
11218
11755
  return import_server.NextResponse.json({ history });
11219
11756
  } catch (err) {
11220
11757
  const message = err instanceof Error ? err.message : "Failed to fetch history";
@@ -11224,7 +11761,7 @@ function createHistoryHandler(configOrPlugin, options) {
11224
11761
  try {
11225
11762
  const body = await req.json().catch(() => ({}));
11226
11763
  const sid = body.sessionId || sessionId;
11227
- await storage.clearHistory(sid);
11764
+ await storage.clearHistory(sid, scope);
11228
11765
  return import_server.NextResponse.json({ success: true });
11229
11766
  } catch (err) {
11230
11767
  const message = err instanceof Error ? err.message : "Failed to clear history";
@@ -11238,18 +11775,20 @@ function createFeedbackHandler(configOrPlugin, options) {
11238
11775
  const plugin = getOrCreatePlugin(configOrPlugin);
11239
11776
  const storage = new DatabaseStorage(plugin.getConfig());
11240
11777
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11778
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
11241
11779
  return async function handler(req) {
11242
11780
  const authResult = await checkAuth(req, onAuthorize);
11243
11781
  if (authResult) return authResult;
11782
+ const scope = onResolveScope ? await onResolveScope(req) : void 0;
11244
11783
  if (req.method === "GET") {
11245
11784
  try {
11246
11785
  const url = new URL(req.url);
11247
11786
  const messageId = url.searchParams.get("messageId");
11248
11787
  if (!messageId) {
11249
- const feedbackList = await storage.listFeedback();
11788
+ const feedbackList = await storage.listFeedback(scope);
11250
11789
  return import_server.NextResponse.json({ feedback: feedbackList });
11251
11790
  }
11252
- const feedback = await storage.getFeedback(messageId);
11791
+ const feedback = await storage.getFeedback(messageId, scope);
11253
11792
  return import_server.NextResponse.json({ feedback });
11254
11793
  } catch (err) {
11255
11794
  const message = err instanceof Error ? err.message : "Failed to fetch feedback";
@@ -11265,6 +11804,17 @@ function createFeedbackHandler(configOrPlugin, options) {
11265
11804
  if (!rating) {
11266
11805
  return import_server.NextResponse.json({ error: "rating is required" }, { status: 400 });
11267
11806
  }
11807
+ if (scope && scope.length > 0) {
11808
+ const matches = scope.some(
11809
+ (pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
11810
+ );
11811
+ if (!matches) {
11812
+ return import_server.NextResponse.json(
11813
+ { error: "sessionId is outside the authorized project scope" },
11814
+ { status: 403 }
11815
+ );
11816
+ }
11817
+ }
11268
11818
  await storage.saveFeedback({ messageId, sessionId, rating, comment });
11269
11819
  return import_server.NextResponse.json({ success: true });
11270
11820
  } catch (err) {
@@ -11279,14 +11829,15 @@ function createSessionsHandler(configOrPlugin, options) {
11279
11829
  const plugin = getOrCreatePlugin(configOrPlugin);
11280
11830
  const storage = new DatabaseStorage(plugin.getConfig());
11281
11831
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11832
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
11282
11833
  return async function GET(req) {
11283
11834
  if (req) {
11284
11835
  const authResult = await checkAuth(req, onAuthorize);
11285
11836
  if (authResult) return authResult;
11286
11837
  }
11287
- void req;
11288
11838
  try {
11289
- const sessions = await storage.listSessions();
11839
+ const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
11840
+ const sessions = await storage.listSessions(scope);
11290
11841
  return import_server.NextResponse.json({ sessions });
11291
11842
  } catch (err) {
11292
11843
  const message = err instanceof Error ? err.message : "Failed to list sessions";
@@ -11297,15 +11848,17 @@ function createSessionsHandler(configOrPlugin, options) {
11297
11848
  function createRagHandler(configOrPlugin, options) {
11298
11849
  const plugin = getOrCreatePlugin(configOrPlugin);
11299
11850
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11300
- const chatHandler = createChatHandler(plugin, { onAuthorize });
11301
- const streamHandler = createStreamHandler(plugin, { onAuthorize });
11302
- const uploadHandler = createUploadHandler(plugin, { onAuthorize });
11303
- const healthHandler = createHealthHandler(plugin, { onAuthorize });
11304
- const suggestionsHandler = createSuggestionsHandler(plugin, { onAuthorize });
11305
- const historyHandler = createHistoryHandler(plugin, { onAuthorize });
11306
- const feedbackHandler = createFeedbackHandler(plugin, { onAuthorize });
11307
- const sessionsHandler = createSessionsHandler(plugin, { onAuthorize });
11308
- const licenseHandler = createLicenseHandler(plugin, { onAuthorize });
11851
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
11852
+ const scopeableOptions = { onAuthorize, onResolveScope };
11853
+ const chatHandler = createChatHandler(plugin, scopeableOptions);
11854
+ const streamHandler = createStreamHandler(plugin, scopeableOptions);
11855
+ const uploadHandler = createUploadHandler(plugin, scopeableOptions);
11856
+ const healthHandler = createHealthHandler(plugin, scopeableOptions);
11857
+ const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
11858
+ const historyHandler = createHistoryHandler(plugin, scopeableOptions);
11859
+ const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
11860
+ const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
11861
+ const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
11309
11862
  async function routePostRequest(req, segment) {
11310
11863
  switch (segment) {
11311
11864
  case "chat":
@@ -11347,7 +11900,7 @@ function createRagHandler(configOrPlugin, options) {
11347
11900
  }
11348
11901
  }
11349
11902
  async function getSegment(req, context) {
11350
- var _a2, _b;
11903
+ var _a3, _b;
11351
11904
  const contentType = req.headers.get("content-type") || "";
11352
11905
  if (contentType.includes("multipart/form-data")) {
11353
11906
  return "upload";
@@ -11364,7 +11917,7 @@ function createRagHandler(configOrPlugin, options) {
11364
11917
  if (pathname.endsWith("/history")) return "history";
11365
11918
  } catch (e) {
11366
11919
  }
11367
- const resolvedParams = typeof ((_a2 = context == null ? void 0 : context.params) == null ? void 0 : _a2.then) === "function" ? await context.params : context == null ? void 0 : context.params;
11920
+ const resolvedParams = typeof ((_a3 = context == null ? void 0 : context.params) == null ? void 0 : _a3.then) === "function" ? await context.params : context == null ? void 0 : context.params;
11368
11921
  const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
11369
11922
  const joined = segments.join("/");
11370
11923
  return joined || "chat";
@@ -11397,6 +11950,7 @@ var _LicenseValidator = class _LicenseValidator {
11397
11950
  constructor() {
11398
11951
  this.cache = /* @__PURE__ */ new Map();
11399
11952
  }
11953
+ /** @returns Singleton instance of the validator (shared cache across all consumers). */
11400
11954
  static getInstance() {
11401
11955
  if (!_LicenseValidator.instance) {
11402
11956
  _LicenseValidator.instance = new _LicenseValidator();
@@ -11404,7 +11958,12 @@ var _LicenseValidator = class _LicenseValidator {
11404
11958
  return _LicenseValidator.instance;
11405
11959
  }
11406
11960
  /**
11407
- * Invalidate local validation cache for a license key
11961
+ * Purge entries from the local success cache.
11962
+ *
11963
+ * @param licenseKey - Optional. If provided, only that key's cache entry is
11964
+ * removed. If omitted the entire cache is cleared.
11965
+ * Callers use this after any 401/403 to ensure the next
11966
+ * validate() call re-validates against the server.
11408
11967
  */
11409
11968
  purgeCache(licenseKey) {
11410
11969
  if (licenseKey) {
@@ -11414,10 +11973,20 @@ var _LicenseValidator = class _LicenseValidator {
11414
11973
  }
11415
11974
  }
11416
11975
  /**
11417
- * Validate license status and SDK version against Retrivora License Service
11976
+ * Primary validation entry-point for UI / hook consumers.
11977
+ *
11978
+ * Resolves the license key, consults the local success cache, performs a
11979
+ * server POST for authoritative status, and falls back to local RSA
11980
+ * signature verification if the server can't be reached.
11981
+ *
11982
+ * @throws LicenseValidationError - When no key is provided OR both the
11983
+ * server call AND the local-RSA fallback report an invalid/expired key.
11984
+ * @throws SDKVersionUnsupportedError - When server reports forceUpgrade=true.
11985
+ * @returns A `LicenseValidationResponse` that the UI can use to enable or
11986
+ * lock the chat widget.
11418
11987
  */
11419
11988
  async validate(request) {
11420
- var _a2;
11989
+ var _a3;
11421
11990
  const {
11422
11991
  licenseKey,
11423
11992
  projectId,
@@ -11435,7 +12004,7 @@ var _LicenseValidator = class _LicenseValidator {
11435
12004
  }
11436
12005
  return void 0;
11437
12006
  };
11438
- const rawKey = licenseKey || getHeader("x-license-key") || ((_a2 = getHeader("authorization")) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
12007
+ const rawKey = licenseKey || getHeader("x-license-key") || ((_a3 = getHeader("authorization")) == null ? void 0 : _a3.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
11439
12008
  const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
11440
12009
  if (!effectiveLicenseKey) {
11441
12010
  this.purgeCache(effectiveLicenseKey);