@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.
@@ -150,7 +150,7 @@ var init_ConfigFetcher = __esm({
150
150
  * Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
151
151
  */
152
152
  static async fetchRemoteConfig(projectId, licenseKey) {
153
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
153
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
154
154
  const cacheKey = `${projectId}:${licenseKey || ""}`;
155
155
  const now = Date.now();
156
156
  const cached = this.cache.get(cacheKey);
@@ -176,7 +176,7 @@ var init_ConfigFetcher = __esm({
176
176
  });
177
177
  if (res.ok) {
178
178
  const data = await res.json();
179
- if ((data == null ? void 0 : data.success) && ((_a2 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a2.apiKey)) {
179
+ if ((data == null ? void 0 : data.success) && ((_a3 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a3.apiKey)) {
180
180
  const fetchedProjectId = data.projectId || projectId;
181
181
  const config = {
182
182
  projectId: fetchedProjectId,
@@ -212,9 +212,9 @@ var init_ConfigFetcher = __esm({
212
212
  }
213
213
  /** Convenience: fetch only vector DB config (backwards compat). */
214
214
  static async fetchRemoteVectorConfig(projectId, licenseKey) {
215
- var _a2;
215
+ var _a3;
216
216
  const config = await this.fetchRemoteConfig(projectId, licenseKey);
217
- return (_a2 = config == null ? void 0 : config.vectorDb) != null ? _a2 : null;
217
+ return (_a3 = config == null ? void 0 : config.vectorDb) != null ? _a3 : null;
218
218
  }
219
219
  };
220
220
  ConfigFetcher.cache = /* @__PURE__ */ new Map();
@@ -263,7 +263,7 @@ var init_PineconeProvider = __esm({
263
263
  static getHealthChecker() {
264
264
  return {
265
265
  async check(config) {
266
- var _a2, _b;
266
+ var _a3, _b;
267
267
  const opts = config.options || {};
268
268
  const indexName = config.indexName;
269
269
  const timestamp = Date.now();
@@ -271,7 +271,7 @@ var init_PineconeProvider = __esm({
271
271
  const { Pinecone: Pinecone2 } = await import("@pinecone-database/pinecone");
272
272
  const client = new Pinecone2({ apiKey: opts.apiKey });
273
273
  const indexes = await client.listIndexes();
274
- const indexNames = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
274
+ const indexNames = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
275
275
  if (!indexNames.includes(indexName)) {
276
276
  return {
277
277
  healthy: false,
@@ -298,7 +298,7 @@ var init_PineconeProvider = __esm({
298
298
  };
299
299
  }
300
300
  async initialize() {
301
- var _a2, _b;
301
+ var _a3, _b;
302
302
  if (this.client) return;
303
303
  let key = this.apiKey || process.env.PINECONE_API_KEY || "";
304
304
  if (!key) {
@@ -335,7 +335,7 @@ var init_PineconeProvider = __esm({
335
335
  this.client = new Pinecone({ apiKey: key });
336
336
  try {
337
337
  const indexes = await this.client.listIndexes();
338
- const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
338
+ const names = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
339
339
  if (!names.includes(this.indexName)) {
340
340
  console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
341
341
  }
@@ -354,13 +354,13 @@ var init_PineconeProvider = __esm({
354
354
  return namespace ? idx.namespace(namespace) : idx.namespace("");
355
355
  }
356
356
  async upsert(doc, namespace) {
357
- var _a2;
357
+ var _a3;
358
358
  const targetIdx = await this.getActiveIndex(namespace);
359
359
  await targetIdx.upsert({
360
360
  records: [{
361
361
  id: String(doc.id),
362
362
  values: doc.vector,
363
- metadata: __spreadValues({ content: doc.content }, (_a2 = doc.metadata) != null ? _a2 : {})
363
+ metadata: __spreadValues({ content: doc.content }, (_a3 = doc.metadata) != null ? _a3 : {})
364
364
  }]
365
365
  });
366
366
  }
@@ -369,18 +369,18 @@ var init_PineconeProvider = __esm({
369
369
  const BATCH = 100;
370
370
  for (let i = 0; i < docs.length; i += BATCH) {
371
371
  const records = docs.slice(i, i + BATCH).map((d) => {
372
- var _a2;
372
+ var _a3;
373
373
  return {
374
374
  id: String(d.id),
375
375
  values: d.vector,
376
- metadata: __spreadValues({ content: d.content }, (_a2 = d.metadata) != null ? _a2 : {})
376
+ metadata: __spreadValues({ content: d.content }, (_a3 = d.metadata) != null ? _a3 : {})
377
377
  };
378
378
  });
379
379
  await targetIdx.upsert({ records });
380
380
  }
381
381
  }
382
382
  async query(vector, topK, namespace, filter) {
383
- var _a2;
383
+ var _a3;
384
384
  const targetIdx = await this.getActiveIndex(namespace);
385
385
  const pineconeFilter = this.sanitizeFilter(filter);
386
386
  const result = await targetIdx.query(__spreadValues({
@@ -388,11 +388,11 @@ var init_PineconeProvider = __esm({
388
388
  topK,
389
389
  includeMetadata: true
390
390
  }, Object.keys(pineconeFilter).length > 0 ? { filter: pineconeFilter } : {}));
391
- return ((_a2 = result.matches) != null ? _a2 : []).map((m) => {
392
- var _a3, _b;
391
+ return ((_a3 = result.matches) != null ? _a3 : []).map((m) => {
392
+ var _a4, _b;
393
393
  return {
394
394
  id: m.id,
395
- score: (_a3 = m.score) != null ? _a3 : 0,
395
+ score: (_a4 = m.score) != null ? _a4 : 0,
396
396
  content: ((_b = m.metadata) == null ? void 0 : _b.content) || "",
397
397
  metadata: m.metadata
398
398
  };
@@ -435,13 +435,13 @@ var init_PostgreSQLProvider = __esm({
435
435
  init_BaseVectorProvider();
436
436
  PostgreSQLProvider = class extends BaseVectorProvider {
437
437
  constructor(config) {
438
- var _a2;
438
+ var _a3;
439
439
  super(config);
440
440
  this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
441
441
  const opts = config.options;
442
442
  if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
443
443
  this.connectionString = opts.connectionString;
444
- this.dimensions = (_a2 = opts.dimensions) != null ? _a2 : 1536;
444
+ this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 1536;
445
445
  }
446
446
  static getValidator() {
447
447
  return {
@@ -522,7 +522,7 @@ var init_PostgreSQLProvider = __esm({
522
522
  }
523
523
  }
524
524
  async upsert(doc, namespace = "") {
525
- var _a2;
525
+ var _a3;
526
526
  const vectorLiteral = `[${doc.vector.join(",")}]`;
527
527
  await this.pool.query(
528
528
  `INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
@@ -532,7 +532,7 @@ var init_PostgreSQLProvider = __esm({
532
532
  content = EXCLUDED.content,
533
533
  metadata = EXCLUDED.metadata,
534
534
  embedding = EXCLUDED.embedding`,
535
- [doc.id, namespace, doc.content, JSON.stringify((_a2 = doc.metadata) != null ? _a2 : {}), vectorLiteral]
535
+ [doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), vectorLiteral]
536
536
  );
537
537
  }
538
538
  async batchUpsert(docs, namespace = "") {
@@ -545,9 +545,9 @@ var init_PostgreSQLProvider = __esm({
545
545
  const batch = docs.slice(i, i + BATCH_SIZE);
546
546
  const values = [];
547
547
  const valuePlaceholders = batch.map((doc, idx) => {
548
- var _a2;
548
+ var _a3;
549
549
  const offset = idx * 5;
550
- values.push(doc.id, namespace, doc.content, JSON.stringify((_a2 = doc.metadata) != null ? _a2 : {}), `[${doc.vector.join(",")}]`);
550
+ values.push(doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), `[${doc.vector.join(",")}]`);
551
551
  return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
552
552
  }).join(", ");
553
553
  const query = `
@@ -630,8 +630,8 @@ var init_PostgreSQLProvider = __esm({
630
630
 
631
631
  // src/utils/synonyms.ts
632
632
  function resolveMetadataValue(meta, uiKey) {
633
- var _a2;
634
- const synonyms = (_a2 = FIELD_SYNONYMS[uiKey]) != null ? _a2 : [];
633
+ var _a3;
634
+ const synonyms = (_a3 = FIELD_SYNONYMS[uiKey]) != null ? _a3 : [];
635
635
  const keys = Object.keys(meta);
636
636
  const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
637
637
  let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
@@ -718,14 +718,14 @@ var init_MultiTablePostgresProvider = __esm({
718
718
  init_synonyms();
719
719
  MultiTablePostgresProvider = class extends BaseVectorProvider {
720
720
  constructor(config) {
721
- var _a2, _b, _c;
721
+ var _a3, _b, _c;
722
722
  super(config);
723
723
  const opts = config.options || {};
724
724
  if (!opts.connectionString) {
725
725
  throw new Error("[MultiTablePostgresProvider] options.connectionString is required");
726
726
  }
727
727
  this.connectionString = opts.connectionString;
728
- this.dimensions = (_a2 = opts.dimensions) != null ? _a2 : 768;
728
+ this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 768;
729
729
  this.tables = [];
730
730
  const rawSearchFields = (_c = (_b = opts.searchFields) != null ? _b : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _c : ["name", "product_name", "productname", "title"];
731
731
  this.searchFields = typeof rawSearchFields === "string" ? rawSearchFields.split(",").map((f) => f.trim()).filter(Boolean) : rawSearchFields;
@@ -783,11 +783,11 @@ var init_MultiTablePostgresProvider = __esm({
783
783
  * Batch upsert documents by dynamically provisioning tables and columns based on CSV headers.
784
784
  */
785
785
  async batchUpsert(docs, namespace = "") {
786
- var _a2;
786
+ var _a3;
787
787
  if (docs.length === 0) return;
788
788
  const docsByFile = {};
789
789
  for (const doc of docs) {
790
- const fileName = ((_a2 = doc.metadata) == null ? void 0 : _a2.fileName) || this.uploadTable;
790
+ const fileName = ((_a3 = doc.metadata) == null ? void 0 : _a3.fileName) || this.uploadTable;
791
791
  if (!docsByFile[fileName]) docsByFile[fileName] = [];
792
792
  docsByFile[fileName].push(doc);
793
793
  }
@@ -840,11 +840,11 @@ var init_MultiTablePostgresProvider = __esm({
840
840
  const headerColumns = csvHeaders.map((h) => `"${h}"`).join(", ");
841
841
  const allColumns = `id, ${headerColumns ? headerColumns + ", " : ""}namespace, content, metadata, embedding`;
842
842
  const valuePlaceholders = batch.map((doc, idx) => {
843
- var _a3, _b;
843
+ var _a4, _b;
844
844
  const offset = idx * (5 + csvHeaders.length);
845
845
  values.push(doc.id);
846
846
  for (const h of csvHeaders) {
847
- values.push(String(((_a3 = doc.metadata) == null ? void 0 : _a3[h]) || ""));
847
+ values.push(String(((_a4 = doc.metadata) == null ? void 0 : _a4[h]) || ""));
848
848
  }
849
849
  values.push(namespace, doc.content, JSON.stringify((_b = doc.metadata) != null ? _b : {}), `[${doc.vector.join(",")}]`);
850
850
  const docPlaceholders = [];
@@ -883,7 +883,7 @@ var init_MultiTablePostgresProvider = __esm({
883
883
  * Query all configured tables and merge results, sorted by cosine similarity score.
884
884
  */
885
885
  async query(vector, topK, _namespace, _filter) {
886
- var _a2;
886
+ var _a3;
887
887
  if (!this.pool) {
888
888
  throw new Error("[MultiTablePostgresProvider] Provider not initialized. Call initialize() first.");
889
889
  }
@@ -914,11 +914,11 @@ var init_MultiTablePostgresProvider = __esm({
914
914
  const filterParams = [];
915
915
  if (metadataFilters && Object.keys(metadataFilters).length > 0) {
916
916
  const conditions = Object.entries(metadataFilters).map(([key, val]) => {
917
- var _a4;
917
+ var _a5;
918
918
  filterParams.push(String(val));
919
919
  const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
920
920
  const paramIdx = baseOffset + filterParams.length;
921
- const synonyms = (_a4 = FIELD_SYNONYMS[key]) != null ? _a4 : [];
921
+ const synonyms = (_a5 = FIELD_SYNONYMS[key]) != null ? _a5 : [];
922
922
  const keysToCheck = [key, ...synonyms];
923
923
  const coalesceExprs = keysToCheck.flatMap((k) => [
924
924
  `metadata->>'${k}'`,
@@ -987,7 +987,7 @@ var init_MultiTablePostgresProvider = __esm({
987
987
  }
988
988
  const tableResults = [];
989
989
  for (const row of result.rows) {
990
- const _a3 = row, { hybrid_score, id } = _a3, rest = __objRest(_a3, ["hybrid_score", "id"]);
990
+ const _a4 = row, { hybrid_score, id } = _a4, rest = __objRest(_a4, ["hybrid_score", "id"]);
991
991
  delete rest.embedding;
992
992
  delete rest.vector_score;
993
993
  delete rest.keyword_score;
@@ -1016,10 +1016,10 @@ var init_MultiTablePostgresProvider = __esm({
1016
1016
  }
1017
1017
  allResults.sort((a, b) => b.score - a.score);
1018
1018
  if (allResults.length === 0) return [];
1019
- const bestMatchTable = (_a2 = allResults[0].metadata) == null ? void 0 : _a2.source_table;
1019
+ const bestMatchTable = (_a3 = allResults[0].metadata) == null ? void 0 : _a3.source_table;
1020
1020
  const finalSorted = allResults.filter((res) => {
1021
- var _a3;
1022
- return ((_a3 = res.metadata) == null ? void 0 : _a3.source_table) === bestMatchTable;
1021
+ var _a4;
1022
+ return ((_a4 = res.metadata) == null ? void 0 : _a4.source_table) === bestMatchTable;
1023
1023
  });
1024
1024
  console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
1025
1025
  console.log(`[MultiTablePostgresProvider] Final top match from "${bestMatchTable}" with score ${finalSorted[0].score.toFixed(4)}`);
@@ -1424,14 +1424,14 @@ var init_QdrantProvider = __esm({
1424
1424
  * Samples points from the collection to discover available payload fields.
1425
1425
  */
1426
1426
  async discoverSchema() {
1427
- var _a2;
1427
+ var _a3;
1428
1428
  try {
1429
1429
  const { data } = await this.http.post(`/collections/${this.indexName}/points/scroll`, {
1430
1430
  limit: 20,
1431
1431
  with_payload: true,
1432
1432
  with_vector: false
1433
1433
  });
1434
- const points = ((_a2 = data.result) == null ? void 0 : _a2.points) || [];
1434
+ const points = ((_a3 = data.result) == null ? void 0 : _a3.points) || [];
1435
1435
  const keys = /* @__PURE__ */ new Set();
1436
1436
  for (const point of points) {
1437
1437
  const payload = point.payload || {};
@@ -1457,12 +1457,12 @@ var init_QdrantProvider = __esm({
1457
1457
  * Ensures the collection exists. Creates it if missing.
1458
1458
  */
1459
1459
  async ensureCollection() {
1460
- var _a2;
1460
+ var _a3;
1461
1461
  try {
1462
1462
  await this.http.get(`/collections/${this.indexName}`);
1463
1463
  console.log(`[QdrantProvider] \u2705 Collection "${this.indexName}" already exists.`);
1464
1464
  } catch (err) {
1465
- if (axios4.isAxiosError(err) && ((_a2 = err.response) == null ? void 0 : _a2.status) === 404) {
1465
+ if (axios4.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
1466
1466
  const opts = this.config.options;
1467
1467
  const dimensionsForCreate = opts.dimensions || 1536;
1468
1468
  console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
@@ -1482,7 +1482,7 @@ var init_QdrantProvider = __esm({
1482
1482
  * Ensures that a payload field has an index.
1483
1483
  */
1484
1484
  async ensureIndex(fieldName, schema = "keyword") {
1485
- var _a2;
1485
+ var _a3;
1486
1486
  let fullPath = fieldName;
1487
1487
  if (!this.isFlatPayload && !fieldName.includes(".") && fieldName !== "namespace" && fieldName !== this.contentField) {
1488
1488
  fullPath = `${this.metadataField}.${fieldName}`;
@@ -1495,7 +1495,7 @@ var init_QdrantProvider = __esm({
1495
1495
  console.log(`[QdrantProvider] \u2705 Ensured ${schema} index for "${fullPath}"`);
1496
1496
  } catch (err) {
1497
1497
  let status;
1498
- if (axios4.isAxiosError(err)) status = (_a2 = err.response) == null ? void 0 : _a2.status;
1498
+ if (axios4.isAxiosError(err)) status = (_a3 = err.response) == null ? void 0 : _a3.status;
1499
1499
  if (status === 409) return;
1500
1500
  console.warn(`[QdrantProvider] \u26A0\uFE0F Could not ensure index for "${fullPath}":`, err instanceof Error ? err.message : String(err));
1501
1501
  }
@@ -1524,7 +1524,7 @@ var init_QdrantProvider = __esm({
1524
1524
  await this.http.put(`/collections/${this.indexName}/points`, payload);
1525
1525
  }
1526
1526
  async query(vector, topK, namespace, _filter) {
1527
- var _a2;
1527
+ var _a3;
1528
1528
  const must = [];
1529
1529
  if (namespace) {
1530
1530
  must.push({ key: "namespace", match: { value: namespace } });
@@ -1546,7 +1546,7 @@ var init_QdrantProvider = __esm({
1546
1546
  limit: topK,
1547
1547
  with_payload: true,
1548
1548
  params: {
1549
- hnsw_ef: ((_a2 = this.config.options) == null ? void 0 : _a2.efSearch) || Math.max(topK * 20, 128),
1549
+ hnsw_ef: ((_a3 = this.config.options) == null ? void 0 : _a3.efSearch) || Math.max(topK * 20, 128),
1550
1550
  exact: false
1551
1551
  },
1552
1552
  filter: must.length > 0 ? { must } : void 0
@@ -1641,13 +1641,13 @@ var init_ChromaDBProvider = __esm({
1641
1641
  * Get or create the ChromaDB collection.
1642
1642
  */
1643
1643
  async initialize() {
1644
- var _a2;
1644
+ var _a3;
1645
1645
  try {
1646
1646
  const { data } = await this.http.get(`/api/v1/collections/${this.indexName}`);
1647
1647
  this.collectionId = data.id;
1648
1648
  console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
1649
1649
  } catch (err) {
1650
- if (axios5.isAxiosError(err) && ((_a2 = err.response) == null ? void 0 : _a2.status) === 404) {
1650
+ if (axios5.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
1651
1651
  console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
1652
1652
  const { data } = await this.http.post("/api/v1/collections", {
1653
1653
  name: this.indexName
@@ -1868,7 +1868,7 @@ var init_WeaviateProvider = __esm({
1868
1868
  await this.http.post("/v1/batch/objects", payload);
1869
1869
  }
1870
1870
  async query(vector, topK, namespace, _filter) {
1871
- var _a2, _b;
1871
+ var _a3, _b;
1872
1872
  const queryText = _filter == null ? void 0 : _filter.queryText;
1873
1873
  const sanitizedFilter = this.sanitizeFilter(_filter);
1874
1874
  const searchParams = queryText ? `hybrid: { query: ${JSON.stringify(queryText)}, alpha: 0.5 }` : `nearVector: { vector: ${JSON.stringify(vector)} }`;
@@ -1894,7 +1894,7 @@ var init_WeaviateProvider = __esm({
1894
1894
  `
1895
1895
  };
1896
1896
  const { data } = await this.http.post("/v1/graphql", graphqlQuery);
1897
- const results = ((_b = (_a2 = data.data) == null ? void 0 : _a2.Get) == null ? void 0 : _b[this.indexName]) || [];
1897
+ const results = ((_b = (_a3 = data.data) == null ? void 0 : _a3.Get) == null ? void 0 : _b[this.indexName]) || [];
1898
1898
  return results.map((res) => ({
1899
1899
  id: res["_additional"].id,
1900
1900
  score: 1 - res["_additional"].distance,
@@ -1977,21 +1977,21 @@ var init_UniversalVectorProvider = __esm({
1977
1977
  }
1978
1978
  }
1979
1979
  async initialize() {
1980
- var _a2;
1980
+ var _a3;
1981
1981
  this.http = axios8.create({
1982
1982
  baseURL: this.opts.baseUrl,
1983
1983
  headers: __spreadValues({
1984
1984
  "Content-Type": "application/json"
1985
1985
  }, this.opts.headers),
1986
- timeout: (_a2 = this.opts.timeout) != null ? _a2 : 3e4
1986
+ timeout: (_a3 = this.opts.timeout) != null ? _a3 : 3e4
1987
1987
  });
1988
1988
  if (!await this.ping()) {
1989
1989
  throw new Error(`[UniversalVectorProvider] Failed to connect to ${this.opts.baseUrl}`);
1990
1990
  }
1991
1991
  }
1992
1992
  async upsert(doc, namespace) {
1993
- var _a2, _b, _c;
1994
- const endpoint = (_a2 = this.opts.upsertEndpoint) != null ? _a2 : "/upsert";
1993
+ var _a3, _b, _c;
1994
+ const endpoint = (_a3 = this.opts.upsertEndpoint) != null ? _a3 : "/upsert";
1995
1995
  const template = (_b = this.opts.upsertTemplate) != null ? _b : JSON.stringify({
1996
1996
  id: "{{id}}",
1997
1997
  vector: "{{vector}}",
@@ -2024,8 +2024,8 @@ var init_UniversalVectorProvider = __esm({
2024
2024
  }
2025
2025
  }
2026
2026
  async query(vector, topK, namespace, filter) {
2027
- var _a2, _b;
2028
- const endpoint = (_a2 = this.opts.queryEndpoint) != null ? _a2 : "/query";
2027
+ var _a3, _b;
2028
+ const endpoint = (_a3 = this.opts.queryEndpoint) != null ? _a3 : "/query";
2029
2029
  const template = (_b = this.opts.queryTemplate) != null ? _b : JSON.stringify({
2030
2030
  vector: "{{vector}}",
2031
2031
  limit: "{{topK}}",
@@ -2051,9 +2051,9 @@ var init_UniversalVectorProvider = __esm({
2051
2051
  );
2052
2052
  }
2053
2053
  return results.map((item) => {
2054
- var _a3, _b2, _c, _d, _e, _f, _g2;
2054
+ var _a4, _b2, _c, _d, _e, _f, _g2;
2055
2055
  return {
2056
- id: item[(_a3 = this.opts.queryIdField) != null ? _a3 : "id"],
2056
+ id: item[(_a4 = this.opts.queryIdField) != null ? _a4 : "id"],
2057
2057
  score: (_c = item[(_b2 = this.opts.queryScoreField) != null ? _b2 : "score"]) != null ? _c : 0,
2058
2058
  content: (_e = item[(_d = this.opts.queryContentField) != null ? _d : "content"]) != null ? _e : "",
2059
2059
  metadata: (_g2 = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g2 : {}
@@ -2066,8 +2066,8 @@ var init_UniversalVectorProvider = __esm({
2066
2066
  }
2067
2067
  }
2068
2068
  async delete(id, namespace) {
2069
- var _a2, _b;
2070
- const endpoint = (_a2 = this.opts.deleteEndpoint) != null ? _a2 : "/delete";
2069
+ var _a3, _b;
2070
+ const endpoint = (_a3 = this.opts.deleteEndpoint) != null ? _a3 : "/delete";
2071
2071
  const template = (_b = this.opts.deleteTemplate) != null ? _b : JSON.stringify({
2072
2072
  id: "{{id}}",
2073
2073
  namespace: "{{namespace}}"
@@ -2085,8 +2085,8 @@ var init_UniversalVectorProvider = __esm({
2085
2085
  }
2086
2086
  }
2087
2087
  async deleteNamespace(namespace) {
2088
- var _a2;
2089
- const endpoint = (_a2 = this.opts.deleteNamespaceEndpoint) != null ? _a2 : "/delete-namespace";
2088
+ var _a3;
2089
+ const endpoint = (_a3 = this.opts.deleteNamespaceEndpoint) != null ? _a3 : "/delete-namespace";
2090
2090
  try {
2091
2091
  await this.http.post(endpoint, { namespace });
2092
2092
  } catch (error) {
@@ -2096,9 +2096,9 @@ var init_UniversalVectorProvider = __esm({
2096
2096
  }
2097
2097
  }
2098
2098
  async ping() {
2099
- var _a2;
2099
+ var _a3;
2100
2100
  try {
2101
- const endpoint = (_a2 = this.opts.pingEndpoint) != null ? _a2 : "/health";
2101
+ const endpoint = (_a3 = this.opts.pingEndpoint) != null ? _a3 : "/health";
2102
2102
  const response = await this.http.get(endpoint, { timeout: 5e3 });
2103
2103
  return response.status >= 200 && response.status < 300;
2104
2104
  } catch (e) {
@@ -2235,13 +2235,13 @@ var AuthenticationException = class extends RetrivoraError {
2235
2235
  }
2236
2236
  };
2237
2237
  function wrapError(err, defaultCode, defaultMessage) {
2238
- var _a2;
2238
+ var _a3;
2239
2239
  if (err instanceof RetrivoraError) {
2240
2240
  return err;
2241
2241
  }
2242
2242
  const error = err;
2243
2243
  const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
2244
- 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);
2244
+ 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);
2245
2245
  const code = error == null ? void 0 : error.code;
2246
2246
  if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
2247
2247
  return new RateLimitException(message, err);
@@ -2310,7 +2310,8 @@ var LicenseVerifier = class {
2310
2310
  };
2311
2311
  }
2312
2312
  try {
2313
- const rawToken = licenseKey.replace(/^rtv_/i, "").trim();
2313
+ const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
2314
+ const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
2314
2315
  const parts = rawToken.split(".");
2315
2316
  if (parts.length !== 3) {
2316
2317
  throw new Error("Malformed token structure (expected 3 parts).");
@@ -2522,8 +2523,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
2522
2523
 
2523
2524
  // src/config/serverConfig.ts
2524
2525
  function readString(env, name) {
2525
- var _a2;
2526
- const value = (_a2 = env[name]) == null ? void 0 : _a2.trim();
2526
+ var _a3;
2527
+ const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
2527
2528
  return value ? value : void 0;
2528
2529
  }
2529
2530
  function readNumber(env, name, fallback) {
@@ -2536,16 +2537,16 @@ function readNumber(env, name, fallback) {
2536
2537
  return parsed;
2537
2538
  }
2538
2539
  function readEnum(env, name, fallback, allowed) {
2539
- var _a2;
2540
- const value = (_a2 = readString(env, name)) != null ? _a2 : fallback;
2540
+ var _a3;
2541
+ const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
2541
2542
  if (allowed.includes(value)) {
2542
2543
  return value;
2543
2544
  }
2544
2545
  throw new Error(`[getRagConfig] ${name} must be one of: ${allowed.join(", ")}`);
2545
2546
  }
2546
2547
  function getEnvConfig(env = process.env, base) {
2547
- 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;
2548
- 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;
2548
+ 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;
2549
+ 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;
2549
2550
  const jwtProjectId = (() => {
2550
2551
  if (!licenseKey) return void 0;
2551
2552
  try {
@@ -2626,7 +2627,7 @@ function getEnvConfig(env = process.env, base) {
2626
2627
  rest: "default",
2627
2628
  custom: "default"
2628
2629
  };
2629
- const isFreeTier = (() => {
2630
+ const isFreeTier2 = (() => {
2630
2631
  if (!licenseKey) return true;
2631
2632
  try {
2632
2633
  const payload = LicenseVerifier.verify(licenseKey, projectId);
@@ -2637,13 +2638,13 @@ function getEnvConfig(env = process.env, base) {
2637
2638
  }
2638
2639
  })();
2639
2640
  const defaultGatewayUrl = (_ra = (_qa = readString(env, "LITELLM_BASE_URL")) != null ? _qa : readString(env, "LLM_BASE_URL")) != null ? _ra : "https://www.retrivora.com/api/v1";
2640
- const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
2641
+ const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
2641
2642
  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;
2642
2643
  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;
2643
- 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";
2644
+ 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";
2644
2645
  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;
2645
2646
  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";
2646
- const defaultEmbeddingProvider = isFreeTier ? "universal_rest" : "universal_rest";
2647
+ const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
2647
2648
  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;
2648
2649
  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;
2649
2650
  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";
@@ -2733,8 +2734,8 @@ function getEnvConfig(env = process.env, base) {
2733
2734
  }
2734
2735
  } : {}), {
2735
2736
  mcpServers: (() => {
2736
- var _a3;
2737
- const raw = (_a3 = readString(env, "MCP_SERVERS")) != null ? _a3 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
2737
+ var _a4;
2738
+ const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
2738
2739
  if (!raw) return void 0;
2739
2740
  try {
2740
2741
  return JSON.parse(raw);
@@ -2779,10 +2780,10 @@ var ConfigResolver = class {
2779
2780
  * fallback behavior.
2780
2781
  */
2781
2782
  static resolveUniversal(hostConfig, env = process.env) {
2782
- var _a2;
2783
+ var _a3;
2783
2784
  if (!hostConfig) return this.resolve(void 0, env);
2784
2785
  const normalized = __spreadProps(__spreadValues({}, hostConfig), {
2785
- vectorDb: (_a2 = hostConfig.vectorDb) != null ? _a2 : hostConfig.vectorDatabase,
2786
+ vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
2786
2787
  rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
2787
2788
  });
2788
2789
  return this.resolve(normalized, env);
@@ -2802,11 +2803,11 @@ var ConfigResolver = class {
2802
2803
  }
2803
2804
  }
2804
2805
  static mergeRetrievalWorkflow(rag, retrieval, workflow) {
2805
- var _a2, _b, _c, _d, _e, _f;
2806
+ var _a3, _b, _c, _d, _e, _f;
2806
2807
  if (!rag && !retrieval && !workflow) return void 0;
2807
2808
  const normalized = __spreadValues({}, rag != null ? rag : {});
2808
2809
  if (retrieval) {
2809
- normalized.topK = (_a2 = retrieval.topK) != null ? _a2 : normalized.topK;
2810
+ normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
2810
2811
  normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
2811
2812
  normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
2812
2813
  if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
@@ -2934,8 +2935,8 @@ var OpenAIProvider = class {
2934
2935
  };
2935
2936
  }
2936
2937
  async chat(messages, context, options) {
2937
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
2938
- 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.";
2938
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
2939
+ 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.";
2939
2940
  const systemMessage = {
2940
2941
  role: "system",
2941
2942
  content: buildSystemContent(basePrompt, context)
@@ -2959,8 +2960,8 @@ var OpenAIProvider = class {
2959
2960
  }
2960
2961
  chatStream(messages, context, options) {
2961
2962
  return __asyncGenerator(this, null, function* () {
2962
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
2963
- 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.";
2963
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
2964
+ 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.";
2964
2965
  const systemMessage = {
2965
2966
  role: "system",
2966
2967
  content: buildSystemContent(basePrompt, context)
@@ -3007,8 +3008,8 @@ var OpenAIProvider = class {
3007
3008
  return results[0];
3008
3009
  }
3009
3010
  async batchEmbed(texts, options) {
3010
- var _a2, _b, _c, _d, _e;
3011
- 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";
3011
+ var _a3, _b, _c, _d, _e;
3012
+ 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";
3012
3013
  const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
3013
3014
  const client = apiKey !== this.llmConfig.apiKey ? new OpenAI({ apiKey }) : this.client;
3014
3015
  const response = await client.embeddings.create({ model, input: texts });
@@ -3085,8 +3086,8 @@ var AnthropicProvider = class {
3085
3086
  };
3086
3087
  }
3087
3088
  async chat(messages, context, options) {
3088
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3089
- 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.";
3089
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3090
+ 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.";
3090
3091
  const system = buildSystemContent(basePrompt, context);
3091
3092
  const anthropicMessages = messages.map((m) => ({
3092
3093
  role: m.role === "assistant" ? "assistant" : "user",
@@ -3124,8 +3125,8 @@ var AnthropicProvider = class {
3124
3125
  }
3125
3126
  chatStream(messages, context, options) {
3126
3127
  return __asyncGenerator(this, null, function* () {
3127
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3128
- 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.";
3128
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3129
+ 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.";
3129
3130
  const system = buildSystemContent(basePrompt, context);
3130
3131
  const anthropicMessages = messages.map((m) => ({
3131
3132
  role: m.role === "assistant" ? "assistant" : "user",
@@ -3209,8 +3210,8 @@ var AnthropicProvider = class {
3209
3210
  import axios from "axios";
3210
3211
  var OllamaProvider = class {
3211
3212
  constructor(llmConfig, embeddingConfig) {
3212
- var _a2, _b, _c;
3213
- const rawBaseURL = ((_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434").replace(/\/+$/, "");
3213
+ var _a3, _b, _c;
3214
+ const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
3214
3215
  const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
3215
3216
  const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
3216
3217
  const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
@@ -3270,8 +3271,8 @@ var OllamaProvider = class {
3270
3271
  };
3271
3272
  }
3272
3273
  async chat(messages, context, options) {
3273
- var _a2, _b, _c, _d, _e, _f;
3274
- 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.";
3274
+ var _a3, _b, _c, _d, _e, _f;
3275
+ 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.";
3275
3276
  const system = buildSystemContent(basePrompt, context);
3276
3277
  const { data } = await this.http.post("/api/chat", {
3277
3278
  model: this.llmConfig.model,
@@ -3289,8 +3290,8 @@ var OllamaProvider = class {
3289
3290
  }
3290
3291
  chatStream(messages, context, options) {
3291
3292
  return __asyncGenerator(this, null, function* () {
3292
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3293
- 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.";
3293
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3294
+ 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.";
3294
3295
  const system = buildSystemContent(basePrompt, context);
3295
3296
  const response = yield new __await(this.http.post("/api/chat", {
3296
3297
  model: this.llmConfig.model,
@@ -3348,8 +3349,8 @@ var OllamaProvider = class {
3348
3349
  });
3349
3350
  }
3350
3351
  async embed(text, options) {
3351
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3352
- 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";
3352
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3353
+ 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";
3353
3354
  const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
3354
3355
  const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? axios.create({ baseURL, timeout: 6e4 }) : this.http;
3355
3356
  let prompt = text;
@@ -3450,9 +3451,9 @@ var GeminiProvider = class {
3450
3451
  static getHealthChecker() {
3451
3452
  return {
3452
3453
  async check(config) {
3453
- var _a2, _b;
3454
+ var _a3, _b;
3454
3455
  const timestamp = Date.now();
3455
- const apiKey = (_b = (_a2 = config.apiKey) != null ? _a2 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
3456
+ const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
3456
3457
  const modelName = sanitizeModel(config.model);
3457
3458
  try {
3458
3459
  const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
@@ -3482,16 +3483,16 @@ var GeminiProvider = class {
3482
3483
  /** Resolve the embedding client — uses a separate client when the embedding
3483
3484
  * API key differs from the LLM API key. */
3484
3485
  get embeddingClient() {
3485
- var _a2;
3486
- if (((_a2 = this.embeddingConfig) == null ? void 0 : _a2.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3486
+ var _a3;
3487
+ if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3487
3488
  return buildClient(this.embeddingConfig.apiKey);
3488
3489
  }
3489
3490
  return this.client;
3490
3491
  }
3491
3492
  /** Resolve the embedding model to use, in order of specificity. */
3492
3493
  resolveEmbeddingModel(optionsModel) {
3493
- var _a2, _b;
3494
- return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a2 = this.embeddingConfig) == null ? void 0 : _a2.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3494
+ var _a3, _b;
3495
+ return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3495
3496
  }
3496
3497
  /**
3497
3498
  * Convert ChatMessage[] to the Gemini contents format.
@@ -3511,8 +3512,8 @@ var GeminiProvider = class {
3511
3512
  // ILLMProvider — chat
3512
3513
  // -------------------------------------------------------------------------
3513
3514
  async chat(messages, context, options) {
3514
- var _a2, _b, _c, _d, _e, _f;
3515
- 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.";
3515
+ var _a3, _b, _c, _d, _e, _f;
3516
+ 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.";
3516
3517
  const model = this.client.getGenerativeModel({
3517
3518
  model: this.llmConfig.model,
3518
3519
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3529,8 +3530,8 @@ var GeminiProvider = class {
3529
3530
  }
3530
3531
  chatStream(messages, context, options) {
3531
3532
  return __asyncGenerator(this, null, function* () {
3532
- var _a2, _b, _c, _d, _e, _f;
3533
- 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.";
3533
+ var _a3, _b, _c, _d, _e, _f;
3534
+ 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.";
3534
3535
  const model = this.client.getGenerativeModel({
3535
3536
  model: this.llmConfig.model,
3536
3537
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3565,11 +3566,11 @@ var GeminiProvider = class {
3565
3566
  // ILLMProvider — embeddings
3566
3567
  // -------------------------------------------------------------------------
3567
3568
  async embed(text, options) {
3568
- var _a2, _b;
3569
+ var _a3, _b;
3569
3570
  const content = applyPrefix(
3570
3571
  text,
3571
3572
  options == null ? void 0 : options.taskType,
3572
- (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3573
+ (_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
3573
3574
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3574
3575
  );
3575
3576
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
@@ -3586,7 +3587,7 @@ var GeminiProvider = class {
3586
3587
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
3587
3588
  const model = this.embeddingClient.getGenerativeModel({ model: modelName });
3588
3589
  const requests = texts.map((text) => {
3589
- var _a2, _b;
3590
+ var _a3, _b;
3590
3591
  return {
3591
3592
  content: {
3592
3593
  role: "user",
@@ -3594,7 +3595,7 @@ var GeminiProvider = class {
3594
3595
  text: applyPrefix(
3595
3596
  text,
3596
3597
  options == null ? void 0 : options.taskType,
3597
- (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3598
+ (_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
3598
3599
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3599
3600
  )
3600
3601
  }]
@@ -3611,8 +3612,8 @@ var GeminiProvider = class {
3611
3612
  throw err;
3612
3613
  });
3613
3614
  return response.embeddings.map((e) => {
3614
- var _a2;
3615
- return (_a2 = e.values) != null ? _a2 : [];
3615
+ var _a3;
3616
+ return (_a3 = e.values) != null ? _a3 : [];
3616
3617
  });
3617
3618
  }
3618
3619
  // -------------------------------------------------------------------------
@@ -3701,8 +3702,8 @@ var GroqProvider = class {
3701
3702
  };
3702
3703
  }
3703
3704
  async chat(messages, context, options) {
3704
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3705
- 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.";
3705
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
3706
+ 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.";
3706
3707
  const systemMessage = {
3707
3708
  role: "system",
3708
3709
  content: buildSystemContent(basePrompt, context)
@@ -3726,8 +3727,8 @@ var GroqProvider = class {
3726
3727
  }
3727
3728
  chatStream(messages, context, options) {
3728
3729
  return __asyncGenerator(this, null, function* () {
3729
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3730
- 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.";
3730
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3731
+ 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.";
3731
3732
  const systemMessage = {
3732
3733
  role: "system",
3733
3734
  content: buildSystemContent(basePrompt, context)
@@ -3861,8 +3862,8 @@ var QwenProvider = class {
3861
3862
  };
3862
3863
  }
3863
3864
  async chat(messages, context, options) {
3864
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3865
- 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.";
3865
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
3866
+ 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.";
3866
3867
  const systemMessage = {
3867
3868
  role: "system",
3868
3869
  content: buildSystemContent(basePrompt, context)
@@ -3886,8 +3887,8 @@ var QwenProvider = class {
3886
3887
  }
3887
3888
  chatStream(messages, context, options) {
3888
3889
  return __asyncGenerator(this, null, function* () {
3889
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3890
- 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.";
3890
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3891
+ 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.";
3891
3892
  const systemMessage = {
3892
3893
  role: "system",
3893
3894
  content: buildSystemContent(basePrompt, context)
@@ -3934,8 +3935,8 @@ var QwenProvider = class {
3934
3935
  return results[0];
3935
3936
  }
3936
3937
  async batchEmbed(texts, options) {
3937
- var _a2, _b, _c, _d, _e, _f;
3938
- 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";
3938
+ var _a3, _b, _c, _d, _e, _f;
3939
+ 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";
3939
3940
  const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
3940
3941
  const client = apiKey !== this.llmConfig.apiKey ? new OpenAI3({
3941
3942
  apiKey,
@@ -3996,9 +3997,9 @@ var LLM_PROFILES = {
3996
3997
 
3997
3998
  // src/llm/providers/UniversalLLMAdapter.ts
3998
3999
  function extractContent(obj) {
3999
- var _a2, _b, _c;
4000
+ var _a3, _b, _c;
4000
4001
  if (!obj || typeof obj !== "object") return void 0;
4001
- const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
4002
+ const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
4002
4003
  if (!choice) return void 0;
4003
4004
  if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
4004
4005
  if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
@@ -4008,10 +4009,10 @@ function extractContent(obj) {
4008
4009
  }
4009
4010
  var UniversalLLMAdapter = class {
4010
4011
  constructor(config) {
4011
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
4012
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
4012
4013
  this.model = config.model;
4013
4014
  const llmConfig = config;
4014
- const options = (_a2 = llmConfig.options) != null ? _a2 : {};
4015
+ const options = (_a3 = llmConfig.options) != null ? _a3 : {};
4015
4016
  let profile = {};
4016
4017
  if (typeof options.profile === "string") {
4017
4018
  profile = LLM_PROFILES[options.profile] || {};
@@ -4037,8 +4038,8 @@ var UniversalLLMAdapter = class {
4037
4038
  });
4038
4039
  }
4039
4040
  async chat(messages, context) {
4040
- var _a2, _b, _c, _d, _e;
4041
- const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4041
+ var _a3, _b, _c, _d, _e;
4042
+ const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
4042
4043
  const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
4043
4044
  role: m.role || "user",
4044
4045
  content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
@@ -4104,8 +4105,8 @@ ${context != null ? context : "None"}` },
4104
4105
  */
4105
4106
  chatStream(messages, context) {
4106
4107
  return __asyncGenerator(this, null, function* () {
4107
- var _a2, _b, _c, _d, _e, _f;
4108
- const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4108
+ var _a3, _b, _c, _d, _e, _f;
4109
+ const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
4109
4110
  const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
4110
4111
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
4111
4112
  const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
@@ -4231,8 +4232,8 @@ ${context != null ? context : "None"}` },
4231
4232
  });
4232
4233
  }
4233
4234
  async embed(text) {
4234
- var _a2, _b, _c, _d, _e;
4235
- const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
4235
+ var _a3, _b, _c, _d, _e;
4236
+ const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
4236
4237
  const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
4237
4238
  try {
4238
4239
  const { data: data2 } = await this.http.post(path2, payload);
@@ -4321,7 +4322,7 @@ var LLMFactory = class _LLMFactory {
4321
4322
  ];
4322
4323
  }
4323
4324
  static create(llmConfig, embeddingConfig) {
4324
- var _a2, _b, _c;
4325
+ var _a3, _b, _c;
4325
4326
  switch (llmConfig.provider) {
4326
4327
  case "openai":
4327
4328
  return new OpenAIProvider(llmConfig, embeddingConfig);
@@ -4340,7 +4341,7 @@ var LLMFactory = class _LLMFactory {
4340
4341
  case "custom":
4341
4342
  return new UniversalLLMAdapter(llmConfig);
4342
4343
  default: {
4343
- const providerName = String((_a2 = llmConfig.provider) != null ? _a2 : "").toLowerCase();
4344
+ const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
4344
4345
  const customFactory = customProviders.get(providerName);
4345
4346
  if (customFactory) {
4346
4347
  return customFactory(llmConfig);
@@ -4442,7 +4443,7 @@ var ProviderRegistry = class {
4442
4443
  return null;
4443
4444
  }
4444
4445
  static async loadVectorProviderClass(provider) {
4445
- var _a2;
4446
+ var _a3;
4446
4447
  if (this.vectorProviders[provider]) return this.vectorProviders[provider];
4447
4448
  switch (provider) {
4448
4449
  case "pinecone": {
@@ -4451,7 +4452,7 @@ var ProviderRegistry = class {
4451
4452
  }
4452
4453
  case "pgvector":
4453
4454
  case "postgresql": {
4454
- const postgresMode = ((_a2 = process.env.POSTGRES_MODE) != null ? _a2 : "multi").toLowerCase();
4455
+ const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
4455
4456
  if (postgresMode === "single") {
4456
4457
  const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
4457
4458
  return PostgreSQLProvider2;
@@ -4674,7 +4675,7 @@ var ConfigValidator = class {
4674
4675
  // package.json
4675
4676
  var package_default = {
4676
4677
  name: "@retrivora-ai/rag-engine",
4677
- version: "2.2.9",
4678
+ version: "2.3.1",
4678
4679
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
4679
4680
  author: "Abhinav Alkuchi",
4680
4681
  license: "UNLICENSED",
@@ -4979,8 +4980,8 @@ var Reranker = class {
4979
4980
  return matches.sort((a, b) => b.score - a.score).slice(0, limit);
4980
4981
  }
4981
4982
  const scoredMatches = matches.map((match) => {
4982
- var _a2;
4983
- const contentLower = ((_a2 = match == null ? void 0 : match.content) != null ? _a2 : "").toLowerCase();
4983
+ var _a3;
4984
+ const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
4984
4985
  let keywordScore = 0;
4985
4986
  keywords.forEach((keyword) => {
4986
4987
  if (contentLower.includes(keyword)) {
@@ -5002,8 +5003,8 @@ var Reranker = class {
5002
5003
 
5003
5004
  Documents:
5004
5005
  ${topN.map((m, i) => {
5005
- var _a2;
5006
- return `[${i}] ${((_a2 = m == null ? void 0 : m.content) != null ? _a2 : "").replace(/\n/g, " ")}`;
5006
+ var _a3;
5007
+ return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
5007
5008
  }).join("\n")}` }],
5008
5009
  "",
5009
5010
  {
@@ -5047,11 +5048,11 @@ var LlamaIndexIngestor = class {
5047
5048
  * than standard character-count splitting.
5048
5049
  */
5049
5050
  async chunk(text, options = {}) {
5050
- var _a2, _b;
5051
+ var _a3, _b;
5051
5052
  try {
5052
5053
  const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
5053
5054
  const splitter = new SentenceSplitter({
5054
- chunkSize: (_a2 = options.chunkSize) != null ? _a2 : 1e3,
5055
+ chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
5055
5056
  chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
5056
5057
  });
5057
5058
  const doc = new Document({ text, metadata: options.metadata || {} });
@@ -5160,7 +5161,7 @@ ${error instanceof Error ? error.message : String(error)}`
5160
5161
  * The agent returns `{ messages: [...] }` — the last message is the final answer.
5161
5162
  */
5162
5163
  async run(input, chatHistory = []) {
5163
- var _a2, _b, _c;
5164
+ var _a3, _b, _c;
5164
5165
  if (!this.agent) {
5165
5166
  throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
5166
5167
  }
@@ -5171,7 +5172,7 @@ ${error instanceof Error ? error.message : String(error)}`
5171
5172
  const response = await this.agent.invoke({
5172
5173
  messages: [...historyMessages, new HumanMessage(input)]
5173
5174
  });
5174
- const lastMessage = (_a2 = response == null ? void 0 : response.messages) == null ? void 0 : _a2.at(-1);
5175
+ const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
5175
5176
  if (lastMessage && typeof lastMessage.content === "string") {
5176
5177
  return lastMessage.content;
5177
5178
  }
@@ -5223,7 +5224,7 @@ var MCPClient = class {
5223
5224
  }
5224
5225
  }
5225
5226
  async connectStdio() {
5226
- var _a2;
5227
+ var _a3;
5227
5228
  const cmd = this.config.command;
5228
5229
  if (!cmd) {
5229
5230
  throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
@@ -5238,7 +5239,7 @@ var MCPClient = class {
5238
5239
  this.stdioBuffer += data.toString("utf-8");
5239
5240
  this.processStdioLines();
5240
5241
  });
5241
- (_a2 = this.childProcess.stderr) == null ? void 0 : _a2.on("data", (data) => {
5242
+ (_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
5242
5243
  console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
5243
5244
  });
5244
5245
  this.childProcess.on("close", (code) => {
@@ -5313,14 +5314,14 @@ var MCPClient = class {
5313
5314
  }
5314
5315
  }
5315
5316
  async sendNotification(method, params) {
5316
- var _a2;
5317
+ var _a3;
5317
5318
  const notification = {
5318
5319
  jsonrpc: "2.0",
5319
5320
  method,
5320
5321
  params
5321
5322
  };
5322
5323
  if (this.config.transport === "stdio") {
5323
- if ((_a2 = this.childProcess) == null ? void 0 : _a2.stdin) {
5324
+ if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
5324
5325
  this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
5325
5326
  }
5326
5327
  } else if (this.sseUrl) {
@@ -5398,11 +5399,11 @@ var MCPRegistry = class {
5398
5399
  // src/core/MultiAgentCoordinator.ts
5399
5400
  var MultiAgentCoordinator = class {
5400
5401
  constructor(options) {
5401
- var _a2;
5402
+ var _a3;
5402
5403
  this.llmProvider = options.llmProvider;
5403
5404
  this.mcpRegistry = options.mcpRegistry;
5404
5405
  this.documentSearch = options.documentSearch;
5405
- this.maxIterations = (_a2 = options.maxIterations) != null ? _a2 : 5;
5406
+ this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
5406
5407
  }
5407
5408
  /**
5408
5409
  * Run the multi-agent coordination loop synchronously and return the final response.
@@ -5454,8 +5455,8 @@ Available Tools:
5454
5455
 
5455
5456
  ${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
5456
5457
  ${mcpTools.map((mt) => {
5457
- var _a2;
5458
- return `- ${mt.tool.name}(${JSON.stringify(((_a2 = mt.tool.inputSchema) == null ? void 0 : _a2.properties) || {})}): ${mt.tool.description || "No description provided."}`;
5458
+ var _a3;
5459
+ return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
5459
5460
  }).join("\n")}
5460
5461
 
5461
5462
  Tool Calling Protocol:
@@ -5613,6 +5614,100 @@ ${toolResultText}`
5613
5614
  }
5614
5615
  };
5615
5616
 
5617
+ // src/core/CircuitBreaker.ts
5618
+ var CircuitBreaker = class {
5619
+ constructor(options = {}) {
5620
+ this.state = "closed";
5621
+ this.failureCount = 0;
5622
+ this.successCount = 0;
5623
+ this.lastFailureAt = 0;
5624
+ this.halfOpenCalls = 0;
5625
+ var _a3, _b, _c;
5626
+ this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
5627
+ this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
5628
+ this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
5629
+ }
5630
+ record(success) {
5631
+ const now = Date.now();
5632
+ if (success) {
5633
+ this.successCount++;
5634
+ if (this.state === "half-open") {
5635
+ this.state = "closed";
5636
+ this.failureCount = 0;
5637
+ this.halfOpenCalls = 0;
5638
+ this.successCount = 1;
5639
+ } else if (this.state === "closed") {
5640
+ if (this.successCount >= this.failureThreshold) {
5641
+ this.failureCount = Math.max(0, this.failureCount - 1);
5642
+ this.successCount = 0;
5643
+ }
5644
+ }
5645
+ } else {
5646
+ this.failureCount++;
5647
+ this.lastFailureAt = now;
5648
+ this.successCount = 0;
5649
+ if (this.state === "half-open") {
5650
+ this.state = "open";
5651
+ this.halfOpenCalls = 0;
5652
+ } else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
5653
+ this.state = "open";
5654
+ }
5655
+ }
5656
+ }
5657
+ canExecute() {
5658
+ const now = Date.now();
5659
+ if (this.state === "closed") {
5660
+ return true;
5661
+ }
5662
+ if (this.state === "open") {
5663
+ if (now - this.lastFailureAt >= this.resetTimeoutMs) {
5664
+ this.state = "half-open";
5665
+ this.halfOpenCalls = 0;
5666
+ return true;
5667
+ }
5668
+ return false;
5669
+ }
5670
+ if (this.state === "half-open") {
5671
+ return this.halfOpenCalls < this.halfOpenMaxCalls;
5672
+ }
5673
+ return true;
5674
+ }
5675
+ async wrap(fn) {
5676
+ if (!this.canExecute()) {
5677
+ const retryAfterSec = Math.ceil(
5678
+ Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
5679
+ );
5680
+ throw new Error(
5681
+ `Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
5682
+ );
5683
+ }
5684
+ if (this.state === "half-open") {
5685
+ this.halfOpenCalls++;
5686
+ }
5687
+ try {
5688
+ const result = await fn();
5689
+ this.record(true);
5690
+ return result;
5691
+ } catch (err) {
5692
+ this.record(false);
5693
+ throw err;
5694
+ }
5695
+ }
5696
+ getState() {
5697
+ return this.state;
5698
+ }
5699
+ getFailureCount() {
5700
+ return this.failureCount;
5701
+ }
5702
+ reset() {
5703
+ this.state = "closed";
5704
+ this.failureCount = 0;
5705
+ this.successCount = 0;
5706
+ this.lastFailureAt = 0;
5707
+ this.halfOpenCalls = 0;
5708
+ }
5709
+ };
5710
+
5616
5711
  // src/core/BatchProcessor.ts
5617
5712
  function isTransientError(error) {
5618
5713
  if (!(error instanceof Error)) return false;
@@ -5636,7 +5731,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
5636
5731
  function sleep(ms) {
5637
5732
  return new Promise((resolve) => setTimeout(resolve, ms));
5638
5733
  }
5639
- var BatchProcessor = class {
5734
+ var _BatchProcessor = class _BatchProcessor {
5735
+ /**
5736
+ * Execute a processor call through the circuit breaker.
5737
+ * Only transient failures count toward opening the circuit.
5738
+ */
5739
+ static async executeWithCircuitBreaker(processor) {
5740
+ if (!this.cb.canExecute()) {
5741
+ const retryAfterSec = Math.ceil(
5742
+ Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
5743
+ );
5744
+ throw new Error(
5745
+ `[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
5746
+ );
5747
+ }
5748
+ if (this.cb.state === "half-open") {
5749
+ this.cb.halfOpenCalls++;
5750
+ }
5751
+ try {
5752
+ const result = await processor();
5753
+ this.cb.record(true);
5754
+ return result;
5755
+ } catch (err) {
5756
+ if (isTransientError(err)) {
5757
+ this.cb.record(false);
5758
+ }
5759
+ throw err;
5760
+ }
5761
+ }
5640
5762
  /**
5641
5763
  * Processes an array of items in configurable batches with retry logic.
5642
5764
  *
@@ -5677,7 +5799,7 @@ var BatchProcessor = class {
5677
5799
  let lastError;
5678
5800
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
5679
5801
  try {
5680
- const result = await processor(batch);
5802
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
5681
5803
  results.push(result);
5682
5804
  success = true;
5683
5805
  break;
@@ -5735,7 +5857,7 @@ ${errorMessages}`
5735
5857
  let lastError;
5736
5858
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
5737
5859
  try {
5738
- const result = await processor(item);
5860
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
5739
5861
  results.push(result);
5740
5862
  success = true;
5741
5863
  break;
@@ -5808,7 +5930,7 @@ ${errorMessages}`
5808
5930
  }));
5809
5931
  const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
5810
5932
  try {
5811
- const result = await processor(item);
5933
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
5812
5934
  return { success: true, result, index: originalIndex };
5813
5935
  } catch (err) {
5814
5936
  const error = err instanceof Error ? err : new Error(String(err));
@@ -5836,6 +5958,12 @@ ${errorMessages}`
5836
5958
  return { results, errors, totalProcessed, totalFailed };
5837
5959
  }
5838
5960
  };
5961
+ _BatchProcessor.cb = new CircuitBreaker({
5962
+ failureThreshold: 5,
5963
+ resetTimeoutMs: 3e4,
5964
+ halfOpenMaxCalls: 1
5965
+ });
5966
+ var BatchProcessor = _BatchProcessor;
5839
5967
 
5840
5968
  // src/config/EmbeddingStrategy.ts
5841
5969
  var EmbeddingStrategyResolver = class {
@@ -5933,7 +6061,7 @@ var QueryProcessor = class {
5933
6061
  * @param validFields Optional list of known filterable fields to look for
5934
6062
  */
5935
6063
  static extractQueryFieldHints(question, validFields = []) {
5936
- var _a2, _b, _c, _d;
6064
+ var _a3, _b, _c, _d;
5937
6065
  if (!question.trim()) return [];
5938
6066
  const hints = /* @__PURE__ */ new Map();
5939
6067
  const addHint = (value, field) => {
@@ -6013,7 +6141,7 @@ var QueryProcessor = class {
6013
6141
  ];
6014
6142
  for (const p of universalPatterns) {
6015
6143
  for (const match of question.matchAll(p.regex)) {
6016
- const val = p.group ? (_a2 = match[p.group]) != null ? _a2 : match[0] : match[0];
6144
+ const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
6017
6145
  if (!val) continue;
6018
6146
  if (p.field) addHint(val, p.field);
6019
6147
  else addHint(val);
@@ -6237,11 +6365,11 @@ var LLMRouter = class {
6237
6365
  * When provided it is used directly as the 'default' role without re-constructing.
6238
6366
  */
6239
6367
  async initialize(prebuiltDefault) {
6240
- var _a2;
6368
+ var _a3;
6241
6369
  const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
6242
6370
  this.models.set("default", defaultModel);
6243
6371
  const envFastModel = process.env.FAST_LLM_MODEL;
6244
- const providerFastDefault = (_a2 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a2 : "";
6372
+ const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
6245
6373
  const fastModelName = envFastModel || providerFastDefault;
6246
6374
  if (fastModelName && fastModelName !== this.config.llm.model) {
6247
6375
  console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
@@ -6260,8 +6388,8 @@ var LLMRouter = class {
6260
6388
  * Falls back to 'default' if the requested role is not registered.
6261
6389
  */
6262
6390
  get(role) {
6263
- var _a2;
6264
- const provider = (_a2 = this.models.get(role)) != null ? _a2 : this.models.get("default");
6391
+ var _a3;
6392
+ const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
6265
6393
  if (!provider) {
6266
6394
  throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
6267
6395
  }
@@ -6347,8 +6475,8 @@ var IntentClassifier = class {
6347
6475
  numericFieldCount = numericKeys.size;
6348
6476
  categoricalFieldCount = catKeys.size;
6349
6477
  if (productKeyMatches >= 2 || docs.some((d) => {
6350
- var _a2, _b;
6351
- 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");
6478
+ var _a3, _b;
6479
+ 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");
6352
6480
  })) {
6353
6481
  isProductLike = true;
6354
6482
  }
@@ -6630,8 +6758,8 @@ var TextRendererStrategy = class {
6630
6758
  }
6631
6759
  const docs = Array.isArray(data) ? data : [];
6632
6760
  const text = docs.map((d) => {
6633
- var _a2;
6634
- return (_a2 = d == null ? void 0 : d.content) != null ? _a2 : "";
6761
+ var _a3;
6762
+ return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
6635
6763
  }).join("\n\n");
6636
6764
  return { type: "text", title, data: { content: text || "No detailed content available." } };
6637
6765
  }
@@ -6774,9 +6902,9 @@ var LRUDecisionCache = class {
6774
6902
  this.maxSize = maxSize;
6775
6903
  }
6776
6904
  generateKey(context) {
6777
- var _a2, _b;
6905
+ var _a3, _b;
6778
6906
  const q = (context.userQuery || "").toLowerCase().trim();
6779
- const docCount = (_b = (_a2 = context.retrievedDocuments) == null ? void 0 : _a2.length) != null ? _b : 0;
6907
+ const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
6780
6908
  return `${q}::docs:${docCount}`;
6781
6909
  }
6782
6910
  get(context) {
@@ -6877,7 +7005,7 @@ var UITransformer = class _UITransformer {
6877
7005
  * Prefer `analyzeAndDecide()` in production.
6878
7006
  */
6879
7007
  static transform(userQuery, retrievedData, config, trainedSchema, intent) {
6880
- var _a2, _b, _c;
7008
+ var _a3, _b, _c;
6881
7009
  if (!retrievedData || retrievedData.length === 0) {
6882
7010
  return this.createTextResponse("No data available", "No relevant data found for your query.");
6883
7011
  }
@@ -6897,7 +7025,7 @@ var UITransformer = class _UITransformer {
6897
7025
  return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
6898
7026
  }
6899
7027
  if (resolvedIntent.visualizationHint === "distribution") {
6900
- return (_a2 = this.transformToHistogram(profile, userQuery)) != null ? _a2 : this.transformToBarChart(filteredData, profile, userQuery);
7028
+ return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
6901
7029
  }
6902
7030
  if (resolvedIntent.visualizationHint === "correlation") {
6903
7031
  return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
@@ -7230,11 +7358,11 @@ ${schemaProfileText}` : ""}`;
7230
7358
  };
7231
7359
  }
7232
7360
  static transformToPieChart(data, profile, query = "") {
7233
- var _a2;
7361
+ var _a3;
7234
7362
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
7235
7363
  const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
7236
- var _a3;
7237
- return String((_a3 = record.fields[dimension.key]) != null ? _a3 : "");
7364
+ var _a4;
7365
+ return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
7238
7366
  }).filter(Boolean))) : this.detectCategories(data);
7239
7367
  if (categories.length === 0) return null;
7240
7368
  const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
@@ -7244,7 +7372,7 @@ ${schemaProfileText}` : ""}`;
7244
7372
  });
7245
7373
  return {
7246
7374
  type: "pie_chart",
7247
- title: `Distribution by ${(_a2 = dimension == null ? void 0 : dimension.label) != null ? _a2 : "Category"}`,
7375
+ title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
7248
7376
  description: `Showing breakdown across ${pieData.length} categories`,
7249
7377
  data: pieData
7250
7378
  };
@@ -7254,8 +7382,8 @@ ${schemaProfileText}` : ""}`;
7254
7382
  const valueField = profile.numericFields[0];
7255
7383
  const buckets = /* @__PURE__ */ new Map();
7256
7384
  profile.records.forEach((record) => {
7257
- var _a2, _b, _c;
7258
- const timestamp = String((_a2 = record.fields[dateField.key]) != null ? _a2 : "");
7385
+ var _a3, _b, _c;
7386
+ const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
7259
7387
  const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
7260
7388
  buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
7261
7389
  });
@@ -7268,23 +7396,23 @@ ${schemaProfileText}` : ""}`;
7268
7396
  };
7269
7397
  }
7270
7398
  static transformToBarChart(data, profile, query = "", horizontal = false) {
7271
- var _a2;
7399
+ var _a3;
7272
7400
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
7273
7401
  const measure = profile ? this.selectNumericField(profile, query) : void 0;
7274
7402
  const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
7275
7403
  const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
7276
7404
  const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
7277
- var _a3, _b, _c, _d, _e;
7405
+ var _a4, _b, _c, _d, _e;
7278
7406
  const meta = item.metadata || {};
7279
7407
  const label = String(
7280
- (_c = (_b = (_a3 = this.getDynamicVal(meta, "name")) != null ? _a3 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
7408
+ (_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
7281
7409
  );
7282
7410
  const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
7283
7411
  return { category: label, value: Number(value) };
7284
7412
  });
7285
7413
  return {
7286
7414
  type: horizontal ? "horizontal_bar" : "bar_chart",
7287
- title: dimension ? `${(_a2 = measure == null ? void 0 : measure.label) != null ? _a2 : "Count"} by ${dimension.label}` : "Comparison",
7415
+ title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
7288
7416
  description: `Showing ${fallbackData.length} comparable values`,
7289
7417
  data: fallbackData
7290
7418
  };
@@ -7319,11 +7447,11 @@ ${schemaProfileText}` : ""}`;
7319
7447
  if (fields.length < 2) return null;
7320
7448
  const [xField, yField] = fields;
7321
7449
  const points = profile.records.map((record) => {
7322
- var _a2;
7450
+ var _a3;
7323
7451
  const x = this.toFiniteNumber(record.fields[xField.key]);
7324
7452
  const y = this.toFiniteNumber(record.fields[yField.key]);
7325
7453
  if (x === null || y === null) return null;
7326
- return { x, y, label: String((_a2 = this.getRecordLabel(record)) != null ? _a2 : record.id) };
7454
+ return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
7327
7455
  }).filter((point) => point !== null).slice(0, 100);
7328
7456
  if (points.length === 0) return null;
7329
7457
  return {
@@ -7353,9 +7481,9 @@ ${schemaProfileText}` : ""}`;
7353
7481
  static transformToRadarChart(data) {
7354
7482
  const attributeMap = {};
7355
7483
  data.forEach((item) => {
7356
- var _a2, _b, _c;
7484
+ var _a3, _b, _c;
7357
7485
  const meta = item.metadata || {};
7358
- const seriesName = String((_c = (_b = (_a2 = meta.name) != null ? _a2 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
7486
+ const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
7359
7487
  Object.entries(meta).forEach(([key, val]) => {
7360
7488
  if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
7361
7489
  if (!attributeMap[key]) attributeMap[key] = {};
@@ -7371,8 +7499,8 @@ ${schemaProfileText}` : ""}`;
7371
7499
  title: "Product Comparison",
7372
7500
  description: `Comparing ${data.length} items across ${radarData.length} attributes`,
7373
7501
  data: radarData.length > 0 ? radarData : data.map((d) => {
7374
- var _a2;
7375
- return { attribute: ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").substring(0, 40) };
7502
+ var _a3;
7503
+ return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
7376
7504
  })
7377
7505
  };
7378
7506
  }
@@ -7391,8 +7519,8 @@ ${schemaProfileText}` : ""}`;
7391
7519
  return this.createTextResponse(
7392
7520
  "Retrieved Context",
7393
7521
  data.map((item) => {
7394
- var _a2;
7395
- return (_a2 = item == null ? void 0 : item.content) != null ? _a2 : "";
7522
+ var _a3;
7523
+ return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
7396
7524
  }).join("\n\n"),
7397
7525
  `Found ${data.length} relevant results`
7398
7526
  );
@@ -7443,11 +7571,11 @@ ${schemaProfileText}` : ""}`;
7443
7571
  return null;
7444
7572
  }
7445
7573
  static normalizeTransformation(payload) {
7446
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
7574
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
7447
7575
  if (!payload || typeof payload !== "object") return null;
7448
7576
  const p = payload;
7449
7577
  const type = this.normalizeVisualizationType(
7450
- String((_c = (_b = (_a2 = p.type) != null ? _a2 : p.view) != null ? _b : p.chartType) != null ? _c : "")
7578
+ String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
7451
7579
  );
7452
7580
  if (!type) return null;
7453
7581
  const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
@@ -7458,7 +7586,7 @@ ${schemaProfileText}` : ""}`;
7458
7586
  return this.validateTransformation(transformation) ? transformation : null;
7459
7587
  }
7460
7588
  static normalizeVisualizationType(type) {
7461
- var _a2;
7589
+ var _a3;
7462
7590
  const mapping = {
7463
7591
  pie: "pie_chart",
7464
7592
  pie_chart: "pie_chart",
@@ -7486,7 +7614,7 @@ ${schemaProfileText}` : ""}`;
7486
7614
  product_carousel: "product_carousel",
7487
7615
  carousel: "carousel"
7488
7616
  };
7489
- return (_a2 = mapping[type.toLowerCase()]) != null ? _a2 : null;
7617
+ return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
7490
7618
  }
7491
7619
  static validateTransformation(t) {
7492
7620
  const { type, data } = t;
@@ -7602,7 +7730,7 @@ ${schemaProfileText}` : ""}`;
7602
7730
  }
7603
7731
  static profileData(data) {
7604
7732
  const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
7605
- var _a2, _b;
7733
+ var _a3, _b;
7606
7734
  const fields2 = {};
7607
7735
  Object.entries(item.metadata || {}).forEach(([key, value]) => {
7608
7736
  const primitive = this.toPrimitive(value);
@@ -7611,7 +7739,7 @@ ${schemaProfileText}` : ""}`;
7611
7739
  if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
7612
7740
  return {
7613
7741
  id: item.id,
7614
- content: (_a2 = item.content) != null ? _a2 : "",
7742
+ content: (_a3 = item.content) != null ? _a3 : "",
7615
7743
  score: (_b = item.score) != null ? _b : 0,
7616
7744
  fields: fields2,
7617
7745
  source: item
@@ -7692,16 +7820,16 @@ ${schemaProfileText}` : ""}`;
7692
7820
  return null;
7693
7821
  }
7694
7822
  static selectDimensionField(profile, query) {
7695
- var _a2, _b;
7823
+ var _a3, _b;
7696
7824
  const productCategory = profile.categoricalFields.find(
7697
7825
  (field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
7698
7826
  );
7699
7827
  const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
7700
- return (_b = (_a2 = ranked[0]) != null ? _a2 : productCategory) != null ? _b : profile.categoricalFields[0];
7828
+ return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
7701
7829
  }
7702
7830
  static selectNumericField(profile, query) {
7703
- var _a2;
7704
- return (_a2 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a2 : profile.numericFields[0];
7831
+ var _a3;
7832
+ return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
7705
7833
  }
7706
7834
  static rankFieldsByQuery(fields, query) {
7707
7835
  const q = query.toLowerCase();
@@ -7730,8 +7858,8 @@ ${schemaProfileText}` : ""}`;
7730
7858
  static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
7731
7859
  const result = {};
7732
7860
  profile.records.forEach((record) => {
7733
- var _a2, _b, _c;
7734
- const category = String((_a2 = record.fields[dimensionKey]) != null ? _a2 : "Other").trim() || "Other";
7861
+ var _a3, _b, _c;
7862
+ const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
7735
7863
  const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
7736
7864
  result[category] = ((_c = result[category]) != null ? _c : 0) + value;
7737
7865
  });
@@ -7811,8 +7939,8 @@ ${schemaProfileText}` : ""}`;
7811
7939
  static aggregateByCategory(data, categories) {
7812
7940
  const result = Object.fromEntries(categories.map((c) => [c, 0]));
7813
7941
  data.forEach((item) => {
7814
- var _a2;
7815
- const cat = (_a2 = this.getProductCategory(item)) != null ? _a2 : "Other";
7942
+ var _a3;
7943
+ const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
7816
7944
  if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
7817
7945
  else result["Other"] = (result["Other"] || 0) + 1;
7818
7946
  });
@@ -7820,17 +7948,17 @@ ${schemaProfileText}` : ""}`;
7820
7948
  }
7821
7949
  static extractTimeSeriesData(data) {
7822
7950
  return data.map((item) => {
7823
- var _a2, _b, _c, _d, _e, _f;
7951
+ var _a3, _b, _c, _d, _e, _f;
7824
7952
  const meta = item.metadata || {};
7825
7953
  return {
7826
- timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
7954
+ timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
7827
7955
  value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
7828
7956
  label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
7829
7957
  };
7830
7958
  });
7831
7959
  }
7832
7960
  static extractNumericValue(meta) {
7833
- var _a2;
7961
+ var _a3;
7834
7962
  const preferredKeys = [
7835
7963
  "value",
7836
7964
  "count",
@@ -7845,7 +7973,7 @@ ${schemaProfileText}` : ""}`;
7845
7973
  "price"
7846
7974
  ];
7847
7975
  for (const key of preferredKeys) {
7848
- const raw = (_a2 = resolveMetadataValue(meta, key)) != null ? _a2 : meta[key];
7976
+ const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
7849
7977
  const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
7850
7978
  if (Number.isFinite(value)) return value;
7851
7979
  }
@@ -7940,8 +8068,8 @@ ${schemaProfileText}` : ""}`;
7940
8068
  }, query.includes(normalizedField) ? 3 : 0);
7941
8069
  }
7942
8070
  static resolveTableCellValue(item, column) {
7943
- var _a2, _b, _c;
7944
- if (column === "Content") return ((_a2 = item == null ? void 0 : item.content) != null ? _a2 : "").substring(0, 100);
8071
+ var _a3, _b, _c;
8072
+ if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
7945
8073
  const meta = item.metadata || {};
7946
8074
  const normalizedColumn = this.normalizeComparableField(column);
7947
8075
  const exactMetadata = Object.entries(meta).find(
@@ -7993,8 +8121,8 @@ ${schemaProfileText}` : ""}`;
7993
8121
  let inStock = 0;
7994
8122
  let outOfStock = 0;
7995
8123
  data.forEach((d) => {
7996
- var _a2, _b;
7997
- const cat = (_a2 = this.getProductCategory(d)) != null ? _a2 : "Other";
8124
+ var _a3, _b;
8125
+ const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
7998
8126
  if (cat === category) {
7999
8127
  const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
8000
8128
  if (this.determineStockStatus(d)) inStock += quantity;
@@ -8040,9 +8168,9 @@ ${schemaProfileText}` : ""}`;
8040
8168
  }
8041
8169
  // ─── Product Extraction ───────────────────────────────────────────────────
8042
8170
  static getDynamicVal(meta, uiKey, config, trainedSchema) {
8043
- var _a2;
8171
+ var _a3;
8044
8172
  if (!meta) return void 0;
8045
- const mapping = (_a2 = config == null ? void 0 : config.rag) == null ? void 0 : _a2.uiMapping;
8173
+ const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
8046
8174
  if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
8047
8175
  if (trainedSchema && typeof trainedSchema === "object") {
8048
8176
  const trainedKey = trainedSchema[uiKey];
@@ -8051,7 +8179,7 @@ ${schemaProfileText}` : ""}`;
8051
8179
  return resolveMetadataValue(meta, uiKey);
8052
8180
  }
8053
8181
  static extractProductInfo(item, config, trainedSchema) {
8054
- var _a2, _b;
8182
+ var _a3, _b;
8055
8183
  if (!item) return null;
8056
8184
  const meta = item.metadata || {};
8057
8185
  const content = item.content || "";
@@ -8059,7 +8187,7 @@ ${schemaProfileText}` : ""}`;
8059
8187
  const price = this.getDynamicVal(meta, "price", config, trainedSchema);
8060
8188
  const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
8061
8189
  const description = this.cleanProductDescription(
8062
- (_a2 = this.extractProductDescriptionFromContent(content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
8190
+ (_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
8063
8191
  );
8064
8192
  if (name || this.isProductData(item)) {
8065
8193
  let finalName = name ? String(name) : void 0;
@@ -8194,10 +8322,10 @@ RULES:
8194
8322
  }
8195
8323
  static buildContextSummary(sources, maxChars = 6e3) {
8196
8324
  const items = (sources || []).filter(Boolean).map((s, i) => {
8197
- var _a2, _b, _c, _d;
8325
+ var _a3, _b, _c, _d;
8198
8326
  return {
8199
8327
  index: i + 1,
8200
- content: (_b = (_a2 = s == null ? void 0 : s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
8328
+ content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
8201
8329
  metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
8202
8330
  score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
8203
8331
  };
@@ -8237,7 +8365,7 @@ var SchemaMapper = class {
8237
8365
  return promise;
8238
8366
  }
8239
8367
  static async _doTrain(llm, cacheKey, keys) {
8240
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8368
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8241
8369
  console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
8242
8370
  const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
8243
8371
  const messages = [
@@ -8253,7 +8381,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
8253
8381
  }
8254
8382
  ];
8255
8383
  try {
8256
- const baseUrl = (_a2 = llm == null ? void 0 : llm.baseUrl) != null ? _a2 : "";
8384
+ const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
8257
8385
  const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
8258
8386
  const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
8259
8387
  let responseText;
@@ -8428,9 +8556,9 @@ var Pipeline = class {
8428
8556
  this.initialised = false;
8429
8557
  /** Namespace-specific static cold context cache for CAG */
8430
8558
  this.coldContexts = /* @__PURE__ */ new Map();
8431
- var _a2, _b, _c, _d, _e;
8559
+ var _a3, _b, _c, _d, _e;
8432
8560
  this.chunker = new DocumentChunker(
8433
- (_b = (_a2 = config.rag) == null ? void 0 : _a2.chunkSize) != null ? _b : 1e3,
8561
+ (_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
8434
8562
  (_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
8435
8563
  );
8436
8564
  if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
@@ -8446,7 +8574,7 @@ var Pipeline = class {
8446
8574
  return this.initialised ? this.llmProvider : void 0;
8447
8575
  }
8448
8576
  async initialize() {
8449
- var _a2, _b, _c, _d;
8577
+ var _a3, _b, _c, _d;
8450
8578
  if (this.initialised) return;
8451
8579
  const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
8452
8580
 
@@ -8489,7 +8617,7 @@ var Pipeline = class {
8489
8617
  this.entityExtractor = new EntityExtractor(this.llmProvider);
8490
8618
  }
8491
8619
  await this.vectorDB.initialize();
8492
- 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) {
8620
+ 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) {
8493
8621
  this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
8494
8622
  this.multiAgentCoordinator = new MultiAgentCoordinator({
8495
8623
  llmProvider: this.llmProvider,
@@ -8507,8 +8635,8 @@ var Pipeline = class {
8507
8635
  this.initialised = true;
8508
8636
  }
8509
8637
  async loadColdContext(ns) {
8510
- var _a2, _b;
8511
- const cagConfig = (_a2 = this.config.rag) == null ? void 0 : _a2.cag;
8638
+ var _a3, _b;
8639
+ const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
8512
8640
  if (!cagConfig || !cagConfig.enabled) return;
8513
8641
  try {
8514
8642
  const coldNs = cagConfig.coldNamespace || ns;
@@ -8561,12 +8689,12 @@ ${m.content}`).join("\n\n---\n\n");
8561
8689
  }
8562
8690
  /** Step 1: Chunk the document content. */
8563
8691
  async prepareChunks(doc) {
8564
- var _a2, _b;
8692
+ var _a3, _b;
8565
8693
  if (this.llamaIngestor) {
8566
8694
  return this.llamaIngestor.chunk(doc.content, {
8567
8695
  docId: doc.docId,
8568
8696
  metadata: doc.metadata,
8569
- chunkSize: (_a2 = this.config.rag) == null ? void 0 : _a2.chunkSize,
8697
+ chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
8570
8698
  chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
8571
8699
  });
8572
8700
  }
@@ -8664,9 +8792,9 @@ ${m.content}`).join("\n\n---\n\n");
8664
8792
  return { reply, sources };
8665
8793
  }
8666
8794
  async ask(question, history = [], namespace) {
8667
- var _a2, _b;
8795
+ var _a3, _b;
8668
8796
  await this.initialize();
8669
- 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) {
8797
+ 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) {
8670
8798
  return await this.multiAgentCoordinator.run(question, history);
8671
8799
  }
8672
8800
  const stream = this.askStream(question, history, namespace);
@@ -8701,9 +8829,9 @@ ${m.content}`).join("\n\n---\n\n");
8701
8829
  }
8702
8830
  askStream(_0) {
8703
8831
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
8704
- var _a2, _b;
8832
+ var _a3, _b;
8705
8833
  yield new __await(this.initialize());
8706
- 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) {
8834
+ 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) {
8707
8835
  const stream2 = this.multiAgentCoordinator.runStream(question, history);
8708
8836
  try {
8709
8837
  for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
@@ -8752,10 +8880,10 @@ ${m.content}`).join("\n\n---\n\n");
8752
8880
  */
8753
8881
  askStreamInternal(_0) {
8754
8882
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
8755
- 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;
8883
+ 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;
8756
8884
  yield new __await(this.initialize());
8757
8885
  const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
8758
- const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
8886
+ const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
8759
8887
  const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
8760
8888
  const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
8761
8889
  const requestStart = performance.now();
@@ -8804,8 +8932,8 @@ ${m.content}`).join("\n\n---\n\n");
8804
8932
  const rerankStart = performance.now();
8805
8933
  const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
8806
8934
  let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
8807
- var _a3;
8808
- return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
8935
+ var _a4;
8936
+ return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
8809
8937
  });
8810
8938
  const rerankLimit = Math.max(retrievalLimit, fullSources.length);
8811
8939
  const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
@@ -8818,13 +8946,13 @@ ${m.content}`).join("\n\n---\n\n");
8818
8946
  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]
8819
8947
 
8820
8948
  ` + promptSources.map((m, i) => {
8821
- var _a3;
8949
+ var _a4;
8822
8950
  return `[Source ${i + 1}]
8823
- ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
8951
+ ${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
8824
8952
  }).join("\n\n---\n\n") : "No relevant context found.";
8825
8953
  const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
8826
- var _a3, _b2;
8827
- return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
8954
+ var _a4, _b2;
8955
+ return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
8828
8956
  });
8829
8957
  if (graphData && graphData.nodes.length > 0) {
8830
8958
  const graphContext = graphData.nodes.map(
@@ -8852,10 +8980,10 @@ ${context}`;
8852
8980
  yield {
8853
8981
  reply: "",
8854
8982
  sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
8855
- var _a3, _b2, _c2;
8983
+ var _a4, _b2, _c2;
8856
8984
  return {
8857
8985
  id: s.id,
8858
- score: (_a3 = s.score) != null ? _a3 : 0,
8986
+ score: (_a4 = s.score) != null ? _a4 : 0,
8859
8987
  content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
8860
8988
  metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
8861
8989
  namespace: ns
@@ -9048,11 +9176,11 @@ ${context}`;
9048
9176
  systemPrompt,
9049
9177
  userPrompt: question + finalRestrictionSuffix,
9050
9178
  chunks: (sources || []).filter(Boolean).map((s) => {
9051
- var _a3, _b2;
9179
+ var _a4, _b2;
9052
9180
  return {
9053
9181
  id: s.id,
9054
9182
  score: s.score,
9055
- content: (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "",
9183
+ content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
9056
9184
  metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
9057
9185
  namespace: ns
9058
9186
  };
@@ -9071,7 +9199,7 @@ ${context}`;
9071
9199
  const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
9072
9200
  const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
9073
9201
  (async () => {
9074
- var _a3, _b2, _c2, _d2, _e2;
9202
+ var _a4, _b2, _c2, _d2, _e2;
9075
9203
  try {
9076
9204
  let finalTrace = trace;
9077
9205
  if (!awaitHallucination && runHallucination) {
@@ -9080,7 +9208,7 @@ ${context}`;
9080
9208
  finalTrace = buildTrace(backgroundScoreResult);
9081
9209
  }
9082
9210
  }
9083
- const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a3 = this.config.llm) == null ? void 0 : _a3.model) || "llama-3.1-8b-instant";
9211
+ const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
9084
9212
  const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
9085
9213
  const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
9086
9214
  const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
@@ -9134,7 +9262,7 @@ ${context}`;
9134
9262
  * Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
9135
9263
  */
9136
9264
  async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
9137
- var _a2;
9265
+ var _a3;
9138
9266
  if (!sources || sources.length === 0) {
9139
9267
  return UITransformer.transform(question, sources, this.config, cachedSchema);
9140
9268
  }
@@ -9147,7 +9275,7 @@ ${context}`;
9147
9275
  { visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
9148
9276
  );
9149
9277
  }
9150
- const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
9278
+ const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
9151
9279
  if (forceDeterministic || !enableLlmUiTransform) {
9152
9280
  return UITransformer.transform(question, sources, this.config, cachedSchema);
9153
9281
  }
@@ -9165,15 +9293,15 @@ ${context}`;
9165
9293
  const value = this.resolveNumericPredicateValue(source, predicate);
9166
9294
  return value !== null && this.matchesNumericPredicate(value, predicate);
9167
9295
  })).sort((a, b) => {
9168
- var _a2, _b;
9296
+ var _a3, _b;
9169
9297
  const primary = predicates[0];
9170
- const aValue = (_a2 = this.resolveNumericPredicateValue(a, primary)) != null ? _a2 : 0;
9298
+ const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
9171
9299
  const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
9172
9300
  return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
9173
9301
  });
9174
9302
  }
9175
9303
  resolveNumericPredicateValue(source, predicate) {
9176
- var _a2;
9304
+ var _a3;
9177
9305
  if (!source) return null;
9178
9306
  const meta = source.metadata || {};
9179
9307
  const field = predicate.field;
@@ -9186,7 +9314,7 @@ ${context}`;
9186
9314
  const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
9187
9315
  if (value !== null) return value;
9188
9316
  }
9189
- const contentValue = this.extractNumericValueFromContent((_a2 = source.content) != null ? _a2 : "", field);
9317
+ const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
9190
9318
  if (contentValue !== null) return contentValue;
9191
9319
  }
9192
9320
  for (const [key, value] of entries) {
@@ -9242,8 +9370,8 @@ ${context}`;
9242
9370
  return Number.isFinite(numeric) ? numeric : null;
9243
9371
  }
9244
9372
  async retrieve(query, options) {
9245
- var _a2, _b, _c, _d, _e, _f, _g2;
9246
- const ns = formatNamespace((_a2 = options.namespace) != null ? _a2 : this.config.projectId);
9373
+ var _a3, _b, _c, _d, _e, _f, _g2;
9374
+ const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
9247
9375
  const topK = (_b = options.topK) != null ? _b : 5;
9248
9376
  const cacheKey = `${ns}::${query}`;
9249
9377
  let queryVector = this.embeddingCache.get(cacheKey);
@@ -9288,11 +9416,11 @@ ${context}`;
9288
9416
  namespace: ns,
9289
9417
  count: resolvedSources.length,
9290
9418
  sample: resolvedSources.slice(0, 2).map((s) => {
9291
- var _a3;
9419
+ var _a4;
9292
9420
  return {
9293
9421
  id: s == null ? void 0 : s.id,
9294
9422
  score: s == null ? void 0 : s.score,
9295
- contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9423
+ contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
9296
9424
  metadata: s == null ? void 0 : s.metadata
9297
9425
  };
9298
9426
  })
@@ -9306,8 +9434,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
9306
9434
 
9307
9435
  History:
9308
9436
  ${(history || []).map((m) => {
9309
- var _a2;
9310
- return `${(m == null ? void 0 : m.role) || "user"}: ${(_a2 = m == null ? void 0 : m.content) != null ? _a2 : ""}`;
9437
+ var _a3;
9438
+ return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
9311
9439
  }).join("\n")}
9312
9440
 
9313
9441
  New Question: ${question}
@@ -9334,8 +9462,8 @@ Optimized Search Query:`;
9334
9462
  const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
9335
9463
  if (!sources || sources.length === 0) return [];
9336
9464
  const context = sources.map((s) => {
9337
- var _a2;
9338
- return (_a2 = s == null ? void 0 : s.content) != null ? _a2 : "";
9465
+ var _a3;
9466
+ return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
9339
9467
  }).join("\n\n---\n\n");
9340
9468
  const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
9341
9469
  Focus on questions that can be answered by the context.
@@ -9473,18 +9601,200 @@ var ProviderHealthCheck = class {
9473
9601
  }
9474
9602
  };
9475
9603
 
9604
+ // src/core/FreeTierLimitsGuard.ts
9605
+ var FREE_TIER_QUOTAS = {
9606
+ MAX_DOCUMENTS: 25,
9607
+ MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
9608
+ MAX_STORAGE_BYTES: 250 * 1024 * 1024,
9609
+ MAX_TRIAL_REQUEST_UNITS: 500,
9610
+ MAX_DAILY_REQUEST_UNITS: 50,
9611
+ TRIAL_DURATION_DAYS: 14,
9612
+ GRACE_PERIOD_DAYS: 2,
9613
+ MAX_RPM: 10,
9614
+ MAX_RPH: 100,
9615
+ MAX_RPD: 500,
9616
+ MAX_CONCURRENT_REQUESTS: 2,
9617
+ MAX_INPUT_TOKENS: 2e4,
9618
+ MAX_OUTPUT_TOKENS: 4e3,
9619
+ UPGRADE_REMINDER_DAYS: [7, 12, 14],
9620
+ MAX_USERS: 1,
9621
+ MAX_NAMESPACES: 1,
9622
+ MAX_PROJECTS: 1
9623
+ };
9624
+ var FreeTierLimitsGuard = class {
9625
+ static calculateTrialTimestamps(startedAt) {
9626
+ const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
9627
+ const trialStartedAtMs = startDate.getTime();
9628
+ const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
9629
+ const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
9630
+ return {
9631
+ trial_started_at: new Date(trialStartedAtMs).toISOString(),
9632
+ trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
9633
+ grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
9634
+ };
9635
+ }
9636
+ static calculateRequestUnits(operationType, options) {
9637
+ var _a3;
9638
+ const op = operationType.toLowerCase().trim();
9639
+ 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")) {
9640
+ return 0;
9641
+ }
9642
+ if (op.includes("image")) {
9643
+ return 10;
9644
+ }
9645
+ if (op.includes("embedding")) {
9646
+ const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
9647
+ return Math.max(1, Math.ceil(chunks / 1e3));
9648
+ }
9649
+ return 1;
9650
+ }
9651
+ static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
9652
+ const timestamps = this.calculateTrialTimestamps(startedAt);
9653
+ const startMs = new Date(timestamps.trial_started_at).getTime();
9654
+ const expireMs = new Date(timestamps.trial_expires_at).getTime();
9655
+ const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
9656
+ const nowMs = nowServerTime.getTime();
9657
+ const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
9658
+ const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
9659
+ const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
9660
+ const isExpiredTime = nowMs > expireMs;
9661
+ const isPastGraceTime = nowMs > graceExpireMs;
9662
+ let status = "active";
9663
+ let reason;
9664
+ if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
9665
+ status = "expired";
9666
+ reason = "Trial period and grace period have expired. Upgrade your plan.";
9667
+ } else if (isExpiredTime || isConsumedUnits) {
9668
+ status = "grace_period";
9669
+ 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).";
9670
+ }
9671
+ let upgradeReminderDue;
9672
+ if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
9673
+ upgradeReminderDue = daysElapsed;
9674
+ }
9675
+ let usageReminderDue;
9676
+ const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
9677
+ if (usagePercent >= 100) {
9678
+ usageReminderDue = "100%";
9679
+ } else if (usagePercent >= 90) {
9680
+ usageReminderDue = "90%";
9681
+ } else if (usagePercent >= 80) {
9682
+ usageReminderDue = "80%";
9683
+ }
9684
+ return {
9685
+ status,
9686
+ daysElapsed,
9687
+ daysRemaining,
9688
+ isGracePeriod: status === "grace_period",
9689
+ isExpired: status === "expired",
9690
+ upgradeReminderDue,
9691
+ usageReminderDue,
9692
+ reason
9693
+ };
9694
+ }
9695
+ static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
9696
+ var _a3, _b;
9697
+ const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
9698
+ const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
9699
+ if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
9700
+ const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
9701
+ return {
9702
+ allowed: false,
9703
+ reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
9704
+ };
9705
+ }
9706
+ if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
9707
+ return {
9708
+ allowed: false,
9709
+ reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
9710
+ };
9711
+ }
9712
+ if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
9713
+ const mbUsed = (storage / (1024 * 1024)).toFixed(1);
9714
+ return {
9715
+ allowed: false,
9716
+ reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
9717
+ };
9718
+ }
9719
+ return { allowed: true };
9720
+ }
9721
+ static checkRequestAllowed(params) {
9722
+ var _a3, _b, _c;
9723
+ const op = (_a3 = params.operationType) != null ? _a3 : "chat";
9724
+ const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
9725
+ if (costUnits === 0) {
9726
+ return { allowed: true, costUnits: 0 };
9727
+ }
9728
+ if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
9729
+ return {
9730
+ allowed: false,
9731
+ reason: "Token limit exceeded. Upgrade your plan.",
9732
+ costUnits
9733
+ };
9734
+ }
9735
+ if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
9736
+ return {
9737
+ allowed: false,
9738
+ reason: "Token limit exceeded. Upgrade your plan.",
9739
+ costUnits
9740
+ };
9741
+ }
9742
+ if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
9743
+ return {
9744
+ allowed: false,
9745
+ reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
9746
+ costUnits
9747
+ };
9748
+ }
9749
+ const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
9750
+ const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
9751
+ if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
9752
+ return {
9753
+ allowed: false,
9754
+ reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
9755
+ costUnits
9756
+ };
9757
+ }
9758
+ if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
9759
+ return {
9760
+ allowed: false,
9761
+ reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
9762
+ costUnits
9763
+ };
9764
+ }
9765
+ const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
9766
+ if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
9767
+ return {
9768
+ allowed: false,
9769
+ reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
9770
+ costUnits
9771
+ };
9772
+ }
9773
+ return { allowed: true, costUnits };
9774
+ }
9775
+ static checkQueryAllowed(dailyQueriesCount = 0) {
9776
+ if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
9777
+ return {
9778
+ allowed: false,
9779
+ reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
9780
+ };
9781
+ }
9782
+ return { allowed: true };
9783
+ }
9784
+ };
9785
+
9476
9786
  // src/core/VectorPlugin.ts
9477
9787
  var VectorPlugin = class {
9478
9788
  constructor(hostConfig) {
9479
9789
  const resolvedConfig = ConfigResolver.resolve(hostConfig);
9480
9790
  this.config = resolvedConfig;
9481
9791
  this.validationPromise = (async () => {
9482
- var _a2;
9792
+ var _a3;
9483
9793
  await ConfigValidator.validateAndThrow(resolvedConfig);
9484
9794
  LicenseVerifier.verify(
9485
9795
  resolvedConfig.licenseKey,
9486
9796
  resolvedConfig.projectId,
9487
- (_a2 = resolvedConfig.vectorDb) == null ? void 0 : _a2.provider
9797
+ (_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
9488
9798
  );
9489
9799
  })();
9490
9800
  this.validationPromise.catch(() => {
@@ -9518,16 +9828,32 @@ var VectorPlugin = class {
9518
9828
  this.config.embedding
9519
9829
  );
9520
9830
  }
9831
+ estimateInputTokens(message, history = []) {
9832
+ const allContent = message.length + history.reduce((acc, m) => {
9833
+ var _a3, _b;
9834
+ 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);
9835
+ }, 0);
9836
+ return Math.ceil(allContent / 4);
9837
+ }
9521
9838
  /**
9522
9839
  * Run a chat query.
9523
9840
  */
9524
9841
  async chat(message, history = [], namespace) {
9842
+ var _a3;
9525
9843
  try {
9526
9844
  await this.validationPromise;
9527
9845
  } catch (err) {
9528
9846
  throw wrapError(err, "CONFIGURATION_ERROR");
9529
9847
  }
9530
9848
  try {
9849
+ const inputTokens = this.estimateInputTokens(message, history);
9850
+ const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
9851
+ operationType: "chat",
9852
+ inputTokens
9853
+ });
9854
+ if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
9855
+ throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
9856
+ }
9531
9857
  return await this.pipeline.ask(message, history, namespace);
9532
9858
  } catch (err) {
9533
9859
  const msg = String(err);
@@ -9535,6 +9861,9 @@ var VectorPlugin = class {
9535
9861
  if (msg.includes("Embed") || msg.includes("embed")) {
9536
9862
  defaultCode = "EMBEDDING_FAILED";
9537
9863
  }
9864
+ if (msg.toLowerCase().includes("token limit")) {
9865
+ defaultCode = "RATE_LIMITED";
9866
+ }
9538
9867
  throw wrapError(err, defaultCode);
9539
9868
  }
9540
9869
  }
@@ -9543,12 +9872,21 @@ var VectorPlugin = class {
9543
9872
  */
9544
9873
  chatStream(_0) {
9545
9874
  return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
9875
+ var _a3;
9546
9876
  try {
9547
9877
  yield new __await(this.validationPromise);
9548
9878
  } catch (err) {
9549
9879
  throw wrapError(err, "CONFIGURATION_ERROR");
9550
9880
  }
9551
9881
  try {
9882
+ const inputTokens = this.estimateInputTokens(message, history);
9883
+ const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
9884
+ operationType: "chat_stream",
9885
+ inputTokens
9886
+ });
9887
+ if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
9888
+ throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
9889
+ }
9552
9890
  const stream = this.pipeline.askStream(message, history, namespace);
9553
9891
  try {
9554
9892
  for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
@@ -9571,6 +9909,9 @@ var VectorPlugin = class {
9571
9909
  if (msg.includes("Embed") || msg.includes("embed")) {
9572
9910
  defaultCode = "EMBEDDING_FAILED";
9573
9911
  }
9912
+ if (msg.toLowerCase().includes("token limit")) {
9913
+ defaultCode = "RATE_LIMITED";
9914
+ }
9574
9915
  throw wrapError(err, defaultCode);
9575
9916
  }
9576
9917
  });
@@ -9618,8 +9959,8 @@ var DocumentParser = class {
9618
9959
  * Extract text from a File or Buffer based on its type.
9619
9960
  */
9620
9961
  static async parse(file, fileName, mimeType) {
9621
- var _a2;
9622
- const extension = ((_a2 = fileName.split(".").pop()) == null ? void 0 : _a2.toLowerCase()) || "";
9962
+ var _a3;
9963
+ const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
9623
9964
  if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
9624
9965
  return this.readAsText(file);
9625
9966
  }
@@ -9710,9 +10051,9 @@ var DatabaseStorage = class {
9710
10051
  this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
9711
10052
  this.historyFile = path.join(this.fallbackDir, "history.json");
9712
10053
  this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
9713
- var _a2, _b, _c, _d, _e;
10054
+ var _a3, _b, _c, _d, _e;
9714
10055
  this.config = config;
9715
- this.provider = ((_a2 = config.vectorDb) == null ? void 0 : _a2.provider) || "fs";
10056
+ this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
9716
10057
  const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
9717
10058
  const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
9718
10059
  this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
@@ -9747,16 +10088,16 @@ var DatabaseStorage = class {
9747
10088
  }
9748
10089
  }
9749
10090
  checkHistoryEnabled() {
9750
- var _a2, _b;
10091
+ var _a3, _b;
9751
10092
  this.checkPremiumSubscription();
9752
- if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.history) == null ? void 0 : _b.enabled) === false) {
10093
+ if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
9753
10094
  throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
9754
10095
  }
9755
10096
  }
9756
10097
  checkFeedbackEnabled() {
9757
- var _a2, _b;
10098
+ var _a3, _b;
9758
10099
  this.checkPremiumSubscription();
9759
- if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.feedback) == null ? void 0 : _b.enabled) === false) {
10100
+ if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
9760
10101
  throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
9761
10102
  }
9762
10103
  }
@@ -9923,8 +10264,11 @@ var DatabaseStorage = class {
9923
10264
  this.writeLocalFile(this.historyFile, history);
9924
10265
  }
9925
10266
  }
9926
- async getHistory(sessionId) {
10267
+ async getHistory(sessionId, projectIds) {
9927
10268
  this.checkHistoryEnabled();
10269
+ if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
10270
+ return [];
10271
+ }
9928
10272
  if (this.provider === "postgresql" || this.provider === "pgvector") {
9929
10273
  const pool = await this.getPGPool();
9930
10274
  const res = await pool.query(
@@ -9954,8 +10298,11 @@ var DatabaseStorage = class {
9954
10298
  return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
9955
10299
  }
9956
10300
  }
9957
- async clearHistory(sessionId) {
10301
+ async clearHistory(sessionId, projectIds) {
9958
10302
  this.checkHistoryEnabled();
10303
+ if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
10304
+ return;
10305
+ }
9959
10306
  if (this.provider === "postgresql" || this.provider === "pgvector") {
9960
10307
  const pool = await this.getPGPool();
9961
10308
  await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
@@ -9974,21 +10321,36 @@ var DatabaseStorage = class {
9974
10321
  this.writeLocalFile(this.feedbackFile, filteredFeedback);
9975
10322
  }
9976
10323
  }
9977
- async listSessions() {
10324
+ /**
10325
+ * Return true when `sessionId` falls into the allowed `projectIds` scope.
10326
+ * When `projectIds` is empty / undefined we allow the call (legacy behavior
10327
+ * for non-multi-tenant consumers). Session ids typically begin with the
10328
+ * project id they were created for, so we prefix-match as well as contains-match
10329
+ * to catch sharded / suffix-style ids used by some integrations.
10330
+ */
10331
+ sessionInScope(sessionId, projectIds) {
10332
+ if (!projectIds || projectIds.length === 0) return true;
10333
+ return projectIds.some(
10334
+ (pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
10335
+ );
10336
+ }
10337
+ async listSessions(projectIds) {
9978
10338
  this.checkHistoryEnabled();
10339
+ let raw = [];
9979
10340
  if (this.provider === "postgresql" || this.provider === "pgvector") {
9980
10341
  const pool = await this.getPGPool();
9981
10342
  const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
9982
- return res.rows.map((r) => r.session_id);
10343
+ raw = res.rows.map((r) => r.session_id);
9983
10344
  } else if (this.provider === "mongodb") {
9984
10345
  await this.getMongoClient();
9985
10346
  const db = this.getMongoDb();
9986
- return db.collection(this.historyTableName).distinct("session_id");
10347
+ raw = await db.collection(this.historyTableName).distinct("session_id");
9987
10348
  } else {
9988
10349
  const history = this.readLocalFile(this.historyFile);
9989
- const sessions = new Set(history.map((h) => h.session_id));
9990
- return Array.from(sessions);
10350
+ raw = Array.from(new Set(history.map((h) => h.session_id)));
9991
10351
  }
10352
+ if (!projectIds || projectIds.length === 0) return raw;
10353
+ return raw.filter((sid) => this.sessionInScope(sid, projectIds));
9992
10354
  }
9993
10355
  // ─── Feedback Operations ──────────────────────────────────────────────────
9994
10356
  async saveFeedback(feedback) {
@@ -10041,8 +10403,9 @@ var DatabaseStorage = class {
10041
10403
  this.writeLocalFile(this.feedbackFile, list);
10042
10404
  }
10043
10405
  }
10044
- async getFeedback(messageId) {
10406
+ async getFeedback(messageId, projectIds) {
10045
10407
  this.checkFeedbackEnabled();
10408
+ let item = null;
10046
10409
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10047
10410
  const pool = await this.getPGPool();
10048
10411
  const res = await pool.query(
@@ -10051,28 +10414,34 @@ var DatabaseStorage = class {
10051
10414
  WHERE message_id = $1`,
10052
10415
  [messageId]
10053
10416
  );
10054
- return res.rows[0] || null;
10417
+ item = res.rows[0] || null;
10055
10418
  } else if (this.provider === "mongodb") {
10056
10419
  await this.getMongoClient();
10057
10420
  const db = this.getMongoDb();
10058
10421
  const col = db.collection(this.feedbackTableName);
10059
- const item = await col.findOne({ message_id: messageId });
10060
- if (!item) return null;
10061
- return {
10062
- id: item.id,
10063
- messageId: item.message_id,
10064
- sessionId: item.session_id,
10065
- rating: item.rating,
10066
- comment: item.comment,
10067
- createdAt: item.created_at
10068
- };
10422
+ const raw = await col.findOne({ message_id: messageId });
10423
+ if (raw) {
10424
+ item = {
10425
+ id: raw.id,
10426
+ messageId: raw.message_id,
10427
+ sessionId: raw.session_id,
10428
+ rating: raw.rating,
10429
+ comment: raw.comment,
10430
+ createdAt: raw.created_at
10431
+ };
10432
+ }
10069
10433
  } else {
10070
10434
  const list = this.readLocalFile(this.feedbackFile);
10071
- return list.find((f) => f.message_id === messageId) || null;
10435
+ item = list.find((f) => f.message_id === messageId) || null;
10436
+ }
10437
+ if (item && projectIds && projectIds.length > 0) {
10438
+ return this.sessionInScope(item.sessionId, projectIds) ? item : null;
10072
10439
  }
10440
+ return item;
10073
10441
  }
10074
- async listFeedback() {
10442
+ async listFeedback(projectIds) {
10075
10443
  this.checkFeedbackEnabled();
10444
+ let raw = [];
10076
10445
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10077
10446
  const pool = await this.getPGPool();
10078
10447
  const res = await pool.query(
@@ -10080,13 +10449,13 @@ var DatabaseStorage = class {
10080
10449
  FROM ${this.feedbackTableName}
10081
10450
  ORDER BY created_at DESC`
10082
10451
  );
10083
- return res.rows;
10452
+ raw = res.rows;
10084
10453
  } else if (this.provider === "mongodb") {
10085
10454
  await this.getMongoClient();
10086
10455
  const db = this.getMongoDb();
10087
10456
  const col = db.collection(this.feedbackTableName);
10088
10457
  const items = await col.find({}).sort({ created_at: -1 }).toArray();
10089
- return items.map((item) => ({
10458
+ raw = items.map((item) => ({
10090
10459
  id: item.id,
10091
10460
  messageId: item.message_id,
10092
10461
  sessionId: item.session_id,
@@ -10096,8 +10465,10 @@ var DatabaseStorage = class {
10096
10465
  }));
10097
10466
  } else {
10098
10467
  const list = this.readLocalFile(this.feedbackFile);
10099
- return [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
10468
+ raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
10100
10469
  }
10470
+ if (!projectIds || projectIds.length === 0) return raw;
10471
+ return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
10101
10472
  }
10102
10473
  async disconnect() {
10103
10474
  if (this.pgPool) {
@@ -10160,8 +10531,8 @@ var _g = global;
10160
10531
  var _a;
10161
10532
  var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
10162
10533
  function getRateLimitKey(req) {
10163
- var _a2, _b;
10164
- 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";
10534
+ var _a3, _b;
10535
+ 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";
10165
10536
  return `ip:${ip}`;
10166
10537
  }
10167
10538
  function checkRateLimit(req) {
@@ -10183,6 +10554,66 @@ function checkRateLimit(req) {
10183
10554
  }
10184
10555
  return null;
10185
10556
  }
10557
+ var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
10558
+ function isFreeTier(tier) {
10559
+ if (!tier) return true;
10560
+ return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
10561
+ }
10562
+ var _a2;
10563
+ var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
10564
+ function createPaymentRequiredResponse(reason, details) {
10565
+ const body = __spreadProps(__spreadValues({
10566
+ type: "https://retrivora.com/docs/errors/payment-required",
10567
+ title: "Payment Required",
10568
+ status: 402,
10569
+ detail: reason,
10570
+ code: "FREE_TIER_LIMIT_EXCEEDED",
10571
+ instance: void 0
10572
+ }, details != null ? details : {}), {
10573
+ quota: {
10574
+ maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
10575
+ maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
10576
+ maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
10577
+ maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
10578
+ upgradeUrl: "https://retrivora.com/pricing"
10579
+ }
10580
+ });
10581
+ return new Response(JSON.stringify(body), {
10582
+ status: 402,
10583
+ headers: {
10584
+ "Content-Type": "application/problem+json"
10585
+ }
10586
+ });
10587
+ }
10588
+ function resolveLicenseKey(req, config, bodyLicenseKey) {
10589
+ var _a3;
10590
+ 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 || "";
10591
+ }
10592
+ function enforceLicense(req, config, bodyLicenseKey) {
10593
+ const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
10594
+ const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
10595
+ const projectId = config.projectId || "my-rag-app";
10596
+ try {
10597
+ const payload = LicenseVerifier.verify(licenseKey, projectId);
10598
+ return { ok: true, payload };
10599
+ } catch (err) {
10600
+ 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.";
10601
+ const body = {
10602
+ error: {
10603
+ code: "LICENSE_REVOKED",
10604
+ message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
10605
+ },
10606
+ details: message
10607
+ };
10608
+ return {
10609
+ ok: false,
10610
+ response: new Response(JSON.stringify(body), {
10611
+ status: 403,
10612
+ headers: { "Content-Type": "application/json" }
10613
+ })
10614
+ };
10615
+ }
10616
+ }
10186
10617
  var MAX_MESSAGE_LENGTH = 8e3;
10187
10618
  function sanitizeInput(raw) {
10188
10619
  const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
@@ -10204,7 +10635,7 @@ function getOrCreatePlugin(configOrPlugin) {
10204
10635
  return _g[cacheKey];
10205
10636
  }
10206
10637
  function reportTelemetry(req, plugin, action, status, details, trace) {
10207
- var _a2, _b, _c, _d, _e, _f, _g2;
10638
+ var _a3, _b, _c, _d, _e, _f, _g2;
10208
10639
  try {
10209
10640
  const config = plugin.getConfig();
10210
10641
  const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
@@ -10219,7 +10650,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
10219
10650
  absoluteUrl = `${proto}://${host}${telemetryUrl}`;
10220
10651
  }
10221
10652
  const projectId = config.projectId || "default";
10222
- 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";
10653
+ 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";
10223
10654
  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";
10224
10655
  const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
10225
10656
  const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
@@ -10243,7 +10674,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
10243
10674
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
10244
10675
  details
10245
10676
  };
10246
- console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
10247
10677
  fetch(absoluteUrl, {
10248
10678
  method: "POST",
10249
10679
  headers: {
@@ -10301,14 +10731,39 @@ function createChatHandler(configOrPlugin, options) {
10301
10731
  const storage = new DatabaseStorage(plugin.getConfig());
10302
10732
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10303
10733
  return async function POST(req, context) {
10304
- var _a2, _b, _c, _d;
10734
+ var _a3, _b, _c, _d, _e, _f;
10305
10735
  const authResult = await checkAuth(req, onAuthorize);
10306
10736
  if (authResult) return authResult;
10307
10737
  const rateLimited = checkRateLimit(req);
10308
10738
  if (rateLimited) return rateLimited;
10739
+ const config = plugin.getConfig();
10309
10740
  try {
10310
10741
  const body = await req.json();
10311
10742
  const bodyObj = body != null ? body : {};
10743
+ const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
10744
+ if (!licenseCheck.ok) return licenseCheck.response;
10745
+ if (isFreeTier(licenseCheck.payload.tier)) {
10746
+ const estimatedInputTokens = Math.ceil(
10747
+ ((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
10748
+ var _a4, _b2;
10749
+ 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);
10750
+ }, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.reduce((a, m) => {
10751
+ var _a4, _b2;
10752
+ 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);
10753
+ }, 0)) || 0)) / 4
10754
+ );
10755
+ const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
10756
+ operationType: "chat",
10757
+ inputTokens: estimatedInputTokens,
10758
+ projectId: licenseCheck.payload.projectId
10759
+ });
10760
+ if (!chatCheck.allowed) {
10761
+ return createPaymentRequiredResponse(
10762
+ chatCheck.reason || "Free tier quota exceeded.",
10763
+ { tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
10764
+ );
10765
+ }
10766
+ }
10312
10767
  let rawMessage = bodyObj.message;
10313
10768
  if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
10314
10769
  const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
@@ -10340,7 +10795,7 @@ function createChatHandler(configOrPlugin, options) {
10340
10795
  uiTransformation: result.ui_transformation,
10341
10796
  trace: result.trace
10342
10797
  }).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
10343
- 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);
10798
+ 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);
10344
10799
  return NextResponse.json(__spreadProps(__spreadValues({}, result), {
10345
10800
  messageId: assistantMsgId,
10346
10801
  userMessageId: userMsgId
@@ -10357,14 +10812,15 @@ function createStreamHandler(configOrPlugin, options) {
10357
10812
  const storage = new DatabaseStorage(plugin.getConfig());
10358
10813
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10359
10814
  return async function POST(req, context) {
10360
- var _a2;
10815
+ var _a3, _b, _c;
10361
10816
  const authResult = await checkAuth(req, onAuthorize);
10362
10817
  if (authResult) return authResult;
10363
10818
  const rateLimited = checkRateLimit(req);
10364
10819
  if (rateLimited) return rateLimited;
10820
+ const config = plugin.getConfig();
10365
10821
  let body;
10366
10822
  try {
10367
- if ((_a2 = req.headers.get("content-type")) == null ? void 0 : _a2.includes("multipart/form-data")) {
10823
+ if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
10368
10824
  const uploader = createUploadHandler(plugin, { onAuthorize });
10369
10825
  return uploader(req);
10370
10826
  }
@@ -10376,6 +10832,30 @@ function createStreamHandler(configOrPlugin, options) {
10376
10832
  });
10377
10833
  }
10378
10834
  const bodyObj = body != null ? body : {};
10835
+ const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
10836
+ if (!licenseCheck.ok) return licenseCheck.response;
10837
+ if (isFreeTier(licenseCheck.payload.tier)) {
10838
+ const estimatedInputTokens = Math.ceil(
10839
+ ((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
10840
+ var _a4, _b2;
10841
+ 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);
10842
+ }, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.reduce((a, m) => {
10843
+ var _a4, _b2;
10844
+ 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);
10845
+ }, 0)) || 0)) / 4
10846
+ );
10847
+ const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
10848
+ operationType: "chat_stream",
10849
+ inputTokens: estimatedInputTokens,
10850
+ projectId: licenseCheck.payload.projectId
10851
+ });
10852
+ if (!chatCheck.allowed) {
10853
+ return createPaymentRequiredResponse(
10854
+ chatCheck.reason || "Free tier quota exceeded.",
10855
+ { tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
10856
+ );
10857
+ }
10858
+ }
10379
10859
  let rawMessage = bodyObj.message;
10380
10860
  if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
10381
10861
  const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
@@ -10405,7 +10885,7 @@ function createStreamHandler(configOrPlugin, options) {
10405
10885
  let isActive = true;
10406
10886
  const stream = new ReadableStream({
10407
10887
  async start(controller) {
10408
- var _a3, _b, _c, _d, _e;
10888
+ var _a4, _b2, _c2, _d, _e;
10409
10889
  const enqueue = (text) => {
10410
10890
  if (!isActive) return;
10411
10891
  try {
@@ -10438,7 +10918,7 @@ function createStreamHandler(configOrPlugin, options) {
10438
10918
  let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
10439
10919
  if (sources.length > 0) {
10440
10920
  try {
10441
- uiTransformation = (_a3 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a3 : UITransformer.transform(message, sources, plugin.getConfig());
10921
+ uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
10442
10922
  if (uiTransformation) {
10443
10923
  enqueue(sseUIFrame(uiTransformation));
10444
10924
  }
@@ -10462,7 +10942,7 @@ function createStreamHandler(configOrPlugin, options) {
10462
10942
  uiTransformation,
10463
10943
  trace: responseChunk == null ? void 0 : responseChunk.trace
10464
10944
  }).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
10465
- 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);
10945
+ 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);
10466
10946
  }
10467
10947
  }
10468
10948
  } catch (temp) {
@@ -10512,12 +10992,36 @@ function createIngestHandler(configOrPlugin, options) {
10512
10992
  return async function POST(req, context) {
10513
10993
  const authResult = await checkAuth(req, onAuthorize);
10514
10994
  if (authResult) return authResult;
10995
+ const config = plugin.getConfig();
10515
10996
  try {
10516
10997
  const body = await req.json();
10998
+ const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
10999
+ if (!licenseCheck.ok) return licenseCheck.response;
10517
11000
  const { documents, namespace } = body;
10518
11001
  if (!Array.isArray(documents) || documents.length === 0) {
10519
11002
  return NextResponse.json({ error: "documents array is required" }, { status: 400 });
10520
11003
  }
11004
+ if (isFreeTier(licenseCheck.payload.tier)) {
11005
+ const totalIncomingBytes = documents.reduce(
11006
+ (sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
11007
+ 0
11008
+ );
11009
+ const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
11010
+ { documentCount: documents.length },
11011
+ totalIncomingBytes
11012
+ );
11013
+ if (!ingestCheck.allowed) {
11014
+ return createPaymentRequiredResponse(
11015
+ ingestCheck.reason || "Free tier ingestion limit reached.",
11016
+ {
11017
+ tier: licenseCheck.payload.tier,
11018
+ projectId: licenseCheck.payload.projectId,
11019
+ documents: documents.length,
11020
+ incomingBytes: totalIncomingBytes
11021
+ }
11022
+ );
11023
+ }
11024
+ }
10521
11025
  const results = await plugin.ingest(documents, namespace);
10522
11026
  reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
10523
11027
  return NextResponse.json({ results });
@@ -10554,7 +11058,7 @@ function createLicenseHandler(configOrPlugin, options) {
10554
11058
  const plugin = getOrCreatePlugin(configOrPlugin);
10555
11059
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10556
11060
  return async function POST(req) {
10557
- var _a2;
11061
+ var _a3;
10558
11062
  if (req) {
10559
11063
  const authResult = await checkAuth(req, onAuthorize);
10560
11064
  if (authResult) return authResult;
@@ -10562,7 +11066,8 @@ function createLicenseHandler(configOrPlugin, options) {
10562
11066
  try {
10563
11067
  const body = await req.json().catch(() => ({}));
10564
11068
  const config = plugin.getConfig();
10565
- 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 || "";
11069
+ 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 || "";
11070
+ const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
10566
11071
  const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
10567
11072
  const payload = LicenseVerifier.verify(licenseKey, projectId);
10568
11073
  return NextResponse.json({
@@ -10596,6 +11101,9 @@ function createUploadHandler(configOrPlugin, options) {
10596
11101
  return async function POST(req, context) {
10597
11102
  const authResult = await checkAuth(req, onAuthorize);
10598
11103
  if (authResult) return authResult;
11104
+ const config = plugin.getConfig();
11105
+ const licenseCheck = enforceLicense(req, config);
11106
+ if (!licenseCheck.ok) return licenseCheck.response;
10599
11107
  try {
10600
11108
  const formData = await req.formData();
10601
11109
  const files = formData.getAll("files");
@@ -10605,6 +11113,26 @@ function createUploadHandler(configOrPlugin, options) {
10605
11113
  if (!files || files.length === 0) {
10606
11114
  return NextResponse.json({ error: "No files provided" }, { status: 400 });
10607
11115
  }
11116
+ if (isFreeTier(licenseCheck.payload.tier)) {
11117
+ const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
11118
+ const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
11119
+ { documentCount: files.length },
11120
+ totalUploadBytes
11121
+ );
11122
+ if (!uploadCheck.allowed) {
11123
+ return createPaymentRequiredResponse(
11124
+ uploadCheck.reason || "Free tier upload limit reached.",
11125
+ {
11126
+ tier: licenseCheck.payload.tier,
11127
+ projectId: licenseCheck.payload.projectId,
11128
+ fileCount: files.length,
11129
+ totalUploadBytes,
11130
+ maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
11131
+ maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
11132
+ }
11133
+ );
11134
+ }
11135
+ }
10608
11136
  const documents = [];
10609
11137
  for (const file of files) {
10610
11138
  const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
@@ -10714,13 +11242,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
10714
11242
  return async function handler(req) {
10715
11243
  const authResult = await checkAuth(req, onAuthorize);
10716
11244
  if (authResult) return authResult;
11245
+ const config = plugin.getConfig();
11246
+ const licenseCheck = enforceLicense(req, config);
11247
+ if (!licenseCheck.ok) return licenseCheck.response;
10717
11248
  try {
10718
11249
  let query = "";
10719
11250
  let namespace = void 0;
11251
+ let bodyLicenseKey = void 0;
10720
11252
  if (req.method === "POST") {
10721
11253
  const body = await req.json().catch(() => ({}));
10722
11254
  query = body.query || "";
10723
11255
  namespace = body.namespace;
11256
+ bodyLicenseKey = body.licenseKey;
11257
+ if (bodyLicenseKey) {
11258
+ const recheck = enforceLicense(req, config, bodyLicenseKey);
11259
+ if (!recheck.ok) return recheck.response;
11260
+ }
10724
11261
  } else {
10725
11262
  const url = new URL(req.url);
10726
11263
  query = url.searchParams.get("query") || "";
@@ -10743,14 +11280,16 @@ function createHistoryHandler(configOrPlugin, options) {
10743
11280
  const plugin = getOrCreatePlugin(configOrPlugin);
10744
11281
  const storage = new DatabaseStorage(plugin.getConfig());
10745
11282
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11283
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
10746
11284
  return async function handler(req) {
10747
11285
  const authResult = await checkAuth(req, onAuthorize);
10748
11286
  if (authResult) return authResult;
11287
+ const scope = onResolveScope ? await onResolveScope(req) : void 0;
10749
11288
  const url = new URL(req.url);
10750
11289
  const sessionId = url.searchParams.get("sessionId") || "default";
10751
11290
  if (req.method === "GET") {
10752
11291
  try {
10753
- const history = await storage.getHistory(sessionId);
11292
+ const history = await storage.getHistory(sessionId, scope);
10754
11293
  return NextResponse.json({ history });
10755
11294
  } catch (err) {
10756
11295
  const message = err instanceof Error ? err.message : "Failed to fetch history";
@@ -10760,7 +11299,7 @@ function createHistoryHandler(configOrPlugin, options) {
10760
11299
  try {
10761
11300
  const body = await req.json().catch(() => ({}));
10762
11301
  const sid = body.sessionId || sessionId;
10763
- await storage.clearHistory(sid);
11302
+ await storage.clearHistory(sid, scope);
10764
11303
  return NextResponse.json({ success: true });
10765
11304
  } catch (err) {
10766
11305
  const message = err instanceof Error ? err.message : "Failed to clear history";
@@ -10774,18 +11313,20 @@ function createFeedbackHandler(configOrPlugin, options) {
10774
11313
  const plugin = getOrCreatePlugin(configOrPlugin);
10775
11314
  const storage = new DatabaseStorage(plugin.getConfig());
10776
11315
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11316
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
10777
11317
  return async function handler(req) {
10778
11318
  const authResult = await checkAuth(req, onAuthorize);
10779
11319
  if (authResult) return authResult;
11320
+ const scope = onResolveScope ? await onResolveScope(req) : void 0;
10780
11321
  if (req.method === "GET") {
10781
11322
  try {
10782
11323
  const url = new URL(req.url);
10783
11324
  const messageId = url.searchParams.get("messageId");
10784
11325
  if (!messageId) {
10785
- const feedbackList = await storage.listFeedback();
11326
+ const feedbackList = await storage.listFeedback(scope);
10786
11327
  return NextResponse.json({ feedback: feedbackList });
10787
11328
  }
10788
- const feedback = await storage.getFeedback(messageId);
11329
+ const feedback = await storage.getFeedback(messageId, scope);
10789
11330
  return NextResponse.json({ feedback });
10790
11331
  } catch (err) {
10791
11332
  const message = err instanceof Error ? err.message : "Failed to fetch feedback";
@@ -10801,6 +11342,17 @@ function createFeedbackHandler(configOrPlugin, options) {
10801
11342
  if (!rating) {
10802
11343
  return NextResponse.json({ error: "rating is required" }, { status: 400 });
10803
11344
  }
11345
+ if (scope && scope.length > 0) {
11346
+ const matches = scope.some(
11347
+ (pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
11348
+ );
11349
+ if (!matches) {
11350
+ return NextResponse.json(
11351
+ { error: "sessionId is outside the authorized project scope" },
11352
+ { status: 403 }
11353
+ );
11354
+ }
11355
+ }
10804
11356
  await storage.saveFeedback({ messageId, sessionId, rating, comment });
10805
11357
  return NextResponse.json({ success: true });
10806
11358
  } catch (err) {
@@ -10815,14 +11367,15 @@ function createSessionsHandler(configOrPlugin, options) {
10815
11367
  const plugin = getOrCreatePlugin(configOrPlugin);
10816
11368
  const storage = new DatabaseStorage(plugin.getConfig());
10817
11369
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11370
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
10818
11371
  return async function GET(req) {
10819
11372
  if (req) {
10820
11373
  const authResult = await checkAuth(req, onAuthorize);
10821
11374
  if (authResult) return authResult;
10822
11375
  }
10823
- void req;
10824
11376
  try {
10825
- const sessions = await storage.listSessions();
11377
+ const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
11378
+ const sessions = await storage.listSessions(scope);
10826
11379
  return NextResponse.json({ sessions });
10827
11380
  } catch (err) {
10828
11381
  const message = err instanceof Error ? err.message : "Failed to list sessions";
@@ -10833,15 +11386,17 @@ function createSessionsHandler(configOrPlugin, options) {
10833
11386
  function createRagHandler(configOrPlugin, options) {
10834
11387
  const plugin = getOrCreatePlugin(configOrPlugin);
10835
11388
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10836
- const chatHandler = createChatHandler(plugin, { onAuthorize });
10837
- const streamHandler = createStreamHandler(plugin, { onAuthorize });
10838
- const uploadHandler = createUploadHandler(plugin, { onAuthorize });
10839
- const healthHandler = createHealthHandler(plugin, { onAuthorize });
10840
- const suggestionsHandler = createSuggestionsHandler(plugin, { onAuthorize });
10841
- const historyHandler = createHistoryHandler(plugin, { onAuthorize });
10842
- const feedbackHandler = createFeedbackHandler(plugin, { onAuthorize });
10843
- const sessionsHandler = createSessionsHandler(plugin, { onAuthorize });
10844
- const licenseHandler = createLicenseHandler(plugin, { onAuthorize });
11389
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
11390
+ const scopeableOptions = { onAuthorize, onResolveScope };
11391
+ const chatHandler = createChatHandler(plugin, scopeableOptions);
11392
+ const streamHandler = createStreamHandler(plugin, scopeableOptions);
11393
+ const uploadHandler = createUploadHandler(plugin, scopeableOptions);
11394
+ const healthHandler = createHealthHandler(plugin, scopeableOptions);
11395
+ const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
11396
+ const historyHandler = createHistoryHandler(plugin, scopeableOptions);
11397
+ const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
11398
+ const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
11399
+ const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
10845
11400
  async function routePostRequest(req, segment) {
10846
11401
  switch (segment) {
10847
11402
  case "chat":
@@ -10883,7 +11438,7 @@ function createRagHandler(configOrPlugin, options) {
10883
11438
  }
10884
11439
  }
10885
11440
  async function getSegment(req, context) {
10886
- var _a2, _b;
11441
+ var _a3, _b;
10887
11442
  const contentType = req.headers.get("content-type") || "";
10888
11443
  if (contentType.includes("multipart/form-data")) {
10889
11444
  return "upload";
@@ -10900,7 +11455,7 @@ function createRagHandler(configOrPlugin, options) {
10900
11455
  if (pathname.endsWith("/history")) return "history";
10901
11456
  } catch (e) {
10902
11457
  }
10903
- 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;
11458
+ 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;
10904
11459
  const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
10905
11460
  const joined = segments.join("/");
10906
11461
  return joined || "chat";