@retrivora-ai/rag-engine 2.2.9 → 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.
@@ -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) {
@@ -2271,13 +2271,13 @@ var AuthenticationException = class extends RetrivoraError {
2271
2271
  }
2272
2272
  };
2273
2273
  function wrapError(err, defaultCode, defaultMessage) {
2274
- var _a2;
2274
+ var _a3;
2275
2275
  if (err instanceof RetrivoraError) {
2276
2276
  return err;
2277
2277
  }
2278
2278
  const error = err;
2279
2279
  const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
2280
- 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);
2280
+ 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);
2281
2281
  const code = error == null ? void 0 : error.code;
2282
2282
  if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
2283
2283
  return new RateLimitException(message, err);
@@ -2346,7 +2346,8 @@ var LicenseVerifier = class {
2346
2346
  };
2347
2347
  }
2348
2348
  try {
2349
- const rawToken = licenseKey.replace(/^rtv_/i, "").trim();
2349
+ const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
2350
+ const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
2350
2351
  const parts = rawToken.split(".");
2351
2352
  if (parts.length !== 3) {
2352
2353
  throw new Error("Malformed token structure (expected 3 parts).");
@@ -2558,8 +2559,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
2558
2559
 
2559
2560
  // src/config/serverConfig.ts
2560
2561
  function readString(env, name) {
2561
- var _a2;
2562
- const value = (_a2 = env[name]) == null ? void 0 : _a2.trim();
2562
+ var _a3;
2563
+ const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
2563
2564
  return value ? value : void 0;
2564
2565
  }
2565
2566
  function readNumber(env, name, fallback) {
@@ -2572,16 +2573,16 @@ function readNumber(env, name, fallback) {
2572
2573
  return parsed;
2573
2574
  }
2574
2575
  function readEnum(env, name, fallback, allowed) {
2575
- var _a2;
2576
- const value = (_a2 = readString(env, name)) != null ? _a2 : fallback;
2576
+ var _a3;
2577
+ const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
2577
2578
  if (allowed.includes(value)) {
2578
2579
  return value;
2579
2580
  }
2580
2581
  throw new Error(`[getRagConfig] ${name} must be one of: ${allowed.join(", ")}`);
2581
2582
  }
2582
2583
  function getEnvConfig(env = process.env, base) {
2583
- 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;
2584
- 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;
2584
+ 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;
2585
+ 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;
2585
2586
  const jwtProjectId = (() => {
2586
2587
  if (!licenseKey) return void 0;
2587
2588
  try {
@@ -2662,7 +2663,7 @@ function getEnvConfig(env = process.env, base) {
2662
2663
  rest: "default",
2663
2664
  custom: "default"
2664
2665
  };
2665
- const isFreeTier = (() => {
2666
+ const isFreeTier2 = (() => {
2666
2667
  if (!licenseKey) return true;
2667
2668
  try {
2668
2669
  const payload = LicenseVerifier.verify(licenseKey, projectId);
@@ -2673,13 +2674,13 @@ function getEnvConfig(env = process.env, base) {
2673
2674
  }
2674
2675
  })();
2675
2676
  const defaultGatewayUrl = (_ra = (_qa = readString(env, "LITELLM_BASE_URL")) != null ? _qa : readString(env, "LLM_BASE_URL")) != null ? _ra : "https://www.retrivora.com/api/v1";
2676
- const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
2677
+ const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
2677
2678
  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;
2678
2679
  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;
2679
- 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";
2680
+ 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";
2680
2681
  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;
2681
2682
  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";
2682
- const defaultEmbeddingProvider = isFreeTier ? "universal_rest" : "universal_rest";
2683
+ const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
2683
2684
  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;
2684
2685
  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;
2685
2686
  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";
@@ -2769,8 +2770,8 @@ function getEnvConfig(env = process.env, base) {
2769
2770
  }
2770
2771
  } : {}), {
2771
2772
  mcpServers: (() => {
2772
- var _a3;
2773
- const raw = (_a3 = readString(env, "MCP_SERVERS")) != null ? _a3 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
2773
+ var _a4;
2774
+ const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
2774
2775
  if (!raw) return void 0;
2775
2776
  try {
2776
2777
  return JSON.parse(raw);
@@ -2815,10 +2816,10 @@ var ConfigResolver = class {
2815
2816
  * fallback behavior.
2816
2817
  */
2817
2818
  static resolveUniversal(hostConfig, env = process.env) {
2818
- var _a2;
2819
+ var _a3;
2819
2820
  if (!hostConfig) return this.resolve(void 0, env);
2820
2821
  const normalized = __spreadProps(__spreadValues({}, hostConfig), {
2821
- vectorDb: (_a2 = hostConfig.vectorDb) != null ? _a2 : hostConfig.vectorDatabase,
2822
+ vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
2822
2823
  rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
2823
2824
  });
2824
2825
  return this.resolve(normalized, env);
@@ -2838,11 +2839,11 @@ var ConfigResolver = class {
2838
2839
  }
2839
2840
  }
2840
2841
  static mergeRetrievalWorkflow(rag, retrieval, workflow) {
2841
- var _a2, _b, _c, _d, _e, _f;
2842
+ var _a3, _b, _c, _d, _e, _f;
2842
2843
  if (!rag && !retrieval && !workflow) return void 0;
2843
2844
  const normalized = __spreadValues({}, rag != null ? rag : {});
2844
2845
  if (retrieval) {
2845
- normalized.topK = (_a2 = retrieval.topK) != null ? _a2 : normalized.topK;
2846
+ normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
2846
2847
  normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
2847
2848
  normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
2848
2849
  if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
@@ -2970,8 +2971,8 @@ var OpenAIProvider = class {
2970
2971
  };
2971
2972
  }
2972
2973
  async chat(messages, context, options) {
2973
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
2974
- 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.";
2974
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
2975
+ 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.";
2975
2976
  const systemMessage = {
2976
2977
  role: "system",
2977
2978
  content: buildSystemContent(basePrompt, context)
@@ -2995,8 +2996,8 @@ var OpenAIProvider = class {
2995
2996
  }
2996
2997
  chatStream(messages, context, options) {
2997
2998
  return __asyncGenerator(this, null, function* () {
2998
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
2999
- 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.";
2999
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3000
+ 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.";
3000
3001
  const systemMessage = {
3001
3002
  role: "system",
3002
3003
  content: buildSystemContent(basePrompt, context)
@@ -3043,8 +3044,8 @@ var OpenAIProvider = class {
3043
3044
  return results[0];
3044
3045
  }
3045
3046
  async batchEmbed(texts, options) {
3046
- var _a2, _b, _c, _d, _e;
3047
- 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";
3047
+ var _a3, _b, _c, _d, _e;
3048
+ 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";
3048
3049
  const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
3049
3050
  const client = apiKey !== this.llmConfig.apiKey ? new import_openai.default({ apiKey }) : this.client;
3050
3051
  const response = await client.embeddings.create({ model, input: texts });
@@ -3121,8 +3122,8 @@ var AnthropicProvider = class {
3121
3122
  };
3122
3123
  }
3123
3124
  async chat(messages, context, options) {
3124
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3125
- 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.";
3125
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3126
+ 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.";
3126
3127
  const system = buildSystemContent(basePrompt, context);
3127
3128
  const anthropicMessages = messages.map((m) => ({
3128
3129
  role: m.role === "assistant" ? "assistant" : "user",
@@ -3160,8 +3161,8 @@ var AnthropicProvider = class {
3160
3161
  }
3161
3162
  chatStream(messages, context, options) {
3162
3163
  return __asyncGenerator(this, null, function* () {
3163
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3164
- 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.";
3164
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3165
+ 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.";
3165
3166
  const system = buildSystemContent(basePrompt, context);
3166
3167
  const anthropicMessages = messages.map((m) => ({
3167
3168
  role: m.role === "assistant" ? "assistant" : "user",
@@ -3245,8 +3246,8 @@ var AnthropicProvider = class {
3245
3246
  var import_axios = __toESM(require("axios"));
3246
3247
  var OllamaProvider = class {
3247
3248
  constructor(llmConfig, embeddingConfig) {
3248
- var _a2, _b, _c;
3249
- const rawBaseURL = ((_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434").replace(/\/+$/, "");
3249
+ var _a3, _b, _c;
3250
+ const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
3250
3251
  const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
3251
3252
  const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
3252
3253
  const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
@@ -3306,8 +3307,8 @@ var OllamaProvider = class {
3306
3307
  };
3307
3308
  }
3308
3309
  async chat(messages, context, options) {
3309
- var _a2, _b, _c, _d, _e, _f;
3310
- 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.";
3310
+ var _a3, _b, _c, _d, _e, _f;
3311
+ 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.";
3311
3312
  const system = buildSystemContent(basePrompt, context);
3312
3313
  const { data } = await this.http.post("/api/chat", {
3313
3314
  model: this.llmConfig.model,
@@ -3325,8 +3326,8 @@ var OllamaProvider = class {
3325
3326
  }
3326
3327
  chatStream(messages, context, options) {
3327
3328
  return __asyncGenerator(this, null, function* () {
3328
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3329
- 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.";
3329
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3330
+ 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.";
3330
3331
  const system = buildSystemContent(basePrompt, context);
3331
3332
  const response = yield new __await(this.http.post("/api/chat", {
3332
3333
  model: this.llmConfig.model,
@@ -3384,8 +3385,8 @@ var OllamaProvider = class {
3384
3385
  });
3385
3386
  }
3386
3387
  async embed(text, options) {
3387
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3388
- 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";
3388
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3389
+ 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";
3389
3390
  const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
3390
3391
  const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? import_axios.default.create({ baseURL, timeout: 6e4 }) : this.http;
3391
3392
  let prompt = text;
@@ -3486,9 +3487,9 @@ var GeminiProvider = class {
3486
3487
  static getHealthChecker() {
3487
3488
  return {
3488
3489
  async check(config) {
3489
- var _a2, _b;
3490
+ var _a3, _b;
3490
3491
  const timestamp = Date.now();
3491
- const apiKey = (_b = (_a2 = config.apiKey) != null ? _a2 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
3492
+ const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
3492
3493
  const modelName = sanitizeModel(config.model);
3493
3494
  try {
3494
3495
  const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
@@ -3518,16 +3519,16 @@ var GeminiProvider = class {
3518
3519
  /** Resolve the embedding client — uses a separate client when the embedding
3519
3520
  * API key differs from the LLM API key. */
3520
3521
  get embeddingClient() {
3521
- var _a2;
3522
- if (((_a2 = this.embeddingConfig) == null ? void 0 : _a2.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3522
+ var _a3;
3523
+ if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3523
3524
  return buildClient(this.embeddingConfig.apiKey);
3524
3525
  }
3525
3526
  return this.client;
3526
3527
  }
3527
3528
  /** Resolve the embedding model to use, in order of specificity. */
3528
3529
  resolveEmbeddingModel(optionsModel) {
3529
- var _a2, _b;
3530
- return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a2 = this.embeddingConfig) == null ? void 0 : _a2.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3530
+ var _a3, _b;
3531
+ return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3531
3532
  }
3532
3533
  /**
3533
3534
  * Convert ChatMessage[] to the Gemini contents format.
@@ -3547,8 +3548,8 @@ var GeminiProvider = class {
3547
3548
  // ILLMProvider — chat
3548
3549
  // -------------------------------------------------------------------------
3549
3550
  async chat(messages, context, options) {
3550
- var _a2, _b, _c, _d, _e, _f;
3551
- 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.";
3551
+ var _a3, _b, _c, _d, _e, _f;
3552
+ 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.";
3552
3553
  const model = this.client.getGenerativeModel({
3553
3554
  model: this.llmConfig.model,
3554
3555
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3565,8 +3566,8 @@ var GeminiProvider = class {
3565
3566
  }
3566
3567
  chatStream(messages, context, options) {
3567
3568
  return __asyncGenerator(this, null, function* () {
3568
- var _a2, _b, _c, _d, _e, _f;
3569
- 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.";
3569
+ var _a3, _b, _c, _d, _e, _f;
3570
+ 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.";
3570
3571
  const model = this.client.getGenerativeModel({
3571
3572
  model: this.llmConfig.model,
3572
3573
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3601,11 +3602,11 @@ var GeminiProvider = class {
3601
3602
  // ILLMProvider — embeddings
3602
3603
  // -------------------------------------------------------------------------
3603
3604
  async embed(text, options) {
3604
- var _a2, _b;
3605
+ var _a3, _b;
3605
3606
  const content = applyPrefix(
3606
3607
  text,
3607
3608
  options == null ? void 0 : options.taskType,
3608
- (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3609
+ (_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
3609
3610
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3610
3611
  );
3611
3612
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
@@ -3622,7 +3623,7 @@ var GeminiProvider = class {
3622
3623
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
3623
3624
  const model = this.embeddingClient.getGenerativeModel({ model: modelName });
3624
3625
  const requests = texts.map((text) => {
3625
- var _a2, _b;
3626
+ var _a3, _b;
3626
3627
  return {
3627
3628
  content: {
3628
3629
  role: "user",
@@ -3630,7 +3631,7 @@ var GeminiProvider = class {
3630
3631
  text: applyPrefix(
3631
3632
  text,
3632
3633
  options == null ? void 0 : options.taskType,
3633
- (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3634
+ (_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
3634
3635
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3635
3636
  )
3636
3637
  }]
@@ -3647,8 +3648,8 @@ var GeminiProvider = class {
3647
3648
  throw err;
3648
3649
  });
3649
3650
  return response.embeddings.map((e) => {
3650
- var _a2;
3651
- return (_a2 = e.values) != null ? _a2 : [];
3651
+ var _a3;
3652
+ return (_a3 = e.values) != null ? _a3 : [];
3652
3653
  });
3653
3654
  }
3654
3655
  // -------------------------------------------------------------------------
@@ -3737,8 +3738,8 @@ var GroqProvider = class {
3737
3738
  };
3738
3739
  }
3739
3740
  async chat(messages, context, options) {
3740
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3741
- 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.";
3741
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
3742
+ 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.";
3742
3743
  const systemMessage = {
3743
3744
  role: "system",
3744
3745
  content: buildSystemContent(basePrompt, context)
@@ -3762,8 +3763,8 @@ var GroqProvider = class {
3762
3763
  }
3763
3764
  chatStream(messages, context, options) {
3764
3765
  return __asyncGenerator(this, null, function* () {
3765
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3766
- 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.";
3766
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3767
+ 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.";
3767
3768
  const systemMessage = {
3768
3769
  role: "system",
3769
3770
  content: buildSystemContent(basePrompt, context)
@@ -3897,8 +3898,8 @@ var QwenProvider = class {
3897
3898
  };
3898
3899
  }
3899
3900
  async chat(messages, context, options) {
3900
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3901
- 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.";
3901
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
3902
+ 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.";
3902
3903
  const systemMessage = {
3903
3904
  role: "system",
3904
3905
  content: buildSystemContent(basePrompt, context)
@@ -3922,8 +3923,8 @@ var QwenProvider = class {
3922
3923
  }
3923
3924
  chatStream(messages, context, options) {
3924
3925
  return __asyncGenerator(this, null, function* () {
3925
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3926
- 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.";
3926
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3927
+ 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.";
3927
3928
  const systemMessage = {
3928
3929
  role: "system",
3929
3930
  content: buildSystemContent(basePrompt, context)
@@ -3970,8 +3971,8 @@ var QwenProvider = class {
3970
3971
  return results[0];
3971
3972
  }
3972
3973
  async batchEmbed(texts, options) {
3973
- var _a2, _b, _c, _d, _e, _f;
3974
- 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";
3974
+ var _a3, _b, _c, _d, _e, _f;
3975
+ 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";
3975
3976
  const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
3976
3977
  const client = apiKey !== this.llmConfig.apiKey ? new import_openai3.default({
3977
3978
  apiKey,
@@ -4032,9 +4033,9 @@ var LLM_PROFILES = {
4032
4033
 
4033
4034
  // src/llm/providers/UniversalLLMAdapter.ts
4034
4035
  function extractContent(obj) {
4035
- var _a2, _b, _c;
4036
+ var _a3, _b, _c;
4036
4037
  if (!obj || typeof obj !== "object") return void 0;
4037
- const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
4038
+ const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
4038
4039
  if (!choice) return void 0;
4039
4040
  if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
4040
4041
  if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
@@ -4044,10 +4045,10 @@ function extractContent(obj) {
4044
4045
  }
4045
4046
  var UniversalLLMAdapter = class {
4046
4047
  constructor(config) {
4047
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
4048
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
4048
4049
  this.model = config.model;
4049
4050
  const llmConfig = config;
4050
- const options = (_a2 = llmConfig.options) != null ? _a2 : {};
4051
+ const options = (_a3 = llmConfig.options) != null ? _a3 : {};
4051
4052
  let profile = {};
4052
4053
  if (typeof options.profile === "string") {
4053
4054
  profile = LLM_PROFILES[options.profile] || {};
@@ -4073,8 +4074,8 @@ var UniversalLLMAdapter = class {
4073
4074
  });
4074
4075
  }
4075
4076
  async chat(messages, context) {
4076
- var _a2, _b, _c, _d, _e;
4077
- const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4077
+ var _a3, _b, _c, _d, _e;
4078
+ const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
4078
4079
  const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
4079
4080
  role: m.role || "user",
4080
4081
  content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
@@ -4140,8 +4141,8 @@ ${context != null ? context : "None"}` },
4140
4141
  */
4141
4142
  chatStream(messages, context) {
4142
4143
  return __asyncGenerator(this, null, function* () {
4143
- var _a2, _b, _c, _d, _e, _f;
4144
- const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4144
+ var _a3, _b, _c, _d, _e, _f;
4145
+ const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
4145
4146
  const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
4146
4147
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
4147
4148
  const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
@@ -4267,8 +4268,8 @@ ${context != null ? context : "None"}` },
4267
4268
  });
4268
4269
  }
4269
4270
  async embed(text) {
4270
- var _a2, _b, _c, _d, _e;
4271
- const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
4271
+ var _a3, _b, _c, _d, _e;
4272
+ const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
4272
4273
  const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
4273
4274
  try {
4274
4275
  const { data: data2 } = await this.http.post(path2, payload);
@@ -4357,7 +4358,7 @@ var LLMFactory = class _LLMFactory {
4357
4358
  ];
4358
4359
  }
4359
4360
  static create(llmConfig, embeddingConfig) {
4360
- var _a2, _b, _c;
4361
+ var _a3, _b, _c;
4361
4362
  switch (llmConfig.provider) {
4362
4363
  case "openai":
4363
4364
  return new OpenAIProvider(llmConfig, embeddingConfig);
@@ -4376,7 +4377,7 @@ var LLMFactory = class _LLMFactory {
4376
4377
  case "custom":
4377
4378
  return new UniversalLLMAdapter(llmConfig);
4378
4379
  default: {
4379
- const providerName = String((_a2 = llmConfig.provider) != null ? _a2 : "").toLowerCase();
4380
+ const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
4380
4381
  const customFactory = customProviders.get(providerName);
4381
4382
  if (customFactory) {
4382
4383
  return customFactory(llmConfig);
@@ -4478,7 +4479,7 @@ var ProviderRegistry = class {
4478
4479
  return null;
4479
4480
  }
4480
4481
  static async loadVectorProviderClass(provider) {
4481
- var _a2;
4482
+ var _a3;
4482
4483
  if (this.vectorProviders[provider]) return this.vectorProviders[provider];
4483
4484
  switch (provider) {
4484
4485
  case "pinecone": {
@@ -4487,7 +4488,7 @@ var ProviderRegistry = class {
4487
4488
  }
4488
4489
  case "pgvector":
4489
4490
  case "postgresql": {
4490
- const postgresMode = ((_a2 = process.env.POSTGRES_MODE) != null ? _a2 : "multi").toLowerCase();
4491
+ const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
4491
4492
  if (postgresMode === "single") {
4492
4493
  const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
4493
4494
  return PostgreSQLProvider2;
@@ -4710,7 +4711,7 @@ var ConfigValidator = class {
4710
4711
  // package.json
4711
4712
  var package_default = {
4712
4713
  name: "@retrivora-ai/rag-engine",
4713
- version: "2.2.9",
4714
+ version: "2.3.1",
4714
4715
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
4715
4716
  author: "Abhinav Alkuchi",
4716
4717
  license: "UNLICENSED",
@@ -5015,8 +5016,8 @@ var Reranker = class {
5015
5016
  return matches.sort((a, b) => b.score - a.score).slice(0, limit);
5016
5017
  }
5017
5018
  const scoredMatches = matches.map((match) => {
5018
- var _a2;
5019
- const contentLower = ((_a2 = match == null ? void 0 : match.content) != null ? _a2 : "").toLowerCase();
5019
+ var _a3;
5020
+ const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
5020
5021
  let keywordScore = 0;
5021
5022
  keywords.forEach((keyword) => {
5022
5023
  if (contentLower.includes(keyword)) {
@@ -5038,8 +5039,8 @@ var Reranker = class {
5038
5039
 
5039
5040
  Documents:
5040
5041
  ${topN.map((m, i) => {
5041
- var _a2;
5042
- return `[${i}] ${((_a2 = m == null ? void 0 : m.content) != null ? _a2 : "").replace(/\n/g, " ")}`;
5042
+ var _a3;
5043
+ return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
5043
5044
  }).join("\n")}` }],
5044
5045
  "",
5045
5046
  {
@@ -5083,11 +5084,11 @@ var LlamaIndexIngestor = class {
5083
5084
  * than standard character-count splitting.
5084
5085
  */
5085
5086
  async chunk(text, options = {}) {
5086
- var _a2, _b;
5087
+ var _a3, _b;
5087
5088
  try {
5088
5089
  const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
5089
5090
  const splitter = new SentenceSplitter({
5090
- chunkSize: (_a2 = options.chunkSize) != null ? _a2 : 1e3,
5091
+ chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
5091
5092
  chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
5092
5093
  });
5093
5094
  const doc = new Document({ text, metadata: options.metadata || {} });
@@ -5196,7 +5197,7 @@ ${error instanceof Error ? error.message : String(error)}`
5196
5197
  * The agent returns `{ messages: [...] }` — the last message is the final answer.
5197
5198
  */
5198
5199
  async run(input, chatHistory = []) {
5199
- var _a2, _b, _c;
5200
+ var _a3, _b, _c;
5200
5201
  if (!this.agent) {
5201
5202
  throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
5202
5203
  }
@@ -5207,7 +5208,7 @@ ${error instanceof Error ? error.message : String(error)}`
5207
5208
  const response = await this.agent.invoke({
5208
5209
  messages: [...historyMessages, new HumanMessage(input)]
5209
5210
  });
5210
- const lastMessage = (_a2 = response == null ? void 0 : response.messages) == null ? void 0 : _a2.at(-1);
5211
+ const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
5211
5212
  if (lastMessage && typeof lastMessage.content === "string") {
5212
5213
  return lastMessage.content;
5213
5214
  }
@@ -5259,7 +5260,7 @@ var MCPClient = class {
5259
5260
  }
5260
5261
  }
5261
5262
  async connectStdio() {
5262
- var _a2;
5263
+ var _a3;
5263
5264
  const cmd = this.config.command;
5264
5265
  if (!cmd) {
5265
5266
  throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
@@ -5274,7 +5275,7 @@ var MCPClient = class {
5274
5275
  this.stdioBuffer += data.toString("utf-8");
5275
5276
  this.processStdioLines();
5276
5277
  });
5277
- (_a2 = this.childProcess.stderr) == null ? void 0 : _a2.on("data", (data) => {
5278
+ (_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
5278
5279
  console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
5279
5280
  });
5280
5281
  this.childProcess.on("close", (code) => {
@@ -5349,14 +5350,14 @@ var MCPClient = class {
5349
5350
  }
5350
5351
  }
5351
5352
  async sendNotification(method, params) {
5352
- var _a2;
5353
+ var _a3;
5353
5354
  const notification = {
5354
5355
  jsonrpc: "2.0",
5355
5356
  method,
5356
5357
  params
5357
5358
  };
5358
5359
  if (this.config.transport === "stdio") {
5359
- if ((_a2 = this.childProcess) == null ? void 0 : _a2.stdin) {
5360
+ if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
5360
5361
  this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
5361
5362
  }
5362
5363
  } else if (this.sseUrl) {
@@ -5434,11 +5435,11 @@ var MCPRegistry = class {
5434
5435
  // src/core/MultiAgentCoordinator.ts
5435
5436
  var MultiAgentCoordinator = class {
5436
5437
  constructor(options) {
5437
- var _a2;
5438
+ var _a3;
5438
5439
  this.llmProvider = options.llmProvider;
5439
5440
  this.mcpRegistry = options.mcpRegistry;
5440
5441
  this.documentSearch = options.documentSearch;
5441
- this.maxIterations = (_a2 = options.maxIterations) != null ? _a2 : 5;
5442
+ this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
5442
5443
  }
5443
5444
  /**
5444
5445
  * Run the multi-agent coordination loop synchronously and return the final response.
@@ -5490,8 +5491,8 @@ Available Tools:
5490
5491
 
5491
5492
  ${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
5492
5493
  ${mcpTools.map((mt) => {
5493
- var _a2;
5494
- return `- ${mt.tool.name}(${JSON.stringify(((_a2 = mt.tool.inputSchema) == null ? void 0 : _a2.properties) || {})}): ${mt.tool.description || "No description provided."}`;
5494
+ var _a3;
5495
+ return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
5495
5496
  }).join("\n")}
5496
5497
 
5497
5498
  Tool Calling Protocol:
@@ -5649,6 +5650,100 @@ ${toolResultText}`
5649
5650
  }
5650
5651
  };
5651
5652
 
5653
+ // src/core/CircuitBreaker.ts
5654
+ var CircuitBreaker = class {
5655
+ constructor(options = {}) {
5656
+ this.state = "closed";
5657
+ this.failureCount = 0;
5658
+ this.successCount = 0;
5659
+ this.lastFailureAt = 0;
5660
+ this.halfOpenCalls = 0;
5661
+ var _a3, _b, _c;
5662
+ this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
5663
+ this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
5664
+ this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
5665
+ }
5666
+ record(success) {
5667
+ const now = Date.now();
5668
+ if (success) {
5669
+ this.successCount++;
5670
+ if (this.state === "half-open") {
5671
+ this.state = "closed";
5672
+ this.failureCount = 0;
5673
+ this.halfOpenCalls = 0;
5674
+ this.successCount = 1;
5675
+ } else if (this.state === "closed") {
5676
+ if (this.successCount >= this.failureThreshold) {
5677
+ this.failureCount = Math.max(0, this.failureCount - 1);
5678
+ this.successCount = 0;
5679
+ }
5680
+ }
5681
+ } else {
5682
+ this.failureCount++;
5683
+ this.lastFailureAt = now;
5684
+ this.successCount = 0;
5685
+ if (this.state === "half-open") {
5686
+ this.state = "open";
5687
+ this.halfOpenCalls = 0;
5688
+ } else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
5689
+ this.state = "open";
5690
+ }
5691
+ }
5692
+ }
5693
+ canExecute() {
5694
+ const now = Date.now();
5695
+ if (this.state === "closed") {
5696
+ return true;
5697
+ }
5698
+ if (this.state === "open") {
5699
+ if (now - this.lastFailureAt >= this.resetTimeoutMs) {
5700
+ this.state = "half-open";
5701
+ this.halfOpenCalls = 0;
5702
+ return true;
5703
+ }
5704
+ return false;
5705
+ }
5706
+ if (this.state === "half-open") {
5707
+ return this.halfOpenCalls < this.halfOpenMaxCalls;
5708
+ }
5709
+ return true;
5710
+ }
5711
+ async wrap(fn) {
5712
+ if (!this.canExecute()) {
5713
+ const retryAfterSec = Math.ceil(
5714
+ Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
5715
+ );
5716
+ throw new Error(
5717
+ `Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
5718
+ );
5719
+ }
5720
+ if (this.state === "half-open") {
5721
+ this.halfOpenCalls++;
5722
+ }
5723
+ try {
5724
+ const result = await fn();
5725
+ this.record(true);
5726
+ return result;
5727
+ } catch (err) {
5728
+ this.record(false);
5729
+ throw err;
5730
+ }
5731
+ }
5732
+ getState() {
5733
+ return this.state;
5734
+ }
5735
+ getFailureCount() {
5736
+ return this.failureCount;
5737
+ }
5738
+ reset() {
5739
+ this.state = "closed";
5740
+ this.failureCount = 0;
5741
+ this.successCount = 0;
5742
+ this.lastFailureAt = 0;
5743
+ this.halfOpenCalls = 0;
5744
+ }
5745
+ };
5746
+
5652
5747
  // src/core/BatchProcessor.ts
5653
5748
  function isTransientError(error) {
5654
5749
  if (!(error instanceof Error)) return false;
@@ -5672,7 +5767,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
5672
5767
  function sleep(ms) {
5673
5768
  return new Promise((resolve) => setTimeout(resolve, ms));
5674
5769
  }
5675
- var BatchProcessor = class {
5770
+ var _BatchProcessor = class _BatchProcessor {
5771
+ /**
5772
+ * Execute a processor call through the circuit breaker.
5773
+ * Only transient failures count toward opening the circuit.
5774
+ */
5775
+ static async executeWithCircuitBreaker(processor) {
5776
+ if (!this.cb.canExecute()) {
5777
+ const retryAfterSec = Math.ceil(
5778
+ Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
5779
+ );
5780
+ throw new Error(
5781
+ `[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
5782
+ );
5783
+ }
5784
+ if (this.cb.state === "half-open") {
5785
+ this.cb.halfOpenCalls++;
5786
+ }
5787
+ try {
5788
+ const result = await processor();
5789
+ this.cb.record(true);
5790
+ return result;
5791
+ } catch (err) {
5792
+ if (isTransientError(err)) {
5793
+ this.cb.record(false);
5794
+ }
5795
+ throw err;
5796
+ }
5797
+ }
5676
5798
  /**
5677
5799
  * Processes an array of items in configurable batches with retry logic.
5678
5800
  *
@@ -5713,7 +5835,7 @@ var BatchProcessor = class {
5713
5835
  let lastError;
5714
5836
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
5715
5837
  try {
5716
- const result = await processor(batch);
5838
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
5717
5839
  results.push(result);
5718
5840
  success = true;
5719
5841
  break;
@@ -5771,7 +5893,7 @@ ${errorMessages}`
5771
5893
  let lastError;
5772
5894
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
5773
5895
  try {
5774
- const result = await processor(item);
5896
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
5775
5897
  results.push(result);
5776
5898
  success = true;
5777
5899
  break;
@@ -5844,7 +5966,7 @@ ${errorMessages}`
5844
5966
  }));
5845
5967
  const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
5846
5968
  try {
5847
- const result = await processor(item);
5969
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
5848
5970
  return { success: true, result, index: originalIndex };
5849
5971
  } catch (err) {
5850
5972
  const error = err instanceof Error ? err : new Error(String(err));
@@ -5872,6 +5994,12 @@ ${errorMessages}`
5872
5994
  return { results, errors, totalProcessed, totalFailed };
5873
5995
  }
5874
5996
  };
5997
+ _BatchProcessor.cb = new CircuitBreaker({
5998
+ failureThreshold: 5,
5999
+ resetTimeoutMs: 3e4,
6000
+ halfOpenMaxCalls: 1
6001
+ });
6002
+ var BatchProcessor = _BatchProcessor;
5875
6003
 
5876
6004
  // src/config/EmbeddingStrategy.ts
5877
6005
  var EmbeddingStrategyResolver = class {
@@ -5969,7 +6097,7 @@ var QueryProcessor = class {
5969
6097
  * @param validFields Optional list of known filterable fields to look for
5970
6098
  */
5971
6099
  static extractQueryFieldHints(question, validFields = []) {
5972
- var _a2, _b, _c, _d;
6100
+ var _a3, _b, _c, _d;
5973
6101
  if (!question.trim()) return [];
5974
6102
  const hints = /* @__PURE__ */ new Map();
5975
6103
  const addHint = (value, field) => {
@@ -6049,7 +6177,7 @@ var QueryProcessor = class {
6049
6177
  ];
6050
6178
  for (const p of universalPatterns) {
6051
6179
  for (const match of question.matchAll(p.regex)) {
6052
- const val = p.group ? (_a2 = match[p.group]) != null ? _a2 : match[0] : match[0];
6180
+ const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
6053
6181
  if (!val) continue;
6054
6182
  if (p.field) addHint(val, p.field);
6055
6183
  else addHint(val);
@@ -6273,11 +6401,11 @@ var LLMRouter = class {
6273
6401
  * When provided it is used directly as the 'default' role without re-constructing.
6274
6402
  */
6275
6403
  async initialize(prebuiltDefault) {
6276
- var _a2;
6404
+ var _a3;
6277
6405
  const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
6278
6406
  this.models.set("default", defaultModel);
6279
6407
  const envFastModel = process.env.FAST_LLM_MODEL;
6280
- const providerFastDefault = (_a2 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a2 : "";
6408
+ const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
6281
6409
  const fastModelName = envFastModel || providerFastDefault;
6282
6410
  if (fastModelName && fastModelName !== this.config.llm.model) {
6283
6411
  console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
@@ -6296,8 +6424,8 @@ var LLMRouter = class {
6296
6424
  * Falls back to 'default' if the requested role is not registered.
6297
6425
  */
6298
6426
  get(role) {
6299
- var _a2;
6300
- const provider = (_a2 = this.models.get(role)) != null ? _a2 : this.models.get("default");
6427
+ var _a3;
6428
+ const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
6301
6429
  if (!provider) {
6302
6430
  throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
6303
6431
  }
@@ -6383,8 +6511,8 @@ var IntentClassifier = class {
6383
6511
  numericFieldCount = numericKeys.size;
6384
6512
  categoricalFieldCount = catKeys.size;
6385
6513
  if (productKeyMatches >= 2 || docs.some((d) => {
6386
- var _a2, _b;
6387
- 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");
6514
+ var _a3, _b;
6515
+ 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");
6388
6516
  })) {
6389
6517
  isProductLike = true;
6390
6518
  }
@@ -6666,8 +6794,8 @@ var TextRendererStrategy = class {
6666
6794
  }
6667
6795
  const docs = Array.isArray(data) ? data : [];
6668
6796
  const text = docs.map((d) => {
6669
- var _a2;
6670
- return (_a2 = d == null ? void 0 : d.content) != null ? _a2 : "";
6797
+ var _a3;
6798
+ return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
6671
6799
  }).join("\n\n");
6672
6800
  return { type: "text", title, data: { content: text || "No detailed content available." } };
6673
6801
  }
@@ -6810,9 +6938,9 @@ var LRUDecisionCache = class {
6810
6938
  this.maxSize = maxSize;
6811
6939
  }
6812
6940
  generateKey(context) {
6813
- var _a2, _b;
6941
+ var _a3, _b;
6814
6942
  const q = (context.userQuery || "").toLowerCase().trim();
6815
- const docCount = (_b = (_a2 = context.retrievedDocuments) == null ? void 0 : _a2.length) != null ? _b : 0;
6943
+ const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
6816
6944
  return `${q}::docs:${docCount}`;
6817
6945
  }
6818
6946
  get(context) {
@@ -6913,7 +7041,7 @@ var UITransformer = class _UITransformer {
6913
7041
  * Prefer `analyzeAndDecide()` in production.
6914
7042
  */
6915
7043
  static transform(userQuery, retrievedData, config, trainedSchema, intent) {
6916
- var _a2, _b, _c;
7044
+ var _a3, _b, _c;
6917
7045
  if (!retrievedData || retrievedData.length === 0) {
6918
7046
  return this.createTextResponse("No data available", "No relevant data found for your query.");
6919
7047
  }
@@ -6933,7 +7061,7 @@ var UITransformer = class _UITransformer {
6933
7061
  return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
6934
7062
  }
6935
7063
  if (resolvedIntent.visualizationHint === "distribution") {
6936
- return (_a2 = this.transformToHistogram(profile, userQuery)) != null ? _a2 : this.transformToBarChart(filteredData, profile, userQuery);
7064
+ return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
6937
7065
  }
6938
7066
  if (resolvedIntent.visualizationHint === "correlation") {
6939
7067
  return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
@@ -7266,11 +7394,11 @@ ${schemaProfileText}` : ""}`;
7266
7394
  };
7267
7395
  }
7268
7396
  static transformToPieChart(data, profile, query = "") {
7269
- var _a2;
7397
+ var _a3;
7270
7398
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
7271
7399
  const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
7272
- var _a3;
7273
- return String((_a3 = record.fields[dimension.key]) != null ? _a3 : "");
7400
+ var _a4;
7401
+ return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
7274
7402
  }).filter(Boolean))) : this.detectCategories(data);
7275
7403
  if (categories.length === 0) return null;
7276
7404
  const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
@@ -7280,7 +7408,7 @@ ${schemaProfileText}` : ""}`;
7280
7408
  });
7281
7409
  return {
7282
7410
  type: "pie_chart",
7283
- title: `Distribution by ${(_a2 = dimension == null ? void 0 : dimension.label) != null ? _a2 : "Category"}`,
7411
+ title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
7284
7412
  description: `Showing breakdown across ${pieData.length} categories`,
7285
7413
  data: pieData
7286
7414
  };
@@ -7290,8 +7418,8 @@ ${schemaProfileText}` : ""}`;
7290
7418
  const valueField = profile.numericFields[0];
7291
7419
  const buckets = /* @__PURE__ */ new Map();
7292
7420
  profile.records.forEach((record) => {
7293
- var _a2, _b, _c;
7294
- const timestamp = String((_a2 = record.fields[dateField.key]) != null ? _a2 : "");
7421
+ var _a3, _b, _c;
7422
+ const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
7295
7423
  const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
7296
7424
  buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
7297
7425
  });
@@ -7304,23 +7432,23 @@ ${schemaProfileText}` : ""}`;
7304
7432
  };
7305
7433
  }
7306
7434
  static transformToBarChart(data, profile, query = "", horizontal = false) {
7307
- var _a2;
7435
+ var _a3;
7308
7436
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
7309
7437
  const measure = profile ? this.selectNumericField(profile, query) : void 0;
7310
7438
  const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
7311
7439
  const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
7312
7440
  const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
7313
- var _a3, _b, _c, _d, _e;
7441
+ var _a4, _b, _c, _d, _e;
7314
7442
  const meta = item.metadata || {};
7315
7443
  const label = String(
7316
- (_c = (_b = (_a3 = this.getDynamicVal(meta, "name")) != null ? _a3 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
7444
+ (_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
7317
7445
  );
7318
7446
  const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
7319
7447
  return { category: label, value: Number(value) };
7320
7448
  });
7321
7449
  return {
7322
7450
  type: horizontal ? "horizontal_bar" : "bar_chart",
7323
- title: dimension ? `${(_a2 = measure == null ? void 0 : measure.label) != null ? _a2 : "Count"} by ${dimension.label}` : "Comparison",
7451
+ title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
7324
7452
  description: `Showing ${fallbackData.length} comparable values`,
7325
7453
  data: fallbackData
7326
7454
  };
@@ -7355,11 +7483,11 @@ ${schemaProfileText}` : ""}`;
7355
7483
  if (fields.length < 2) return null;
7356
7484
  const [xField, yField] = fields;
7357
7485
  const points = profile.records.map((record) => {
7358
- var _a2;
7486
+ var _a3;
7359
7487
  const x = this.toFiniteNumber(record.fields[xField.key]);
7360
7488
  const y = this.toFiniteNumber(record.fields[yField.key]);
7361
7489
  if (x === null || y === null) return null;
7362
- return { x, y, label: String((_a2 = this.getRecordLabel(record)) != null ? _a2 : record.id) };
7490
+ return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
7363
7491
  }).filter((point) => point !== null).slice(0, 100);
7364
7492
  if (points.length === 0) return null;
7365
7493
  return {
@@ -7389,9 +7517,9 @@ ${schemaProfileText}` : ""}`;
7389
7517
  static transformToRadarChart(data) {
7390
7518
  const attributeMap = {};
7391
7519
  data.forEach((item) => {
7392
- var _a2, _b, _c;
7520
+ var _a3, _b, _c;
7393
7521
  const meta = item.metadata || {};
7394
- const seriesName = String((_c = (_b = (_a2 = meta.name) != null ? _a2 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
7522
+ const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
7395
7523
  Object.entries(meta).forEach(([key, val]) => {
7396
7524
  if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
7397
7525
  if (!attributeMap[key]) attributeMap[key] = {};
@@ -7407,8 +7535,8 @@ ${schemaProfileText}` : ""}`;
7407
7535
  title: "Product Comparison",
7408
7536
  description: `Comparing ${data.length} items across ${radarData.length} attributes`,
7409
7537
  data: radarData.length > 0 ? radarData : data.map((d) => {
7410
- var _a2;
7411
- return { attribute: ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").substring(0, 40) };
7538
+ var _a3;
7539
+ return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
7412
7540
  })
7413
7541
  };
7414
7542
  }
@@ -7427,8 +7555,8 @@ ${schemaProfileText}` : ""}`;
7427
7555
  return this.createTextResponse(
7428
7556
  "Retrieved Context",
7429
7557
  data.map((item) => {
7430
- var _a2;
7431
- return (_a2 = item == null ? void 0 : item.content) != null ? _a2 : "";
7558
+ var _a3;
7559
+ return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
7432
7560
  }).join("\n\n"),
7433
7561
  `Found ${data.length} relevant results`
7434
7562
  );
@@ -7479,11 +7607,11 @@ ${schemaProfileText}` : ""}`;
7479
7607
  return null;
7480
7608
  }
7481
7609
  static normalizeTransformation(payload) {
7482
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
7610
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
7483
7611
  if (!payload || typeof payload !== "object") return null;
7484
7612
  const p = payload;
7485
7613
  const type = this.normalizeVisualizationType(
7486
- String((_c = (_b = (_a2 = p.type) != null ? _a2 : p.view) != null ? _b : p.chartType) != null ? _c : "")
7614
+ String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
7487
7615
  );
7488
7616
  if (!type) return null;
7489
7617
  const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
@@ -7494,7 +7622,7 @@ ${schemaProfileText}` : ""}`;
7494
7622
  return this.validateTransformation(transformation) ? transformation : null;
7495
7623
  }
7496
7624
  static normalizeVisualizationType(type) {
7497
- var _a2;
7625
+ var _a3;
7498
7626
  const mapping = {
7499
7627
  pie: "pie_chart",
7500
7628
  pie_chart: "pie_chart",
@@ -7522,7 +7650,7 @@ ${schemaProfileText}` : ""}`;
7522
7650
  product_carousel: "product_carousel",
7523
7651
  carousel: "carousel"
7524
7652
  };
7525
- return (_a2 = mapping[type.toLowerCase()]) != null ? _a2 : null;
7653
+ return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
7526
7654
  }
7527
7655
  static validateTransformation(t) {
7528
7656
  const { type, data } = t;
@@ -7638,7 +7766,7 @@ ${schemaProfileText}` : ""}`;
7638
7766
  }
7639
7767
  static profileData(data) {
7640
7768
  const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
7641
- var _a2, _b;
7769
+ var _a3, _b;
7642
7770
  const fields2 = {};
7643
7771
  Object.entries(item.metadata || {}).forEach(([key, value]) => {
7644
7772
  const primitive = this.toPrimitive(value);
@@ -7647,7 +7775,7 @@ ${schemaProfileText}` : ""}`;
7647
7775
  if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
7648
7776
  return {
7649
7777
  id: item.id,
7650
- content: (_a2 = item.content) != null ? _a2 : "",
7778
+ content: (_a3 = item.content) != null ? _a3 : "",
7651
7779
  score: (_b = item.score) != null ? _b : 0,
7652
7780
  fields: fields2,
7653
7781
  source: item
@@ -7728,16 +7856,16 @@ ${schemaProfileText}` : ""}`;
7728
7856
  return null;
7729
7857
  }
7730
7858
  static selectDimensionField(profile, query) {
7731
- var _a2, _b;
7859
+ var _a3, _b;
7732
7860
  const productCategory = profile.categoricalFields.find(
7733
7861
  (field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
7734
7862
  );
7735
7863
  const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
7736
- return (_b = (_a2 = ranked[0]) != null ? _a2 : productCategory) != null ? _b : profile.categoricalFields[0];
7864
+ return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
7737
7865
  }
7738
7866
  static selectNumericField(profile, query) {
7739
- var _a2;
7740
- return (_a2 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a2 : profile.numericFields[0];
7867
+ var _a3;
7868
+ return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
7741
7869
  }
7742
7870
  static rankFieldsByQuery(fields, query) {
7743
7871
  const q = query.toLowerCase();
@@ -7766,8 +7894,8 @@ ${schemaProfileText}` : ""}`;
7766
7894
  static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
7767
7895
  const result = {};
7768
7896
  profile.records.forEach((record) => {
7769
- var _a2, _b, _c;
7770
- const category = String((_a2 = record.fields[dimensionKey]) != null ? _a2 : "Other").trim() || "Other";
7897
+ var _a3, _b, _c;
7898
+ const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
7771
7899
  const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
7772
7900
  result[category] = ((_c = result[category]) != null ? _c : 0) + value;
7773
7901
  });
@@ -7847,8 +7975,8 @@ ${schemaProfileText}` : ""}`;
7847
7975
  static aggregateByCategory(data, categories) {
7848
7976
  const result = Object.fromEntries(categories.map((c) => [c, 0]));
7849
7977
  data.forEach((item) => {
7850
- var _a2;
7851
- const cat = (_a2 = this.getProductCategory(item)) != null ? _a2 : "Other";
7978
+ var _a3;
7979
+ const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
7852
7980
  if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
7853
7981
  else result["Other"] = (result["Other"] || 0) + 1;
7854
7982
  });
@@ -7856,17 +7984,17 @@ ${schemaProfileText}` : ""}`;
7856
7984
  }
7857
7985
  static extractTimeSeriesData(data) {
7858
7986
  return data.map((item) => {
7859
- var _a2, _b, _c, _d, _e, _f;
7987
+ var _a3, _b, _c, _d, _e, _f;
7860
7988
  const meta = item.metadata || {};
7861
7989
  return {
7862
- timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
7990
+ timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
7863
7991
  value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
7864
7992
  label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
7865
7993
  };
7866
7994
  });
7867
7995
  }
7868
7996
  static extractNumericValue(meta) {
7869
- var _a2;
7997
+ var _a3;
7870
7998
  const preferredKeys = [
7871
7999
  "value",
7872
8000
  "count",
@@ -7881,7 +8009,7 @@ ${schemaProfileText}` : ""}`;
7881
8009
  "price"
7882
8010
  ];
7883
8011
  for (const key of preferredKeys) {
7884
- const raw = (_a2 = resolveMetadataValue(meta, key)) != null ? _a2 : meta[key];
8012
+ const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
7885
8013
  const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
7886
8014
  if (Number.isFinite(value)) return value;
7887
8015
  }
@@ -7976,8 +8104,8 @@ ${schemaProfileText}` : ""}`;
7976
8104
  }, query.includes(normalizedField) ? 3 : 0);
7977
8105
  }
7978
8106
  static resolveTableCellValue(item, column) {
7979
- var _a2, _b, _c;
7980
- if (column === "Content") return ((_a2 = item == null ? void 0 : item.content) != null ? _a2 : "").substring(0, 100);
8107
+ var _a3, _b, _c;
8108
+ if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
7981
8109
  const meta = item.metadata || {};
7982
8110
  const normalizedColumn = this.normalizeComparableField(column);
7983
8111
  const exactMetadata = Object.entries(meta).find(
@@ -8029,8 +8157,8 @@ ${schemaProfileText}` : ""}`;
8029
8157
  let inStock = 0;
8030
8158
  let outOfStock = 0;
8031
8159
  data.forEach((d) => {
8032
- var _a2, _b;
8033
- const cat = (_a2 = this.getProductCategory(d)) != null ? _a2 : "Other";
8160
+ var _a3, _b;
8161
+ const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
8034
8162
  if (cat === category) {
8035
8163
  const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
8036
8164
  if (this.determineStockStatus(d)) inStock += quantity;
@@ -8076,9 +8204,9 @@ ${schemaProfileText}` : ""}`;
8076
8204
  }
8077
8205
  // ─── Product Extraction ───────────────────────────────────────────────────
8078
8206
  static getDynamicVal(meta, uiKey, config, trainedSchema) {
8079
- var _a2;
8207
+ var _a3;
8080
8208
  if (!meta) return void 0;
8081
- const mapping = (_a2 = config == null ? void 0 : config.rag) == null ? void 0 : _a2.uiMapping;
8209
+ const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
8082
8210
  if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
8083
8211
  if (trainedSchema && typeof trainedSchema === "object") {
8084
8212
  const trainedKey = trainedSchema[uiKey];
@@ -8087,7 +8215,7 @@ ${schemaProfileText}` : ""}`;
8087
8215
  return resolveMetadataValue(meta, uiKey);
8088
8216
  }
8089
8217
  static extractProductInfo(item, config, trainedSchema) {
8090
- var _a2, _b;
8218
+ var _a3, _b;
8091
8219
  if (!item) return null;
8092
8220
  const meta = item.metadata || {};
8093
8221
  const content = item.content || "";
@@ -8095,7 +8223,7 @@ ${schemaProfileText}` : ""}`;
8095
8223
  const price = this.getDynamicVal(meta, "price", config, trainedSchema);
8096
8224
  const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
8097
8225
  const description = this.cleanProductDescription(
8098
- (_a2 = this.extractProductDescriptionFromContent(content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
8226
+ (_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
8099
8227
  );
8100
8228
  if (name || this.isProductData(item)) {
8101
8229
  let finalName = name ? String(name) : void 0;
@@ -8230,10 +8358,10 @@ RULES:
8230
8358
  }
8231
8359
  static buildContextSummary(sources, maxChars = 6e3) {
8232
8360
  const items = (sources || []).filter(Boolean).map((s, i) => {
8233
- var _a2, _b, _c, _d;
8361
+ var _a3, _b, _c, _d;
8234
8362
  return {
8235
8363
  index: i + 1,
8236
- content: (_b = (_a2 = s == null ? void 0 : s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
8364
+ content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
8237
8365
  metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
8238
8366
  score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
8239
8367
  };
@@ -8273,7 +8401,7 @@ var SchemaMapper = class {
8273
8401
  return promise;
8274
8402
  }
8275
8403
  static async _doTrain(llm, cacheKey, keys) {
8276
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8404
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8277
8405
  console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
8278
8406
  const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
8279
8407
  const messages = [
@@ -8289,7 +8417,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
8289
8417
  }
8290
8418
  ];
8291
8419
  try {
8292
- const baseUrl = (_a2 = llm == null ? void 0 : llm.baseUrl) != null ? _a2 : "";
8420
+ const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
8293
8421
  const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
8294
8422
  const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
8295
8423
  let responseText;
@@ -8464,9 +8592,9 @@ var Pipeline = class {
8464
8592
  this.initialised = false;
8465
8593
  /** Namespace-specific static cold context cache for CAG */
8466
8594
  this.coldContexts = /* @__PURE__ */ new Map();
8467
- var _a2, _b, _c, _d, _e;
8595
+ var _a3, _b, _c, _d, _e;
8468
8596
  this.chunker = new DocumentChunker(
8469
- (_b = (_a2 = config.rag) == null ? void 0 : _a2.chunkSize) != null ? _b : 1e3,
8597
+ (_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
8470
8598
  (_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
8471
8599
  );
8472
8600
  if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
@@ -8482,7 +8610,7 @@ var Pipeline = class {
8482
8610
  return this.initialised ? this.llmProvider : void 0;
8483
8611
  }
8484
8612
  async initialize() {
8485
- var _a2, _b, _c, _d;
8613
+ var _a3, _b, _c, _d;
8486
8614
  if (this.initialised) return;
8487
8615
  const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
8488
8616
 
@@ -8525,7 +8653,7 @@ var Pipeline = class {
8525
8653
  this.entityExtractor = new EntityExtractor(this.llmProvider);
8526
8654
  }
8527
8655
  await this.vectorDB.initialize();
8528
- 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) {
8656
+ 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) {
8529
8657
  this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
8530
8658
  this.multiAgentCoordinator = new MultiAgentCoordinator({
8531
8659
  llmProvider: this.llmProvider,
@@ -8543,8 +8671,8 @@ var Pipeline = class {
8543
8671
  this.initialised = true;
8544
8672
  }
8545
8673
  async loadColdContext(ns) {
8546
- var _a2, _b;
8547
- const cagConfig = (_a2 = this.config.rag) == null ? void 0 : _a2.cag;
8674
+ var _a3, _b;
8675
+ const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
8548
8676
  if (!cagConfig || !cagConfig.enabled) return;
8549
8677
  try {
8550
8678
  const coldNs = cagConfig.coldNamespace || ns;
@@ -8597,12 +8725,12 @@ ${m.content}`).join("\n\n---\n\n");
8597
8725
  }
8598
8726
  /** Step 1: Chunk the document content. */
8599
8727
  async prepareChunks(doc) {
8600
- var _a2, _b;
8728
+ var _a3, _b;
8601
8729
  if (this.llamaIngestor) {
8602
8730
  return this.llamaIngestor.chunk(doc.content, {
8603
8731
  docId: doc.docId,
8604
8732
  metadata: doc.metadata,
8605
- chunkSize: (_a2 = this.config.rag) == null ? void 0 : _a2.chunkSize,
8733
+ chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
8606
8734
  chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
8607
8735
  });
8608
8736
  }
@@ -8700,9 +8828,9 @@ ${m.content}`).join("\n\n---\n\n");
8700
8828
  return { reply, sources };
8701
8829
  }
8702
8830
  async ask(question, history = [], namespace) {
8703
- var _a2, _b;
8831
+ var _a3, _b;
8704
8832
  await this.initialize();
8705
- 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) {
8833
+ 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) {
8706
8834
  return await this.multiAgentCoordinator.run(question, history);
8707
8835
  }
8708
8836
  const stream = this.askStream(question, history, namespace);
@@ -8737,9 +8865,9 @@ ${m.content}`).join("\n\n---\n\n");
8737
8865
  }
8738
8866
  askStream(_0) {
8739
8867
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
8740
- var _a2, _b;
8868
+ var _a3, _b;
8741
8869
  yield new __await(this.initialize());
8742
- 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) {
8870
+ 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) {
8743
8871
  const stream2 = this.multiAgentCoordinator.runStream(question, history);
8744
8872
  try {
8745
8873
  for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
@@ -8788,10 +8916,10 @@ ${m.content}`).join("\n\n---\n\n");
8788
8916
  */
8789
8917
  askStreamInternal(_0) {
8790
8918
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
8791
- 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;
8919
+ 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;
8792
8920
  yield new __await(this.initialize());
8793
8921
  const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
8794
- const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
8922
+ const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
8795
8923
  const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
8796
8924
  const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
8797
8925
  const requestStart = performance.now();
@@ -8840,8 +8968,8 @@ ${m.content}`).join("\n\n---\n\n");
8840
8968
  const rerankStart = performance.now();
8841
8969
  const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
8842
8970
  let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
8843
- var _a3;
8844
- return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
8971
+ var _a4;
8972
+ return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
8845
8973
  });
8846
8974
  const rerankLimit = Math.max(retrievalLimit, fullSources.length);
8847
8975
  const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
@@ -8854,13 +8982,13 @@ ${m.content}`).join("\n\n---\n\n");
8854
8982
  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]
8855
8983
 
8856
8984
  ` + promptSources.map((m, i) => {
8857
- var _a3;
8985
+ var _a4;
8858
8986
  return `[Source ${i + 1}]
8859
- ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
8987
+ ${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
8860
8988
  }).join("\n\n---\n\n") : "No relevant context found.";
8861
8989
  const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
8862
- var _a3, _b2;
8863
- return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
8990
+ var _a4, _b2;
8991
+ return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
8864
8992
  });
8865
8993
  if (graphData && graphData.nodes.length > 0) {
8866
8994
  const graphContext = graphData.nodes.map(
@@ -8888,10 +9016,10 @@ ${context}`;
8888
9016
  yield {
8889
9017
  reply: "",
8890
9018
  sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
8891
- var _a3, _b2, _c2;
9019
+ var _a4, _b2, _c2;
8892
9020
  return {
8893
9021
  id: s.id,
8894
- score: (_a3 = s.score) != null ? _a3 : 0,
9022
+ score: (_a4 = s.score) != null ? _a4 : 0,
8895
9023
  content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
8896
9024
  metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
8897
9025
  namespace: ns
@@ -9084,11 +9212,11 @@ ${context}`;
9084
9212
  systemPrompt,
9085
9213
  userPrompt: question + finalRestrictionSuffix,
9086
9214
  chunks: (sources || []).filter(Boolean).map((s) => {
9087
- var _a3, _b2;
9215
+ var _a4, _b2;
9088
9216
  return {
9089
9217
  id: s.id,
9090
9218
  score: s.score,
9091
- content: (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "",
9219
+ content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
9092
9220
  metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
9093
9221
  namespace: ns
9094
9222
  };
@@ -9107,7 +9235,7 @@ ${context}`;
9107
9235
  const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
9108
9236
  const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
9109
9237
  (async () => {
9110
- var _a3, _b2, _c2, _d2, _e2;
9238
+ var _a4, _b2, _c2, _d2, _e2;
9111
9239
  try {
9112
9240
  let finalTrace = trace;
9113
9241
  if (!awaitHallucination && runHallucination) {
@@ -9116,7 +9244,7 @@ ${context}`;
9116
9244
  finalTrace = buildTrace(backgroundScoreResult);
9117
9245
  }
9118
9246
  }
9119
- const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a3 = this.config.llm) == null ? void 0 : _a3.model) || "llama-3.1-8b-instant";
9247
+ const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
9120
9248
  const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
9121
9249
  const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
9122
9250
  const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
@@ -9170,7 +9298,7 @@ ${context}`;
9170
9298
  * Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
9171
9299
  */
9172
9300
  async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
9173
- var _a2;
9301
+ var _a3;
9174
9302
  if (!sources || sources.length === 0) {
9175
9303
  return UITransformer.transform(question, sources, this.config, cachedSchema);
9176
9304
  }
@@ -9183,7 +9311,7 @@ ${context}`;
9183
9311
  { visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
9184
9312
  );
9185
9313
  }
9186
- const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
9314
+ const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
9187
9315
  if (forceDeterministic || !enableLlmUiTransform) {
9188
9316
  return UITransformer.transform(question, sources, this.config, cachedSchema);
9189
9317
  }
@@ -9201,15 +9329,15 @@ ${context}`;
9201
9329
  const value = this.resolveNumericPredicateValue(source, predicate);
9202
9330
  return value !== null && this.matchesNumericPredicate(value, predicate);
9203
9331
  })).sort((a, b) => {
9204
- var _a2, _b;
9332
+ var _a3, _b;
9205
9333
  const primary = predicates[0];
9206
- const aValue = (_a2 = this.resolveNumericPredicateValue(a, primary)) != null ? _a2 : 0;
9334
+ const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
9207
9335
  const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
9208
9336
  return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
9209
9337
  });
9210
9338
  }
9211
9339
  resolveNumericPredicateValue(source, predicate) {
9212
- var _a2;
9340
+ var _a3;
9213
9341
  if (!source) return null;
9214
9342
  const meta = source.metadata || {};
9215
9343
  const field = predicate.field;
@@ -9222,7 +9350,7 @@ ${context}`;
9222
9350
  const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
9223
9351
  if (value !== null) return value;
9224
9352
  }
9225
- const contentValue = this.extractNumericValueFromContent((_a2 = source.content) != null ? _a2 : "", field);
9353
+ const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
9226
9354
  if (contentValue !== null) return contentValue;
9227
9355
  }
9228
9356
  for (const [key, value] of entries) {
@@ -9278,8 +9406,8 @@ ${context}`;
9278
9406
  return Number.isFinite(numeric) ? numeric : null;
9279
9407
  }
9280
9408
  async retrieve(query, options) {
9281
- var _a2, _b, _c, _d, _e, _f, _g2;
9282
- const ns = formatNamespace((_a2 = options.namespace) != null ? _a2 : this.config.projectId);
9409
+ var _a3, _b, _c, _d, _e, _f, _g2;
9410
+ const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
9283
9411
  const topK = (_b = options.topK) != null ? _b : 5;
9284
9412
  const cacheKey = `${ns}::${query}`;
9285
9413
  let queryVector = this.embeddingCache.get(cacheKey);
@@ -9324,11 +9452,11 @@ ${context}`;
9324
9452
  namespace: ns,
9325
9453
  count: resolvedSources.length,
9326
9454
  sample: resolvedSources.slice(0, 2).map((s) => {
9327
- var _a3;
9455
+ var _a4;
9328
9456
  return {
9329
9457
  id: s == null ? void 0 : s.id,
9330
9458
  score: s == null ? void 0 : s.score,
9331
- contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9459
+ contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
9332
9460
  metadata: s == null ? void 0 : s.metadata
9333
9461
  };
9334
9462
  })
@@ -9342,8 +9470,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
9342
9470
 
9343
9471
  History:
9344
9472
  ${(history || []).map((m) => {
9345
- var _a2;
9346
- return `${(m == null ? void 0 : m.role) || "user"}: ${(_a2 = m == null ? void 0 : m.content) != null ? _a2 : ""}`;
9473
+ var _a3;
9474
+ return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
9347
9475
  }).join("\n")}
9348
9476
 
9349
9477
  New Question: ${question}
@@ -9370,8 +9498,8 @@ Optimized Search Query:`;
9370
9498
  const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
9371
9499
  if (!sources || sources.length === 0) return [];
9372
9500
  const context = sources.map((s) => {
9373
- var _a2;
9374
- return (_a2 = s == null ? void 0 : s.content) != null ? _a2 : "";
9501
+ var _a3;
9502
+ return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
9375
9503
  }).join("\n\n---\n\n");
9376
9504
  const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
9377
9505
  Focus on questions that can be answered by the context.
@@ -9509,18 +9637,200 @@ var ProviderHealthCheck = class {
9509
9637
  }
9510
9638
  };
9511
9639
 
9640
+ // src/core/FreeTierLimitsGuard.ts
9641
+ var FREE_TIER_QUOTAS = {
9642
+ MAX_DOCUMENTS: 25,
9643
+ MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
9644
+ MAX_STORAGE_BYTES: 250 * 1024 * 1024,
9645
+ MAX_TRIAL_REQUEST_UNITS: 500,
9646
+ MAX_DAILY_REQUEST_UNITS: 50,
9647
+ TRIAL_DURATION_DAYS: 14,
9648
+ GRACE_PERIOD_DAYS: 2,
9649
+ MAX_RPM: 10,
9650
+ MAX_RPH: 100,
9651
+ MAX_RPD: 500,
9652
+ MAX_CONCURRENT_REQUESTS: 2,
9653
+ MAX_INPUT_TOKENS: 2e4,
9654
+ MAX_OUTPUT_TOKENS: 4e3,
9655
+ UPGRADE_REMINDER_DAYS: [7, 12, 14],
9656
+ MAX_USERS: 1,
9657
+ MAX_NAMESPACES: 1,
9658
+ MAX_PROJECTS: 1
9659
+ };
9660
+ var FreeTierLimitsGuard = class {
9661
+ static calculateTrialTimestamps(startedAt) {
9662
+ const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
9663
+ const trialStartedAtMs = startDate.getTime();
9664
+ const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
9665
+ const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
9666
+ return {
9667
+ trial_started_at: new Date(trialStartedAtMs).toISOString(),
9668
+ trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
9669
+ grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
9670
+ };
9671
+ }
9672
+ static calculateRequestUnits(operationType, options) {
9673
+ var _a3;
9674
+ const op = operationType.toLowerCase().trim();
9675
+ 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")) {
9676
+ return 0;
9677
+ }
9678
+ if (op.includes("image")) {
9679
+ return 10;
9680
+ }
9681
+ if (op.includes("embedding")) {
9682
+ const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
9683
+ return Math.max(1, Math.ceil(chunks / 1e3));
9684
+ }
9685
+ return 1;
9686
+ }
9687
+ static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
9688
+ const timestamps = this.calculateTrialTimestamps(startedAt);
9689
+ const startMs = new Date(timestamps.trial_started_at).getTime();
9690
+ const expireMs = new Date(timestamps.trial_expires_at).getTime();
9691
+ const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
9692
+ const nowMs = nowServerTime.getTime();
9693
+ const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
9694
+ const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
9695
+ const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
9696
+ const isExpiredTime = nowMs > expireMs;
9697
+ const isPastGraceTime = nowMs > graceExpireMs;
9698
+ let status = "active";
9699
+ let reason;
9700
+ if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
9701
+ status = "expired";
9702
+ reason = "Trial period and grace period have expired. Upgrade your plan.";
9703
+ } else if (isExpiredTime || isConsumedUnits) {
9704
+ status = "grace_period";
9705
+ 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).";
9706
+ }
9707
+ let upgradeReminderDue;
9708
+ if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
9709
+ upgradeReminderDue = daysElapsed;
9710
+ }
9711
+ let usageReminderDue;
9712
+ const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
9713
+ if (usagePercent >= 100) {
9714
+ usageReminderDue = "100%";
9715
+ } else if (usagePercent >= 90) {
9716
+ usageReminderDue = "90%";
9717
+ } else if (usagePercent >= 80) {
9718
+ usageReminderDue = "80%";
9719
+ }
9720
+ return {
9721
+ status,
9722
+ daysElapsed,
9723
+ daysRemaining,
9724
+ isGracePeriod: status === "grace_period",
9725
+ isExpired: status === "expired",
9726
+ upgradeReminderDue,
9727
+ usageReminderDue,
9728
+ reason
9729
+ };
9730
+ }
9731
+ static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
9732
+ var _a3, _b;
9733
+ const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
9734
+ const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
9735
+ if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
9736
+ const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
9737
+ return {
9738
+ allowed: false,
9739
+ reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
9740
+ };
9741
+ }
9742
+ if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
9743
+ return {
9744
+ allowed: false,
9745
+ reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
9746
+ };
9747
+ }
9748
+ if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
9749
+ const mbUsed = (storage / (1024 * 1024)).toFixed(1);
9750
+ return {
9751
+ allowed: false,
9752
+ reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
9753
+ };
9754
+ }
9755
+ return { allowed: true };
9756
+ }
9757
+ static checkRequestAllowed(params) {
9758
+ var _a3, _b, _c;
9759
+ const op = (_a3 = params.operationType) != null ? _a3 : "chat";
9760
+ const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
9761
+ if (costUnits === 0) {
9762
+ return { allowed: true, costUnits: 0 };
9763
+ }
9764
+ if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
9765
+ return {
9766
+ allowed: false,
9767
+ reason: "Token limit exceeded. Upgrade your plan.",
9768
+ costUnits
9769
+ };
9770
+ }
9771
+ if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
9772
+ return {
9773
+ allowed: false,
9774
+ reason: "Token limit exceeded. Upgrade your plan.",
9775
+ costUnits
9776
+ };
9777
+ }
9778
+ if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
9779
+ return {
9780
+ allowed: false,
9781
+ reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
9782
+ costUnits
9783
+ };
9784
+ }
9785
+ const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
9786
+ const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
9787
+ if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
9788
+ return {
9789
+ allowed: false,
9790
+ reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
9791
+ costUnits
9792
+ };
9793
+ }
9794
+ if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
9795
+ return {
9796
+ allowed: false,
9797
+ reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
9798
+ costUnits
9799
+ };
9800
+ }
9801
+ const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
9802
+ if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
9803
+ return {
9804
+ allowed: false,
9805
+ reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
9806
+ costUnits
9807
+ };
9808
+ }
9809
+ return { allowed: true, costUnits };
9810
+ }
9811
+ static checkQueryAllowed(dailyQueriesCount = 0) {
9812
+ if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
9813
+ return {
9814
+ allowed: false,
9815
+ reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
9816
+ };
9817
+ }
9818
+ return { allowed: true };
9819
+ }
9820
+ };
9821
+
9512
9822
  // src/core/VectorPlugin.ts
9513
9823
  var VectorPlugin = class {
9514
9824
  constructor(hostConfig) {
9515
9825
  const resolvedConfig = ConfigResolver.resolve(hostConfig);
9516
9826
  this.config = resolvedConfig;
9517
9827
  this.validationPromise = (async () => {
9518
- var _a2;
9828
+ var _a3;
9519
9829
  await ConfigValidator.validateAndThrow(resolvedConfig);
9520
9830
  LicenseVerifier.verify(
9521
9831
  resolvedConfig.licenseKey,
9522
9832
  resolvedConfig.projectId,
9523
- (_a2 = resolvedConfig.vectorDb) == null ? void 0 : _a2.provider
9833
+ (_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
9524
9834
  );
9525
9835
  })();
9526
9836
  this.validationPromise.catch(() => {
@@ -9554,16 +9864,32 @@ var VectorPlugin = class {
9554
9864
  this.config.embedding
9555
9865
  );
9556
9866
  }
9867
+ estimateInputTokens(message, history = []) {
9868
+ const allContent = message.length + history.reduce((acc, m) => {
9869
+ var _a3, _b;
9870
+ 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);
9871
+ }, 0);
9872
+ return Math.ceil(allContent / 4);
9873
+ }
9557
9874
  /**
9558
9875
  * Run a chat query.
9559
9876
  */
9560
9877
  async chat(message, history = [], namespace) {
9878
+ var _a3;
9561
9879
  try {
9562
9880
  await this.validationPromise;
9563
9881
  } catch (err) {
9564
9882
  throw wrapError(err, "CONFIGURATION_ERROR");
9565
9883
  }
9566
9884
  try {
9885
+ const inputTokens = this.estimateInputTokens(message, history);
9886
+ const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
9887
+ operationType: "chat",
9888
+ inputTokens
9889
+ });
9890
+ if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
9891
+ throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
9892
+ }
9567
9893
  return await this.pipeline.ask(message, history, namespace);
9568
9894
  } catch (err) {
9569
9895
  const msg = String(err);
@@ -9571,6 +9897,9 @@ var VectorPlugin = class {
9571
9897
  if (msg.includes("Embed") || msg.includes("embed")) {
9572
9898
  defaultCode = "EMBEDDING_FAILED";
9573
9899
  }
9900
+ if (msg.toLowerCase().includes("token limit")) {
9901
+ defaultCode = "RATE_LIMITED";
9902
+ }
9574
9903
  throw wrapError(err, defaultCode);
9575
9904
  }
9576
9905
  }
@@ -9579,12 +9908,21 @@ var VectorPlugin = class {
9579
9908
  */
9580
9909
  chatStream(_0) {
9581
9910
  return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
9911
+ var _a3;
9582
9912
  try {
9583
9913
  yield new __await(this.validationPromise);
9584
9914
  } catch (err) {
9585
9915
  throw wrapError(err, "CONFIGURATION_ERROR");
9586
9916
  }
9587
9917
  try {
9918
+ const inputTokens = this.estimateInputTokens(message, history);
9919
+ const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
9920
+ operationType: "chat_stream",
9921
+ inputTokens
9922
+ });
9923
+ if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
9924
+ throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
9925
+ }
9588
9926
  const stream = this.pipeline.askStream(message, history, namespace);
9589
9927
  try {
9590
9928
  for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
@@ -9607,6 +9945,9 @@ var VectorPlugin = class {
9607
9945
  if (msg.includes("Embed") || msg.includes("embed")) {
9608
9946
  defaultCode = "EMBEDDING_FAILED";
9609
9947
  }
9948
+ if (msg.toLowerCase().includes("token limit")) {
9949
+ defaultCode = "RATE_LIMITED";
9950
+ }
9610
9951
  throw wrapError(err, defaultCode);
9611
9952
  }
9612
9953
  });
@@ -9654,8 +9995,8 @@ var DocumentParser = class {
9654
9995
  * Extract text from a File or Buffer based on its type.
9655
9996
  */
9656
9997
  static async parse(file, fileName, mimeType) {
9657
- var _a2;
9658
- const extension = ((_a2 = fileName.split(".").pop()) == null ? void 0 : _a2.toLowerCase()) || "";
9998
+ var _a3;
9999
+ const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
9659
10000
  if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
9660
10001
  return this.readAsText(file);
9661
10002
  }
@@ -9746,9 +10087,9 @@ var DatabaseStorage = class {
9746
10087
  this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
9747
10088
  this.historyFile = path.join(this.fallbackDir, "history.json");
9748
10089
  this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
9749
- var _a2, _b, _c, _d, _e;
10090
+ var _a3, _b, _c, _d, _e;
9750
10091
  this.config = config;
9751
- this.provider = ((_a2 = config.vectorDb) == null ? void 0 : _a2.provider) || "fs";
10092
+ this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
9752
10093
  const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
9753
10094
  const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
9754
10095
  this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
@@ -9783,16 +10124,16 @@ var DatabaseStorage = class {
9783
10124
  }
9784
10125
  }
9785
10126
  checkHistoryEnabled() {
9786
- var _a2, _b;
10127
+ var _a3, _b;
9787
10128
  this.checkPremiumSubscription();
9788
- if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.history) == null ? void 0 : _b.enabled) === false) {
10129
+ if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
9789
10130
  throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
9790
10131
  }
9791
10132
  }
9792
10133
  checkFeedbackEnabled() {
9793
- var _a2, _b;
10134
+ var _a3, _b;
9794
10135
  this.checkPremiumSubscription();
9795
- if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.feedback) == null ? void 0 : _b.enabled) === false) {
10136
+ if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
9796
10137
  throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
9797
10138
  }
9798
10139
  }
@@ -9959,8 +10300,11 @@ var DatabaseStorage = class {
9959
10300
  this.writeLocalFile(this.historyFile, history);
9960
10301
  }
9961
10302
  }
9962
- async getHistory(sessionId) {
10303
+ async getHistory(sessionId, projectIds) {
9963
10304
  this.checkHistoryEnabled();
10305
+ if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
10306
+ return [];
10307
+ }
9964
10308
  if (this.provider === "postgresql" || this.provider === "pgvector") {
9965
10309
  const pool = await this.getPGPool();
9966
10310
  const res = await pool.query(
@@ -9990,8 +10334,11 @@ var DatabaseStorage = class {
9990
10334
  return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
9991
10335
  }
9992
10336
  }
9993
- async clearHistory(sessionId) {
10337
+ async clearHistory(sessionId, projectIds) {
9994
10338
  this.checkHistoryEnabled();
10339
+ if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
10340
+ return;
10341
+ }
9995
10342
  if (this.provider === "postgresql" || this.provider === "pgvector") {
9996
10343
  const pool = await this.getPGPool();
9997
10344
  await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
@@ -10010,21 +10357,36 @@ var DatabaseStorage = class {
10010
10357
  this.writeLocalFile(this.feedbackFile, filteredFeedback);
10011
10358
  }
10012
10359
  }
10013
- async listSessions() {
10360
+ /**
10361
+ * Return true when `sessionId` falls into the allowed `projectIds` scope.
10362
+ * When `projectIds` is empty / undefined we allow the call (legacy behavior
10363
+ * for non-multi-tenant consumers). Session ids typically begin with the
10364
+ * project id they were created for, so we prefix-match as well as contains-match
10365
+ * to catch sharded / suffix-style ids used by some integrations.
10366
+ */
10367
+ sessionInScope(sessionId, projectIds) {
10368
+ if (!projectIds || projectIds.length === 0) return true;
10369
+ return projectIds.some(
10370
+ (pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
10371
+ );
10372
+ }
10373
+ async listSessions(projectIds) {
10014
10374
  this.checkHistoryEnabled();
10375
+ let raw = [];
10015
10376
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10016
10377
  const pool = await this.getPGPool();
10017
10378
  const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
10018
- return res.rows.map((r) => r.session_id);
10379
+ raw = res.rows.map((r) => r.session_id);
10019
10380
  } else if (this.provider === "mongodb") {
10020
10381
  await this.getMongoClient();
10021
10382
  const db = this.getMongoDb();
10022
- return db.collection(this.historyTableName).distinct("session_id");
10383
+ raw = await db.collection(this.historyTableName).distinct("session_id");
10023
10384
  } else {
10024
10385
  const history = this.readLocalFile(this.historyFile);
10025
- const sessions = new Set(history.map((h) => h.session_id));
10026
- return Array.from(sessions);
10386
+ raw = Array.from(new Set(history.map((h) => h.session_id)));
10027
10387
  }
10388
+ if (!projectIds || projectIds.length === 0) return raw;
10389
+ return raw.filter((sid) => this.sessionInScope(sid, projectIds));
10028
10390
  }
10029
10391
  // ─── Feedback Operations ──────────────────────────────────────────────────
10030
10392
  async saveFeedback(feedback) {
@@ -10077,8 +10439,9 @@ var DatabaseStorage = class {
10077
10439
  this.writeLocalFile(this.feedbackFile, list);
10078
10440
  }
10079
10441
  }
10080
- async getFeedback(messageId) {
10442
+ async getFeedback(messageId, projectIds) {
10081
10443
  this.checkFeedbackEnabled();
10444
+ let item = null;
10082
10445
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10083
10446
  const pool = await this.getPGPool();
10084
10447
  const res = await pool.query(
@@ -10087,28 +10450,34 @@ var DatabaseStorage = class {
10087
10450
  WHERE message_id = $1`,
10088
10451
  [messageId]
10089
10452
  );
10090
- return res.rows[0] || null;
10453
+ item = res.rows[0] || null;
10091
10454
  } else if (this.provider === "mongodb") {
10092
10455
  await this.getMongoClient();
10093
10456
  const db = this.getMongoDb();
10094
10457
  const col = db.collection(this.feedbackTableName);
10095
- const item = await col.findOne({ message_id: messageId });
10096
- if (!item) return null;
10097
- return {
10098
- id: item.id,
10099
- messageId: item.message_id,
10100
- sessionId: item.session_id,
10101
- rating: item.rating,
10102
- comment: item.comment,
10103
- createdAt: item.created_at
10104
- };
10458
+ const raw = await col.findOne({ message_id: messageId });
10459
+ if (raw) {
10460
+ item = {
10461
+ id: raw.id,
10462
+ messageId: raw.message_id,
10463
+ sessionId: raw.session_id,
10464
+ rating: raw.rating,
10465
+ comment: raw.comment,
10466
+ createdAt: raw.created_at
10467
+ };
10468
+ }
10105
10469
  } else {
10106
10470
  const list = this.readLocalFile(this.feedbackFile);
10107
- return list.find((f) => f.message_id === messageId) || null;
10471
+ item = list.find((f) => f.message_id === messageId) || null;
10472
+ }
10473
+ if (item && projectIds && projectIds.length > 0) {
10474
+ return this.sessionInScope(item.sessionId, projectIds) ? item : null;
10108
10475
  }
10476
+ return item;
10109
10477
  }
10110
- async listFeedback() {
10478
+ async listFeedback(projectIds) {
10111
10479
  this.checkFeedbackEnabled();
10480
+ let raw = [];
10112
10481
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10113
10482
  const pool = await this.getPGPool();
10114
10483
  const res = await pool.query(
@@ -10116,13 +10485,13 @@ var DatabaseStorage = class {
10116
10485
  FROM ${this.feedbackTableName}
10117
10486
  ORDER BY created_at DESC`
10118
10487
  );
10119
- return res.rows;
10488
+ raw = res.rows;
10120
10489
  } else if (this.provider === "mongodb") {
10121
10490
  await this.getMongoClient();
10122
10491
  const db = this.getMongoDb();
10123
10492
  const col = db.collection(this.feedbackTableName);
10124
10493
  const items = await col.find({}).sort({ created_at: -1 }).toArray();
10125
- return items.map((item) => ({
10494
+ raw = items.map((item) => ({
10126
10495
  id: item.id,
10127
10496
  messageId: item.message_id,
10128
10497
  sessionId: item.session_id,
@@ -10132,8 +10501,10 @@ var DatabaseStorage = class {
10132
10501
  }));
10133
10502
  } else {
10134
10503
  const list = this.readLocalFile(this.feedbackFile);
10135
- return [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
10504
+ raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
10136
10505
  }
10506
+ if (!projectIds || projectIds.length === 0) return raw;
10507
+ return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
10137
10508
  }
10138
10509
  async disconnect() {
10139
10510
  if (this.pgPool) {
@@ -10196,8 +10567,8 @@ var _g = global;
10196
10567
  var _a;
10197
10568
  var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
10198
10569
  function getRateLimitKey(req) {
10199
- var _a2, _b;
10200
- 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";
10570
+ var _a3, _b;
10571
+ 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";
10201
10572
  return `ip:${ip}`;
10202
10573
  }
10203
10574
  function checkRateLimit(req) {
@@ -10219,6 +10590,66 @@ function checkRateLimit(req) {
10219
10590
  }
10220
10591
  return null;
10221
10592
  }
10593
+ var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
10594
+ function isFreeTier(tier) {
10595
+ if (!tier) return true;
10596
+ return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
10597
+ }
10598
+ var _a2;
10599
+ var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
10600
+ function createPaymentRequiredResponse(reason, details) {
10601
+ const body = __spreadProps(__spreadValues({
10602
+ type: "https://retrivora.com/docs/errors/payment-required",
10603
+ title: "Payment Required",
10604
+ status: 402,
10605
+ detail: reason,
10606
+ code: "FREE_TIER_LIMIT_EXCEEDED",
10607
+ instance: void 0
10608
+ }, details != null ? details : {}), {
10609
+ quota: {
10610
+ maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
10611
+ maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
10612
+ maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
10613
+ maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
10614
+ upgradeUrl: "https://retrivora.com/pricing"
10615
+ }
10616
+ });
10617
+ return new Response(JSON.stringify(body), {
10618
+ status: 402,
10619
+ headers: {
10620
+ "Content-Type": "application/problem+json"
10621
+ }
10622
+ });
10623
+ }
10624
+ function resolveLicenseKey(req, config, bodyLicenseKey) {
10625
+ var _a3;
10626
+ 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 || "";
10627
+ }
10628
+ function enforceLicense(req, config, bodyLicenseKey) {
10629
+ const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
10630
+ const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
10631
+ const projectId = config.projectId || "my-rag-app";
10632
+ try {
10633
+ const payload = LicenseVerifier.verify(licenseKey, projectId);
10634
+ return { ok: true, payload };
10635
+ } catch (err) {
10636
+ 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.";
10637
+ const body = {
10638
+ error: {
10639
+ code: "LICENSE_REVOKED",
10640
+ message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
10641
+ },
10642
+ details: message
10643
+ };
10644
+ return {
10645
+ ok: false,
10646
+ response: new Response(JSON.stringify(body), {
10647
+ status: 403,
10648
+ headers: { "Content-Type": "application/json" }
10649
+ })
10650
+ };
10651
+ }
10652
+ }
10222
10653
  var MAX_MESSAGE_LENGTH = 8e3;
10223
10654
  function sanitizeInput(raw) {
10224
10655
  const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
@@ -10240,7 +10671,7 @@ function getOrCreatePlugin(configOrPlugin) {
10240
10671
  return _g[cacheKey];
10241
10672
  }
10242
10673
  function reportTelemetry(req, plugin, action, status, details, trace) {
10243
- var _a2, _b, _c, _d, _e, _f, _g2;
10674
+ var _a3, _b, _c, _d, _e, _f, _g2;
10244
10675
  try {
10245
10676
  const config = plugin.getConfig();
10246
10677
  const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
@@ -10255,7 +10686,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
10255
10686
  absoluteUrl = `${proto}://${host}${telemetryUrl}`;
10256
10687
  }
10257
10688
  const projectId = config.projectId || "default";
10258
- 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";
10689
+ 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";
10259
10690
  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";
10260
10691
  const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
10261
10692
  const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
@@ -10279,7 +10710,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
10279
10710
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
10280
10711
  details
10281
10712
  };
10282
- console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
10283
10713
  fetch(absoluteUrl, {
10284
10714
  method: "POST",
10285
10715
  headers: {
@@ -10337,14 +10767,39 @@ function createChatHandler(configOrPlugin, options) {
10337
10767
  const storage = new DatabaseStorage(plugin.getConfig());
10338
10768
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10339
10769
  return async function POST(req, context) {
10340
- var _a2, _b, _c, _d;
10770
+ var _a3, _b, _c, _d, _e, _f;
10341
10771
  const authResult = await checkAuth(req, onAuthorize);
10342
10772
  if (authResult) return authResult;
10343
10773
  const rateLimited = checkRateLimit(req);
10344
10774
  if (rateLimited) return rateLimited;
10775
+ const config = plugin.getConfig();
10345
10776
  try {
10346
10777
  const body = await req.json();
10347
10778
  const bodyObj = body != null ? body : {};
10779
+ const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
10780
+ if (!licenseCheck.ok) return licenseCheck.response;
10781
+ if (isFreeTier(licenseCheck.payload.tier)) {
10782
+ const estimatedInputTokens = Math.ceil(
10783
+ ((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
10784
+ var _a4, _b2;
10785
+ 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);
10786
+ }, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.reduce((a, m) => {
10787
+ var _a4, _b2;
10788
+ 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);
10789
+ }, 0)) || 0)) / 4
10790
+ );
10791
+ const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
10792
+ operationType: "chat",
10793
+ inputTokens: estimatedInputTokens,
10794
+ projectId: licenseCheck.payload.projectId
10795
+ });
10796
+ if (!chatCheck.allowed) {
10797
+ return createPaymentRequiredResponse(
10798
+ chatCheck.reason || "Free tier quota exceeded.",
10799
+ { tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
10800
+ );
10801
+ }
10802
+ }
10348
10803
  let rawMessage = bodyObj.message;
10349
10804
  if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
10350
10805
  const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
@@ -10376,7 +10831,7 @@ function createChatHandler(configOrPlugin, options) {
10376
10831
  uiTransformation: result.ui_transformation,
10377
10832
  trace: result.trace
10378
10833
  }).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
10379
- 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);
10834
+ 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);
10380
10835
  return import_server.NextResponse.json(__spreadProps(__spreadValues({}, result), {
10381
10836
  messageId: assistantMsgId,
10382
10837
  userMessageId: userMsgId
@@ -10393,14 +10848,15 @@ function createStreamHandler(configOrPlugin, options) {
10393
10848
  const storage = new DatabaseStorage(plugin.getConfig());
10394
10849
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10395
10850
  return async function POST(req, context) {
10396
- var _a2;
10851
+ var _a3, _b, _c;
10397
10852
  const authResult = await checkAuth(req, onAuthorize);
10398
10853
  if (authResult) return authResult;
10399
10854
  const rateLimited = checkRateLimit(req);
10400
10855
  if (rateLimited) return rateLimited;
10856
+ const config = plugin.getConfig();
10401
10857
  let body;
10402
10858
  try {
10403
- if ((_a2 = req.headers.get("content-type")) == null ? void 0 : _a2.includes("multipart/form-data")) {
10859
+ if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
10404
10860
  const uploader = createUploadHandler(plugin, { onAuthorize });
10405
10861
  return uploader(req);
10406
10862
  }
@@ -10412,6 +10868,30 @@ function createStreamHandler(configOrPlugin, options) {
10412
10868
  });
10413
10869
  }
10414
10870
  const bodyObj = body != null ? body : {};
10871
+ const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
10872
+ if (!licenseCheck.ok) return licenseCheck.response;
10873
+ if (isFreeTier(licenseCheck.payload.tier)) {
10874
+ const estimatedInputTokens = Math.ceil(
10875
+ ((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
10876
+ var _a4, _b2;
10877
+ 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);
10878
+ }, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.reduce((a, m) => {
10879
+ var _a4, _b2;
10880
+ 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);
10881
+ }, 0)) || 0)) / 4
10882
+ );
10883
+ const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
10884
+ operationType: "chat_stream",
10885
+ inputTokens: estimatedInputTokens,
10886
+ projectId: licenseCheck.payload.projectId
10887
+ });
10888
+ if (!chatCheck.allowed) {
10889
+ return createPaymentRequiredResponse(
10890
+ chatCheck.reason || "Free tier quota exceeded.",
10891
+ { tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
10892
+ );
10893
+ }
10894
+ }
10415
10895
  let rawMessage = bodyObj.message;
10416
10896
  if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
10417
10897
  const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
@@ -10441,7 +10921,7 @@ function createStreamHandler(configOrPlugin, options) {
10441
10921
  let isActive = true;
10442
10922
  const stream = new ReadableStream({
10443
10923
  async start(controller) {
10444
- var _a3, _b, _c, _d, _e;
10924
+ var _a4, _b2, _c2, _d, _e;
10445
10925
  const enqueue = (text) => {
10446
10926
  if (!isActive) return;
10447
10927
  try {
@@ -10474,7 +10954,7 @@ function createStreamHandler(configOrPlugin, options) {
10474
10954
  let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
10475
10955
  if (sources.length > 0) {
10476
10956
  try {
10477
- uiTransformation = (_a3 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a3 : UITransformer.transform(message, sources, plugin.getConfig());
10957
+ uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
10478
10958
  if (uiTransformation) {
10479
10959
  enqueue(sseUIFrame(uiTransformation));
10480
10960
  }
@@ -10498,7 +10978,7 @@ function createStreamHandler(configOrPlugin, options) {
10498
10978
  uiTransformation,
10499
10979
  trace: responseChunk == null ? void 0 : responseChunk.trace
10500
10980
  }).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
10501
- 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);
10981
+ 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);
10502
10982
  }
10503
10983
  }
10504
10984
  } catch (temp) {
@@ -10548,12 +11028,36 @@ function createIngestHandler(configOrPlugin, options) {
10548
11028
  return async function POST(req, context) {
10549
11029
  const authResult = await checkAuth(req, onAuthorize);
10550
11030
  if (authResult) return authResult;
11031
+ const config = plugin.getConfig();
10551
11032
  try {
10552
11033
  const body = await req.json();
11034
+ const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
11035
+ if (!licenseCheck.ok) return licenseCheck.response;
10553
11036
  const { documents, namespace } = body;
10554
11037
  if (!Array.isArray(documents) || documents.length === 0) {
10555
11038
  return import_server.NextResponse.json({ error: "documents array is required" }, { status: 400 });
10556
11039
  }
11040
+ if (isFreeTier(licenseCheck.payload.tier)) {
11041
+ const totalIncomingBytes = documents.reduce(
11042
+ (sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
11043
+ 0
11044
+ );
11045
+ const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
11046
+ { documentCount: documents.length },
11047
+ totalIncomingBytes
11048
+ );
11049
+ if (!ingestCheck.allowed) {
11050
+ return createPaymentRequiredResponse(
11051
+ ingestCheck.reason || "Free tier ingestion limit reached.",
11052
+ {
11053
+ tier: licenseCheck.payload.tier,
11054
+ projectId: licenseCheck.payload.projectId,
11055
+ documents: documents.length,
11056
+ incomingBytes: totalIncomingBytes
11057
+ }
11058
+ );
11059
+ }
11060
+ }
10557
11061
  const results = await plugin.ingest(documents, namespace);
10558
11062
  reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
10559
11063
  return import_server.NextResponse.json({ results });
@@ -10590,7 +11094,7 @@ function createLicenseHandler(configOrPlugin, options) {
10590
11094
  const plugin = getOrCreatePlugin(configOrPlugin);
10591
11095
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10592
11096
  return async function POST(req) {
10593
- var _a2;
11097
+ var _a3;
10594
11098
  if (req) {
10595
11099
  const authResult = await checkAuth(req, onAuthorize);
10596
11100
  if (authResult) return authResult;
@@ -10598,7 +11102,8 @@ function createLicenseHandler(configOrPlugin, options) {
10598
11102
  try {
10599
11103
  const body = await req.json().catch(() => ({}));
10600
11104
  const config = plugin.getConfig();
10601
- const licenseKey = 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.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || "";
11105
+ 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 || "";
11106
+ const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
10602
11107
  const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
10603
11108
  const payload = LicenseVerifier.verify(licenseKey, projectId);
10604
11109
  return import_server.NextResponse.json({
@@ -10632,6 +11137,9 @@ function createUploadHandler(configOrPlugin, options) {
10632
11137
  return async function POST(req, context) {
10633
11138
  const authResult = await checkAuth(req, onAuthorize);
10634
11139
  if (authResult) return authResult;
11140
+ const config = plugin.getConfig();
11141
+ const licenseCheck = enforceLicense(req, config);
11142
+ if (!licenseCheck.ok) return licenseCheck.response;
10635
11143
  try {
10636
11144
  const formData = await req.formData();
10637
11145
  const files = formData.getAll("files");
@@ -10641,6 +11149,26 @@ function createUploadHandler(configOrPlugin, options) {
10641
11149
  if (!files || files.length === 0) {
10642
11150
  return import_server.NextResponse.json({ error: "No files provided" }, { status: 400 });
10643
11151
  }
11152
+ if (isFreeTier(licenseCheck.payload.tier)) {
11153
+ const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
11154
+ const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
11155
+ { documentCount: files.length },
11156
+ totalUploadBytes
11157
+ );
11158
+ if (!uploadCheck.allowed) {
11159
+ return createPaymentRequiredResponse(
11160
+ uploadCheck.reason || "Free tier upload limit reached.",
11161
+ {
11162
+ tier: licenseCheck.payload.tier,
11163
+ projectId: licenseCheck.payload.projectId,
11164
+ fileCount: files.length,
11165
+ totalUploadBytes,
11166
+ maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
11167
+ maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
11168
+ }
11169
+ );
11170
+ }
11171
+ }
10644
11172
  const documents = [];
10645
11173
  for (const file of files) {
10646
11174
  const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
@@ -10750,13 +11278,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
10750
11278
  return async function handler(req) {
10751
11279
  const authResult = await checkAuth(req, onAuthorize);
10752
11280
  if (authResult) return authResult;
11281
+ const config = plugin.getConfig();
11282
+ const licenseCheck = enforceLicense(req, config);
11283
+ if (!licenseCheck.ok) return licenseCheck.response;
10753
11284
  try {
10754
11285
  let query = "";
10755
11286
  let namespace = void 0;
11287
+ let bodyLicenseKey = void 0;
10756
11288
  if (req.method === "POST") {
10757
11289
  const body = await req.json().catch(() => ({}));
10758
11290
  query = body.query || "";
10759
11291
  namespace = body.namespace;
11292
+ bodyLicenseKey = body.licenseKey;
11293
+ if (bodyLicenseKey) {
11294
+ const recheck = enforceLicense(req, config, bodyLicenseKey);
11295
+ if (!recheck.ok) return recheck.response;
11296
+ }
10760
11297
  } else {
10761
11298
  const url = new URL(req.url);
10762
11299
  query = url.searchParams.get("query") || "";
@@ -10779,14 +11316,16 @@ function createHistoryHandler(configOrPlugin, options) {
10779
11316
  const plugin = getOrCreatePlugin(configOrPlugin);
10780
11317
  const storage = new DatabaseStorage(plugin.getConfig());
10781
11318
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11319
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
10782
11320
  return async function handler(req) {
10783
11321
  const authResult = await checkAuth(req, onAuthorize);
10784
11322
  if (authResult) return authResult;
11323
+ const scope = onResolveScope ? await onResolveScope(req) : void 0;
10785
11324
  const url = new URL(req.url);
10786
11325
  const sessionId = url.searchParams.get("sessionId") || "default";
10787
11326
  if (req.method === "GET") {
10788
11327
  try {
10789
- const history = await storage.getHistory(sessionId);
11328
+ const history = await storage.getHistory(sessionId, scope);
10790
11329
  return import_server.NextResponse.json({ history });
10791
11330
  } catch (err) {
10792
11331
  const message = err instanceof Error ? err.message : "Failed to fetch history";
@@ -10796,7 +11335,7 @@ function createHistoryHandler(configOrPlugin, options) {
10796
11335
  try {
10797
11336
  const body = await req.json().catch(() => ({}));
10798
11337
  const sid = body.sessionId || sessionId;
10799
- await storage.clearHistory(sid);
11338
+ await storage.clearHistory(sid, scope);
10800
11339
  return import_server.NextResponse.json({ success: true });
10801
11340
  } catch (err) {
10802
11341
  const message = err instanceof Error ? err.message : "Failed to clear history";
@@ -10810,18 +11349,20 @@ function createFeedbackHandler(configOrPlugin, options) {
10810
11349
  const plugin = getOrCreatePlugin(configOrPlugin);
10811
11350
  const storage = new DatabaseStorage(plugin.getConfig());
10812
11351
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11352
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
10813
11353
  return async function handler(req) {
10814
11354
  const authResult = await checkAuth(req, onAuthorize);
10815
11355
  if (authResult) return authResult;
11356
+ const scope = onResolveScope ? await onResolveScope(req) : void 0;
10816
11357
  if (req.method === "GET") {
10817
11358
  try {
10818
11359
  const url = new URL(req.url);
10819
11360
  const messageId = url.searchParams.get("messageId");
10820
11361
  if (!messageId) {
10821
- const feedbackList = await storage.listFeedback();
11362
+ const feedbackList = await storage.listFeedback(scope);
10822
11363
  return import_server.NextResponse.json({ feedback: feedbackList });
10823
11364
  }
10824
- const feedback = await storage.getFeedback(messageId);
11365
+ const feedback = await storage.getFeedback(messageId, scope);
10825
11366
  return import_server.NextResponse.json({ feedback });
10826
11367
  } catch (err) {
10827
11368
  const message = err instanceof Error ? err.message : "Failed to fetch feedback";
@@ -10837,6 +11378,17 @@ function createFeedbackHandler(configOrPlugin, options) {
10837
11378
  if (!rating) {
10838
11379
  return import_server.NextResponse.json({ error: "rating is required" }, { status: 400 });
10839
11380
  }
11381
+ if (scope && scope.length > 0) {
11382
+ const matches = scope.some(
11383
+ (pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
11384
+ );
11385
+ if (!matches) {
11386
+ return import_server.NextResponse.json(
11387
+ { error: "sessionId is outside the authorized project scope" },
11388
+ { status: 403 }
11389
+ );
11390
+ }
11391
+ }
10840
11392
  await storage.saveFeedback({ messageId, sessionId, rating, comment });
10841
11393
  return import_server.NextResponse.json({ success: true });
10842
11394
  } catch (err) {
@@ -10851,14 +11403,15 @@ function createSessionsHandler(configOrPlugin, options) {
10851
11403
  const plugin = getOrCreatePlugin(configOrPlugin);
10852
11404
  const storage = new DatabaseStorage(plugin.getConfig());
10853
11405
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11406
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
10854
11407
  return async function GET(req) {
10855
11408
  if (req) {
10856
11409
  const authResult = await checkAuth(req, onAuthorize);
10857
11410
  if (authResult) return authResult;
10858
11411
  }
10859
- void req;
10860
11412
  try {
10861
- const sessions = await storage.listSessions();
11413
+ const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
11414
+ const sessions = await storage.listSessions(scope);
10862
11415
  return import_server.NextResponse.json({ sessions });
10863
11416
  } catch (err) {
10864
11417
  const message = err instanceof Error ? err.message : "Failed to list sessions";
@@ -10869,15 +11422,17 @@ function createSessionsHandler(configOrPlugin, options) {
10869
11422
  function createRagHandler(configOrPlugin, options) {
10870
11423
  const plugin = getOrCreatePlugin(configOrPlugin);
10871
11424
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10872
- const chatHandler = createChatHandler(plugin, { onAuthorize });
10873
- const streamHandler = createStreamHandler(plugin, { onAuthorize });
10874
- const uploadHandler = createUploadHandler(plugin, { onAuthorize });
10875
- const healthHandler = createHealthHandler(plugin, { onAuthorize });
10876
- const suggestionsHandler = createSuggestionsHandler(plugin, { onAuthorize });
10877
- const historyHandler = createHistoryHandler(plugin, { onAuthorize });
10878
- const feedbackHandler = createFeedbackHandler(plugin, { onAuthorize });
10879
- const sessionsHandler = createSessionsHandler(plugin, { onAuthorize });
10880
- const licenseHandler = createLicenseHandler(plugin, { onAuthorize });
11425
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
11426
+ const scopeableOptions = { onAuthorize, onResolveScope };
11427
+ const chatHandler = createChatHandler(plugin, scopeableOptions);
11428
+ const streamHandler = createStreamHandler(plugin, scopeableOptions);
11429
+ const uploadHandler = createUploadHandler(plugin, scopeableOptions);
11430
+ const healthHandler = createHealthHandler(plugin, scopeableOptions);
11431
+ const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
11432
+ const historyHandler = createHistoryHandler(plugin, scopeableOptions);
11433
+ const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
11434
+ const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
11435
+ const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
10881
11436
  async function routePostRequest(req, segment) {
10882
11437
  switch (segment) {
10883
11438
  case "chat":
@@ -10919,7 +11474,7 @@ function createRagHandler(configOrPlugin, options) {
10919
11474
  }
10920
11475
  }
10921
11476
  async function getSegment(req, context) {
10922
- var _a2, _b;
11477
+ var _a3, _b;
10923
11478
  const contentType = req.headers.get("content-type") || "";
10924
11479
  if (contentType.includes("multipart/form-data")) {
10925
11480
  return "upload";
@@ -10936,7 +11491,7 @@ function createRagHandler(configOrPlugin, options) {
10936
11491
  if (pathname.endsWith("/history")) return "history";
10937
11492
  } catch (e) {
10938
11493
  }
10939
- 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;
11494
+ 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;
10940
11495
  const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
10941
11496
  const joined = segments.join("/");
10942
11497
  return joined || "chat";