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