@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.
package/dist/server.mjs CHANGED
@@ -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) {
@@ -2242,13 +2242,13 @@ var LicenseValidationError = class extends RetrivoraError {
2242
2242
  }
2243
2243
  };
2244
2244
  function wrapError(err, defaultCode, defaultMessage) {
2245
- var _a2;
2245
+ var _a3;
2246
2246
  if (err instanceof RetrivoraError) {
2247
2247
  return err;
2248
2248
  }
2249
2249
  const error = err;
2250
2250
  const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
2251
- 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);
2251
+ 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);
2252
2252
  const code = error == null ? void 0 : error.code;
2253
2253
  if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
2254
2254
  return new RateLimitException(message, err);
@@ -2317,7 +2317,8 @@ var LicenseVerifier = class {
2317
2317
  };
2318
2318
  }
2319
2319
  try {
2320
- const rawToken = licenseKey.replace(/^rtv_/i, "").trim();
2320
+ const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
2321
+ const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
2321
2322
  const parts = rawToken.split(".");
2322
2323
  if (parts.length !== 3) {
2323
2324
  throw new Error("Malformed token structure (expected 3 parts).");
@@ -2529,8 +2530,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
2529
2530
 
2530
2531
  // src/config/serverConfig.ts
2531
2532
  function readString(env, name) {
2532
- var _a2;
2533
- const value = (_a2 = env[name]) == null ? void 0 : _a2.trim();
2533
+ var _a3;
2534
+ const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
2534
2535
  return value ? value : void 0;
2535
2536
  }
2536
2537
  function readNumber(env, name, fallback) {
@@ -2543,8 +2544,8 @@ function readNumber(env, name, fallback) {
2543
2544
  return parsed;
2544
2545
  }
2545
2546
  function readEnum(env, name, fallback, allowed) {
2546
- var _a2;
2547
- const value = (_a2 = readString(env, name)) != null ? _a2 : fallback;
2547
+ var _a3;
2548
+ const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
2548
2549
  if (allowed.includes(value)) {
2549
2550
  return value;
2550
2551
  }
@@ -2554,8 +2555,8 @@ function getRagConfig(baseConfig, env = process.env) {
2554
2555
  return getEnvConfig(env, baseConfig);
2555
2556
  }
2556
2557
  function getEnvConfig(env = process.env, base) {
2557
- 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;
2558
- 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;
2558
+ 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;
2559
+ 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;
2559
2560
  const jwtProjectId = (() => {
2560
2561
  if (!licenseKey) return void 0;
2561
2562
  try {
@@ -2636,7 +2637,7 @@ function getEnvConfig(env = process.env, base) {
2636
2637
  rest: "default",
2637
2638
  custom: "default"
2638
2639
  };
2639
- const isFreeTier = (() => {
2640
+ const isFreeTier2 = (() => {
2640
2641
  if (!licenseKey) return true;
2641
2642
  try {
2642
2643
  const payload = LicenseVerifier.verify(licenseKey, projectId);
@@ -2647,13 +2648,13 @@ function getEnvConfig(env = process.env, base) {
2647
2648
  }
2648
2649
  })();
2649
2650
  const defaultGatewayUrl = (_ra = (_qa = readString(env, "LITELLM_BASE_URL")) != null ? _qa : readString(env, "LLM_BASE_URL")) != null ? _ra : "https://www.retrivora.com/api/v1";
2650
- const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
2651
+ const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
2651
2652
  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;
2652
2653
  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;
2653
- 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";
2654
+ 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";
2654
2655
  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;
2655
2656
  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";
2656
- const defaultEmbeddingProvider = isFreeTier ? "universal_rest" : "universal_rest";
2657
+ const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
2657
2658
  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;
2658
2659
  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;
2659
2660
  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";
@@ -2743,8 +2744,8 @@ function getEnvConfig(env = process.env, base) {
2743
2744
  }
2744
2745
  } : {}), {
2745
2746
  mcpServers: (() => {
2746
- var _a3;
2747
- const raw = (_a3 = readString(env, "MCP_SERVERS")) != null ? _a3 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
2747
+ var _a4;
2748
+ const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
2748
2749
  if (!raw) return void 0;
2749
2750
  try {
2750
2751
  return JSON.parse(raw);
@@ -2789,10 +2790,10 @@ var ConfigResolver = class {
2789
2790
  * fallback behavior.
2790
2791
  */
2791
2792
  static resolveUniversal(hostConfig, env = process.env) {
2792
- var _a2;
2793
+ var _a3;
2793
2794
  if (!hostConfig) return this.resolve(void 0, env);
2794
2795
  const normalized = __spreadProps(__spreadValues({}, hostConfig), {
2795
- vectorDb: (_a2 = hostConfig.vectorDb) != null ? _a2 : hostConfig.vectorDatabase,
2796
+ vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
2796
2797
  rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
2797
2798
  });
2798
2799
  return this.resolve(normalized, env);
@@ -2812,11 +2813,11 @@ var ConfigResolver = class {
2812
2813
  }
2813
2814
  }
2814
2815
  static mergeRetrievalWorkflow(rag, retrieval, workflow) {
2815
- var _a2, _b, _c, _d, _e, _f;
2816
+ var _a3, _b, _c, _d, _e, _f;
2816
2817
  if (!rag && !retrieval && !workflow) return void 0;
2817
2818
  const normalized = __spreadValues({}, rag != null ? rag : {});
2818
2819
  if (retrieval) {
2819
- normalized.topK = (_a2 = retrieval.topK) != null ? _a2 : normalized.topK;
2820
+ normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
2820
2821
  normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
2821
2822
  normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
2822
2823
  if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
@@ -2944,8 +2945,8 @@ var OpenAIProvider = class {
2944
2945
  };
2945
2946
  }
2946
2947
  async chat(messages, context, options) {
2947
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
2948
- 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.";
2948
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
2949
+ 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.";
2949
2950
  const systemMessage = {
2950
2951
  role: "system",
2951
2952
  content: buildSystemContent(basePrompt, context)
@@ -2969,8 +2970,8 @@ var OpenAIProvider = class {
2969
2970
  }
2970
2971
  chatStream(messages, context, options) {
2971
2972
  return __asyncGenerator(this, null, function* () {
2972
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
2973
- 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.";
2973
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
2974
+ 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.";
2974
2975
  const systemMessage = {
2975
2976
  role: "system",
2976
2977
  content: buildSystemContent(basePrompt, context)
@@ -3017,8 +3018,8 @@ var OpenAIProvider = class {
3017
3018
  return results[0];
3018
3019
  }
3019
3020
  async batchEmbed(texts, options) {
3020
- var _a2, _b, _c, _d, _e;
3021
- 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";
3021
+ var _a3, _b, _c, _d, _e;
3022
+ 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";
3022
3023
  const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
3023
3024
  const client = apiKey !== this.llmConfig.apiKey ? new OpenAI({ apiKey }) : this.client;
3024
3025
  const response = await client.embeddings.create({ model, input: texts });
@@ -3095,8 +3096,8 @@ var AnthropicProvider = class {
3095
3096
  };
3096
3097
  }
3097
3098
  async chat(messages, context, options) {
3098
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3099
- 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.";
3099
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3100
+ 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.";
3100
3101
  const system = buildSystemContent(basePrompt, context);
3101
3102
  const anthropicMessages = messages.map((m) => ({
3102
3103
  role: m.role === "assistant" ? "assistant" : "user",
@@ -3134,8 +3135,8 @@ var AnthropicProvider = class {
3134
3135
  }
3135
3136
  chatStream(messages, context, options) {
3136
3137
  return __asyncGenerator(this, null, function* () {
3137
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3138
- 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.";
3138
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3139
+ 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.";
3139
3140
  const system = buildSystemContent(basePrompt, context);
3140
3141
  const anthropicMessages = messages.map((m) => ({
3141
3142
  role: m.role === "assistant" ? "assistant" : "user",
@@ -3219,8 +3220,8 @@ var AnthropicProvider = class {
3219
3220
  import axios from "axios";
3220
3221
  var OllamaProvider = class {
3221
3222
  constructor(llmConfig, embeddingConfig) {
3222
- var _a2, _b, _c;
3223
- const rawBaseURL = ((_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434").replace(/\/+$/, "");
3223
+ var _a3, _b, _c;
3224
+ const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
3224
3225
  const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
3225
3226
  const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
3226
3227
  const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
@@ -3280,8 +3281,8 @@ var OllamaProvider = class {
3280
3281
  };
3281
3282
  }
3282
3283
  async chat(messages, context, options) {
3283
- var _a2, _b, _c, _d, _e, _f;
3284
- 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.";
3284
+ var _a3, _b, _c, _d, _e, _f;
3285
+ 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.";
3285
3286
  const system = buildSystemContent(basePrompt, context);
3286
3287
  const { data } = await this.http.post("/api/chat", {
3287
3288
  model: this.llmConfig.model,
@@ -3299,8 +3300,8 @@ var OllamaProvider = class {
3299
3300
  }
3300
3301
  chatStream(messages, context, options) {
3301
3302
  return __asyncGenerator(this, null, function* () {
3302
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3303
- 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.";
3303
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3304
+ 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.";
3304
3305
  const system = buildSystemContent(basePrompt, context);
3305
3306
  const response = yield new __await(this.http.post("/api/chat", {
3306
3307
  model: this.llmConfig.model,
@@ -3358,8 +3359,8 @@ var OllamaProvider = class {
3358
3359
  });
3359
3360
  }
3360
3361
  async embed(text, options) {
3361
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3362
- 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";
3362
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
3363
+ 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";
3363
3364
  const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
3364
3365
  const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? axios.create({ baseURL, timeout: 6e4 }) : this.http;
3365
3366
  let prompt = text;
@@ -3460,9 +3461,9 @@ var GeminiProvider = class {
3460
3461
  static getHealthChecker() {
3461
3462
  return {
3462
3463
  async check(config) {
3463
- var _a2, _b;
3464
+ var _a3, _b;
3464
3465
  const timestamp = Date.now();
3465
- const apiKey = (_b = (_a2 = config.apiKey) != null ? _a2 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
3466
+ const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
3466
3467
  const modelName = sanitizeModel(config.model);
3467
3468
  try {
3468
3469
  const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
@@ -3492,16 +3493,16 @@ var GeminiProvider = class {
3492
3493
  /** Resolve the embedding client — uses a separate client when the embedding
3493
3494
  * API key differs from the LLM API key. */
3494
3495
  get embeddingClient() {
3495
- var _a2;
3496
- if (((_a2 = this.embeddingConfig) == null ? void 0 : _a2.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3496
+ var _a3;
3497
+ if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3497
3498
  return buildClient(this.embeddingConfig.apiKey);
3498
3499
  }
3499
3500
  return this.client;
3500
3501
  }
3501
3502
  /** Resolve the embedding model to use, in order of specificity. */
3502
3503
  resolveEmbeddingModel(optionsModel) {
3503
- var _a2, _b;
3504
- return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a2 = this.embeddingConfig) == null ? void 0 : _a2.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3504
+ var _a3, _b;
3505
+ return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3505
3506
  }
3506
3507
  /**
3507
3508
  * Convert ChatMessage[] to the Gemini contents format.
@@ -3521,8 +3522,8 @@ var GeminiProvider = class {
3521
3522
  // ILLMProvider — chat
3522
3523
  // -------------------------------------------------------------------------
3523
3524
  async chat(messages, context, options) {
3524
- var _a2, _b, _c, _d, _e, _f;
3525
- 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.";
3525
+ var _a3, _b, _c, _d, _e, _f;
3526
+ 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.";
3526
3527
  const model = this.client.getGenerativeModel({
3527
3528
  model: this.llmConfig.model,
3528
3529
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3539,8 +3540,8 @@ var GeminiProvider = class {
3539
3540
  }
3540
3541
  chatStream(messages, context, options) {
3541
3542
  return __asyncGenerator(this, null, function* () {
3542
- var _a2, _b, _c, _d, _e, _f;
3543
- 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.";
3543
+ var _a3, _b, _c, _d, _e, _f;
3544
+ 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.";
3544
3545
  const model = this.client.getGenerativeModel({
3545
3546
  model: this.llmConfig.model,
3546
3547
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3575,11 +3576,11 @@ var GeminiProvider = class {
3575
3576
  // ILLMProvider — embeddings
3576
3577
  // -------------------------------------------------------------------------
3577
3578
  async embed(text, options) {
3578
- var _a2, _b;
3579
+ var _a3, _b;
3579
3580
  const content = applyPrefix(
3580
3581
  text,
3581
3582
  options == null ? void 0 : options.taskType,
3582
- (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3583
+ (_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
3583
3584
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3584
3585
  );
3585
3586
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
@@ -3596,7 +3597,7 @@ var GeminiProvider = class {
3596
3597
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
3597
3598
  const model = this.embeddingClient.getGenerativeModel({ model: modelName });
3598
3599
  const requests = texts.map((text) => {
3599
- var _a2, _b;
3600
+ var _a3, _b;
3600
3601
  return {
3601
3602
  content: {
3602
3603
  role: "user",
@@ -3604,7 +3605,7 @@ var GeminiProvider = class {
3604
3605
  text: applyPrefix(
3605
3606
  text,
3606
3607
  options == null ? void 0 : options.taskType,
3607
- (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3608
+ (_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
3608
3609
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3609
3610
  )
3610
3611
  }]
@@ -3621,8 +3622,8 @@ var GeminiProvider = class {
3621
3622
  throw err;
3622
3623
  });
3623
3624
  return response.embeddings.map((e) => {
3624
- var _a2;
3625
- return (_a2 = e.values) != null ? _a2 : [];
3625
+ var _a3;
3626
+ return (_a3 = e.values) != null ? _a3 : [];
3626
3627
  });
3627
3628
  }
3628
3629
  // -------------------------------------------------------------------------
@@ -3711,8 +3712,8 @@ var GroqProvider = class {
3711
3712
  };
3712
3713
  }
3713
3714
  async chat(messages, context, options) {
3714
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3715
- 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.";
3715
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
3716
+ 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.";
3716
3717
  const systemMessage = {
3717
3718
  role: "system",
3718
3719
  content: buildSystemContent(basePrompt, context)
@@ -3736,8 +3737,8 @@ var GroqProvider = class {
3736
3737
  }
3737
3738
  chatStream(messages, context, options) {
3738
3739
  return __asyncGenerator(this, null, function* () {
3739
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3740
- 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.";
3740
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3741
+ 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.";
3741
3742
  const systemMessage = {
3742
3743
  role: "system",
3743
3744
  content: buildSystemContent(basePrompt, context)
@@ -3871,8 +3872,8 @@ var QwenProvider = class {
3871
3872
  };
3872
3873
  }
3873
3874
  async chat(messages, context, options) {
3874
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3875
- 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.";
3875
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
3876
+ 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.";
3876
3877
  const systemMessage = {
3877
3878
  role: "system",
3878
3879
  content: buildSystemContent(basePrompt, context)
@@ -3896,8 +3897,8 @@ var QwenProvider = class {
3896
3897
  }
3897
3898
  chatStream(messages, context, options) {
3898
3899
  return __asyncGenerator(this, null, function* () {
3899
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
3900
- 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.";
3900
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
3901
+ 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.";
3901
3902
  const systemMessage = {
3902
3903
  role: "system",
3903
3904
  content: buildSystemContent(basePrompt, context)
@@ -3944,8 +3945,8 @@ var QwenProvider = class {
3944
3945
  return results[0];
3945
3946
  }
3946
3947
  async batchEmbed(texts, options) {
3947
- var _a2, _b, _c, _d, _e, _f;
3948
- 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";
3948
+ var _a3, _b, _c, _d, _e, _f;
3949
+ 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";
3949
3950
  const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
3950
3951
  const client = apiKey !== this.llmConfig.apiKey ? new OpenAI3({
3951
3952
  apiKey,
@@ -4045,9 +4046,9 @@ var VECTOR_PROFILES = {
4045
4046
 
4046
4047
  // src/llm/providers/UniversalLLMAdapter.ts
4047
4048
  function extractContent(obj) {
4048
- var _a2, _b, _c;
4049
+ var _a3, _b, _c;
4049
4050
  if (!obj || typeof obj !== "object") return void 0;
4050
- const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
4051
+ const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
4051
4052
  if (!choice) return void 0;
4052
4053
  if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
4053
4054
  if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
@@ -4057,10 +4058,10 @@ function extractContent(obj) {
4057
4058
  }
4058
4059
  var UniversalLLMAdapter = class {
4059
4060
  constructor(config) {
4060
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
4061
+ var _a3, _b, _c, _d, _e, _f, _g2, _h;
4061
4062
  this.model = config.model;
4062
4063
  const llmConfig = config;
4063
- const options = (_a2 = llmConfig.options) != null ? _a2 : {};
4064
+ const options = (_a3 = llmConfig.options) != null ? _a3 : {};
4064
4065
  let profile = {};
4065
4066
  if (typeof options.profile === "string") {
4066
4067
  profile = LLM_PROFILES[options.profile] || {};
@@ -4086,8 +4087,8 @@ var UniversalLLMAdapter = class {
4086
4087
  });
4087
4088
  }
4088
4089
  async chat(messages, context) {
4089
- var _a2, _b, _c, _d, _e;
4090
- const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4090
+ var _a3, _b, _c, _d, _e;
4091
+ const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
4091
4092
  const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
4092
4093
  role: m.role || "user",
4093
4094
  content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
@@ -4153,8 +4154,8 @@ ${context != null ? context : "None"}` },
4153
4154
  */
4154
4155
  chatStream(messages, context) {
4155
4156
  return __asyncGenerator(this, null, function* () {
4156
- var _a2, _b, _c, _d, _e, _f;
4157
- const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4157
+ var _a3, _b, _c, _d, _e, _f;
4158
+ const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
4158
4159
  const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
4159
4160
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
4160
4161
  const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
@@ -4280,8 +4281,8 @@ ${context != null ? context : "None"}` },
4280
4281
  });
4281
4282
  }
4282
4283
  async embed(text) {
4283
- var _a2, _b, _c, _d, _e;
4284
- const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
4284
+ var _a3, _b, _c, _d, _e;
4285
+ const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
4285
4286
  const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
4286
4287
  try {
4287
4288
  const { data: data2 } = await this.http.post(path2, payload);
@@ -4370,7 +4371,7 @@ var LLMFactory = class _LLMFactory {
4370
4371
  ];
4371
4372
  }
4372
4373
  static create(llmConfig, embeddingConfig) {
4373
- var _a2, _b, _c;
4374
+ var _a3, _b, _c;
4374
4375
  switch (llmConfig.provider) {
4375
4376
  case "openai":
4376
4377
  return new OpenAIProvider(llmConfig, embeddingConfig);
@@ -4389,7 +4390,7 @@ var LLMFactory = class _LLMFactory {
4389
4390
  case "custom":
4390
4391
  return new UniversalLLMAdapter(llmConfig);
4391
4392
  default: {
4392
- const providerName = String((_a2 = llmConfig.provider) != null ? _a2 : "").toLowerCase();
4393
+ const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
4393
4394
  const customFactory = customProviders.get(providerName);
4394
4395
  if (customFactory) {
4395
4396
  return customFactory(llmConfig);
@@ -4491,7 +4492,7 @@ var ProviderRegistry = class {
4491
4492
  return null;
4492
4493
  }
4493
4494
  static async loadVectorProviderClass(provider) {
4494
- var _a2;
4495
+ var _a3;
4495
4496
  if (this.vectorProviders[provider]) return this.vectorProviders[provider];
4496
4497
  switch (provider) {
4497
4498
  case "pinecone": {
@@ -4500,7 +4501,7 @@ var ProviderRegistry = class {
4500
4501
  }
4501
4502
  case "pgvector":
4502
4503
  case "postgresql": {
4503
- const postgresMode = ((_a2 = process.env.POSTGRES_MODE) != null ? _a2 : "multi").toLowerCase();
4504
+ const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
4504
4505
  if (postgresMode === "single") {
4505
4506
  const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
4506
4507
  return PostgreSQLProvider2;
@@ -4723,7 +4724,7 @@ var ConfigValidator = class {
4723
4724
  // package.json
4724
4725
  var package_default = {
4725
4726
  name: "@retrivora-ai/rag-engine",
4726
- version: "2.2.9",
4727
+ version: "2.3.1",
4727
4728
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
4728
4729
  author: "Abhinav Alkuchi",
4729
4730
  license: "UNLICENSED",
@@ -5028,8 +5029,8 @@ var Reranker = class {
5028
5029
  return matches.sort((a, b) => b.score - a.score).slice(0, limit);
5029
5030
  }
5030
5031
  const scoredMatches = matches.map((match) => {
5031
- var _a2;
5032
- const contentLower = ((_a2 = match == null ? void 0 : match.content) != null ? _a2 : "").toLowerCase();
5032
+ var _a3;
5033
+ const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
5033
5034
  let keywordScore = 0;
5034
5035
  keywords.forEach((keyword) => {
5035
5036
  if (contentLower.includes(keyword)) {
@@ -5051,8 +5052,8 @@ var Reranker = class {
5051
5052
 
5052
5053
  Documents:
5053
5054
  ${topN.map((m, i) => {
5054
- var _a2;
5055
- return `[${i}] ${((_a2 = m == null ? void 0 : m.content) != null ? _a2 : "").replace(/\n/g, " ")}`;
5055
+ var _a3;
5056
+ return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
5056
5057
  }).join("\n")}` }],
5057
5058
  "",
5058
5059
  {
@@ -5096,11 +5097,11 @@ var LlamaIndexIngestor = class {
5096
5097
  * than standard character-count splitting.
5097
5098
  */
5098
5099
  async chunk(text, options = {}) {
5099
- var _a2, _b;
5100
+ var _a3, _b;
5100
5101
  try {
5101
5102
  const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
5102
5103
  const splitter = new SentenceSplitter({
5103
- chunkSize: (_a2 = options.chunkSize) != null ? _a2 : 1e3,
5104
+ chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
5104
5105
  chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
5105
5106
  });
5106
5107
  const doc = new Document({ text, metadata: options.metadata || {} });
@@ -5209,7 +5210,7 @@ ${error instanceof Error ? error.message : String(error)}`
5209
5210
  * The agent returns `{ messages: [...] }` — the last message is the final answer.
5210
5211
  */
5211
5212
  async run(input, chatHistory = []) {
5212
- var _a2, _b, _c;
5213
+ var _a3, _b, _c;
5213
5214
  if (!this.agent) {
5214
5215
  throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
5215
5216
  }
@@ -5220,7 +5221,7 @@ ${error instanceof Error ? error.message : String(error)}`
5220
5221
  const response = await this.agent.invoke({
5221
5222
  messages: [...historyMessages, new HumanMessage(input)]
5222
5223
  });
5223
- const lastMessage = (_a2 = response == null ? void 0 : response.messages) == null ? void 0 : _a2.at(-1);
5224
+ const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
5224
5225
  if (lastMessage && typeof lastMessage.content === "string") {
5225
5226
  return lastMessage.content;
5226
5227
  }
@@ -5272,7 +5273,7 @@ var MCPClient = class {
5272
5273
  }
5273
5274
  }
5274
5275
  async connectStdio() {
5275
- var _a2;
5276
+ var _a3;
5276
5277
  const cmd = this.config.command;
5277
5278
  if (!cmd) {
5278
5279
  throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
@@ -5287,7 +5288,7 @@ var MCPClient = class {
5287
5288
  this.stdioBuffer += data.toString("utf-8");
5288
5289
  this.processStdioLines();
5289
5290
  });
5290
- (_a2 = this.childProcess.stderr) == null ? void 0 : _a2.on("data", (data) => {
5291
+ (_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
5291
5292
  console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
5292
5293
  });
5293
5294
  this.childProcess.on("close", (code) => {
@@ -5362,14 +5363,14 @@ var MCPClient = class {
5362
5363
  }
5363
5364
  }
5364
5365
  async sendNotification(method, params) {
5365
- var _a2;
5366
+ var _a3;
5366
5367
  const notification = {
5367
5368
  jsonrpc: "2.0",
5368
5369
  method,
5369
5370
  params
5370
5371
  };
5371
5372
  if (this.config.transport === "stdio") {
5372
- if ((_a2 = this.childProcess) == null ? void 0 : _a2.stdin) {
5373
+ if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
5373
5374
  this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
5374
5375
  }
5375
5376
  } else if (this.sseUrl) {
@@ -5447,11 +5448,11 @@ var MCPRegistry = class {
5447
5448
  // src/core/MultiAgentCoordinator.ts
5448
5449
  var MultiAgentCoordinator = class {
5449
5450
  constructor(options) {
5450
- var _a2;
5451
+ var _a3;
5451
5452
  this.llmProvider = options.llmProvider;
5452
5453
  this.mcpRegistry = options.mcpRegistry;
5453
5454
  this.documentSearch = options.documentSearch;
5454
- this.maxIterations = (_a2 = options.maxIterations) != null ? _a2 : 5;
5455
+ this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
5455
5456
  }
5456
5457
  /**
5457
5458
  * Run the multi-agent coordination loop synchronously and return the final response.
@@ -5503,8 +5504,8 @@ Available Tools:
5503
5504
 
5504
5505
  ${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
5505
5506
  ${mcpTools.map((mt) => {
5506
- var _a2;
5507
- return `- ${mt.tool.name}(${JSON.stringify(((_a2 = mt.tool.inputSchema) == null ? void 0 : _a2.properties) || {})}): ${mt.tool.description || "No description provided."}`;
5507
+ var _a3;
5508
+ return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
5508
5509
  }).join("\n")}
5509
5510
 
5510
5511
  Tool Calling Protocol:
@@ -5662,6 +5663,100 @@ ${toolResultText}`
5662
5663
  }
5663
5664
  };
5664
5665
 
5666
+ // src/core/CircuitBreaker.ts
5667
+ var CircuitBreaker = class {
5668
+ constructor(options = {}) {
5669
+ this.state = "closed";
5670
+ this.failureCount = 0;
5671
+ this.successCount = 0;
5672
+ this.lastFailureAt = 0;
5673
+ this.halfOpenCalls = 0;
5674
+ var _a3, _b, _c;
5675
+ this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
5676
+ this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
5677
+ this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
5678
+ }
5679
+ record(success) {
5680
+ const now = Date.now();
5681
+ if (success) {
5682
+ this.successCount++;
5683
+ if (this.state === "half-open") {
5684
+ this.state = "closed";
5685
+ this.failureCount = 0;
5686
+ this.halfOpenCalls = 0;
5687
+ this.successCount = 1;
5688
+ } else if (this.state === "closed") {
5689
+ if (this.successCount >= this.failureThreshold) {
5690
+ this.failureCount = Math.max(0, this.failureCount - 1);
5691
+ this.successCount = 0;
5692
+ }
5693
+ }
5694
+ } else {
5695
+ this.failureCount++;
5696
+ this.lastFailureAt = now;
5697
+ this.successCount = 0;
5698
+ if (this.state === "half-open") {
5699
+ this.state = "open";
5700
+ this.halfOpenCalls = 0;
5701
+ } else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
5702
+ this.state = "open";
5703
+ }
5704
+ }
5705
+ }
5706
+ canExecute() {
5707
+ const now = Date.now();
5708
+ if (this.state === "closed") {
5709
+ return true;
5710
+ }
5711
+ if (this.state === "open") {
5712
+ if (now - this.lastFailureAt >= this.resetTimeoutMs) {
5713
+ this.state = "half-open";
5714
+ this.halfOpenCalls = 0;
5715
+ return true;
5716
+ }
5717
+ return false;
5718
+ }
5719
+ if (this.state === "half-open") {
5720
+ return this.halfOpenCalls < this.halfOpenMaxCalls;
5721
+ }
5722
+ return true;
5723
+ }
5724
+ async wrap(fn) {
5725
+ if (!this.canExecute()) {
5726
+ const retryAfterSec = Math.ceil(
5727
+ Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
5728
+ );
5729
+ throw new Error(
5730
+ `Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
5731
+ );
5732
+ }
5733
+ if (this.state === "half-open") {
5734
+ this.halfOpenCalls++;
5735
+ }
5736
+ try {
5737
+ const result = await fn();
5738
+ this.record(true);
5739
+ return result;
5740
+ } catch (err) {
5741
+ this.record(false);
5742
+ throw err;
5743
+ }
5744
+ }
5745
+ getState() {
5746
+ return this.state;
5747
+ }
5748
+ getFailureCount() {
5749
+ return this.failureCount;
5750
+ }
5751
+ reset() {
5752
+ this.state = "closed";
5753
+ this.failureCount = 0;
5754
+ this.successCount = 0;
5755
+ this.lastFailureAt = 0;
5756
+ this.halfOpenCalls = 0;
5757
+ }
5758
+ };
5759
+
5665
5760
  // src/core/BatchProcessor.ts
5666
5761
  function isTransientError(error) {
5667
5762
  if (!(error instanceof Error)) return false;
@@ -5685,7 +5780,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
5685
5780
  function sleep(ms) {
5686
5781
  return new Promise((resolve) => setTimeout(resolve, ms));
5687
5782
  }
5688
- var BatchProcessor = class {
5783
+ var _BatchProcessor = class _BatchProcessor {
5784
+ /**
5785
+ * Execute a processor call through the circuit breaker.
5786
+ * Only transient failures count toward opening the circuit.
5787
+ */
5788
+ static async executeWithCircuitBreaker(processor) {
5789
+ if (!this.cb.canExecute()) {
5790
+ const retryAfterSec = Math.ceil(
5791
+ Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
5792
+ );
5793
+ throw new Error(
5794
+ `[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
5795
+ );
5796
+ }
5797
+ if (this.cb.state === "half-open") {
5798
+ this.cb.halfOpenCalls++;
5799
+ }
5800
+ try {
5801
+ const result = await processor();
5802
+ this.cb.record(true);
5803
+ return result;
5804
+ } catch (err) {
5805
+ if (isTransientError(err)) {
5806
+ this.cb.record(false);
5807
+ }
5808
+ throw err;
5809
+ }
5810
+ }
5689
5811
  /**
5690
5812
  * Processes an array of items in configurable batches with retry logic.
5691
5813
  *
@@ -5726,7 +5848,7 @@ var BatchProcessor = class {
5726
5848
  let lastError;
5727
5849
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
5728
5850
  try {
5729
- const result = await processor(batch);
5851
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
5730
5852
  results.push(result);
5731
5853
  success = true;
5732
5854
  break;
@@ -5784,7 +5906,7 @@ ${errorMessages}`
5784
5906
  let lastError;
5785
5907
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
5786
5908
  try {
5787
- const result = await processor(item);
5909
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
5788
5910
  results.push(result);
5789
5911
  success = true;
5790
5912
  break;
@@ -5857,7 +5979,7 @@ ${errorMessages}`
5857
5979
  }));
5858
5980
  const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
5859
5981
  try {
5860
- const result = await processor(item);
5982
+ const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
5861
5983
  return { success: true, result, index: originalIndex };
5862
5984
  } catch (err) {
5863
5985
  const error = err instanceof Error ? err : new Error(String(err));
@@ -5885,6 +6007,12 @@ ${errorMessages}`
5885
6007
  return { results, errors, totalProcessed, totalFailed };
5886
6008
  }
5887
6009
  };
6010
+ _BatchProcessor.cb = new CircuitBreaker({
6011
+ failureThreshold: 5,
6012
+ resetTimeoutMs: 3e4,
6013
+ halfOpenMaxCalls: 1
6014
+ });
6015
+ var BatchProcessor = _BatchProcessor;
5888
6016
 
5889
6017
  // src/config/EmbeddingStrategy.ts
5890
6018
  var EmbeddingStrategy = /* @__PURE__ */ ((EmbeddingStrategy2) => {
@@ -5988,7 +6116,7 @@ var QueryProcessor = class {
5988
6116
  * @param validFields Optional list of known filterable fields to look for
5989
6117
  */
5990
6118
  static extractQueryFieldHints(question, validFields = []) {
5991
- var _a2, _b, _c, _d;
6119
+ var _a3, _b, _c, _d;
5992
6120
  if (!question.trim()) return [];
5993
6121
  const hints = /* @__PURE__ */ new Map();
5994
6122
  const addHint = (value, field) => {
@@ -6068,7 +6196,7 @@ var QueryProcessor = class {
6068
6196
  ];
6069
6197
  for (const p of universalPatterns) {
6070
6198
  for (const match of question.matchAll(p.regex)) {
6071
- const val = p.group ? (_a2 = match[p.group]) != null ? _a2 : match[0] : match[0];
6199
+ const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
6072
6200
  if (!val) continue;
6073
6201
  if (p.field) addHint(val, p.field);
6074
6202
  else addHint(val);
@@ -6292,11 +6420,11 @@ var LLMRouter = class {
6292
6420
  * When provided it is used directly as the 'default' role without re-constructing.
6293
6421
  */
6294
6422
  async initialize(prebuiltDefault) {
6295
- var _a2;
6423
+ var _a3;
6296
6424
  const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
6297
6425
  this.models.set("default", defaultModel);
6298
6426
  const envFastModel = process.env.FAST_LLM_MODEL;
6299
- const providerFastDefault = (_a2 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a2 : "";
6427
+ const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
6300
6428
  const fastModelName = envFastModel || providerFastDefault;
6301
6429
  if (fastModelName && fastModelName !== this.config.llm.model) {
6302
6430
  console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
@@ -6315,8 +6443,8 @@ var LLMRouter = class {
6315
6443
  * Falls back to 'default' if the requested role is not registered.
6316
6444
  */
6317
6445
  get(role) {
6318
- var _a2;
6319
- const provider = (_a2 = this.models.get(role)) != null ? _a2 : this.models.get("default");
6446
+ var _a3;
6447
+ const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
6320
6448
  if (!provider) {
6321
6449
  throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
6322
6450
  }
@@ -6402,8 +6530,8 @@ var IntentClassifier = class {
6402
6530
  numericFieldCount = numericKeys.size;
6403
6531
  categoricalFieldCount = catKeys.size;
6404
6532
  if (productKeyMatches >= 2 || docs.some((d) => {
6405
- var _a2, _b;
6406
- 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");
6533
+ var _a3, _b;
6534
+ 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");
6407
6535
  })) {
6408
6536
  isProductLike = true;
6409
6537
  }
@@ -6685,8 +6813,8 @@ var TextRendererStrategy = class {
6685
6813
  }
6686
6814
  const docs = Array.isArray(data) ? data : [];
6687
6815
  const text = docs.map((d) => {
6688
- var _a2;
6689
- return (_a2 = d == null ? void 0 : d.content) != null ? _a2 : "";
6816
+ var _a3;
6817
+ return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
6690
6818
  }).join("\n\n");
6691
6819
  return { type: "text", title, data: { content: text || "No detailed content available." } };
6692
6820
  }
@@ -6829,9 +6957,9 @@ var LRUDecisionCache = class {
6829
6957
  this.maxSize = maxSize;
6830
6958
  }
6831
6959
  generateKey(context) {
6832
- var _a2, _b;
6960
+ var _a3, _b;
6833
6961
  const q = (context.userQuery || "").toLowerCase().trim();
6834
- const docCount = (_b = (_a2 = context.retrievedDocuments) == null ? void 0 : _a2.length) != null ? _b : 0;
6962
+ const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
6835
6963
  return `${q}::docs:${docCount}`;
6836
6964
  }
6837
6965
  get(context) {
@@ -6940,7 +7068,7 @@ var UITransformer = class _UITransformer {
6940
7068
  * Prefer `analyzeAndDecide()` in production.
6941
7069
  */
6942
7070
  static transform(userQuery, retrievedData, config, trainedSchema, intent) {
6943
- var _a2, _b, _c;
7071
+ var _a3, _b, _c;
6944
7072
  if (!retrievedData || retrievedData.length === 0) {
6945
7073
  return this.createTextResponse("No data available", "No relevant data found for your query.");
6946
7074
  }
@@ -6960,7 +7088,7 @@ var UITransformer = class _UITransformer {
6960
7088
  return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
6961
7089
  }
6962
7090
  if (resolvedIntent.visualizationHint === "distribution") {
6963
- return (_a2 = this.transformToHistogram(profile, userQuery)) != null ? _a2 : this.transformToBarChart(filteredData, profile, userQuery);
7091
+ return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
6964
7092
  }
6965
7093
  if (resolvedIntent.visualizationHint === "correlation") {
6966
7094
  return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
@@ -7293,11 +7421,11 @@ ${schemaProfileText}` : ""}`;
7293
7421
  };
7294
7422
  }
7295
7423
  static transformToPieChart(data, profile, query = "") {
7296
- var _a2;
7424
+ var _a3;
7297
7425
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
7298
7426
  const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
7299
- var _a3;
7300
- return String((_a3 = record.fields[dimension.key]) != null ? _a3 : "");
7427
+ var _a4;
7428
+ return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
7301
7429
  }).filter(Boolean))) : this.detectCategories(data);
7302
7430
  if (categories.length === 0) return null;
7303
7431
  const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
@@ -7307,7 +7435,7 @@ ${schemaProfileText}` : ""}`;
7307
7435
  });
7308
7436
  return {
7309
7437
  type: "pie_chart",
7310
- title: `Distribution by ${(_a2 = dimension == null ? void 0 : dimension.label) != null ? _a2 : "Category"}`,
7438
+ title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
7311
7439
  description: `Showing breakdown across ${pieData.length} categories`,
7312
7440
  data: pieData
7313
7441
  };
@@ -7317,8 +7445,8 @@ ${schemaProfileText}` : ""}`;
7317
7445
  const valueField = profile.numericFields[0];
7318
7446
  const buckets = /* @__PURE__ */ new Map();
7319
7447
  profile.records.forEach((record) => {
7320
- var _a2, _b, _c;
7321
- const timestamp = String((_a2 = record.fields[dateField.key]) != null ? _a2 : "");
7448
+ var _a3, _b, _c;
7449
+ const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
7322
7450
  const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
7323
7451
  buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
7324
7452
  });
@@ -7331,23 +7459,23 @@ ${schemaProfileText}` : ""}`;
7331
7459
  };
7332
7460
  }
7333
7461
  static transformToBarChart(data, profile, query = "", horizontal = false) {
7334
- var _a2;
7462
+ var _a3;
7335
7463
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
7336
7464
  const measure = profile ? this.selectNumericField(profile, query) : void 0;
7337
7465
  const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
7338
7466
  const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
7339
7467
  const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
7340
- var _a3, _b, _c, _d, _e;
7468
+ var _a4, _b, _c, _d, _e;
7341
7469
  const meta = item.metadata || {};
7342
7470
  const label = String(
7343
- (_c = (_b = (_a3 = this.getDynamicVal(meta, "name")) != null ? _a3 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
7471
+ (_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
7344
7472
  );
7345
7473
  const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
7346
7474
  return { category: label, value: Number(value) };
7347
7475
  });
7348
7476
  return {
7349
7477
  type: horizontal ? "horizontal_bar" : "bar_chart",
7350
- title: dimension ? `${(_a2 = measure == null ? void 0 : measure.label) != null ? _a2 : "Count"} by ${dimension.label}` : "Comparison",
7478
+ title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
7351
7479
  description: `Showing ${fallbackData.length} comparable values`,
7352
7480
  data: fallbackData
7353
7481
  };
@@ -7382,11 +7510,11 @@ ${schemaProfileText}` : ""}`;
7382
7510
  if (fields.length < 2) return null;
7383
7511
  const [xField, yField] = fields;
7384
7512
  const points = profile.records.map((record) => {
7385
- var _a2;
7513
+ var _a3;
7386
7514
  const x = this.toFiniteNumber(record.fields[xField.key]);
7387
7515
  const y = this.toFiniteNumber(record.fields[yField.key]);
7388
7516
  if (x === null || y === null) return null;
7389
- return { x, y, label: String((_a2 = this.getRecordLabel(record)) != null ? _a2 : record.id) };
7517
+ return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
7390
7518
  }).filter((point) => point !== null).slice(0, 100);
7391
7519
  if (points.length === 0) return null;
7392
7520
  return {
@@ -7416,9 +7544,9 @@ ${schemaProfileText}` : ""}`;
7416
7544
  static transformToRadarChart(data) {
7417
7545
  const attributeMap = {};
7418
7546
  data.forEach((item) => {
7419
- var _a2, _b, _c;
7547
+ var _a3, _b, _c;
7420
7548
  const meta = item.metadata || {};
7421
- const seriesName = String((_c = (_b = (_a2 = meta.name) != null ? _a2 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
7549
+ const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
7422
7550
  Object.entries(meta).forEach(([key, val]) => {
7423
7551
  if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
7424
7552
  if (!attributeMap[key]) attributeMap[key] = {};
@@ -7434,8 +7562,8 @@ ${schemaProfileText}` : ""}`;
7434
7562
  title: "Product Comparison",
7435
7563
  description: `Comparing ${data.length} items across ${radarData.length} attributes`,
7436
7564
  data: radarData.length > 0 ? radarData : data.map((d) => {
7437
- var _a2;
7438
- return { attribute: ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").substring(0, 40) };
7565
+ var _a3;
7566
+ return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
7439
7567
  })
7440
7568
  };
7441
7569
  }
@@ -7454,8 +7582,8 @@ ${schemaProfileText}` : ""}`;
7454
7582
  return this.createTextResponse(
7455
7583
  "Retrieved Context",
7456
7584
  data.map((item) => {
7457
- var _a2;
7458
- return (_a2 = item == null ? void 0 : item.content) != null ? _a2 : "";
7585
+ var _a3;
7586
+ return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
7459
7587
  }).join("\n\n"),
7460
7588
  `Found ${data.length} relevant results`
7461
7589
  );
@@ -7506,11 +7634,11 @@ ${schemaProfileText}` : ""}`;
7506
7634
  return null;
7507
7635
  }
7508
7636
  static normalizeTransformation(payload) {
7509
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
7637
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
7510
7638
  if (!payload || typeof payload !== "object") return null;
7511
7639
  const p = payload;
7512
7640
  const type = this.normalizeVisualizationType(
7513
- String((_c = (_b = (_a2 = p.type) != null ? _a2 : p.view) != null ? _b : p.chartType) != null ? _c : "")
7641
+ String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
7514
7642
  );
7515
7643
  if (!type) return null;
7516
7644
  const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
@@ -7521,7 +7649,7 @@ ${schemaProfileText}` : ""}`;
7521
7649
  return this.validateTransformation(transformation) ? transformation : null;
7522
7650
  }
7523
7651
  static normalizeVisualizationType(type) {
7524
- var _a2;
7652
+ var _a3;
7525
7653
  const mapping = {
7526
7654
  pie: "pie_chart",
7527
7655
  pie_chart: "pie_chart",
@@ -7549,7 +7677,7 @@ ${schemaProfileText}` : ""}`;
7549
7677
  product_carousel: "product_carousel",
7550
7678
  carousel: "carousel"
7551
7679
  };
7552
- return (_a2 = mapping[type.toLowerCase()]) != null ? _a2 : null;
7680
+ return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
7553
7681
  }
7554
7682
  static validateTransformation(t) {
7555
7683
  const { type, data } = t;
@@ -7665,7 +7793,7 @@ ${schemaProfileText}` : ""}`;
7665
7793
  }
7666
7794
  static profileData(data) {
7667
7795
  const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
7668
- var _a2, _b;
7796
+ var _a3, _b;
7669
7797
  const fields2 = {};
7670
7798
  Object.entries(item.metadata || {}).forEach(([key, value]) => {
7671
7799
  const primitive = this.toPrimitive(value);
@@ -7674,7 +7802,7 @@ ${schemaProfileText}` : ""}`;
7674
7802
  if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
7675
7803
  return {
7676
7804
  id: item.id,
7677
- content: (_a2 = item.content) != null ? _a2 : "",
7805
+ content: (_a3 = item.content) != null ? _a3 : "",
7678
7806
  score: (_b = item.score) != null ? _b : 0,
7679
7807
  fields: fields2,
7680
7808
  source: item
@@ -7755,16 +7883,16 @@ ${schemaProfileText}` : ""}`;
7755
7883
  return null;
7756
7884
  }
7757
7885
  static selectDimensionField(profile, query) {
7758
- var _a2, _b;
7886
+ var _a3, _b;
7759
7887
  const productCategory = profile.categoricalFields.find(
7760
7888
  (field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
7761
7889
  );
7762
7890
  const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
7763
- return (_b = (_a2 = ranked[0]) != null ? _a2 : productCategory) != null ? _b : profile.categoricalFields[0];
7891
+ return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
7764
7892
  }
7765
7893
  static selectNumericField(profile, query) {
7766
- var _a2;
7767
- return (_a2 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a2 : profile.numericFields[0];
7894
+ var _a3;
7895
+ return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
7768
7896
  }
7769
7897
  static rankFieldsByQuery(fields, query) {
7770
7898
  const q = query.toLowerCase();
@@ -7793,8 +7921,8 @@ ${schemaProfileText}` : ""}`;
7793
7921
  static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
7794
7922
  const result = {};
7795
7923
  profile.records.forEach((record) => {
7796
- var _a2, _b, _c;
7797
- const category = String((_a2 = record.fields[dimensionKey]) != null ? _a2 : "Other").trim() || "Other";
7924
+ var _a3, _b, _c;
7925
+ const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
7798
7926
  const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
7799
7927
  result[category] = ((_c = result[category]) != null ? _c : 0) + value;
7800
7928
  });
@@ -7874,8 +8002,8 @@ ${schemaProfileText}` : ""}`;
7874
8002
  static aggregateByCategory(data, categories) {
7875
8003
  const result = Object.fromEntries(categories.map((c) => [c, 0]));
7876
8004
  data.forEach((item) => {
7877
- var _a2;
7878
- const cat = (_a2 = this.getProductCategory(item)) != null ? _a2 : "Other";
8005
+ var _a3;
8006
+ const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
7879
8007
  if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
7880
8008
  else result["Other"] = (result["Other"] || 0) + 1;
7881
8009
  });
@@ -7883,17 +8011,17 @@ ${schemaProfileText}` : ""}`;
7883
8011
  }
7884
8012
  static extractTimeSeriesData(data) {
7885
8013
  return data.map((item) => {
7886
- var _a2, _b, _c, _d, _e, _f;
8014
+ var _a3, _b, _c, _d, _e, _f;
7887
8015
  const meta = item.metadata || {};
7888
8016
  return {
7889
- timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
8017
+ timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
7890
8018
  value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
7891
8019
  label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
7892
8020
  };
7893
8021
  });
7894
8022
  }
7895
8023
  static extractNumericValue(meta) {
7896
- var _a2;
8024
+ var _a3;
7897
8025
  const preferredKeys = [
7898
8026
  "value",
7899
8027
  "count",
@@ -7908,7 +8036,7 @@ ${schemaProfileText}` : ""}`;
7908
8036
  "price"
7909
8037
  ];
7910
8038
  for (const key of preferredKeys) {
7911
- const raw = (_a2 = resolveMetadataValue(meta, key)) != null ? _a2 : meta[key];
8039
+ const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
7912
8040
  const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
7913
8041
  if (Number.isFinite(value)) return value;
7914
8042
  }
@@ -8003,8 +8131,8 @@ ${schemaProfileText}` : ""}`;
8003
8131
  }, query.includes(normalizedField) ? 3 : 0);
8004
8132
  }
8005
8133
  static resolveTableCellValue(item, column) {
8006
- var _a2, _b, _c;
8007
- if (column === "Content") return ((_a2 = item == null ? void 0 : item.content) != null ? _a2 : "").substring(0, 100);
8134
+ var _a3, _b, _c;
8135
+ if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
8008
8136
  const meta = item.metadata || {};
8009
8137
  const normalizedColumn = this.normalizeComparableField(column);
8010
8138
  const exactMetadata = Object.entries(meta).find(
@@ -8056,8 +8184,8 @@ ${schemaProfileText}` : ""}`;
8056
8184
  let inStock = 0;
8057
8185
  let outOfStock = 0;
8058
8186
  data.forEach((d) => {
8059
- var _a2, _b;
8060
- const cat = (_a2 = this.getProductCategory(d)) != null ? _a2 : "Other";
8187
+ var _a3, _b;
8188
+ const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
8061
8189
  if (cat === category) {
8062
8190
  const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
8063
8191
  if (this.determineStockStatus(d)) inStock += quantity;
@@ -8103,9 +8231,9 @@ ${schemaProfileText}` : ""}`;
8103
8231
  }
8104
8232
  // ─── Product Extraction ───────────────────────────────────────────────────
8105
8233
  static getDynamicVal(meta, uiKey, config, trainedSchema) {
8106
- var _a2;
8234
+ var _a3;
8107
8235
  if (!meta) return void 0;
8108
- const mapping = (_a2 = config == null ? void 0 : config.rag) == null ? void 0 : _a2.uiMapping;
8236
+ const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
8109
8237
  if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
8110
8238
  if (trainedSchema && typeof trainedSchema === "object") {
8111
8239
  const trainedKey = trainedSchema[uiKey];
@@ -8114,7 +8242,7 @@ ${schemaProfileText}` : ""}`;
8114
8242
  return resolveMetadataValue(meta, uiKey);
8115
8243
  }
8116
8244
  static extractProductInfo(item, config, trainedSchema) {
8117
- var _a2, _b;
8245
+ var _a3, _b;
8118
8246
  if (!item) return null;
8119
8247
  const meta = item.metadata || {};
8120
8248
  const content = item.content || "";
@@ -8122,7 +8250,7 @@ ${schemaProfileText}` : ""}`;
8122
8250
  const price = this.getDynamicVal(meta, "price", config, trainedSchema);
8123
8251
  const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
8124
8252
  const description = this.cleanProductDescription(
8125
- (_a2 = this.extractProductDescriptionFromContent(content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
8253
+ (_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
8126
8254
  );
8127
8255
  if (name || this.isProductData(item)) {
8128
8256
  let finalName = name ? String(name) : void 0;
@@ -8257,10 +8385,10 @@ RULES:
8257
8385
  }
8258
8386
  static buildContextSummary(sources, maxChars = 6e3) {
8259
8387
  const items = (sources || []).filter(Boolean).map((s, i) => {
8260
- var _a2, _b, _c, _d;
8388
+ var _a3, _b, _c, _d;
8261
8389
  return {
8262
8390
  index: i + 1,
8263
- content: (_b = (_a2 = s == null ? void 0 : s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
8391
+ content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
8264
8392
  metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
8265
8393
  score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
8266
8394
  };
@@ -8300,7 +8428,7 @@ var SchemaMapper = class {
8300
8428
  return promise;
8301
8429
  }
8302
8430
  static async _doTrain(llm, cacheKey, keys) {
8303
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8431
+ var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8304
8432
  console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
8305
8433
  const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
8306
8434
  const messages = [
@@ -8316,7 +8444,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
8316
8444
  }
8317
8445
  ];
8318
8446
  try {
8319
- const baseUrl = (_a2 = llm == null ? void 0 : llm.baseUrl) != null ? _a2 : "";
8447
+ const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
8320
8448
  const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
8321
8449
  const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
8322
8450
  let responseText;
@@ -8491,9 +8619,9 @@ var Pipeline = class {
8491
8619
  this.initialised = false;
8492
8620
  /** Namespace-specific static cold context cache for CAG */
8493
8621
  this.coldContexts = /* @__PURE__ */ new Map();
8494
- var _a2, _b, _c, _d, _e;
8622
+ var _a3, _b, _c, _d, _e;
8495
8623
  this.chunker = new DocumentChunker(
8496
- (_b = (_a2 = config.rag) == null ? void 0 : _a2.chunkSize) != null ? _b : 1e3,
8624
+ (_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
8497
8625
  (_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
8498
8626
  );
8499
8627
  if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
@@ -8509,7 +8637,7 @@ var Pipeline = class {
8509
8637
  return this.initialised ? this.llmProvider : void 0;
8510
8638
  }
8511
8639
  async initialize() {
8512
- var _a2, _b, _c, _d;
8640
+ var _a3, _b, _c, _d;
8513
8641
  if (this.initialised) return;
8514
8642
  const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
8515
8643
 
@@ -8552,7 +8680,7 @@ var Pipeline = class {
8552
8680
  this.entityExtractor = new EntityExtractor(this.llmProvider);
8553
8681
  }
8554
8682
  await this.vectorDB.initialize();
8555
- 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) {
8683
+ 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) {
8556
8684
  this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
8557
8685
  this.multiAgentCoordinator = new MultiAgentCoordinator({
8558
8686
  llmProvider: this.llmProvider,
@@ -8570,8 +8698,8 @@ var Pipeline = class {
8570
8698
  this.initialised = true;
8571
8699
  }
8572
8700
  async loadColdContext(ns) {
8573
- var _a2, _b;
8574
- const cagConfig = (_a2 = this.config.rag) == null ? void 0 : _a2.cag;
8701
+ var _a3, _b;
8702
+ const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
8575
8703
  if (!cagConfig || !cagConfig.enabled) return;
8576
8704
  try {
8577
8705
  const coldNs = cagConfig.coldNamespace || ns;
@@ -8624,12 +8752,12 @@ ${m.content}`).join("\n\n---\n\n");
8624
8752
  }
8625
8753
  /** Step 1: Chunk the document content. */
8626
8754
  async prepareChunks(doc) {
8627
- var _a2, _b;
8755
+ var _a3, _b;
8628
8756
  if (this.llamaIngestor) {
8629
8757
  return this.llamaIngestor.chunk(doc.content, {
8630
8758
  docId: doc.docId,
8631
8759
  metadata: doc.metadata,
8632
- chunkSize: (_a2 = this.config.rag) == null ? void 0 : _a2.chunkSize,
8760
+ chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
8633
8761
  chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
8634
8762
  });
8635
8763
  }
@@ -8727,9 +8855,9 @@ ${m.content}`).join("\n\n---\n\n");
8727
8855
  return { reply, sources };
8728
8856
  }
8729
8857
  async ask(question, history = [], namespace) {
8730
- var _a2, _b;
8858
+ var _a3, _b;
8731
8859
  await this.initialize();
8732
- 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) {
8860
+ 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) {
8733
8861
  return await this.multiAgentCoordinator.run(question, history);
8734
8862
  }
8735
8863
  const stream = this.askStream(question, history, namespace);
@@ -8764,9 +8892,9 @@ ${m.content}`).join("\n\n---\n\n");
8764
8892
  }
8765
8893
  askStream(_0) {
8766
8894
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
8767
- var _a2, _b;
8895
+ var _a3, _b;
8768
8896
  yield new __await(this.initialize());
8769
- 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) {
8897
+ 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) {
8770
8898
  const stream2 = this.multiAgentCoordinator.runStream(question, history);
8771
8899
  try {
8772
8900
  for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
@@ -8815,10 +8943,10 @@ ${m.content}`).join("\n\n---\n\n");
8815
8943
  */
8816
8944
  askStreamInternal(_0) {
8817
8945
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
8818
- 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;
8946
+ 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;
8819
8947
  yield new __await(this.initialize());
8820
8948
  const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
8821
- const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
8949
+ const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
8822
8950
  const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
8823
8951
  const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
8824
8952
  const requestStart = performance.now();
@@ -8867,8 +8995,8 @@ ${m.content}`).join("\n\n---\n\n");
8867
8995
  const rerankStart = performance.now();
8868
8996
  const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
8869
8997
  let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
8870
- var _a3;
8871
- return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
8998
+ var _a4;
8999
+ return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
8872
9000
  });
8873
9001
  const rerankLimit = Math.max(retrievalLimit, fullSources.length);
8874
9002
  const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
@@ -8881,13 +9009,13 @@ ${m.content}`).join("\n\n---\n\n");
8881
9009
  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]
8882
9010
 
8883
9011
  ` + promptSources.map((m, i) => {
8884
- var _a3;
9012
+ var _a4;
8885
9013
  return `[Source ${i + 1}]
8886
- ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
9014
+ ${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
8887
9015
  }).join("\n\n---\n\n") : "No relevant context found.";
8888
9016
  const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
8889
- var _a3, _b2;
8890
- return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
9017
+ var _a4, _b2;
9018
+ return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
8891
9019
  });
8892
9020
  if (graphData && graphData.nodes.length > 0) {
8893
9021
  const graphContext = graphData.nodes.map(
@@ -8915,10 +9043,10 @@ ${context}`;
8915
9043
  yield {
8916
9044
  reply: "",
8917
9045
  sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
8918
- var _a3, _b2, _c2;
9046
+ var _a4, _b2, _c2;
8919
9047
  return {
8920
9048
  id: s.id,
8921
- score: (_a3 = s.score) != null ? _a3 : 0,
9049
+ score: (_a4 = s.score) != null ? _a4 : 0,
8922
9050
  content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
8923
9051
  metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
8924
9052
  namespace: ns
@@ -9111,11 +9239,11 @@ ${context}`;
9111
9239
  systemPrompt,
9112
9240
  userPrompt: question + finalRestrictionSuffix,
9113
9241
  chunks: (sources || []).filter(Boolean).map((s) => {
9114
- var _a3, _b2;
9242
+ var _a4, _b2;
9115
9243
  return {
9116
9244
  id: s.id,
9117
9245
  score: s.score,
9118
- content: (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "",
9246
+ content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
9119
9247
  metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
9120
9248
  namespace: ns
9121
9249
  };
@@ -9134,7 +9262,7 @@ ${context}`;
9134
9262
  const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
9135
9263
  const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
9136
9264
  (async () => {
9137
- var _a3, _b2, _c2, _d2, _e2;
9265
+ var _a4, _b2, _c2, _d2, _e2;
9138
9266
  try {
9139
9267
  let finalTrace = trace;
9140
9268
  if (!awaitHallucination && runHallucination) {
@@ -9143,7 +9271,7 @@ ${context}`;
9143
9271
  finalTrace = buildTrace(backgroundScoreResult);
9144
9272
  }
9145
9273
  }
9146
- const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a3 = this.config.llm) == null ? void 0 : _a3.model) || "llama-3.1-8b-instant";
9274
+ const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
9147
9275
  const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
9148
9276
  const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
9149
9277
  const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
@@ -9197,7 +9325,7 @@ ${context}`;
9197
9325
  * Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
9198
9326
  */
9199
9327
  async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
9200
- var _a2;
9328
+ var _a3;
9201
9329
  if (!sources || sources.length === 0) {
9202
9330
  return UITransformer.transform(question, sources, this.config, cachedSchema);
9203
9331
  }
@@ -9210,7 +9338,7 @@ ${context}`;
9210
9338
  { visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
9211
9339
  );
9212
9340
  }
9213
- const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
9341
+ const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
9214
9342
  if (forceDeterministic || !enableLlmUiTransform) {
9215
9343
  return UITransformer.transform(question, sources, this.config, cachedSchema);
9216
9344
  }
@@ -9228,15 +9356,15 @@ ${context}`;
9228
9356
  const value = this.resolveNumericPredicateValue(source, predicate);
9229
9357
  return value !== null && this.matchesNumericPredicate(value, predicate);
9230
9358
  })).sort((a, b) => {
9231
- var _a2, _b;
9359
+ var _a3, _b;
9232
9360
  const primary = predicates[0];
9233
- const aValue = (_a2 = this.resolveNumericPredicateValue(a, primary)) != null ? _a2 : 0;
9361
+ const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
9234
9362
  const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
9235
9363
  return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
9236
9364
  });
9237
9365
  }
9238
9366
  resolveNumericPredicateValue(source, predicate) {
9239
- var _a2;
9367
+ var _a3;
9240
9368
  if (!source) return null;
9241
9369
  const meta = source.metadata || {};
9242
9370
  const field = predicate.field;
@@ -9249,7 +9377,7 @@ ${context}`;
9249
9377
  const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
9250
9378
  if (value !== null) return value;
9251
9379
  }
9252
- const contentValue = this.extractNumericValueFromContent((_a2 = source.content) != null ? _a2 : "", field);
9380
+ const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
9253
9381
  if (contentValue !== null) return contentValue;
9254
9382
  }
9255
9383
  for (const [key, value] of entries) {
@@ -9305,8 +9433,8 @@ ${context}`;
9305
9433
  return Number.isFinite(numeric) ? numeric : null;
9306
9434
  }
9307
9435
  async retrieve(query, options) {
9308
- var _a2, _b, _c, _d, _e, _f, _g2;
9309
- const ns = formatNamespace((_a2 = options.namespace) != null ? _a2 : this.config.projectId);
9436
+ var _a3, _b, _c, _d, _e, _f, _g2;
9437
+ const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
9310
9438
  const topK = (_b = options.topK) != null ? _b : 5;
9311
9439
  const cacheKey = `${ns}::${query}`;
9312
9440
  let queryVector = this.embeddingCache.get(cacheKey);
@@ -9351,11 +9479,11 @@ ${context}`;
9351
9479
  namespace: ns,
9352
9480
  count: resolvedSources.length,
9353
9481
  sample: resolvedSources.slice(0, 2).map((s) => {
9354
- var _a3;
9482
+ var _a4;
9355
9483
  return {
9356
9484
  id: s == null ? void 0 : s.id,
9357
9485
  score: s == null ? void 0 : s.score,
9358
- contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9486
+ contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
9359
9487
  metadata: s == null ? void 0 : s.metadata
9360
9488
  };
9361
9489
  })
@@ -9369,8 +9497,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
9369
9497
 
9370
9498
  History:
9371
9499
  ${(history || []).map((m) => {
9372
- var _a2;
9373
- return `${(m == null ? void 0 : m.role) || "user"}: ${(_a2 = m == null ? void 0 : m.content) != null ? _a2 : ""}`;
9500
+ var _a3;
9501
+ return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
9374
9502
  }).join("\n")}
9375
9503
 
9376
9504
  New Question: ${question}
@@ -9397,8 +9525,8 @@ Optimized Search Query:`;
9397
9525
  const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
9398
9526
  if (!sources || sources.length === 0) return [];
9399
9527
  const context = sources.map((s) => {
9400
- var _a2;
9401
- return (_a2 = s == null ? void 0 : s.content) != null ? _a2 : "";
9528
+ var _a3;
9529
+ return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
9402
9530
  }).join("\n\n---\n\n");
9403
9531
  const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
9404
9532
  Focus on questions that can be answered by the context.
@@ -9440,13 +9568,13 @@ var Retrivora = class {
9440
9568
  this.pipeline = new Pipeline(this.config);
9441
9569
  }
9442
9570
  async initialize() {
9443
- var _a2;
9571
+ var _a3;
9444
9572
  try {
9445
9573
  await ConfigValidator.validateAndThrow(this.config);
9446
9574
  LicenseVerifier.verify(
9447
9575
  this.config.licenseKey,
9448
9576
  this.config.projectId,
9449
- (_a2 = this.config.vectorDb) == null ? void 0 : _a2.provider
9577
+ (_a3 = this.config.vectorDb) == null ? void 0 : _a3.provider
9450
9578
  );
9451
9579
  await LicenseVerifier.verifyIP(this.config.licenseKey);
9452
9580
  } catch (err) {
@@ -9619,18 +9747,200 @@ var ProviderHealthCheck = class {
9619
9747
  }
9620
9748
  };
9621
9749
 
9750
+ // src/core/FreeTierLimitsGuard.ts
9751
+ var FREE_TIER_QUOTAS = {
9752
+ MAX_DOCUMENTS: 25,
9753
+ MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
9754
+ MAX_STORAGE_BYTES: 250 * 1024 * 1024,
9755
+ MAX_TRIAL_REQUEST_UNITS: 500,
9756
+ MAX_DAILY_REQUEST_UNITS: 50,
9757
+ TRIAL_DURATION_DAYS: 14,
9758
+ GRACE_PERIOD_DAYS: 2,
9759
+ MAX_RPM: 10,
9760
+ MAX_RPH: 100,
9761
+ MAX_RPD: 500,
9762
+ MAX_CONCURRENT_REQUESTS: 2,
9763
+ MAX_INPUT_TOKENS: 2e4,
9764
+ MAX_OUTPUT_TOKENS: 4e3,
9765
+ UPGRADE_REMINDER_DAYS: [7, 12, 14],
9766
+ MAX_USERS: 1,
9767
+ MAX_NAMESPACES: 1,
9768
+ MAX_PROJECTS: 1
9769
+ };
9770
+ var FreeTierLimitsGuard = class {
9771
+ static calculateTrialTimestamps(startedAt) {
9772
+ const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
9773
+ const trialStartedAtMs = startDate.getTime();
9774
+ const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
9775
+ const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
9776
+ return {
9777
+ trial_started_at: new Date(trialStartedAtMs).toISOString(),
9778
+ trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
9779
+ grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
9780
+ };
9781
+ }
9782
+ static calculateRequestUnits(operationType, options) {
9783
+ var _a3;
9784
+ const op = operationType.toLowerCase().trim();
9785
+ 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")) {
9786
+ return 0;
9787
+ }
9788
+ if (op.includes("image")) {
9789
+ return 10;
9790
+ }
9791
+ if (op.includes("embedding")) {
9792
+ const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
9793
+ return Math.max(1, Math.ceil(chunks / 1e3));
9794
+ }
9795
+ return 1;
9796
+ }
9797
+ static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
9798
+ const timestamps = this.calculateTrialTimestamps(startedAt);
9799
+ const startMs = new Date(timestamps.trial_started_at).getTime();
9800
+ const expireMs = new Date(timestamps.trial_expires_at).getTime();
9801
+ const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
9802
+ const nowMs = nowServerTime.getTime();
9803
+ const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
9804
+ const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
9805
+ const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
9806
+ const isExpiredTime = nowMs > expireMs;
9807
+ const isPastGraceTime = nowMs > graceExpireMs;
9808
+ let status = "active";
9809
+ let reason;
9810
+ if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
9811
+ status = "expired";
9812
+ reason = "Trial period and grace period have expired. Upgrade your plan.";
9813
+ } else if (isExpiredTime || isConsumedUnits) {
9814
+ status = "grace_period";
9815
+ 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).";
9816
+ }
9817
+ let upgradeReminderDue;
9818
+ if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
9819
+ upgradeReminderDue = daysElapsed;
9820
+ }
9821
+ let usageReminderDue;
9822
+ const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
9823
+ if (usagePercent >= 100) {
9824
+ usageReminderDue = "100%";
9825
+ } else if (usagePercent >= 90) {
9826
+ usageReminderDue = "90%";
9827
+ } else if (usagePercent >= 80) {
9828
+ usageReminderDue = "80%";
9829
+ }
9830
+ return {
9831
+ status,
9832
+ daysElapsed,
9833
+ daysRemaining,
9834
+ isGracePeriod: status === "grace_period",
9835
+ isExpired: status === "expired",
9836
+ upgradeReminderDue,
9837
+ usageReminderDue,
9838
+ reason
9839
+ };
9840
+ }
9841
+ static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
9842
+ var _a3, _b;
9843
+ const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
9844
+ const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
9845
+ if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
9846
+ const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
9847
+ return {
9848
+ allowed: false,
9849
+ reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
9850
+ };
9851
+ }
9852
+ if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
9853
+ return {
9854
+ allowed: false,
9855
+ reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
9856
+ };
9857
+ }
9858
+ if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
9859
+ const mbUsed = (storage / (1024 * 1024)).toFixed(1);
9860
+ return {
9861
+ allowed: false,
9862
+ reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
9863
+ };
9864
+ }
9865
+ return { allowed: true };
9866
+ }
9867
+ static checkRequestAllowed(params) {
9868
+ var _a3, _b, _c;
9869
+ const op = (_a3 = params.operationType) != null ? _a3 : "chat";
9870
+ const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
9871
+ if (costUnits === 0) {
9872
+ return { allowed: true, costUnits: 0 };
9873
+ }
9874
+ if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
9875
+ return {
9876
+ allowed: false,
9877
+ reason: "Token limit exceeded. Upgrade your plan.",
9878
+ costUnits
9879
+ };
9880
+ }
9881
+ if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
9882
+ return {
9883
+ allowed: false,
9884
+ reason: "Token limit exceeded. Upgrade your plan.",
9885
+ costUnits
9886
+ };
9887
+ }
9888
+ if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
9889
+ return {
9890
+ allowed: false,
9891
+ reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
9892
+ costUnits
9893
+ };
9894
+ }
9895
+ const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
9896
+ const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
9897
+ if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
9898
+ return {
9899
+ allowed: false,
9900
+ reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
9901
+ costUnits
9902
+ };
9903
+ }
9904
+ if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
9905
+ return {
9906
+ allowed: false,
9907
+ reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
9908
+ costUnits
9909
+ };
9910
+ }
9911
+ const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
9912
+ if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
9913
+ return {
9914
+ allowed: false,
9915
+ reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
9916
+ costUnits
9917
+ };
9918
+ }
9919
+ return { allowed: true, costUnits };
9920
+ }
9921
+ static checkQueryAllowed(dailyQueriesCount = 0) {
9922
+ if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
9923
+ return {
9924
+ allowed: false,
9925
+ reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
9926
+ };
9927
+ }
9928
+ return { allowed: true };
9929
+ }
9930
+ };
9931
+
9622
9932
  // src/core/VectorPlugin.ts
9623
9933
  var VectorPlugin = class {
9624
9934
  constructor(hostConfig) {
9625
9935
  const resolvedConfig = ConfigResolver.resolve(hostConfig);
9626
9936
  this.config = resolvedConfig;
9627
9937
  this.validationPromise = (async () => {
9628
- var _a2;
9938
+ var _a3;
9629
9939
  await ConfigValidator.validateAndThrow(resolvedConfig);
9630
9940
  LicenseVerifier.verify(
9631
9941
  resolvedConfig.licenseKey,
9632
9942
  resolvedConfig.projectId,
9633
- (_a2 = resolvedConfig.vectorDb) == null ? void 0 : _a2.provider
9943
+ (_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
9634
9944
  );
9635
9945
  })();
9636
9946
  this.validationPromise.catch(() => {
@@ -9664,16 +9974,32 @@ var VectorPlugin = class {
9664
9974
  this.config.embedding
9665
9975
  );
9666
9976
  }
9977
+ estimateInputTokens(message, history = []) {
9978
+ const allContent = message.length + history.reduce((acc, m) => {
9979
+ var _a3, _b;
9980
+ 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);
9981
+ }, 0);
9982
+ return Math.ceil(allContent / 4);
9983
+ }
9667
9984
  /**
9668
9985
  * Run a chat query.
9669
9986
  */
9670
9987
  async chat(message, history = [], namespace) {
9988
+ var _a3;
9671
9989
  try {
9672
9990
  await this.validationPromise;
9673
9991
  } catch (err) {
9674
9992
  throw wrapError(err, "CONFIGURATION_ERROR");
9675
9993
  }
9676
9994
  try {
9995
+ const inputTokens = this.estimateInputTokens(message, history);
9996
+ const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
9997
+ operationType: "chat",
9998
+ inputTokens
9999
+ });
10000
+ if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
10001
+ throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
10002
+ }
9677
10003
  return await this.pipeline.ask(message, history, namespace);
9678
10004
  } catch (err) {
9679
10005
  const msg = String(err);
@@ -9681,6 +10007,9 @@ var VectorPlugin = class {
9681
10007
  if (msg.includes("Embed") || msg.includes("embed")) {
9682
10008
  defaultCode = "EMBEDDING_FAILED";
9683
10009
  }
10010
+ if (msg.toLowerCase().includes("token limit")) {
10011
+ defaultCode = "RATE_LIMITED";
10012
+ }
9684
10013
  throw wrapError(err, defaultCode);
9685
10014
  }
9686
10015
  }
@@ -9689,12 +10018,21 @@ var VectorPlugin = class {
9689
10018
  */
9690
10019
  chatStream(_0) {
9691
10020
  return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
10021
+ var _a3;
9692
10022
  try {
9693
10023
  yield new __await(this.validationPromise);
9694
10024
  } catch (err) {
9695
10025
  throw wrapError(err, "CONFIGURATION_ERROR");
9696
10026
  }
9697
10027
  try {
10028
+ const inputTokens = this.estimateInputTokens(message, history);
10029
+ const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
10030
+ operationType: "chat_stream",
10031
+ inputTokens
10032
+ });
10033
+ if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
10034
+ throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
10035
+ }
9698
10036
  const stream = this.pipeline.askStream(message, history, namespace);
9699
10037
  try {
9700
10038
  for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
@@ -9717,6 +10055,9 @@ var VectorPlugin = class {
9717
10055
  if (msg.includes("Embed") || msg.includes("embed")) {
9718
10056
  defaultCode = "EMBEDDING_FAILED";
9719
10057
  }
10058
+ if (msg.toLowerCase().includes("token limit")) {
10059
+ defaultCode = "RATE_LIMITED";
10060
+ }
9720
10061
  throw wrapError(err, defaultCode);
9721
10062
  }
9722
10063
  });
@@ -9771,13 +10112,13 @@ var ConfigBuilder = class {
9771
10112
  * Configure the vector database provider
9772
10113
  */
9773
10114
  vectorDb(provider, options) {
9774
- var _a2;
10115
+ var _a3;
9775
10116
  if (provider === "auto") {
9776
10117
  this._vectorDb = this._autoDetectVectorDb();
9777
10118
  } else {
9778
10119
  this._vectorDb = {
9779
10120
  provider,
9780
- indexName: (_a2 = options == null ? void 0 : options.indexName) != null ? _a2 : "default",
10121
+ indexName: (_a3 = options == null ? void 0 : options.indexName) != null ? _a3 : "default",
9781
10122
  options: __spreadValues({}, options)
9782
10123
  };
9783
10124
  }
@@ -9787,7 +10128,7 @@ var ConfigBuilder = class {
9787
10128
  * Configure the LLM provider for chat
9788
10129
  */
9789
10130
  llm(provider, model, apiKey, options) {
9790
- var _a2, _b;
10131
+ var _a3, _b;
9791
10132
  if (provider === "auto") {
9792
10133
  this._llm = this._autoDetectLLM();
9793
10134
  } else {
@@ -9796,7 +10137,7 @@ var ConfigBuilder = class {
9796
10137
  model: model != null ? model : "default-model",
9797
10138
  apiKey,
9798
10139
  systemPrompt: options == null ? void 0 : options.systemPrompt,
9799
- maxTokens: (_a2 = options == null ? void 0 : options.maxTokens) != null ? _a2 : 1024,
10140
+ maxTokens: (_a3 = options == null ? void 0 : options.maxTokens) != null ? _a3 : 1024,
9800
10141
  temperature: (_b = options == null ? void 0 : options.temperature) != null ? _b : 0.7,
9801
10142
  baseUrl: options == null ? void 0 : options.baseUrl,
9802
10143
  options
@@ -9839,8 +10180,8 @@ var ConfigBuilder = class {
9839
10180
  * Set RAG-specific pipeline parameters
9840
10181
  */
9841
10182
  rag(options) {
9842
- var _a2;
9843
- this._rag = __spreadValues(__spreadValues({}, (_a2 = this._rag) != null ? _a2 : {}), options);
10183
+ var _a3;
10184
+ this._rag = __spreadValues(__spreadValues({}, (_a3 = this._rag) != null ? _a3 : {}), options);
9844
10185
  return this;
9845
10186
  }
9846
10187
  /**
@@ -9856,7 +10197,7 @@ var ConfigBuilder = class {
9856
10197
  * Throws if required fields (projectId, vectorDb, llm, embedding) are not set.
9857
10198
  */
9858
10199
  build() {
9859
- var _a2;
10200
+ var _a3;
9860
10201
  const missing = [];
9861
10202
  if (!this._projectId) missing.push('projectId (call .projectId("my-app"))');
9862
10203
  if (!this._vectorDb) missing.push('vectorDb (call .vectorDb("pinecone", { ... }))');
@@ -9868,7 +10209,7 @@ var ConfigBuilder = class {
9868
10209
  ${missing.join("\n ")}`
9869
10210
  );
9870
10211
  }
9871
- const ragConfig = (_a2 = this._rag) != null ? _a2 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
10212
+ const ragConfig = (_a3 = this._rag) != null ? _a3 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
9872
10213
  if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
9873
10214
  ragConfig.useGraphRetrieval = true;
9874
10215
  }
@@ -9964,8 +10305,8 @@ var DocumentParser = class {
9964
10305
  * Extract text from a File or Buffer based on its type.
9965
10306
  */
9966
10307
  static async parse(file, fileName, mimeType) {
9967
- var _a2;
9968
- const extension = ((_a2 = fileName.split(".").pop()) == null ? void 0 : _a2.toLowerCase()) || "";
10308
+ var _a3;
10309
+ const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
9969
10310
  if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
9970
10311
  return this.readAsText(file);
9971
10312
  }
@@ -10072,9 +10413,9 @@ var DatabaseStorage = class {
10072
10413
  this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
10073
10414
  this.historyFile = path.join(this.fallbackDir, "history.json");
10074
10415
  this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
10075
- var _a2, _b, _c, _d, _e;
10416
+ var _a3, _b, _c, _d, _e;
10076
10417
  this.config = config;
10077
- this.provider = ((_a2 = config.vectorDb) == null ? void 0 : _a2.provider) || "fs";
10418
+ this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
10078
10419
  const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
10079
10420
  const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
10080
10421
  this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
@@ -10109,16 +10450,16 @@ var DatabaseStorage = class {
10109
10450
  }
10110
10451
  }
10111
10452
  checkHistoryEnabled() {
10112
- var _a2, _b;
10453
+ var _a3, _b;
10113
10454
  this.checkPremiumSubscription();
10114
- if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.history) == null ? void 0 : _b.enabled) === false) {
10455
+ if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
10115
10456
  throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
10116
10457
  }
10117
10458
  }
10118
10459
  checkFeedbackEnabled() {
10119
- var _a2, _b;
10460
+ var _a3, _b;
10120
10461
  this.checkPremiumSubscription();
10121
- if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.feedback) == null ? void 0 : _b.enabled) === false) {
10462
+ if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
10122
10463
  throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
10123
10464
  }
10124
10465
  }
@@ -10285,8 +10626,11 @@ var DatabaseStorage = class {
10285
10626
  this.writeLocalFile(this.historyFile, history);
10286
10627
  }
10287
10628
  }
10288
- async getHistory(sessionId) {
10629
+ async getHistory(sessionId, projectIds) {
10289
10630
  this.checkHistoryEnabled();
10631
+ if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
10632
+ return [];
10633
+ }
10290
10634
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10291
10635
  const pool = await this.getPGPool();
10292
10636
  const res = await pool.query(
@@ -10316,8 +10660,11 @@ var DatabaseStorage = class {
10316
10660
  return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
10317
10661
  }
10318
10662
  }
10319
- async clearHistory(sessionId) {
10663
+ async clearHistory(sessionId, projectIds) {
10320
10664
  this.checkHistoryEnabled();
10665
+ if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
10666
+ return;
10667
+ }
10321
10668
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10322
10669
  const pool = await this.getPGPool();
10323
10670
  await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
@@ -10336,21 +10683,36 @@ var DatabaseStorage = class {
10336
10683
  this.writeLocalFile(this.feedbackFile, filteredFeedback);
10337
10684
  }
10338
10685
  }
10339
- async listSessions() {
10686
+ /**
10687
+ * Return true when `sessionId` falls into the allowed `projectIds` scope.
10688
+ * When `projectIds` is empty / undefined we allow the call (legacy behavior
10689
+ * for non-multi-tenant consumers). Session ids typically begin with the
10690
+ * project id they were created for, so we prefix-match as well as contains-match
10691
+ * to catch sharded / suffix-style ids used by some integrations.
10692
+ */
10693
+ sessionInScope(sessionId, projectIds) {
10694
+ if (!projectIds || projectIds.length === 0) return true;
10695
+ return projectIds.some(
10696
+ (pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
10697
+ );
10698
+ }
10699
+ async listSessions(projectIds) {
10340
10700
  this.checkHistoryEnabled();
10701
+ let raw = [];
10341
10702
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10342
10703
  const pool = await this.getPGPool();
10343
10704
  const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
10344
- return res.rows.map((r) => r.session_id);
10705
+ raw = res.rows.map((r) => r.session_id);
10345
10706
  } else if (this.provider === "mongodb") {
10346
10707
  await this.getMongoClient();
10347
10708
  const db = this.getMongoDb();
10348
- return db.collection(this.historyTableName).distinct("session_id");
10709
+ raw = await db.collection(this.historyTableName).distinct("session_id");
10349
10710
  } else {
10350
10711
  const history = this.readLocalFile(this.historyFile);
10351
- const sessions = new Set(history.map((h) => h.session_id));
10352
- return Array.from(sessions);
10712
+ raw = Array.from(new Set(history.map((h) => h.session_id)));
10353
10713
  }
10714
+ if (!projectIds || projectIds.length === 0) return raw;
10715
+ return raw.filter((sid) => this.sessionInScope(sid, projectIds));
10354
10716
  }
10355
10717
  // ─── Feedback Operations ──────────────────────────────────────────────────
10356
10718
  async saveFeedback(feedback) {
@@ -10403,8 +10765,9 @@ var DatabaseStorage = class {
10403
10765
  this.writeLocalFile(this.feedbackFile, list);
10404
10766
  }
10405
10767
  }
10406
- async getFeedback(messageId) {
10768
+ async getFeedback(messageId, projectIds) {
10407
10769
  this.checkFeedbackEnabled();
10770
+ let item = null;
10408
10771
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10409
10772
  const pool = await this.getPGPool();
10410
10773
  const res = await pool.query(
@@ -10413,28 +10776,34 @@ var DatabaseStorage = class {
10413
10776
  WHERE message_id = $1`,
10414
10777
  [messageId]
10415
10778
  );
10416
- return res.rows[0] || null;
10779
+ item = res.rows[0] || null;
10417
10780
  } else if (this.provider === "mongodb") {
10418
10781
  await this.getMongoClient();
10419
10782
  const db = this.getMongoDb();
10420
10783
  const col = db.collection(this.feedbackTableName);
10421
- const item = await col.findOne({ message_id: messageId });
10422
- if (!item) return null;
10423
- return {
10424
- id: item.id,
10425
- messageId: item.message_id,
10426
- sessionId: item.session_id,
10427
- rating: item.rating,
10428
- comment: item.comment,
10429
- createdAt: item.created_at
10430
- };
10784
+ const raw = await col.findOne({ message_id: messageId });
10785
+ if (raw) {
10786
+ item = {
10787
+ id: raw.id,
10788
+ messageId: raw.message_id,
10789
+ sessionId: raw.session_id,
10790
+ rating: raw.rating,
10791
+ comment: raw.comment,
10792
+ createdAt: raw.created_at
10793
+ };
10794
+ }
10431
10795
  } else {
10432
10796
  const list = this.readLocalFile(this.feedbackFile);
10433
- return list.find((f) => f.message_id === messageId) || null;
10797
+ item = list.find((f) => f.message_id === messageId) || null;
10434
10798
  }
10799
+ if (item && projectIds && projectIds.length > 0) {
10800
+ return this.sessionInScope(item.sessionId, projectIds) ? item : null;
10801
+ }
10802
+ return item;
10435
10803
  }
10436
- async listFeedback() {
10804
+ async listFeedback(projectIds) {
10437
10805
  this.checkFeedbackEnabled();
10806
+ let raw = [];
10438
10807
  if (this.provider === "postgresql" || this.provider === "pgvector") {
10439
10808
  const pool = await this.getPGPool();
10440
10809
  const res = await pool.query(
@@ -10442,13 +10811,13 @@ var DatabaseStorage = class {
10442
10811
  FROM ${this.feedbackTableName}
10443
10812
  ORDER BY created_at DESC`
10444
10813
  );
10445
- return res.rows;
10814
+ raw = res.rows;
10446
10815
  } else if (this.provider === "mongodb") {
10447
10816
  await this.getMongoClient();
10448
10817
  const db = this.getMongoDb();
10449
10818
  const col = db.collection(this.feedbackTableName);
10450
10819
  const items = await col.find({}).sort({ created_at: -1 }).toArray();
10451
- return items.map((item) => ({
10820
+ raw = items.map((item) => ({
10452
10821
  id: item.id,
10453
10822
  messageId: item.message_id,
10454
10823
  sessionId: item.session_id,
@@ -10458,8 +10827,10 @@ var DatabaseStorage = class {
10458
10827
  }));
10459
10828
  } else {
10460
10829
  const list = this.readLocalFile(this.feedbackFile);
10461
- return [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
10830
+ raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
10462
10831
  }
10832
+ if (!projectIds || projectIds.length === 0) return raw;
10833
+ return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
10463
10834
  }
10464
10835
  async disconnect() {
10465
10836
  if (this.pgPool) {
@@ -10522,8 +10893,8 @@ var _g = global;
10522
10893
  var _a;
10523
10894
  var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
10524
10895
  function getRateLimitKey(req) {
10525
- var _a2, _b;
10526
- 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";
10896
+ var _a3, _b;
10897
+ 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";
10527
10898
  return `ip:${ip}`;
10528
10899
  }
10529
10900
  function checkRateLimit(req) {
@@ -10545,6 +10916,66 @@ function checkRateLimit(req) {
10545
10916
  }
10546
10917
  return null;
10547
10918
  }
10919
+ var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
10920
+ function isFreeTier(tier) {
10921
+ if (!tier) return true;
10922
+ return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
10923
+ }
10924
+ var _a2;
10925
+ var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
10926
+ function createPaymentRequiredResponse(reason, details) {
10927
+ const body = __spreadProps(__spreadValues({
10928
+ type: "https://retrivora.com/docs/errors/payment-required",
10929
+ title: "Payment Required",
10930
+ status: 402,
10931
+ detail: reason,
10932
+ code: "FREE_TIER_LIMIT_EXCEEDED",
10933
+ instance: void 0
10934
+ }, details != null ? details : {}), {
10935
+ quota: {
10936
+ maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
10937
+ maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
10938
+ maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
10939
+ maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
10940
+ upgradeUrl: "https://retrivora.com/pricing"
10941
+ }
10942
+ });
10943
+ return new Response(JSON.stringify(body), {
10944
+ status: 402,
10945
+ headers: {
10946
+ "Content-Type": "application/problem+json"
10947
+ }
10948
+ });
10949
+ }
10950
+ function resolveLicenseKey(req, config, bodyLicenseKey) {
10951
+ var _a3;
10952
+ 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 || "";
10953
+ }
10954
+ function enforceLicense(req, config, bodyLicenseKey) {
10955
+ const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
10956
+ const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
10957
+ const projectId = config.projectId || "my-rag-app";
10958
+ try {
10959
+ const payload = LicenseVerifier.verify(licenseKey, projectId);
10960
+ return { ok: true, payload };
10961
+ } catch (err) {
10962
+ 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.";
10963
+ const body = {
10964
+ error: {
10965
+ code: "LICENSE_REVOKED",
10966
+ message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
10967
+ },
10968
+ details: message
10969
+ };
10970
+ return {
10971
+ ok: false,
10972
+ response: new Response(JSON.stringify(body), {
10973
+ status: 403,
10974
+ headers: { "Content-Type": "application/json" }
10975
+ })
10976
+ };
10977
+ }
10978
+ }
10548
10979
  var MAX_MESSAGE_LENGTH = 8e3;
10549
10980
  function sanitizeInput(raw) {
10550
10981
  const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
@@ -10566,7 +10997,7 @@ function getOrCreatePlugin(configOrPlugin) {
10566
10997
  return _g[cacheKey];
10567
10998
  }
10568
10999
  function reportTelemetry(req, plugin, action, status, details, trace) {
10569
- var _a2, _b, _c, _d, _e, _f, _g2;
11000
+ var _a3, _b, _c, _d, _e, _f, _g2;
10570
11001
  try {
10571
11002
  const config = plugin.getConfig();
10572
11003
  const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
@@ -10581,7 +11012,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
10581
11012
  absoluteUrl = `${proto}://${host}${telemetryUrl}`;
10582
11013
  }
10583
11014
  const projectId = config.projectId || "default";
10584
- 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";
11015
+ 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";
10585
11016
  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";
10586
11017
  const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
10587
11018
  const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
@@ -10605,7 +11036,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
10605
11036
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
10606
11037
  details
10607
11038
  };
10608
- console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
10609
11039
  fetch(absoluteUrl, {
10610
11040
  method: "POST",
10611
11041
  headers: {
@@ -10663,14 +11093,39 @@ function createChatHandler(configOrPlugin, options) {
10663
11093
  const storage = new DatabaseStorage(plugin.getConfig());
10664
11094
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10665
11095
  return async function POST(req, context) {
10666
- var _a2, _b, _c, _d;
11096
+ var _a3, _b, _c, _d, _e, _f;
10667
11097
  const authResult = await checkAuth(req, onAuthorize);
10668
11098
  if (authResult) return authResult;
10669
11099
  const rateLimited = checkRateLimit(req);
10670
11100
  if (rateLimited) return rateLimited;
11101
+ const config = plugin.getConfig();
10671
11102
  try {
10672
11103
  const body = await req.json();
10673
11104
  const bodyObj = body != null ? body : {};
11105
+ const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
11106
+ if (!licenseCheck.ok) return licenseCheck.response;
11107
+ if (isFreeTier(licenseCheck.payload.tier)) {
11108
+ const estimatedInputTokens = Math.ceil(
11109
+ ((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
11110
+ var _a4, _b2;
11111
+ 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);
11112
+ }, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.reduce((a, m) => {
11113
+ var _a4, _b2;
11114
+ 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);
11115
+ }, 0)) || 0)) / 4
11116
+ );
11117
+ const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
11118
+ operationType: "chat",
11119
+ inputTokens: estimatedInputTokens,
11120
+ projectId: licenseCheck.payload.projectId
11121
+ });
11122
+ if (!chatCheck.allowed) {
11123
+ return createPaymentRequiredResponse(
11124
+ chatCheck.reason || "Free tier quota exceeded.",
11125
+ { tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
11126
+ );
11127
+ }
11128
+ }
10674
11129
  let rawMessage = bodyObj.message;
10675
11130
  if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
10676
11131
  const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
@@ -10702,7 +11157,7 @@ function createChatHandler(configOrPlugin, options) {
10702
11157
  uiTransformation: result.ui_transformation,
10703
11158
  trace: result.trace
10704
11159
  }).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
10705
- 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);
11160
+ 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);
10706
11161
  return NextResponse.json(__spreadProps(__spreadValues({}, result), {
10707
11162
  messageId: assistantMsgId,
10708
11163
  userMessageId: userMsgId
@@ -10719,14 +11174,15 @@ function createStreamHandler(configOrPlugin, options) {
10719
11174
  const storage = new DatabaseStorage(plugin.getConfig());
10720
11175
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10721
11176
  return async function POST(req, context) {
10722
- var _a2;
11177
+ var _a3, _b, _c;
10723
11178
  const authResult = await checkAuth(req, onAuthorize);
10724
11179
  if (authResult) return authResult;
10725
11180
  const rateLimited = checkRateLimit(req);
10726
11181
  if (rateLimited) return rateLimited;
11182
+ const config = plugin.getConfig();
10727
11183
  let body;
10728
11184
  try {
10729
- if ((_a2 = req.headers.get("content-type")) == null ? void 0 : _a2.includes("multipart/form-data")) {
11185
+ if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
10730
11186
  const uploader = createUploadHandler(plugin, { onAuthorize });
10731
11187
  return uploader(req);
10732
11188
  }
@@ -10738,6 +11194,30 @@ function createStreamHandler(configOrPlugin, options) {
10738
11194
  });
10739
11195
  }
10740
11196
  const bodyObj = body != null ? body : {};
11197
+ const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
11198
+ if (!licenseCheck.ok) return licenseCheck.response;
11199
+ if (isFreeTier(licenseCheck.payload.tier)) {
11200
+ const estimatedInputTokens = Math.ceil(
11201
+ ((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
11202
+ var _a4, _b2;
11203
+ 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);
11204
+ }, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.reduce((a, m) => {
11205
+ var _a4, _b2;
11206
+ 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);
11207
+ }, 0)) || 0)) / 4
11208
+ );
11209
+ const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
11210
+ operationType: "chat_stream",
11211
+ inputTokens: estimatedInputTokens,
11212
+ projectId: licenseCheck.payload.projectId
11213
+ });
11214
+ if (!chatCheck.allowed) {
11215
+ return createPaymentRequiredResponse(
11216
+ chatCheck.reason || "Free tier quota exceeded.",
11217
+ { tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
11218
+ );
11219
+ }
11220
+ }
10741
11221
  let rawMessage = bodyObj.message;
10742
11222
  if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
10743
11223
  const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
@@ -10767,7 +11247,7 @@ function createStreamHandler(configOrPlugin, options) {
10767
11247
  let isActive = true;
10768
11248
  const stream = new ReadableStream({
10769
11249
  async start(controller) {
10770
- var _a3, _b, _c, _d, _e;
11250
+ var _a4, _b2, _c2, _d, _e;
10771
11251
  const enqueue = (text) => {
10772
11252
  if (!isActive) return;
10773
11253
  try {
@@ -10800,7 +11280,7 @@ function createStreamHandler(configOrPlugin, options) {
10800
11280
  let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
10801
11281
  if (sources.length > 0) {
10802
11282
  try {
10803
- uiTransformation = (_a3 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a3 : UITransformer.transform(message, sources, plugin.getConfig());
11283
+ uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
10804
11284
  if (uiTransformation) {
10805
11285
  enqueue(sseUIFrame(uiTransformation));
10806
11286
  }
@@ -10824,7 +11304,7 @@ function createStreamHandler(configOrPlugin, options) {
10824
11304
  uiTransformation,
10825
11305
  trace: responseChunk == null ? void 0 : responseChunk.trace
10826
11306
  }).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
10827
- 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);
11307
+ 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);
10828
11308
  }
10829
11309
  }
10830
11310
  } catch (temp) {
@@ -10874,12 +11354,36 @@ function createIngestHandler(configOrPlugin, options) {
10874
11354
  return async function POST(req, context) {
10875
11355
  const authResult = await checkAuth(req, onAuthorize);
10876
11356
  if (authResult) return authResult;
11357
+ const config = plugin.getConfig();
10877
11358
  try {
10878
11359
  const body = await req.json();
11360
+ const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
11361
+ if (!licenseCheck.ok) return licenseCheck.response;
10879
11362
  const { documents, namespace } = body;
10880
11363
  if (!Array.isArray(documents) || documents.length === 0) {
10881
11364
  return NextResponse.json({ error: "documents array is required" }, { status: 400 });
10882
11365
  }
11366
+ if (isFreeTier(licenseCheck.payload.tier)) {
11367
+ const totalIncomingBytes = documents.reduce(
11368
+ (sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
11369
+ 0
11370
+ );
11371
+ const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
11372
+ { documentCount: documents.length },
11373
+ totalIncomingBytes
11374
+ );
11375
+ if (!ingestCheck.allowed) {
11376
+ return createPaymentRequiredResponse(
11377
+ ingestCheck.reason || "Free tier ingestion limit reached.",
11378
+ {
11379
+ tier: licenseCheck.payload.tier,
11380
+ projectId: licenseCheck.payload.projectId,
11381
+ documents: documents.length,
11382
+ incomingBytes: totalIncomingBytes
11383
+ }
11384
+ );
11385
+ }
11386
+ }
10883
11387
  const results = await plugin.ingest(documents, namespace);
10884
11388
  reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
10885
11389
  return NextResponse.json({ results });
@@ -10916,7 +11420,7 @@ function createLicenseHandler(configOrPlugin, options) {
10916
11420
  const plugin = getOrCreatePlugin(configOrPlugin);
10917
11421
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10918
11422
  return async function POST(req) {
10919
- var _a2;
11423
+ var _a3;
10920
11424
  if (req) {
10921
11425
  const authResult = await checkAuth(req, onAuthorize);
10922
11426
  if (authResult) return authResult;
@@ -10924,7 +11428,8 @@ function createLicenseHandler(configOrPlugin, options) {
10924
11428
  try {
10925
11429
  const body = await req.json().catch(() => ({}));
10926
11430
  const config = plugin.getConfig();
10927
- 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 || "";
11431
+ 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 || "";
11432
+ const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
10928
11433
  const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
10929
11434
  const payload = LicenseVerifier.verify(licenseKey, projectId);
10930
11435
  return NextResponse.json({
@@ -10958,6 +11463,9 @@ function createUploadHandler(configOrPlugin, options) {
10958
11463
  return async function POST(req, context) {
10959
11464
  const authResult = await checkAuth(req, onAuthorize);
10960
11465
  if (authResult) return authResult;
11466
+ const config = plugin.getConfig();
11467
+ const licenseCheck = enforceLicense(req, config);
11468
+ if (!licenseCheck.ok) return licenseCheck.response;
10961
11469
  try {
10962
11470
  const formData = await req.formData();
10963
11471
  const files = formData.getAll("files");
@@ -10967,6 +11475,26 @@ function createUploadHandler(configOrPlugin, options) {
10967
11475
  if (!files || files.length === 0) {
10968
11476
  return NextResponse.json({ error: "No files provided" }, { status: 400 });
10969
11477
  }
11478
+ if (isFreeTier(licenseCheck.payload.tier)) {
11479
+ const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
11480
+ const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
11481
+ { documentCount: files.length },
11482
+ totalUploadBytes
11483
+ );
11484
+ if (!uploadCheck.allowed) {
11485
+ return createPaymentRequiredResponse(
11486
+ uploadCheck.reason || "Free tier upload limit reached.",
11487
+ {
11488
+ tier: licenseCheck.payload.tier,
11489
+ projectId: licenseCheck.payload.projectId,
11490
+ fileCount: files.length,
11491
+ totalUploadBytes,
11492
+ maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
11493
+ maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
11494
+ }
11495
+ );
11496
+ }
11497
+ }
10970
11498
  const documents = [];
10971
11499
  for (const file of files) {
10972
11500
  const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
@@ -11076,13 +11604,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
11076
11604
  return async function handler(req) {
11077
11605
  const authResult = await checkAuth(req, onAuthorize);
11078
11606
  if (authResult) return authResult;
11607
+ const config = plugin.getConfig();
11608
+ const licenseCheck = enforceLicense(req, config);
11609
+ if (!licenseCheck.ok) return licenseCheck.response;
11079
11610
  try {
11080
11611
  let query = "";
11081
11612
  let namespace = void 0;
11613
+ let bodyLicenseKey = void 0;
11082
11614
  if (req.method === "POST") {
11083
11615
  const body = await req.json().catch(() => ({}));
11084
11616
  query = body.query || "";
11085
11617
  namespace = body.namespace;
11618
+ bodyLicenseKey = body.licenseKey;
11619
+ if (bodyLicenseKey) {
11620
+ const recheck = enforceLicense(req, config, bodyLicenseKey);
11621
+ if (!recheck.ok) return recheck.response;
11622
+ }
11086
11623
  } else {
11087
11624
  const url = new URL(req.url);
11088
11625
  query = url.searchParams.get("query") || "";
@@ -11105,14 +11642,16 @@ function createHistoryHandler(configOrPlugin, options) {
11105
11642
  const plugin = getOrCreatePlugin(configOrPlugin);
11106
11643
  const storage = new DatabaseStorage(plugin.getConfig());
11107
11644
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11645
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
11108
11646
  return async function handler(req) {
11109
11647
  const authResult = await checkAuth(req, onAuthorize);
11110
11648
  if (authResult) return authResult;
11649
+ const scope = onResolveScope ? await onResolveScope(req) : void 0;
11111
11650
  const url = new URL(req.url);
11112
11651
  const sessionId = url.searchParams.get("sessionId") || "default";
11113
11652
  if (req.method === "GET") {
11114
11653
  try {
11115
- const history = await storage.getHistory(sessionId);
11654
+ const history = await storage.getHistory(sessionId, scope);
11116
11655
  return NextResponse.json({ history });
11117
11656
  } catch (err) {
11118
11657
  const message = err instanceof Error ? err.message : "Failed to fetch history";
@@ -11122,7 +11661,7 @@ function createHistoryHandler(configOrPlugin, options) {
11122
11661
  try {
11123
11662
  const body = await req.json().catch(() => ({}));
11124
11663
  const sid = body.sessionId || sessionId;
11125
- await storage.clearHistory(sid);
11664
+ await storage.clearHistory(sid, scope);
11126
11665
  return NextResponse.json({ success: true });
11127
11666
  } catch (err) {
11128
11667
  const message = err instanceof Error ? err.message : "Failed to clear history";
@@ -11136,18 +11675,20 @@ function createFeedbackHandler(configOrPlugin, options) {
11136
11675
  const plugin = getOrCreatePlugin(configOrPlugin);
11137
11676
  const storage = new DatabaseStorage(plugin.getConfig());
11138
11677
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11678
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
11139
11679
  return async function handler(req) {
11140
11680
  const authResult = await checkAuth(req, onAuthorize);
11141
11681
  if (authResult) return authResult;
11682
+ const scope = onResolveScope ? await onResolveScope(req) : void 0;
11142
11683
  if (req.method === "GET") {
11143
11684
  try {
11144
11685
  const url = new URL(req.url);
11145
11686
  const messageId = url.searchParams.get("messageId");
11146
11687
  if (!messageId) {
11147
- const feedbackList = await storage.listFeedback();
11688
+ const feedbackList = await storage.listFeedback(scope);
11148
11689
  return NextResponse.json({ feedback: feedbackList });
11149
11690
  }
11150
- const feedback = await storage.getFeedback(messageId);
11691
+ const feedback = await storage.getFeedback(messageId, scope);
11151
11692
  return NextResponse.json({ feedback });
11152
11693
  } catch (err) {
11153
11694
  const message = err instanceof Error ? err.message : "Failed to fetch feedback";
@@ -11163,6 +11704,17 @@ function createFeedbackHandler(configOrPlugin, options) {
11163
11704
  if (!rating) {
11164
11705
  return NextResponse.json({ error: "rating is required" }, { status: 400 });
11165
11706
  }
11707
+ if (scope && scope.length > 0) {
11708
+ const matches = scope.some(
11709
+ (pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
11710
+ );
11711
+ if (!matches) {
11712
+ return NextResponse.json(
11713
+ { error: "sessionId is outside the authorized project scope" },
11714
+ { status: 403 }
11715
+ );
11716
+ }
11717
+ }
11166
11718
  await storage.saveFeedback({ messageId, sessionId, rating, comment });
11167
11719
  return NextResponse.json({ success: true });
11168
11720
  } catch (err) {
@@ -11177,14 +11729,15 @@ function createSessionsHandler(configOrPlugin, options) {
11177
11729
  const plugin = getOrCreatePlugin(configOrPlugin);
11178
11730
  const storage = new DatabaseStorage(plugin.getConfig());
11179
11731
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11732
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
11180
11733
  return async function GET(req) {
11181
11734
  if (req) {
11182
11735
  const authResult = await checkAuth(req, onAuthorize);
11183
11736
  if (authResult) return authResult;
11184
11737
  }
11185
- void req;
11186
11738
  try {
11187
- const sessions = await storage.listSessions();
11739
+ const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
11740
+ const sessions = await storage.listSessions(scope);
11188
11741
  return NextResponse.json({ sessions });
11189
11742
  } catch (err) {
11190
11743
  const message = err instanceof Error ? err.message : "Failed to list sessions";
@@ -11195,15 +11748,17 @@ function createSessionsHandler(configOrPlugin, options) {
11195
11748
  function createRagHandler(configOrPlugin, options) {
11196
11749
  const plugin = getOrCreatePlugin(configOrPlugin);
11197
11750
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11198
- const chatHandler = createChatHandler(plugin, { onAuthorize });
11199
- const streamHandler = createStreamHandler(plugin, { onAuthorize });
11200
- const uploadHandler = createUploadHandler(plugin, { onAuthorize });
11201
- const healthHandler = createHealthHandler(plugin, { onAuthorize });
11202
- const suggestionsHandler = createSuggestionsHandler(plugin, { onAuthorize });
11203
- const historyHandler = createHistoryHandler(plugin, { onAuthorize });
11204
- const feedbackHandler = createFeedbackHandler(plugin, { onAuthorize });
11205
- const sessionsHandler = createSessionsHandler(plugin, { onAuthorize });
11206
- const licenseHandler = createLicenseHandler(plugin, { onAuthorize });
11751
+ const onResolveScope = options == null ? void 0 : options.onResolveScope;
11752
+ const scopeableOptions = { onAuthorize, onResolveScope };
11753
+ const chatHandler = createChatHandler(plugin, scopeableOptions);
11754
+ const streamHandler = createStreamHandler(plugin, scopeableOptions);
11755
+ const uploadHandler = createUploadHandler(plugin, scopeableOptions);
11756
+ const healthHandler = createHealthHandler(plugin, scopeableOptions);
11757
+ const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
11758
+ const historyHandler = createHistoryHandler(plugin, scopeableOptions);
11759
+ const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
11760
+ const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
11761
+ const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
11207
11762
  async function routePostRequest(req, segment) {
11208
11763
  switch (segment) {
11209
11764
  case "chat":
@@ -11245,7 +11800,7 @@ function createRagHandler(configOrPlugin, options) {
11245
11800
  }
11246
11801
  }
11247
11802
  async function getSegment(req, context) {
11248
- var _a2, _b;
11803
+ var _a3, _b;
11249
11804
  const contentType = req.headers.get("content-type") || "";
11250
11805
  if (contentType.includes("multipart/form-data")) {
11251
11806
  return "upload";
@@ -11262,7 +11817,7 @@ function createRagHandler(configOrPlugin, options) {
11262
11817
  if (pathname.endsWith("/history")) return "history";
11263
11818
  } catch (e) {
11264
11819
  }
11265
- 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;
11820
+ 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;
11266
11821
  const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
11267
11822
  const joined = segments.join("/");
11268
11823
  return joined || "chat";
@@ -11295,6 +11850,7 @@ var _LicenseValidator = class _LicenseValidator {
11295
11850
  constructor() {
11296
11851
  this.cache = /* @__PURE__ */ new Map();
11297
11852
  }
11853
+ /** @returns Singleton instance of the validator (shared cache across all consumers). */
11298
11854
  static getInstance() {
11299
11855
  if (!_LicenseValidator.instance) {
11300
11856
  _LicenseValidator.instance = new _LicenseValidator();
@@ -11302,7 +11858,12 @@ var _LicenseValidator = class _LicenseValidator {
11302
11858
  return _LicenseValidator.instance;
11303
11859
  }
11304
11860
  /**
11305
- * Invalidate local validation cache for a license key
11861
+ * Purge entries from the local success cache.
11862
+ *
11863
+ * @param licenseKey - Optional. If provided, only that key's cache entry is
11864
+ * removed. If omitted the entire cache is cleared.
11865
+ * Callers use this after any 401/403 to ensure the next
11866
+ * validate() call re-validates against the server.
11306
11867
  */
11307
11868
  purgeCache(licenseKey) {
11308
11869
  if (licenseKey) {
@@ -11312,10 +11873,20 @@ var _LicenseValidator = class _LicenseValidator {
11312
11873
  }
11313
11874
  }
11314
11875
  /**
11315
- * Validate license status and SDK version against Retrivora License Service
11876
+ * Primary validation entry-point for UI / hook consumers.
11877
+ *
11878
+ * Resolves the license key, consults the local success cache, performs a
11879
+ * server POST for authoritative status, and falls back to local RSA
11880
+ * signature verification if the server can't be reached.
11881
+ *
11882
+ * @throws LicenseValidationError - When no key is provided OR both the
11883
+ * server call AND the local-RSA fallback report an invalid/expired key.
11884
+ * @throws SDKVersionUnsupportedError - When server reports forceUpgrade=true.
11885
+ * @returns A `LicenseValidationResponse` that the UI can use to enable or
11886
+ * lock the chat widget.
11316
11887
  */
11317
11888
  async validate(request) {
11318
- var _a2;
11889
+ var _a3;
11319
11890
  const {
11320
11891
  licenseKey,
11321
11892
  projectId,
@@ -11333,7 +11904,8 @@ var _LicenseValidator = class _LicenseValidator {
11333
11904
  }
11334
11905
  return void 0;
11335
11906
  };
11336
- const effectiveLicenseKey = licenseKey || getHeader("x-license-key") || ((_a2 = getHeader("authorization")) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
11907
+ const rawKey = licenseKey || getHeader("x-license-key") || ((_a3 = getHeader("authorization")) == null ? void 0 : _a3.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
11908
+ const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
11337
11909
  if (!effectiveLicenseKey) {
11338
11910
  this.purgeCache(effectiveLicenseKey);
11339
11911
  throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.");