@retrivora-ai/rag-engine 1.9.7 → 1.9.8

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.
Files changed (58) hide show
  1. package/README.md +127 -135
  2. package/dist/{ILLMProvider-Bhk6zJOK.d.mts → ILLMProvider-B8ROITYK.d.mts} +57 -2
  3. package/dist/{ILLMProvider-Bhk6zJOK.d.ts → ILLMProvider-B8ROITYK.d.ts} +57 -2
  4. package/dist/handlers/index.d.mts +2 -2
  5. package/dist/handlers/index.d.ts +2 -2
  6. package/dist/handlers/index.js +2198 -457
  7. package/dist/handlers/index.mjs +2195 -457
  8. package/dist/{index-BJ4cd-t5.d.mts → index-B8PbEFSY.d.mts} +12 -2
  9. package/dist/{index-Bu7T6xgr.d.ts → index-BCPKUAVL.d.ts} +27 -52
  10. package/dist/{index-C3SVtPYg.d.mts → index-CrxCy36A.d.mts} +27 -52
  11. package/dist/{index-B9J_XEh0.d.ts → index-DNvoi-sV.d.ts} +12 -2
  12. package/dist/index.css +578 -273
  13. package/dist/index.d.mts +29 -7
  14. package/dist/index.d.ts +29 -7
  15. package/dist/index.js +1160 -282
  16. package/dist/index.mjs +1185 -292
  17. package/dist/server.d.mts +62 -6
  18. package/dist/server.d.ts +62 -6
  19. package/dist/server.js +2061 -306
  20. package/dist/server.mjs +2055 -306
  21. package/package.json +11 -7
  22. package/src/app/constants.tsx +37 -7
  23. package/src/components/AmbientBackground.tsx +10 -10
  24. package/src/components/ArchitectureCard.tsx +43 -7
  25. package/src/components/ArchitectureCardsSection.tsx +37 -4
  26. package/src/components/ChatWidget.tsx +2 -1
  27. package/src/components/ChatWindow.tsx +4 -1
  28. package/src/components/CodeViewer.tsx +19 -14
  29. package/src/components/DocViewer.tsx +43 -49
  30. package/src/components/Documentation.tsx +71 -51
  31. package/src/components/Hero.tsx +103 -20
  32. package/src/components/Lifecycle.tsx +65 -25
  33. package/src/components/MarkdownComponents.tsx +44 -1
  34. package/src/components/MessageBubble.tsx +162 -50
  35. package/src/components/constants.tsx +4 -0
  36. package/src/config/RagConfig.ts +46 -0
  37. package/src/config/constants.ts +4 -0
  38. package/src/config/serverConfig.ts +15 -0
  39. package/src/core/ConfigResolver.ts +6 -0
  40. package/src/core/DatabaseStorage.ts +469 -0
  41. package/src/core/LicenseVerifier.ts +154 -0
  42. package/src/core/MultiAgentCoordinator.ts +239 -0
  43. package/src/core/Pipeline.ts +146 -15
  44. package/src/core/Retrivora.ts +6 -0
  45. package/src/core/VectorPlugin.ts +12 -3
  46. package/src/core/mcp.ts +261 -0
  47. package/src/handlers/index.ts +449 -63
  48. package/src/hooks/useRagChat.ts +96 -42
  49. package/src/hooks/useStoredMessages.ts +15 -4
  50. package/src/index.ts +5 -0
  51. package/src/llm/LLMFactory.ts +9 -1
  52. package/src/llm/providers/GroqProvider.ts +176 -0
  53. package/src/llm/providers/QwenProvider.ts +191 -0
  54. package/src/server.ts +7 -0
  55. package/src/types/chat.ts +14 -0
  56. package/src/types/props.ts +12 -0
  57. package/.env.example +0 -80
  58. package/LICENSE.txt +0 -21
package/dist/server.js CHANGED
@@ -80,9 +80,9 @@ var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")])
80
80
  function isRecord(value) {
81
81
  return typeof value === "object" && value !== null;
82
82
  }
83
- function resolvePath(obj, path) {
84
- if (!path || !obj) return void 0;
85
- return path.replace(/\[(\w+)\]/g, ".$1").replace(/^\./, "").split(".").reduce((current, segment) => {
83
+ function resolvePath(obj, path2) {
84
+ if (!path2 || !obj) return void 0;
85
+ return path2.replace(/\[(\w+)\]/g, ".$1").replace(/^\./, "").split(".").reduce((current, segment) => {
86
86
  if (!isRecord(current) && !Array.isArray(current)) {
87
87
  return void 0;
88
88
  }
@@ -192,7 +192,7 @@ var init_PineconeProvider = __esm({
192
192
  static getHealthChecker() {
193
193
  return {
194
194
  async check(config) {
195
- var _a, _b;
195
+ var _a2, _b;
196
196
  const opts = config.options || {};
197
197
  const indexName = config.indexName;
198
198
  const timestamp = Date.now();
@@ -200,7 +200,7 @@ var init_PineconeProvider = __esm({
200
200
  const { Pinecone: Pinecone2 } = await import("@pinecone-database/pinecone");
201
201
  const client = new Pinecone2({ apiKey: opts.apiKey });
202
202
  const indexes = await client.listIndexes();
203
- const indexNames = (_b = (_a = indexes.indexes) == null ? void 0 : _a.map((i) => i.name)) != null ? _b : [];
203
+ const indexNames = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
204
204
  if (!indexNames.includes(indexName)) {
205
205
  return {
206
206
  healthy: false,
@@ -227,10 +227,10 @@ var init_PineconeProvider = __esm({
227
227
  };
228
228
  }
229
229
  async initialize() {
230
- var _a, _b;
230
+ var _a2, _b;
231
231
  this.client = new import_pinecone.Pinecone({ apiKey: this.apiKey });
232
232
  const indexes = await this.client.listIndexes();
233
- const names = (_b = (_a = indexes.indexes) == null ? void 0 : _a.map((i) => i.name)) != null ? _b : [];
233
+ const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
234
234
  if (!names.includes(this.indexName)) {
235
235
  throw new Error(
236
236
  `[PineconeProvider] Index "${this.indexName}" not found. Available: ${names.join(", ")}`
@@ -242,12 +242,12 @@ var init_PineconeProvider = __esm({
242
242
  return namespace ? idx.namespace(namespace) : idx.namespace("");
243
243
  }
244
244
  async upsert(doc, namespace) {
245
- var _a;
245
+ var _a2;
246
246
  await this.index(namespace).upsert({
247
247
  records: [{
248
248
  id: String(doc.id),
249
249
  values: doc.vector,
250
- metadata: __spreadValues({ content: doc.content }, (_a = doc.metadata) != null ? _a : {})
250
+ metadata: __spreadValues({ content: doc.content }, (_a2 = doc.metadata) != null ? _a2 : {})
251
251
  }]
252
252
  });
253
253
  }
@@ -255,29 +255,29 @@ var init_PineconeProvider = __esm({
255
255
  const BATCH = 100;
256
256
  for (let i = 0; i < docs.length; i += BATCH) {
257
257
  const records = docs.slice(i, i + BATCH).map((d) => {
258
- var _a;
258
+ var _a2;
259
259
  return {
260
260
  id: String(d.id),
261
261
  values: d.vector,
262
- metadata: __spreadValues({ content: d.content }, (_a = d.metadata) != null ? _a : {})
262
+ metadata: __spreadValues({ content: d.content }, (_a2 = d.metadata) != null ? _a2 : {})
263
263
  };
264
264
  });
265
265
  await this.index(namespace).upsert({ records });
266
266
  }
267
267
  }
268
268
  async query(vector, topK, namespace, filter) {
269
- var _a;
269
+ var _a2;
270
270
  const pineconeFilter = this.sanitizeFilter(filter);
271
271
  const result = await this.index(namespace).query(__spreadValues({
272
272
  vector,
273
273
  topK,
274
274
  includeMetadata: true
275
275
  }, Object.keys(pineconeFilter).length > 0 ? { filter: pineconeFilter } : {}));
276
- return ((_a = result.matches) != null ? _a : []).map((m) => {
277
- var _a2, _b;
276
+ return ((_a2 = result.matches) != null ? _a2 : []).map((m) => {
277
+ var _a3, _b;
278
278
  return {
279
279
  id: m.id,
280
- score: (_a2 = m.score) != null ? _a2 : 0,
280
+ score: (_a3 = m.score) != null ? _a3 : 0,
281
281
  content: ((_b = m.metadata) == null ? void 0 : _b.content) || "",
282
282
  metadata: m.metadata
283
283
  };
@@ -316,13 +316,13 @@ var init_PostgreSQLProvider = __esm({
316
316
  init_BaseVectorProvider();
317
317
  PostgreSQLProvider = class extends BaseVectorProvider {
318
318
  constructor(config) {
319
- var _a;
319
+ var _a2;
320
320
  super(config);
321
321
  this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
322
322
  const opts = config.options;
323
323
  if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
324
324
  this.connectionString = opts.connectionString;
325
- this.dimensions = (_a = opts.dimensions) != null ? _a : 1536;
325
+ this.dimensions = (_a2 = opts.dimensions) != null ? _a2 : 1536;
326
326
  }
327
327
  static getValidator() {
328
328
  return {
@@ -403,7 +403,7 @@ var init_PostgreSQLProvider = __esm({
403
403
  }
404
404
  }
405
405
  async upsert(doc, namespace = "") {
406
- var _a;
406
+ var _a2;
407
407
  const vectorLiteral = `[${doc.vector.join(",")}]`;
408
408
  await this.pool.query(
409
409
  `INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
@@ -413,7 +413,7 @@ var init_PostgreSQLProvider = __esm({
413
413
  content = EXCLUDED.content,
414
414
  metadata = EXCLUDED.metadata,
415
415
  embedding = EXCLUDED.embedding`,
416
- [doc.id, namespace, doc.content, JSON.stringify((_a = doc.metadata) != null ? _a : {}), vectorLiteral]
416
+ [doc.id, namespace, doc.content, JSON.stringify((_a2 = doc.metadata) != null ? _a2 : {}), vectorLiteral]
417
417
  );
418
418
  }
419
419
  async batchUpsert(docs, namespace = "") {
@@ -426,9 +426,9 @@ var init_PostgreSQLProvider = __esm({
426
426
  const batch = docs.slice(i, i + BATCH_SIZE);
427
427
  const values = [];
428
428
  const valuePlaceholders = batch.map((doc, idx) => {
429
- var _a;
429
+ var _a2;
430
430
  const offset = idx * 5;
431
- values.push(doc.id, namespace, doc.content, JSON.stringify((_a = doc.metadata) != null ? _a : {}), `[${doc.vector.join(",")}]`);
431
+ values.push(doc.id, namespace, doc.content, JSON.stringify((_a2 = doc.metadata) != null ? _a2 : {}), `[${doc.vector.join(",")}]`);
432
432
  return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
433
433
  }).join(", ");
434
434
  const query = `
@@ -511,8 +511,8 @@ var init_PostgreSQLProvider = __esm({
511
511
 
512
512
  // src/utils/synonyms.ts
513
513
  function resolveMetadataValue(meta, uiKey) {
514
- var _a;
515
- const synonyms = (_a = FIELD_SYNONYMS[uiKey]) != null ? _a : [];
514
+ var _a2;
515
+ const synonyms = (_a2 = FIELD_SYNONYMS[uiKey]) != null ? _a2 : [];
516
516
  const keys = Object.keys(meta);
517
517
  const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
518
518
  let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
@@ -599,14 +599,14 @@ var init_MultiTablePostgresProvider = __esm({
599
599
  init_synonyms();
600
600
  MultiTablePostgresProvider = class extends BaseVectorProvider {
601
601
  constructor(config) {
602
- var _a, _b, _c;
602
+ var _a2, _b, _c;
603
603
  super(config);
604
604
  const opts = config.options || {};
605
605
  if (!opts.connectionString) {
606
606
  throw new Error("[MultiTablePostgresProvider] options.connectionString is required");
607
607
  }
608
608
  this.connectionString = opts.connectionString;
609
- this.dimensions = (_a = opts.dimensions) != null ? _a : 768;
609
+ this.dimensions = (_a2 = opts.dimensions) != null ? _a2 : 768;
610
610
  this.tables = [];
611
611
  const rawSearchFields = (_c = (_b = opts.searchFields) != null ? _b : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _c : ["name", "product_name", "productname", "title"];
612
612
  this.searchFields = typeof rawSearchFields === "string" ? rawSearchFields.split(",").map((f) => f.trim()).filter(Boolean) : rawSearchFields;
@@ -664,11 +664,11 @@ var init_MultiTablePostgresProvider = __esm({
664
664
  * Batch upsert documents by dynamically provisioning tables and columns based on CSV headers.
665
665
  */
666
666
  async batchUpsert(docs, namespace = "") {
667
- var _a;
667
+ var _a2;
668
668
  if (docs.length === 0) return;
669
669
  const docsByFile = {};
670
670
  for (const doc of docs) {
671
- const fileName = ((_a = doc.metadata) == null ? void 0 : _a.fileName) || this.uploadTable;
671
+ const fileName = ((_a2 = doc.metadata) == null ? void 0 : _a2.fileName) || this.uploadTable;
672
672
  if (!docsByFile[fileName]) docsByFile[fileName] = [];
673
673
  docsByFile[fileName].push(doc);
674
674
  }
@@ -721,11 +721,11 @@ var init_MultiTablePostgresProvider = __esm({
721
721
  const headerColumns = csvHeaders.map((h) => `"${h}"`).join(", ");
722
722
  const allColumns = `id, ${headerColumns ? headerColumns + ", " : ""}namespace, content, metadata, embedding`;
723
723
  const valuePlaceholders = batch.map((doc, idx) => {
724
- var _a2, _b;
724
+ var _a3, _b;
725
725
  const offset = idx * (5 + csvHeaders.length);
726
726
  values.push(doc.id);
727
727
  for (const h of csvHeaders) {
728
- values.push(String(((_a2 = doc.metadata) == null ? void 0 : _a2[h]) || ""));
728
+ values.push(String(((_a3 = doc.metadata) == null ? void 0 : _a3[h]) || ""));
729
729
  }
730
730
  values.push(namespace, doc.content, JSON.stringify((_b = doc.metadata) != null ? _b : {}), `[${doc.vector.join(",")}]`);
731
731
  const docPlaceholders = [];
@@ -764,7 +764,7 @@ var init_MultiTablePostgresProvider = __esm({
764
764
  * Query all configured tables and merge results, sorted by cosine similarity score.
765
765
  */
766
766
  async query(vector, topK, _namespace, _filter) {
767
- var _a;
767
+ var _a2;
768
768
  if (!this.pool) {
769
769
  throw new Error("[MultiTablePostgresProvider] Provider not initialized. Call initialize() first.");
770
770
  }
@@ -795,11 +795,11 @@ var init_MultiTablePostgresProvider = __esm({
795
795
  const filterParams = [];
796
796
  if (metadataFilters && Object.keys(metadataFilters).length > 0) {
797
797
  const conditions = Object.entries(metadataFilters).map(([key, val]) => {
798
- var _a3;
798
+ var _a4;
799
799
  filterParams.push(String(val));
800
800
  const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
801
801
  const paramIdx = baseOffset + filterParams.length;
802
- const synonyms = (_a3 = FIELD_SYNONYMS[key]) != null ? _a3 : [];
802
+ const synonyms = (_a4 = FIELD_SYNONYMS[key]) != null ? _a4 : [];
803
803
  const keysToCheck = [key, ...synonyms];
804
804
  const coalesceExprs = keysToCheck.flatMap((k) => [
805
805
  `metadata->>'${k}'`,
@@ -868,7 +868,7 @@ var init_MultiTablePostgresProvider = __esm({
868
868
  }
869
869
  const tableResults = [];
870
870
  for (const row of result.rows) {
871
- const _a2 = row, { hybrid_score, id } = _a2, rest = __objRest(_a2, ["hybrid_score", "id"]);
871
+ const _a3 = row, { hybrid_score, id } = _a3, rest = __objRest(_a3, ["hybrid_score", "id"]);
872
872
  delete rest.embedding;
873
873
  delete rest.vector_score;
874
874
  delete rest.keyword_score;
@@ -897,10 +897,10 @@ var init_MultiTablePostgresProvider = __esm({
897
897
  }
898
898
  allResults.sort((a, b) => b.score - a.score);
899
899
  if (allResults.length === 0) return [];
900
- const bestMatchTable = (_a = allResults[0].metadata) == null ? void 0 : _a.source_table;
900
+ const bestMatchTable = (_a2 = allResults[0].metadata) == null ? void 0 : _a2.source_table;
901
901
  const finalSorted = allResults.filter((res) => {
902
- var _a2;
903
- return ((_a2 = res.metadata) == null ? void 0 : _a2.source_table) === bestMatchTable;
902
+ var _a3;
903
+ return ((_a3 = res.metadata) == null ? void 0 : _a3.source_table) === bestMatchTable;
904
904
  });
905
905
  console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
906
906
  console.log(`[MultiTablePostgresProvider] Final top match from "${bestMatchTable}" with score ${finalSorted[0].score.toFixed(4)}`);
@@ -1305,14 +1305,14 @@ var init_QdrantProvider = __esm({
1305
1305
  * Samples points from the collection to discover available payload fields.
1306
1306
  */
1307
1307
  async discoverSchema() {
1308
- var _a;
1308
+ var _a2;
1309
1309
  try {
1310
1310
  const { data } = await this.http.post(`/collections/${this.indexName}/points/scroll`, {
1311
1311
  limit: 20,
1312
1312
  with_payload: true,
1313
1313
  with_vector: false
1314
1314
  });
1315
- const points = ((_a = data.result) == null ? void 0 : _a.points) || [];
1315
+ const points = ((_a2 = data.result) == null ? void 0 : _a2.points) || [];
1316
1316
  const keys = /* @__PURE__ */ new Set();
1317
1317
  for (const point of points) {
1318
1318
  const payload = point.payload || {};
@@ -1338,12 +1338,12 @@ var init_QdrantProvider = __esm({
1338
1338
  * Ensures the collection exists. Creates it if missing.
1339
1339
  */
1340
1340
  async ensureCollection() {
1341
- var _a;
1341
+ var _a2;
1342
1342
  try {
1343
1343
  await this.http.get(`/collections/${this.indexName}`);
1344
1344
  console.log(`[QdrantProvider] \u2705 Collection "${this.indexName}" already exists.`);
1345
1345
  } catch (err) {
1346
- if (import_axios4.default.isAxiosError(err) && ((_a = err.response) == null ? void 0 : _a.status) === 404) {
1346
+ if (import_axios4.default.isAxiosError(err) && ((_a2 = err.response) == null ? void 0 : _a2.status) === 404) {
1347
1347
  const opts = this.config.options;
1348
1348
  const dimensionsForCreate = opts.dimensions || 1536;
1349
1349
  console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
@@ -1363,7 +1363,7 @@ var init_QdrantProvider = __esm({
1363
1363
  * Ensures that a payload field has an index.
1364
1364
  */
1365
1365
  async ensureIndex(fieldName, schema = "keyword") {
1366
- var _a;
1366
+ var _a2;
1367
1367
  let fullPath = fieldName;
1368
1368
  if (!this.isFlatPayload && !fieldName.includes(".") && fieldName !== "namespace" && fieldName !== this.contentField) {
1369
1369
  fullPath = `${this.metadataField}.${fieldName}`;
@@ -1376,7 +1376,7 @@ var init_QdrantProvider = __esm({
1376
1376
  console.log(`[QdrantProvider] \u2705 Ensured ${schema} index for "${fullPath}"`);
1377
1377
  } catch (err) {
1378
1378
  let status;
1379
- if (import_axios4.default.isAxiosError(err)) status = (_a = err.response) == null ? void 0 : _a.status;
1379
+ if (import_axios4.default.isAxiosError(err)) status = (_a2 = err.response) == null ? void 0 : _a2.status;
1380
1380
  if (status === 409) return;
1381
1381
  console.warn(`[QdrantProvider] \u26A0\uFE0F Could not ensure index for "${fullPath}":`, err instanceof Error ? err.message : String(err));
1382
1382
  }
@@ -1405,7 +1405,7 @@ var init_QdrantProvider = __esm({
1405
1405
  await this.http.put(`/collections/${this.indexName}/points`, payload);
1406
1406
  }
1407
1407
  async query(vector, topK, namespace, _filter) {
1408
- var _a;
1408
+ var _a2;
1409
1409
  const must = [];
1410
1410
  if (namespace) {
1411
1411
  must.push({ key: "namespace", match: { value: namespace } });
@@ -1427,7 +1427,7 @@ var init_QdrantProvider = __esm({
1427
1427
  limit: topK,
1428
1428
  with_payload: true,
1429
1429
  params: {
1430
- hnsw_ef: ((_a = this.config.options) == null ? void 0 : _a.efSearch) || Math.max(topK * 20, 128),
1430
+ hnsw_ef: ((_a2 = this.config.options) == null ? void 0 : _a2.efSearch) || Math.max(topK * 20, 128),
1431
1431
  exact: false
1432
1432
  },
1433
1433
  filter: must.length > 0 ? { must } : void 0
@@ -1522,13 +1522,13 @@ var init_ChromaDBProvider = __esm({
1522
1522
  * Get or create the ChromaDB collection.
1523
1523
  */
1524
1524
  async initialize() {
1525
- var _a;
1525
+ var _a2;
1526
1526
  try {
1527
1527
  const { data } = await this.http.get(`/api/v1/collections/${this.indexName}`);
1528
1528
  this.collectionId = data.id;
1529
1529
  console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
1530
1530
  } catch (err) {
1531
- if (import_axios5.default.isAxiosError(err) && ((_a = err.response) == null ? void 0 : _a.status) === 404) {
1531
+ if (import_axios5.default.isAxiosError(err) && ((_a2 = err.response) == null ? void 0 : _a2.status) === 404) {
1532
1532
  console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
1533
1533
  const { data } = await this.http.post("/api/v1/collections", {
1534
1534
  name: this.indexName
@@ -1749,7 +1749,7 @@ var init_WeaviateProvider = __esm({
1749
1749
  await this.http.post("/v1/batch/objects", payload);
1750
1750
  }
1751
1751
  async query(vector, topK, namespace, _filter) {
1752
- var _a, _b;
1752
+ var _a2, _b;
1753
1753
  const queryText = _filter == null ? void 0 : _filter.queryText;
1754
1754
  const sanitizedFilter = this.sanitizeFilter(_filter);
1755
1755
  const searchParams = queryText ? `hybrid: { query: ${JSON.stringify(queryText)}, alpha: 0.5 }` : `nearVector: { vector: ${JSON.stringify(vector)} }`;
@@ -1775,7 +1775,7 @@ var init_WeaviateProvider = __esm({
1775
1775
  `
1776
1776
  };
1777
1777
  const { data } = await this.http.post("/v1/graphql", graphqlQuery);
1778
- const results = ((_b = (_a = data.data) == null ? void 0 : _a.Get) == null ? void 0 : _b[this.indexName]) || [];
1778
+ const results = ((_b = (_a2 = data.data) == null ? void 0 : _a2.Get) == null ? void 0 : _b[this.indexName]) || [];
1779
1779
  return results.map((res) => ({
1780
1780
  id: res["_additional"].id,
1781
1781
  score: 1 - res["_additional"].distance,
@@ -1828,10 +1828,10 @@ var init_WeaviateProvider = __esm({
1828
1828
  return `{ operator: And, operands: [${operands.join(", ")}] }`;
1829
1829
  }
1830
1830
  weaviateOperand(key, value) {
1831
- const path = `path: [${JSON.stringify(key)}], operator: Equal`;
1832
- if (typeof value === "number") return `{ ${path}, valueNumber: ${value} }`;
1833
- if (typeof value === "boolean") return `{ ${path}, valueBoolean: ${value} }`;
1834
- return `{ ${path}, valueString: ${JSON.stringify(value)} }`;
1831
+ const path2 = `path: [${JSON.stringify(key)}], operator: Equal`;
1832
+ if (typeof value === "number") return `{ ${path2}, valueNumber: ${value} }`;
1833
+ if (typeof value === "boolean") return `{ ${path2}, valueBoolean: ${value} }`;
1834
+ return `{ ${path2}, valueString: ${JSON.stringify(value)} }`;
1835
1835
  }
1836
1836
  };
1837
1837
  }
@@ -1858,21 +1858,21 @@ var init_UniversalVectorProvider = __esm({
1858
1858
  }
1859
1859
  }
1860
1860
  async initialize() {
1861
- var _a;
1861
+ var _a2;
1862
1862
  this.http = import_axios8.default.create({
1863
1863
  baseURL: this.opts.baseUrl,
1864
1864
  headers: __spreadValues({
1865
1865
  "Content-Type": "application/json"
1866
1866
  }, this.opts.headers),
1867
- timeout: (_a = this.opts.timeout) != null ? _a : 3e4
1867
+ timeout: (_a2 = this.opts.timeout) != null ? _a2 : 3e4
1868
1868
  });
1869
1869
  if (!await this.ping()) {
1870
1870
  throw new Error(`[UniversalVectorProvider] Failed to connect to ${this.opts.baseUrl}`);
1871
1871
  }
1872
1872
  }
1873
1873
  async upsert(doc, namespace) {
1874
- var _a, _b, _c;
1875
- const endpoint = (_a = this.opts.upsertEndpoint) != null ? _a : "/upsert";
1874
+ var _a2, _b, _c;
1875
+ const endpoint = (_a2 = this.opts.upsertEndpoint) != null ? _a2 : "/upsert";
1876
1876
  const template = (_b = this.opts.upsertTemplate) != null ? _b : JSON.stringify({
1877
1877
  id: "{{id}}",
1878
1878
  vector: "{{vector}}",
@@ -1905,8 +1905,8 @@ var init_UniversalVectorProvider = __esm({
1905
1905
  }
1906
1906
  }
1907
1907
  async query(vector, topK, namespace, filter) {
1908
- var _a, _b;
1909
- const endpoint = (_a = this.opts.queryEndpoint) != null ? _a : "/query";
1908
+ var _a2, _b;
1909
+ const endpoint = (_a2 = this.opts.queryEndpoint) != null ? _a2 : "/query";
1910
1910
  const template = (_b = this.opts.queryTemplate) != null ? _b : JSON.stringify({
1911
1911
  vector: "{{vector}}",
1912
1912
  limit: "{{topK}}",
@@ -1932,12 +1932,12 @@ var init_UniversalVectorProvider = __esm({
1932
1932
  );
1933
1933
  }
1934
1934
  return results.map((item) => {
1935
- var _a2, _b2, _c, _d, _e, _f, _g;
1935
+ var _a3, _b2, _c, _d, _e, _f, _g2;
1936
1936
  return {
1937
- id: item[(_a2 = this.opts.queryIdField) != null ? _a2 : "id"],
1937
+ id: item[(_a3 = this.opts.queryIdField) != null ? _a3 : "id"],
1938
1938
  score: (_c = item[(_b2 = this.opts.queryScoreField) != null ? _b2 : "score"]) != null ? _c : 0,
1939
1939
  content: (_e = item[(_d = this.opts.queryContentField) != null ? _d : "content"]) != null ? _e : "",
1940
- metadata: (_g = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g : {}
1940
+ metadata: (_g2 = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g2 : {}
1941
1941
  };
1942
1942
  });
1943
1943
  } catch (error) {
@@ -1947,8 +1947,8 @@ var init_UniversalVectorProvider = __esm({
1947
1947
  }
1948
1948
  }
1949
1949
  async delete(id, namespace) {
1950
- var _a, _b;
1951
- const endpoint = (_a = this.opts.deleteEndpoint) != null ? _a : "/delete";
1950
+ var _a2, _b;
1951
+ const endpoint = (_a2 = this.opts.deleteEndpoint) != null ? _a2 : "/delete";
1952
1952
  const template = (_b = this.opts.deleteTemplate) != null ? _b : JSON.stringify({
1953
1953
  id: "{{id}}",
1954
1954
  namespace: "{{namespace}}"
@@ -1966,8 +1966,8 @@ var init_UniversalVectorProvider = __esm({
1966
1966
  }
1967
1967
  }
1968
1968
  async deleteNamespace(namespace) {
1969
- var _a;
1970
- const endpoint = (_a = this.opts.deleteNamespaceEndpoint) != null ? _a : "/delete-namespace";
1969
+ var _a2;
1970
+ const endpoint = (_a2 = this.opts.deleteNamespaceEndpoint) != null ? _a2 : "/delete-namespace";
1971
1971
  try {
1972
1972
  await this.http.post(endpoint, { namespace });
1973
1973
  } catch (error) {
@@ -1977,9 +1977,9 @@ var init_UniversalVectorProvider = __esm({
1977
1977
  }
1978
1978
  }
1979
1979
  async ping() {
1980
- var _a;
1980
+ var _a2;
1981
1981
  try {
1982
- const endpoint = (_a = this.opts.pingEndpoint) != null ? _a : "/health";
1982
+ const endpoint = (_a2 = this.opts.pingEndpoint) != null ? _a2 : "/health";
1983
1983
  const response = await this.http.get(endpoint, { timeout: 5e3 });
1984
1984
  return response.status >= 200 && response.status < 300;
1985
1985
  } catch (e) {
@@ -2084,8 +2084,10 @@ __export(server_exports, {
2084
2084
  EmbeddingFailedException: () => EmbeddingFailedException,
2085
2085
  EmbeddingStrategy: () => EmbeddingStrategy,
2086
2086
  EmbeddingStrategyResolver: () => EmbeddingStrategyResolver,
2087
+ GroqProvider: () => GroqProvider,
2087
2088
  LLMFactory: () => LLMFactory,
2088
2089
  LLM_PROFILES: () => LLM_PROFILES,
2090
+ LicenseVerifier: () => LicenseVerifier,
2089
2091
  MilvusProvider: () => MilvusProvider,
2090
2092
  MongoDBProvider: () => MongoDBProvider,
2091
2093
  MultiTablePostgresProvider: () => MultiTablePostgresProvider,
@@ -2099,6 +2101,7 @@ __export(server_exports, {
2099
2101
  ProviderNotFoundException: () => ProviderNotFoundException,
2100
2102
  ProviderRegistry: () => ProviderRegistry,
2101
2103
  QdrantProvider: () => QdrantProvider,
2104
+ QwenProvider: () => QwenProvider,
2102
2105
  RateLimitException: () => RateLimitException,
2103
2106
  RedisProvider: () => RedisProvider,
2104
2107
  RetrievalException: () => RetrievalException,
@@ -2110,10 +2113,13 @@ __export(server_exports, {
2110
2113
  VectorPlugin: () => VectorPlugin,
2111
2114
  WeaviateProvider: () => WeaviateProvider,
2112
2115
  createChatHandler: () => createChatHandler,
2116
+ createFeedbackHandler: () => createFeedbackHandler,
2113
2117
  createFromPreset: () => createFromPreset,
2114
2118
  createHealthHandler: () => createHealthHandler,
2119
+ createHistoryHandler: () => createHistoryHandler,
2115
2120
  createIngestHandler: () => createIngestHandler,
2116
2121
  createRagHandler: () => createRagHandler,
2122
+ createSessionsHandler: () => createSessionsHandler,
2117
2123
  createStreamHandler: () => createStreamHandler,
2118
2124
  createUploadHandler: () => createUploadHandler,
2119
2125
  getRagConfig: () => getRagConfig,
@@ -2148,6 +2154,8 @@ var LLM_PROVIDERS = [
2148
2154
  "anthropic",
2149
2155
  "ollama",
2150
2156
  "gemini",
2157
+ "groq",
2158
+ "qwen",
2151
2159
  "rest",
2152
2160
  "universal_rest",
2153
2161
  "custom"
@@ -2156,6 +2164,7 @@ var EMBEDDING_PROVIDERS = [
2156
2164
  "openai",
2157
2165
  "ollama",
2158
2166
  "gemini",
2167
+ "qwen",
2159
2168
  "rest",
2160
2169
  "universal_rest",
2161
2170
  "custom"
@@ -2164,6 +2173,7 @@ var PROVIDERS_WITH_EMBEDDINGS = [
2164
2173
  "openai",
2165
2174
  "ollama",
2166
2175
  "gemini",
2176
+ "qwen",
2167
2177
  "rest",
2168
2178
  "universal_rest"
2169
2179
  ];
@@ -2171,8 +2181,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
2171
2181
 
2172
2182
  // src/config/serverConfig.ts
2173
2183
  function readString(env, name) {
2174
- var _a;
2175
- const value = (_a = env[name]) == null ? void 0 : _a.trim();
2184
+ var _a2;
2185
+ const value = (_a2 = env[name]) == null ? void 0 : _a2.trim();
2176
2186
  return value ? value : void 0;
2177
2187
  }
2178
2188
  function readNumber(env, name, fallback) {
@@ -2185,8 +2195,8 @@ function readNumber(env, name, fallback) {
2185
2195
  return parsed;
2186
2196
  }
2187
2197
  function readEnum(env, name, fallback, allowed) {
2188
- var _a;
2189
- const value = (_a = readString(env, name)) != null ? _a : fallback;
2198
+ var _a2;
2199
+ const value = (_a2 = readString(env, name)) != null ? _a2 : fallback;
2190
2200
  if (allowed.includes(value)) {
2191
2201
  return value;
2192
2202
  }
@@ -2196,15 +2206,15 @@ function getRagConfig(baseConfig, env = process.env) {
2196
2206
  return getEnvConfig(env, baseConfig);
2197
2207
  }
2198
2208
  function getEnvConfig(env = process.env, base) {
2199
- var _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, _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;
2200
- const projectId = (_c = (_b = (_a = readString(env, "RAG_PROJECT_ID")) != null ? _a : readString(env, "NEXT_PUBLIC_PROJECT_ID")) != null ? _b : base == null ? void 0 : base.projectId) != null ? _c : "__default__";
2209
+ 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;
2210
+ const projectId = (_c = (_b = (_a2 = readString(env, "RAG_PROJECT_ID")) != null ? _a2 : readString(env, "NEXT_PUBLIC_PROJECT_ID")) != null ? _b : base == null ? void 0 : base.projectId) != null ? _c : "__default__";
2201
2211
  const vectorProvider = readEnum(env, "VECTOR_DB_PROVIDER", "pinecone", VECTOR_DB_PROVIDERS);
2202
2212
  const llmProvider = readEnum(env, "LLM_PROVIDER", "openai", LLM_PROVIDERS);
2203
2213
  const embeddingProvider = readEnum(env, "EMBEDDING_PROVIDER", "openai", EMBEDDING_PROVIDERS);
2204
2214
  const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 1536);
2205
2215
  const vectorDbOptions = {};
2206
2216
  if (vectorProvider === "pinecone") {
2207
- vectorDbOptions.apiKey = (_g = (_f = readString(env, "PINECONE_API_KEY")) != null ? _f : (_e = (_d = base == null ? void 0 : base.vectorDb) == null ? void 0 : _d.options) == null ? void 0 : _e.apiKey) != null ? _g : "";
2217
+ vectorDbOptions.apiKey = (_g2 = (_f = readString(env, "PINECONE_API_KEY")) != null ? _f : (_e = (_d = base == null ? void 0 : base.vectorDb) == null ? void 0 : _d.options) == null ? void 0 : _e.apiKey) != null ? _g2 : "";
2208
2218
  vectorDbOptions.indexName = (_l = (_i = readString(env, "PINECONE_INDEX")) != null ? _i : (_h = base == null ? void 0 : base.vectorDb) == null ? void 0 : _h.indexName) != null ? _l : (_k = (_j = base == null ? void 0 : base.vectorDb) == null ? void 0 : _j.options) == null ? void 0 : _k.indexName;
2209
2219
  } else if (vectorProvider === "pgvector" || vectorProvider === "postgresql") {
2210
2220
  vectorDbOptions.connectionString = (_q = (_p = (_m = readString(env, "PGVECTOR_CONNECTION_STRING")) != null ? _m : readString(env, "POSTGRES_URL")) != null ? _p : (_o = (_n = base == null ? void 0 : base.vectorDb) == null ? void 0 : _n.options) == null ? void 0 : _o.connectionString) != null ? _q : "";
@@ -2266,17 +2276,18 @@ function getEnvConfig(env = process.env, base) {
2266
2276
  rest: "default",
2267
2277
  custom: "default"
2268
2278
  };
2269
- return __spreadValues({
2279
+ return __spreadProps(__spreadValues({
2270
2280
  projectId,
2281
+ licenseKey: (_ha = (_ga = readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _ga : readString(env, "LICENSE_KEY")) != null ? _ha : base == null ? void 0 : base.licenseKey,
2271
2282
  vectorDb: {
2272
2283
  provider: vectorProvider,
2273
- indexName: (_ha = (_ga = readString(env, "VECTOR_DB_INDEX")) != null ? _ga : vectorDbOptions.indexName) != null ? _ha : "rag-index",
2284
+ indexName: (_ja = (_ia = readString(env, "VECTOR_DB_INDEX")) != null ? _ia : vectorDbOptions.indexName) != null ? _ja : "rag-index",
2274
2285
  options: vectorDbOptions
2275
2286
  },
2276
2287
  llm: {
2277
2288
  provider: llmProvider,
2278
- model: (_ja = (_ia = readString(env, "LLM_MODEL")) != null ? _ia : DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _ja : "gpt-4o",
2279
- apiKey: (_ka = llmApiKeyByProvider[llmProvider]) != null ? _ka : "",
2289
+ model: (_la = (_ka = readString(env, "LLM_MODEL")) != null ? _ka : DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _la : "gpt-4o",
2290
+ apiKey: (_ma = llmApiKeyByProvider[llmProvider]) != null ? _ma : "",
2280
2291
  baseUrl: readString(env, "LLM_BASE_URL"),
2281
2292
  systemPrompt: readString(env, "LLM_SYSTEM_PROMPT"),
2282
2293
  maxTokens: readNumber(env, "LLM_MAX_TOKENS", 4096),
@@ -2289,7 +2300,7 @@ function getEnvConfig(env = process.env, base) {
2289
2300
  },
2290
2301
  embedding: {
2291
2302
  provider: embeddingProvider,
2292
- model: (_la = readString(env, "EMBEDDING_MODEL")) != null ? _la : "text-embedding-3-small",
2303
+ model: (_na = readString(env, "EMBEDDING_MODEL")) != null ? _na : "text-embedding-3-small",
2293
2304
  apiKey: embeddingApiKeyByProvider[embeddingProvider],
2294
2305
  baseUrl: readString(env, "EMBEDDING_BASE_URL"),
2295
2306
  dimensions: embeddingDimensions,
@@ -2300,30 +2311,30 @@ function getEnvConfig(env = process.env, base) {
2300
2311
  }
2301
2312
  },
2302
2313
  ui: {
2303
- title: (_na = (_ma = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _ma : readString(env, "UI_TITLE")) != null ? _na : "AI Assistant",
2304
- subtitle: (_pa = (_oa = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _oa : readString(env, "UI_SUBTITLE")) != null ? _pa : "Powered by RAG",
2305
- primaryColor: (_ra = (_qa = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _qa : readString(env, "UI_PRIMARY_COLOR")) != null ? _ra : "#10b981",
2306
- accentColor: (_ta = (_sa = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _sa : readString(env, "UI_ACCENT_COLOR")) != null ? _ta : "#3b82f6",
2307
- logoUrl: (_ua = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _ua : readString(env, "UI_LOGO_URL"),
2308
- placeholder: (_wa = (_va = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _va : readString(env, "UI_PLACEHOLDER")) != null ? _wa : "Ask me anything\u2026",
2309
- showSources: ((_ya = (_xa = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _xa : readString(env, "UI_SHOW_SOURCES")) != null ? _ya : "true") !== "false",
2310
- welcomeMessage: (_Aa = (_za = readString(env, "NEXT_PUBLIC_WELCOME_MESSAGE")) != null ? _za : readString(env, "UI_WELCOME_MESSAGE")) != null ? _Aa : "Hello! I'm your AI assistant. Ask me anything about your documents.",
2311
- visualStyle: (_Ca = (_Ba = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _Ba : readString(env, "UI_VISUAL_STYLE")) != null ? _Ca : "glass",
2312
- borderRadius: (_Ea = (_Da = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _Da : readString(env, "UI_BORDER_RADIUS")) != null ? _Ea : "xl",
2313
- allowUpload: ((_Ga = (_Fa = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _Fa : readString(env, "UI_ALLOW_UPLOAD")) != null ? _Ga : "false") === "true"
2314
+ title: (_pa = (_oa = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _oa : readString(env, "UI_TITLE")) != null ? _pa : "AI Assistant",
2315
+ subtitle: (_ra = (_qa = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _qa : readString(env, "UI_SUBTITLE")) != null ? _ra : "Powered by RAG",
2316
+ primaryColor: (_ta = (_sa = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _sa : readString(env, "UI_PRIMARY_COLOR")) != null ? _ta : "#10b981",
2317
+ accentColor: (_va = (_ua = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _ua : readString(env, "UI_ACCENT_COLOR")) != null ? _va : "#3b82f6",
2318
+ logoUrl: (_wa = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _wa : readString(env, "UI_LOGO_URL"),
2319
+ placeholder: (_ya = (_xa = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _xa : readString(env, "UI_PLACEHOLDER")) != null ? _ya : "Ask me anything\u2026",
2320
+ showSources: ((_Aa = (_za = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _za : readString(env, "UI_SHOW_SOURCES")) != null ? _Aa : "true") !== "false",
2321
+ welcomeMessage: (_Ca = (_Ba = readString(env, "NEXT_PUBLIC_WELCOME_MESSAGE")) != null ? _Ba : readString(env, "UI_WELCOME_MESSAGE")) != null ? _Ca : "Hello! I'm your AI assistant. Ask me anything about your documents.",
2322
+ visualStyle: (_Ea = (_Da = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _Da : readString(env, "UI_VISUAL_STYLE")) != null ? _Ea : "glass",
2323
+ borderRadius: (_Ga = (_Fa = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _Fa : readString(env, "UI_BORDER_RADIUS")) != null ? _Ga : "xl",
2324
+ allowUpload: ((_Ia = (_Ha = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _Ha : readString(env, "UI_ALLOW_UPLOAD")) != null ? _Ia : "false") === "true"
2314
2325
  },
2315
2326
  rag: {
2316
2327
  topK: readNumber(env, "RAG_TOP_K", 5),
2317
2328
  scoreThreshold: readNumber(env, "RAG_SCORE_THRESHOLD", 0),
2318
2329
  chunkSize: readNumber(env, "RAG_CHUNK_SIZE", 1e3),
2319
2330
  chunkOverlap: readNumber(env, "RAG_CHUNK_OVERLAP", 200),
2320
- filterableFields: (_Ha = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _Ha.split(",").map((f) => f.trim()),
2331
+ filterableFields: (_Ja = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _Ja.split(",").map((f) => f.trim()),
2321
2332
  // Query pipeline toggles — read from .env.local
2322
2333
  useQueryTransformation: readString(env, "RAG_USE_QUERY_TRANSFORMATION") === "true",
2323
2334
  useReranking: readString(env, "RAG_USE_RERANKING") === "true",
2324
2335
  useGraphRetrieval: readString(env, "RAG_USE_GRAPH_RETRIEVAL") === "true",
2325
- architecture: (_Ia = readString(env, "RAG_ARCHITECTURE")) != null ? _Ia : "simple",
2326
- chunkingStrategy: (_Ja = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _Ja : "recursive",
2336
+ architecture: (_Ka = readString(env, "RAG_ARCHITECTURE")) != null ? _Ka : "simple",
2337
+ chunkingStrategy: (_La = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _La : "recursive",
2327
2338
  uiMapping: (() => {
2328
2339
  const raw = readString(env, "RAG_UI_MAPPING");
2329
2340
  if (!raw) return void 0;
@@ -2333,6 +2344,10 @@ function getEnvConfig(env = process.env, base) {
2333
2344
  return void 0;
2334
2345
  }
2335
2346
  })()
2347
+ },
2348
+ telemetry: {
2349
+ enabled: readString(env, "TELEMETRY_ENABLED") === "true" || readString(env, "NEXT_PUBLIC_TELEMETRY_ENABLED") === "true" || ((_Ma = base == null ? void 0 : base.telemetry) == null ? void 0 : _Ma.enabled) || false,
2350
+ url: (_Qa = (_Pa = (_Na = readString(env, "TELEMETRY_URL")) != null ? _Na : readString(env, "NEXT_PUBLIC_TELEMETRY_URL")) != null ? _Pa : (_Oa = base == null ? void 0 : base.telemetry) == null ? void 0 : _Oa.url) != null ? _Qa : "/api/telemetry"
2336
2351
  }
2337
2352
  }, readString(env, "GRAPH_DB_PROVIDER") ? {
2338
2353
  graphDb: {
@@ -2343,7 +2358,19 @@ function getEnvConfig(env = process.env, base) {
2343
2358
  password: readString(env, "GRAPH_DB_PASSWORD")
2344
2359
  }
2345
2360
  }
2346
- } : {});
2361
+ } : {}), {
2362
+ mcpServers: (() => {
2363
+ var _a3;
2364
+ const raw = (_a3 = readString(env, "MCP_SERVERS")) != null ? _a3 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
2365
+ if (!raw) return void 0;
2366
+ try {
2367
+ return JSON.parse(raw);
2368
+ } catch (e) {
2369
+ console.warn("[serverConfig] Failed to parse MCP_SERVERS env:", e);
2370
+ return void 0;
2371
+ }
2372
+ })()
2373
+ });
2347
2374
  }
2348
2375
 
2349
2376
  // src/core/ConfigResolver.ts
@@ -2369,7 +2396,8 @@ var ConfigResolver = class {
2369
2396
  options: __spreadValues(__spreadValues({}, envConfig.embedding.options || {}), hostConfig.embedding.options || {})
2370
2397
  }) : envConfig.embedding,
2371
2398
  ui: hostConfig.ui ? mergeDefined(envConfig.ui, hostConfig.ui) : envConfig.ui,
2372
- rag: hostConfig.rag ? __spreadValues(__spreadValues({}, envConfig.rag), hostConfig.rag) : envConfig.rag
2399
+ rag: hostConfig.rag ? __spreadValues(__spreadValues({}, envConfig.rag), hostConfig.rag) : envConfig.rag,
2400
+ telemetry: hostConfig.telemetry ? __spreadValues(__spreadValues({}, envConfig.telemetry), hostConfig.telemetry) : envConfig.telemetry
2373
2401
  });
2374
2402
  }
2375
2403
  /**
@@ -2378,10 +2406,10 @@ var ConfigResolver = class {
2378
2406
  * fallback behavior.
2379
2407
  */
2380
2408
  static resolveUniversal(hostConfig, env = process.env) {
2381
- var _a;
2409
+ var _a2;
2382
2410
  if (!hostConfig) return this.resolve(void 0, env);
2383
2411
  const normalized = __spreadProps(__spreadValues({}, hostConfig), {
2384
- vectorDb: (_a = hostConfig.vectorDb) != null ? _a : hostConfig.vectorDatabase,
2412
+ vectorDb: (_a2 = hostConfig.vectorDb) != null ? _a2 : hostConfig.vectorDatabase,
2385
2413
  rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
2386
2414
  });
2387
2415
  return this.resolve(normalized, env);
@@ -2401,11 +2429,11 @@ var ConfigResolver = class {
2401
2429
  }
2402
2430
  }
2403
2431
  static mergeRetrievalWorkflow(rag, retrieval, workflow) {
2404
- var _a, _b, _c, _d, _e;
2432
+ var _a2, _b, _c, _d, _e;
2405
2433
  if (!rag && !retrieval && !workflow) return void 0;
2406
2434
  const normalized = __spreadValues({}, rag != null ? rag : {});
2407
2435
  if (retrieval) {
2408
- normalized.topK = (_a = retrieval.topK) != null ? _a : normalized.topK;
2436
+ normalized.topK = (_a2 = retrieval.topK) != null ? _a2 : normalized.topK;
2409
2437
  normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
2410
2438
  normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
2411
2439
  if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
@@ -2487,8 +2515,8 @@ var OpenAIProvider = class {
2487
2515
  const apiKey = config.apiKey;
2488
2516
  const modelName = config.model;
2489
2517
  try {
2490
- const OpenAI2 = await import("openai");
2491
- const client = new OpenAI2.default({ apiKey });
2518
+ const OpenAI4 = await import("openai");
2519
+ const client = new OpenAI4.default({ apiKey });
2492
2520
  const models = await client.models.list();
2493
2521
  const hasModel = models.data.some((m) => m.id === modelName);
2494
2522
  return {
@@ -2509,8 +2537,8 @@ var OpenAIProvider = class {
2509
2537
  };
2510
2538
  }
2511
2539
  async chat(messages, context, options) {
2512
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2513
- const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
2540
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
2541
+ 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.";
2514
2542
  const systemMessage = {
2515
2543
  role: "system",
2516
2544
  content: buildSystemContent(basePrompt, context)
@@ -2529,12 +2557,12 @@ var OpenAIProvider = class {
2529
2557
  temperature: (_f = (_e = options == null ? void 0 : options.temperature) != null ? _e : this.llmConfig.temperature) != null ? _f : 0.7,
2530
2558
  stop: options == null ? void 0 : options.stop
2531
2559
  });
2532
- return (_i = (_h = (_g = completion.choices[0]) == null ? void 0 : _g.message) == null ? void 0 : _h.content) != null ? _i : "";
2560
+ return (_i = (_h = (_g2 = completion.choices[0]) == null ? void 0 : _g2.message) == null ? void 0 : _h.content) != null ? _i : "";
2533
2561
  }
2534
2562
  chatStream(messages, context, options) {
2535
2563
  return __asyncGenerator(this, null, function* () {
2536
- var _a, _b, _c, _d, _e, _f, _g, _h;
2537
- const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
2564
+ var _a2, _b, _c, _d, _e, _f, _g2, _h;
2565
+ 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.";
2538
2566
  const systemMessage = {
2539
2567
  role: "system",
2540
2568
  content: buildSystemContent(basePrompt, context)
@@ -2560,7 +2588,7 @@ var OpenAIProvider = class {
2560
2588
  try {
2561
2589
  for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
2562
2590
  const chunk = temp.value;
2563
- const content = ((_h = (_g = chunk.choices[0]) == null ? void 0 : _g.delta) == null ? void 0 : _h.content) || "";
2591
+ const content = ((_h = (_g2 = chunk.choices[0]) == null ? void 0 : _g2.delta) == null ? void 0 : _h.content) || "";
2564
2592
  if (content) yield content;
2565
2593
  }
2566
2594
  } catch (temp) {
@@ -2580,8 +2608,8 @@ var OpenAIProvider = class {
2580
2608
  return results[0];
2581
2609
  }
2582
2610
  async batchEmbed(texts, options) {
2583
- var _a, _b, _c, _d, _e;
2584
- const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a = this.embeddingConfig) == null ? void 0 : _a.model) != null ? _c : "text-embedding-3-small";
2611
+ var _a2, _b, _c, _d, _e;
2612
+ 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";
2585
2613
  const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
2586
2614
  const client = apiKey !== this.llmConfig.apiKey ? new import_openai.default({ apiKey }) : this.client;
2587
2615
  const response = await client.embeddings.create({ model, input: texts });
@@ -2658,8 +2686,8 @@ var AnthropicProvider = class {
2658
2686
  };
2659
2687
  }
2660
2688
  async chat(messages, context, options) {
2661
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2662
- const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
2689
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
2690
+ 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.";
2663
2691
  const system = buildSystemContent(basePrompt, context);
2664
2692
  const anthropicMessages = messages.map((m) => ({
2665
2693
  role: m.role === "assistant" ? "assistant" : "user",
@@ -2670,7 +2698,7 @@ var AnthropicProvider = class {
2670
2698
  const extraParams = {};
2671
2699
  if (isThinkingEnabled && isClaude37) {
2672
2700
  extraParams.betas = ["interleaved-thinking-2025-05-14"];
2673
- const maxTokens = (_g = (_f = options == null ? void 0 : options.maxTokens) != null ? _f : this.llmConfig.maxTokens) != null ? _g : 4096;
2701
+ const maxTokens = (_g2 = (_f = options == null ? void 0 : options.maxTokens) != null ? _f : this.llmConfig.maxTokens) != null ? _g2 : 4096;
2674
2702
  const budget = Math.min(
2675
2703
  typeof ((_h = this.llmConfig.options) == null ? void 0 : _h.thinkingBudget) === "number" ? (_i = this.llmConfig.options) == null ? void 0 : _i.thinkingBudget : 2048,
2676
2704
  maxTokens - 1
@@ -2697,8 +2725,8 @@ var AnthropicProvider = class {
2697
2725
  }
2698
2726
  chatStream(messages, context, options) {
2699
2727
  return __asyncGenerator(this, null, function* () {
2700
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2701
- const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
2728
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
2729
+ 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.";
2702
2730
  const system = buildSystemContent(basePrompt, context);
2703
2731
  const anthropicMessages = messages.map((m) => ({
2704
2732
  role: m.role === "assistant" ? "assistant" : "user",
@@ -2709,7 +2737,7 @@ var AnthropicProvider = class {
2709
2737
  const extraParams = {};
2710
2738
  if (isThinkingEnabled && isClaude37) {
2711
2739
  extraParams.betas = ["interleaved-thinking-2025-05-14"];
2712
- const maxTokens = (_g = (_f = options == null ? void 0 : options.maxTokens) != null ? _f : this.llmConfig.maxTokens) != null ? _g : 4096;
2740
+ const maxTokens = (_g2 = (_f = options == null ? void 0 : options.maxTokens) != null ? _f : this.llmConfig.maxTokens) != null ? _g2 : 4096;
2713
2741
  const budget = Math.min(
2714
2742
  typeof ((_h = this.llmConfig.options) == null ? void 0 : _h.thinkingBudget) === "number" ? (_i = this.llmConfig.options) == null ? void 0 : _i.thinkingBudget : 2048,
2715
2743
  maxTokens - 1
@@ -2782,8 +2810,8 @@ var AnthropicProvider = class {
2782
2810
  var import_axios = __toESM(require("axios"));
2783
2811
  var OllamaProvider = class {
2784
2812
  constructor(llmConfig, embeddingConfig) {
2785
- var _a, _b;
2786
- const baseURL = (_a = llmConfig.baseUrl) != null ? _a : "http://localhost:11434";
2813
+ var _a2, _b;
2814
+ const baseURL = (_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434";
2787
2815
  const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
2788
2816
  this.http = import_axios.default.create({ baseURL, timeout });
2789
2817
  this.llmConfig = llmConfig;
@@ -2841,8 +2869,8 @@ var OllamaProvider = class {
2841
2869
  };
2842
2870
  }
2843
2871
  async chat(messages, context, options) {
2844
- var _a, _b, _c, _d, _e, _f;
2845
- const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
2872
+ var _a2, _b, _c, _d, _e, _f;
2873
+ 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.";
2846
2874
  const system = buildSystemContent(basePrompt, context);
2847
2875
  const { data } = await this.http.post("/api/chat", {
2848
2876
  model: this.llmConfig.model,
@@ -2860,8 +2888,8 @@ var OllamaProvider = class {
2860
2888
  }
2861
2889
  chatStream(messages, context, options) {
2862
2890
  return __asyncGenerator(this, null, function* () {
2863
- var _a, _b, _c, _d, _e, _f, _g, _h;
2864
- const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
2891
+ var _a2, _b, _c, _d, _e, _f, _g2, _h;
2892
+ 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.";
2865
2893
  const system = buildSystemContent(basePrompt, context);
2866
2894
  const response = yield new __await(this.http.post("/api/chat", {
2867
2895
  model: this.llmConfig.model,
@@ -2890,7 +2918,7 @@ var OllamaProvider = class {
2890
2918
  if (!line.trim()) continue;
2891
2919
  try {
2892
2920
  const json = JSON.parse(line);
2893
- if ((_g = json.message) == null ? void 0 : _g.content) {
2921
+ if ((_g2 = json.message) == null ? void 0 : _g2.content) {
2894
2922
  yield json.message.content;
2895
2923
  }
2896
2924
  if (json.done) return;
@@ -2919,10 +2947,10 @@ var OllamaProvider = class {
2919
2947
  });
2920
2948
  }
2921
2949
  async embed(text, options) {
2922
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2923
- const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a = this.embeddingConfig) == null ? void 0 : _a.model) != null ? _c : "nomic-embed-text";
2950
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
2951
+ 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";
2924
2952
  const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
2925
- const client = baseURL !== ((_g = this.llmConfig.baseUrl) != null ? _g : "http://localhost:11434") ? import_axios.default.create({ baseURL, timeout: 6e4 }) : this.http;
2953
+ const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? import_axios.default.create({ baseURL, timeout: 6e4 }) : this.http;
2926
2954
  let prompt = text;
2927
2955
  const queryPrefix = (_i = (_h = this.embeddingConfig) == null ? void 0 : _h.queryPrefix) != null ? _i : model.includes("nomic") ? "search_query: " : "";
2928
2956
  const docPrefix = (_k = (_j = this.embeddingConfig) == null ? void 0 : _j.documentPrefix) != null ? _k : model.includes("nomic") ? "search_document: " : "";
@@ -3021,9 +3049,9 @@ var GeminiProvider = class {
3021
3049
  static getHealthChecker() {
3022
3050
  return {
3023
3051
  async check(config) {
3024
- var _a, _b;
3052
+ var _a2, _b;
3025
3053
  const timestamp = Date.now();
3026
- const apiKey = (_b = (_a = config.apiKey) != null ? _a : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
3054
+ const apiKey = (_b = (_a2 = config.apiKey) != null ? _a2 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
3027
3055
  const modelName = sanitizeModel(config.model);
3028
3056
  try {
3029
3057
  const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
@@ -3053,16 +3081,16 @@ var GeminiProvider = class {
3053
3081
  /** Resolve the embedding client — uses a separate client when the embedding
3054
3082
  * API key differs from the LLM API key. */
3055
3083
  get embeddingClient() {
3056
- var _a;
3057
- if (((_a = this.embeddingConfig) == null ? void 0 : _a.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3084
+ var _a2;
3085
+ if (((_a2 = this.embeddingConfig) == null ? void 0 : _a2.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3058
3086
  return buildClient(this.embeddingConfig.apiKey);
3059
3087
  }
3060
3088
  return this.client;
3061
3089
  }
3062
3090
  /** Resolve the embedding model to use, in order of specificity. */
3063
3091
  resolveEmbeddingModel(optionsModel) {
3064
- var _a, _b;
3065
- return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a = this.embeddingConfig) == null ? void 0 : _a.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3092
+ var _a2, _b;
3093
+ return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a2 = this.embeddingConfig) == null ? void 0 : _a2.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3066
3094
  }
3067
3095
  /**
3068
3096
  * Convert ChatMessage[] to the Gemini contents format.
@@ -3082,8 +3110,8 @@ var GeminiProvider = class {
3082
3110
  // ILLMProvider — chat
3083
3111
  // -------------------------------------------------------------------------
3084
3112
  async chat(messages, context, options) {
3085
- var _a, _b, _c, _d, _e, _f;
3086
- const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3113
+ var _a2, _b, _c, _d, _e, _f;
3114
+ 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.";
3087
3115
  const model = this.client.getGenerativeModel({
3088
3116
  model: this.llmConfig.model,
3089
3117
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3100,8 +3128,8 @@ var GeminiProvider = class {
3100
3128
  }
3101
3129
  chatStream(messages, context, options) {
3102
3130
  return __asyncGenerator(this, null, function* () {
3103
- var _a, _b, _c, _d, _e, _f;
3104
- const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
3131
+ var _a2, _b, _c, _d, _e, _f;
3132
+ 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.";
3105
3133
  const model = this.client.getGenerativeModel({
3106
3134
  model: this.llmConfig.model,
3107
3135
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3136,11 +3164,11 @@ var GeminiProvider = class {
3136
3164
  // ILLMProvider — embeddings
3137
3165
  // -------------------------------------------------------------------------
3138
3166
  async embed(text, options) {
3139
- var _a, _b;
3167
+ var _a2, _b;
3140
3168
  const content = applyPrefix(
3141
3169
  text,
3142
3170
  options == null ? void 0 : options.taskType,
3143
- (_a = this.embeddingConfig) == null ? void 0 : _a.queryPrefix,
3171
+ (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3144
3172
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3145
3173
  );
3146
3174
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
@@ -3157,7 +3185,7 @@ var GeminiProvider = class {
3157
3185
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
3158
3186
  const model = this.embeddingClient.getGenerativeModel({ model: modelName });
3159
3187
  const requests = texts.map((text) => {
3160
- var _a, _b;
3188
+ var _a2, _b;
3161
3189
  return {
3162
3190
  content: {
3163
3191
  role: "user",
@@ -3165,7 +3193,7 @@ var GeminiProvider = class {
3165
3193
  text: applyPrefix(
3166
3194
  text,
3167
3195
  options == null ? void 0 : options.taskType,
3168
- (_a = this.embeddingConfig) == null ? void 0 : _a.queryPrefix,
3196
+ (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3169
3197
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3170
3198
  )
3171
3199
  }]
@@ -3182,8 +3210,8 @@ var GeminiProvider = class {
3182
3210
  throw err;
3183
3211
  });
3184
3212
  return response.embeddings.map((e) => {
3185
- var _a;
3186
- return (_a = e.values) != null ? _a : [];
3213
+ var _a2;
3214
+ return (_a2 = e.values) != null ? _a2 : [];
3187
3215
  });
3188
3216
  }
3189
3217
  // -------------------------------------------------------------------------
@@ -3203,6 +3231,325 @@ var GeminiProvider = class {
3203
3231
  }
3204
3232
  };
3205
3233
 
3234
+ // src/llm/providers/GroqProvider.ts
3235
+ var import_openai2 = __toESM(require("openai"));
3236
+ var GroqProvider = class {
3237
+ constructor(llmConfig, embeddingConfig) {
3238
+ void embeddingConfig;
3239
+ const apiKey = llmConfig.apiKey || process.env.GROQ_API_KEY;
3240
+ if (!apiKey) throw new Error("[GroqProvider] llmConfig.apiKey or GROQ_API_KEY environment variable is required");
3241
+ this.client = new import_openai2.default({
3242
+ apiKey,
3243
+ baseURL: llmConfig.baseUrl || "https://api.groq.com/openai/v1"
3244
+ });
3245
+ this.llmConfig = llmConfig;
3246
+ }
3247
+ static getValidator() {
3248
+ return {
3249
+ validate(config) {
3250
+ const errors = [];
3251
+ if (!config.apiKey && !process.env.GROQ_API_KEY) {
3252
+ errors.push({
3253
+ field: "llm.apiKey",
3254
+ message: "Groq API key is required",
3255
+ suggestion: "Set GROQ_API_KEY environment variable",
3256
+ severity: "error"
3257
+ });
3258
+ }
3259
+ if (!config.model) {
3260
+ errors.push({
3261
+ field: "llm.model",
3262
+ message: "Groq model name is required",
3263
+ suggestion: 'e.g., "llama-3.3-70b-versatile"',
3264
+ severity: "error"
3265
+ });
3266
+ }
3267
+ return errors;
3268
+ }
3269
+ };
3270
+ }
3271
+ static getHealthChecker() {
3272
+ return {
3273
+ async check(config) {
3274
+ const timestamp = Date.now();
3275
+ const apiKey = config.apiKey || process.env.GROQ_API_KEY || "";
3276
+ const modelName = config.model;
3277
+ try {
3278
+ const OpenAI4 = await import("openai");
3279
+ const client = new OpenAI4.default({
3280
+ apiKey,
3281
+ baseURL: config.baseUrl || "https://api.groq.com/openai/v1"
3282
+ });
3283
+ const models = await client.models.list();
3284
+ const hasModel = models.data.some((m) => m.id === modelName);
3285
+ return {
3286
+ healthy: true,
3287
+ provider: "groq",
3288
+ capabilities: { model: modelName, available: hasModel, totalModels: models.data.length },
3289
+ timestamp
3290
+ };
3291
+ } catch (error) {
3292
+ return {
3293
+ healthy: false,
3294
+ provider: "groq",
3295
+ error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
3296
+ timestamp
3297
+ };
3298
+ }
3299
+ }
3300
+ };
3301
+ }
3302
+ async chat(messages, context, options) {
3303
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3304
+ 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.";
3305
+ const systemMessage = {
3306
+ role: "system",
3307
+ content: buildSystemContent(basePrompt, context)
3308
+ };
3309
+ const formattedMessages = [
3310
+ systemMessage,
3311
+ ...messages.map((m) => ({
3312
+ role: m.role,
3313
+ content: m.content
3314
+ }))
3315
+ ];
3316
+ const completion = await this.client.chat.completions.create({
3317
+ model: this.llmConfig.model,
3318
+ messages: formattedMessages,
3319
+ max_tokens: (_d = (_c = options == null ? void 0 : options.maxTokens) != null ? _c : this.llmConfig.maxTokens) != null ? _d : 1024,
3320
+ temperature: (_f = (_e = options == null ? void 0 : options.temperature) != null ? _e : this.llmConfig.temperature) != null ? _f : 0.7,
3321
+ stop: options == null ? void 0 : options.stop
3322
+ });
3323
+ return (_i = (_h = (_g2 = completion.choices[0]) == null ? void 0 : _g2.message) == null ? void 0 : _h.content) != null ? _i : "";
3324
+ }
3325
+ chatStream(messages, context, options) {
3326
+ return __asyncGenerator(this, null, function* () {
3327
+ var _a2, _b, _c, _d, _e, _f, _g2, _h;
3328
+ 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.";
3329
+ const systemMessage = {
3330
+ role: "system",
3331
+ content: buildSystemContent(basePrompt, context)
3332
+ };
3333
+ const formattedMessages = [
3334
+ systemMessage,
3335
+ ...messages.map((m) => ({
3336
+ role: m.role,
3337
+ content: m.content
3338
+ }))
3339
+ ];
3340
+ const stream = yield new __await(this.client.chat.completions.create({
3341
+ model: this.llmConfig.model,
3342
+ messages: formattedMessages,
3343
+ max_tokens: (_d = (_c = options == null ? void 0 : options.maxTokens) != null ? _c : this.llmConfig.maxTokens) != null ? _d : 1024,
3344
+ temperature: (_f = (_e = options == null ? void 0 : options.temperature) != null ? _e : this.llmConfig.temperature) != null ? _f : 0.7,
3345
+ stop: options == null ? void 0 : options.stop,
3346
+ stream: true
3347
+ }));
3348
+ if (!stream) {
3349
+ throw new Error("[GroqProvider] completions.create stream is undefined");
3350
+ }
3351
+ try {
3352
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
3353
+ const chunk = temp.value;
3354
+ const content = ((_h = (_g2 = chunk.choices[0]) == null ? void 0 : _g2.delta) == null ? void 0 : _h.content) || "";
3355
+ if (content) yield content;
3356
+ }
3357
+ } catch (temp) {
3358
+ error = [temp];
3359
+ } finally {
3360
+ try {
3361
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
3362
+ } finally {
3363
+ if (error)
3364
+ throw error[0];
3365
+ }
3366
+ }
3367
+ });
3368
+ }
3369
+ async embed(text, options) {
3370
+ void text;
3371
+ void options;
3372
+ throw new Error('[GroqProvider] Groq does not provide a native embedding API. Please configure "openai" or "gemini" for embeddings in RagConfig.');
3373
+ }
3374
+ async batchEmbed(texts, options) {
3375
+ void texts;
3376
+ void options;
3377
+ throw new Error('[GroqProvider] Groq does not provide a native embedding API. Please configure "openai" or "gemini" for embeddings in RagConfig.');
3378
+ }
3379
+ async ping() {
3380
+ try {
3381
+ await this.client.models.list();
3382
+ return true;
3383
+ } catch (err) {
3384
+ console.error("[GroqProvider] Ping failed:", err);
3385
+ return false;
3386
+ }
3387
+ }
3388
+ };
3389
+
3390
+ // src/llm/providers/QwenProvider.ts
3391
+ var import_openai3 = __toESM(require("openai"));
3392
+ var QwenProvider = class {
3393
+ constructor(llmConfig, embeddingConfig) {
3394
+ const apiKey = llmConfig.apiKey || process.env.DASHSCOPE_API_KEY || process.env.QWEN_API_KEY;
3395
+ if (!apiKey) throw new Error("[QwenProvider] llmConfig.apiKey, DASHSCOPE_API_KEY, or QWEN_API_KEY environment variable is required");
3396
+ this.client = new import_openai3.default({
3397
+ apiKey,
3398
+ baseURL: llmConfig.baseUrl || "https://dashscope.aliyuncs.com/compatible-mode/v1"
3399
+ });
3400
+ this.llmConfig = llmConfig;
3401
+ this.embeddingConfig = embeddingConfig;
3402
+ }
3403
+ static getValidator() {
3404
+ return {
3405
+ validate(config) {
3406
+ const errors = [];
3407
+ const isEmbedding = config.provider === "qwen" && "dimensions" in config;
3408
+ const prefix = isEmbedding ? "embedding" : "llm";
3409
+ if (!config.apiKey && !process.env.DASHSCOPE_API_KEY && !process.env.QWEN_API_KEY) {
3410
+ errors.push({
3411
+ field: `${prefix}.apiKey`,
3412
+ message: "Qwen API key is required",
3413
+ suggestion: "Set DASHSCOPE_API_KEY or QWEN_API_KEY environment variable",
3414
+ severity: "error"
3415
+ });
3416
+ }
3417
+ if (!config.model) {
3418
+ errors.push({
3419
+ field: `${prefix}.model`,
3420
+ message: "Qwen model name is required",
3421
+ suggestion: isEmbedding ? 'e.g., "text-embedding-v3"' : 'e.g., "qwen-plus" or "qwen-max"',
3422
+ severity: "error"
3423
+ });
3424
+ }
3425
+ return errors;
3426
+ }
3427
+ };
3428
+ }
3429
+ static getHealthChecker() {
3430
+ return {
3431
+ async check(config) {
3432
+ const timestamp = Date.now();
3433
+ const apiKey = config.apiKey || process.env.DASHSCOPE_API_KEY || process.env.QWEN_API_KEY || "";
3434
+ const modelName = config.model;
3435
+ try {
3436
+ const OpenAI4 = await import("openai");
3437
+ const client = new OpenAI4.default({
3438
+ apiKey,
3439
+ baseURL: config.baseUrl || "https://dashscope.aliyuncs.com/compatible-mode/v1"
3440
+ });
3441
+ const models = await client.models.list();
3442
+ const hasModel = models.data.some((m) => m.id === modelName);
3443
+ return {
3444
+ healthy: true,
3445
+ provider: "qwen",
3446
+ capabilities: { model: modelName, available: hasModel, totalModels: models.data.length },
3447
+ timestamp
3448
+ };
3449
+ } catch (error) {
3450
+ return {
3451
+ healthy: false,
3452
+ provider: "qwen",
3453
+ error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
3454
+ timestamp
3455
+ };
3456
+ }
3457
+ }
3458
+ };
3459
+ }
3460
+ async chat(messages, context, options) {
3461
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3462
+ 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.";
3463
+ const systemMessage = {
3464
+ role: "system",
3465
+ content: buildSystemContent(basePrompt, context)
3466
+ };
3467
+ const formattedMessages = [
3468
+ systemMessage,
3469
+ ...messages.map((m) => ({
3470
+ role: m.role,
3471
+ content: m.content
3472
+ }))
3473
+ ];
3474
+ const completion = await this.client.chat.completions.create({
3475
+ model: this.llmConfig.model,
3476
+ messages: formattedMessages,
3477
+ max_tokens: (_d = (_c = options == null ? void 0 : options.maxTokens) != null ? _c : this.llmConfig.maxTokens) != null ? _d : 1024,
3478
+ temperature: (_f = (_e = options == null ? void 0 : options.temperature) != null ? _e : this.llmConfig.temperature) != null ? _f : 0.7,
3479
+ stop: options == null ? void 0 : options.stop
3480
+ });
3481
+ return (_i = (_h = (_g2 = completion.choices[0]) == null ? void 0 : _g2.message) == null ? void 0 : _h.content) != null ? _i : "";
3482
+ }
3483
+ chatStream(messages, context, options) {
3484
+ return __asyncGenerator(this, null, function* () {
3485
+ var _a2, _b, _c, _d, _e, _f, _g2, _h;
3486
+ 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.";
3487
+ const systemMessage = {
3488
+ role: "system",
3489
+ content: buildSystemContent(basePrompt, context)
3490
+ };
3491
+ const formattedMessages = [
3492
+ systemMessage,
3493
+ ...messages.map((m) => ({
3494
+ role: m.role,
3495
+ content: m.content
3496
+ }))
3497
+ ];
3498
+ const stream = yield new __await(this.client.chat.completions.create({
3499
+ model: this.llmConfig.model,
3500
+ messages: formattedMessages,
3501
+ max_tokens: (_d = (_c = options == null ? void 0 : options.maxTokens) != null ? _c : this.llmConfig.maxTokens) != null ? _d : 1024,
3502
+ temperature: (_f = (_e = options == null ? void 0 : options.temperature) != null ? _e : this.llmConfig.temperature) != null ? _f : 0.7,
3503
+ stop: options == null ? void 0 : options.stop,
3504
+ stream: true
3505
+ }));
3506
+ if (!stream) {
3507
+ throw new Error("[QwenProvider] completions.create stream is undefined");
3508
+ }
3509
+ try {
3510
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
3511
+ const chunk = temp.value;
3512
+ const content = ((_h = (_g2 = chunk.choices[0]) == null ? void 0 : _g2.delta) == null ? void 0 : _h.content) || "";
3513
+ if (content) yield content;
3514
+ }
3515
+ } catch (temp) {
3516
+ error = [temp];
3517
+ } finally {
3518
+ try {
3519
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
3520
+ } finally {
3521
+ if (error)
3522
+ throw error[0];
3523
+ }
3524
+ }
3525
+ });
3526
+ }
3527
+ async embed(text, options) {
3528
+ const results = await this.batchEmbed([text], options);
3529
+ return results[0];
3530
+ }
3531
+ async batchEmbed(texts, options) {
3532
+ var _a2, _b, _c, _d, _e, _f;
3533
+ 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";
3534
+ const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
3535
+ const client = apiKey !== this.llmConfig.apiKey ? new import_openai3.default({
3536
+ apiKey,
3537
+ baseURL: ((_f = this.embeddingConfig) == null ? void 0 : _f.baseUrl) || "https://dashscope.aliyuncs.com/compatible-mode/v1"
3538
+ }) : this.client;
3539
+ const response = await client.embeddings.create({ model, input: texts });
3540
+ return response.data.map((d) => d.embedding);
3541
+ }
3542
+ async ping() {
3543
+ try {
3544
+ await this.client.models.list();
3545
+ return true;
3546
+ } catch (err) {
3547
+ console.error("[QwenProvider] Ping failed:", err);
3548
+ return false;
3549
+ }
3550
+ }
3551
+ };
3552
+
3206
3553
  // src/llm/providers/UniversalLLMAdapter.ts
3207
3554
  var import_axios2 = __toESM(require("axios"));
3208
3555
  init_templateUtils();
@@ -3286,10 +3633,10 @@ var VECTOR_PROFILES = {
3286
3633
  // src/llm/providers/UniversalLLMAdapter.ts
3287
3634
  var UniversalLLMAdapter = class {
3288
3635
  constructor(config) {
3289
- var _a, _b, _c, _d, _e, _f, _g, _h;
3636
+ var _a2, _b, _c, _d, _e, _f, _g2, _h;
3290
3637
  this.model = config.model;
3291
3638
  const llmConfig = config;
3292
- const options = (_a = llmConfig.options) != null ? _a : {};
3639
+ const options = (_a2 = llmConfig.options) != null ? _a2 : {};
3293
3640
  let profile = {};
3294
3641
  if (typeof options.profile === "string") {
3295
3642
  profile = LLM_PROFILES[options.profile] || {};
@@ -3301,7 +3648,7 @@ var UniversalLLMAdapter = class {
3301
3648
  this.maxTokens = (_d = llmConfig.maxTokens) != null ? _d : 1024;
3302
3649
  this.temperature = (_e = llmConfig.temperature) != null ? _e : 0;
3303
3650
  this.apiKey = config.apiKey;
3304
- this.baseUrl = (_g = (_f = llmConfig.baseUrl) != null ? _f : this.opts.baseUrl) != null ? _g : "";
3651
+ this.baseUrl = (_g2 = (_f = llmConfig.baseUrl) != null ? _f : this.opts.baseUrl) != null ? _g2 : "";
3305
3652
  if (!this.baseUrl) {
3306
3653
  throw new Error("[UniversalLLMAdapter] baseUrl is required in config or config.options");
3307
3654
  }
@@ -3315,8 +3662,8 @@ var UniversalLLMAdapter = class {
3315
3662
  });
3316
3663
  }
3317
3664
  async chat(messages, context) {
3318
- var _a, _b;
3319
- const path = (_a = this.opts.chatPath) != null ? _a : "/chat/completions";
3665
+ var _a2, _b;
3666
+ const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
3320
3667
  const formattedMessages = [
3321
3668
  { role: "system", content: `${this.systemPrompt}
3322
3669
 
@@ -3340,7 +3687,7 @@ ${context != null ? context : "None"}` },
3340
3687
  temperature: this.temperature
3341
3688
  };
3342
3689
  }
3343
- const { data } = await this.http.post(path, payload);
3690
+ const { data } = await this.http.post(path2, payload);
3344
3691
  const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
3345
3692
  const result = resolvePath(data, extractPath);
3346
3693
  if (result === void 0) {
@@ -3355,9 +3702,9 @@ ${context != null ? context : "None"}` },
3355
3702
  */
3356
3703
  chatStream(messages, context) {
3357
3704
  return __asyncGenerator(this, null, function* () {
3358
- var _a, _b, _c;
3359
- const path = (_a = this.opts.chatPath) != null ? _a : "/chat/completions";
3360
- const url = `${this.baseUrl.replace(/\/$/, "")}${path}`;
3705
+ var _a2, _b, _c;
3706
+ const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
3707
+ const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
3361
3708
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
3362
3709
  const formattedMessages = [
3363
3710
  { role: "system", content: `${this.systemPrompt}
@@ -3435,8 +3782,8 @@ ${context != null ? context : "None"}` },
3435
3782
  });
3436
3783
  }
3437
3784
  async embed(text) {
3438
- var _a, _b;
3439
- const path = (_a = this.opts.embedPath) != null ? _a : "/embeddings";
3785
+ var _a2, _b;
3786
+ const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
3440
3787
  let payload;
3441
3788
  if (this.opts.embedPayloadTemplate) {
3442
3789
  payload = buildPayload(this.opts.embedPayloadTemplate, {
@@ -3449,7 +3796,7 @@ ${context != null ? context : "None"}` },
3449
3796
  input: text
3450
3797
  };
3451
3798
  }
3452
- const { data } = await this.http.post(path, payload);
3799
+ const { data } = await this.http.post(path2, payload);
3453
3800
  const extractPath = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
3454
3801
  const vector = resolvePath(data, extractPath);
3455
3802
  if (!Array.isArray(vector)) {
@@ -3517,13 +3864,13 @@ var AuthenticationException = class extends RetrivoraError {
3517
3864
  }
3518
3865
  };
3519
3866
  function wrapError(err, defaultCode, defaultMessage) {
3520
- var _a;
3867
+ var _a2;
3521
3868
  if (err instanceof RetrivoraError) {
3522
3869
  return err;
3523
3870
  }
3524
3871
  const error = err;
3525
3872
  const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
3526
- const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((_a = error == null ? void 0 : error.response) == null ? void 0 : _a.status);
3873
+ 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);
3527
3874
  const code = error == null ? void 0 : error.code;
3528
3875
  if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
3529
3876
  return new RateLimitException(message, err);
@@ -3587,6 +3934,8 @@ var LLMFactory = class _LLMFactory {
3587
3934
  "anthropic",
3588
3935
  "ollama",
3589
3936
  "gemini",
3937
+ "groq",
3938
+ "qwen",
3590
3939
  "rest",
3591
3940
  "universal_rest",
3592
3941
  "custom",
@@ -3594,7 +3943,7 @@ var LLMFactory = class _LLMFactory {
3594
3943
  ];
3595
3944
  }
3596
3945
  static create(llmConfig, embeddingConfig) {
3597
- var _a, _b, _c;
3946
+ var _a2, _b, _c;
3598
3947
  switch (llmConfig.provider) {
3599
3948
  case "openai":
3600
3949
  return new OpenAIProvider(llmConfig, embeddingConfig);
@@ -3604,12 +3953,16 @@ var LLMFactory = class _LLMFactory {
3604
3953
  return new OllamaProvider(llmConfig, embeddingConfig);
3605
3954
  case "gemini":
3606
3955
  return new GeminiProvider(llmConfig, embeddingConfig);
3956
+ case "groq":
3957
+ return new GroqProvider(llmConfig, embeddingConfig);
3958
+ case "qwen":
3959
+ return new QwenProvider(llmConfig, embeddingConfig);
3607
3960
  case "rest":
3608
3961
  case "universal_rest":
3609
3962
  case "custom":
3610
3963
  return new UniversalLLMAdapter(llmConfig);
3611
3964
  default: {
3612
- const providerName = String((_a = llmConfig.provider) != null ? _a : "").toLowerCase();
3965
+ const providerName = String((_a2 = llmConfig.provider) != null ? _a2 : "").toLowerCase();
3613
3966
  const customFactory = customProviders.get(providerName);
3614
3967
  if (customFactory) {
3615
3968
  return customFactory(llmConfig);
@@ -3646,6 +3999,10 @@ var LLMFactory = class _LLMFactory {
3646
3999
  return OllamaProvider;
3647
4000
  case "gemini":
3648
4001
  return GeminiProvider;
4002
+ case "groq":
4003
+ return GroqProvider;
4004
+ case "qwen":
4005
+ return QwenProvider;
3649
4006
  case "rest":
3650
4007
  case "universal_rest":
3651
4008
  case "custom":
@@ -3707,7 +4064,7 @@ var ProviderRegistry = class {
3707
4064
  return null;
3708
4065
  }
3709
4066
  static async loadVectorProviderClass(provider) {
3710
- var _a;
4067
+ var _a2;
3711
4068
  if (this.vectorProviders[provider]) return this.vectorProviders[provider];
3712
4069
  switch (provider) {
3713
4070
  case "pinecone": {
@@ -3716,7 +4073,7 @@ var ProviderRegistry = class {
3716
4073
  }
3717
4074
  case "pgvector":
3718
4075
  case "postgresql": {
3719
- const postgresMode = ((_a = process.env.POSTGRES_MODE) != null ? _a : "multi").toLowerCase();
4076
+ const postgresMode = ((_a2 = process.env.POSTGRES_MODE) != null ? _a2 : "multi").toLowerCase();
3720
4077
  if (postgresMode === "single") {
3721
4078
  const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
3722
4079
  return PostgreSQLProvider2;
@@ -3936,6 +4293,125 @@ var ConfigValidator = class {
3936
4293
  }
3937
4294
  };
3938
4295
 
4296
+ // src/core/LicenseVerifier.ts
4297
+ var crypto2 = __toESM(require("crypto"));
4298
+ var LicenseVerifier = class {
4299
+ /**
4300
+ * Decodes, verifies signature, and checks metadata of a license key.
4301
+ *
4302
+ * @param licenseKey - Base64url signed JWT license key.
4303
+ * @param currentProjectId - Project namespace ID.
4304
+ * @param publicKeyOverride - Optional override for unit/integration tests.
4305
+ */
4306
+ static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
4307
+ const isProduction = process.env.NODE_ENV === "production";
4308
+ if (!licenseKey) {
4309
+ if (isProduction) {
4310
+ throw new ConfigurationException(
4311
+ "[Retrivora SDK] License key (licenseKey) is required in production environments."
4312
+ );
4313
+ }
4314
+ console.warn(
4315
+ `\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
4316
+ );
4317
+ return {
4318
+ projectId: currentProjectId,
4319
+ expiresAt: Math.floor(Date.now() / 1e3) + 86400,
4320
+ // Valid for 24h
4321
+ tier: "hobby"
4322
+ };
4323
+ }
4324
+ try {
4325
+ const parts = licenseKey.split(".");
4326
+ if (parts.length !== 3) {
4327
+ throw new Error("Malformed token structure (expected 3 parts).");
4328
+ }
4329
+ const [headerB64, payloadB64, signatureB64] = parts;
4330
+ const dataToVerify = `${headerB64}.${payloadB64}`;
4331
+ const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
4332
+ const signature = Buffer.from(signatureB64, "base64url");
4333
+ const data = Buffer.from(dataToVerify);
4334
+ const isValid = crypto2.verify(
4335
+ "sha256",
4336
+ data,
4337
+ publicKey,
4338
+ signature
4339
+ );
4340
+ if (!isValid) {
4341
+ throw new Error("Signature verification failed.");
4342
+ }
4343
+ const payload = JSON.parse(
4344
+ Buffer.from(payloadB64, "base64url").toString("utf8")
4345
+ );
4346
+ if (!payload.projectId) {
4347
+ throw new Error('License payload is missing "projectId".');
4348
+ }
4349
+ if (payload.projectId !== currentProjectId) {
4350
+ throw new Error(
4351
+ `Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
4352
+ );
4353
+ }
4354
+ if (!payload.expiresAt) {
4355
+ throw new Error('License payload is missing expiration ("expiresAt").');
4356
+ }
4357
+ const currentTimestampSec = Math.floor(Date.now() / 1e3);
4358
+ if (currentTimestampSec > payload.expiresAt) {
4359
+ throw new Error(
4360
+ `License key has expired. Expiration: ${new Date(
4361
+ payload.expiresAt * 1e3
4362
+ ).toDateString()}`
4363
+ );
4364
+ }
4365
+ if (isProduction && provider) {
4366
+ const tier = (payload.tier || "").toLowerCase();
4367
+ const normalizedProvider = provider.toLowerCase();
4368
+ if (tier === "hobby") {
4369
+ const allowedHobby = ["postgresql", "pgvector", "supabase"];
4370
+ if (!allowedHobby.includes(normalizedProvider)) {
4371
+ throw new Error(
4372
+ `The database provider "${provider}" is not allowed on the Hobby tier. Hobby tier is restricted to PostgreSQL and Supabase. Please upgrade to a Developer Pro or Enterprise plan.`
4373
+ );
4374
+ }
4375
+ } else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth") {
4376
+ const allowedPro = [
4377
+ "postgresql",
4378
+ "pgvector",
4379
+ "supabase",
4380
+ "pinecone",
4381
+ "qdrant",
4382
+ "mongodb",
4383
+ "milvus",
4384
+ "chroma",
4385
+ "chromadb"
4386
+ ];
4387
+ if (!allowedPro.includes(normalizedProvider)) {
4388
+ throw new Error(
4389
+ `The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
4390
+ );
4391
+ }
4392
+ }
4393
+ }
4394
+ return payload;
4395
+ } catch (err) {
4396
+ const message = err instanceof Error ? err.message : String(err);
4397
+ throw new ConfigurationException(
4398
+ `[Retrivora SDK] License key validation failed: ${message}`
4399
+ );
4400
+ }
4401
+ }
4402
+ };
4403
+ // Retrivora's Public Key used to verify the license key signature.
4404
+ // In production, this matches the private key held by Retrivora SaaS.
4405
+ LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
4406
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
4407
+ XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
4408
+ xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
4409
+ NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
4410
+ iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
4411
+ +Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
4412
+ MwIDAQAB
4413
+ -----END PUBLIC KEY-----`;
4414
+
3939
4415
  // src/rag/DocumentChunker.ts
3940
4416
  var DocumentChunker = class {
3941
4417
  constructor(chunkSize = 1e3, chunkOverlap = 200, separators = ["\n# ", "\n## ", "\n### ", "\n#### ", "\n\n", "\n", " ", ""]) {
@@ -4165,11 +4641,11 @@ var LlamaIndexIngestor = class {
4165
4641
  * than standard character-count splitting.
4166
4642
  */
4167
4643
  async chunk(text, options = {}) {
4168
- var _a, _b;
4644
+ var _a2, _b;
4169
4645
  try {
4170
4646
  const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
4171
4647
  const splitter = new SentenceSplitter({
4172
- chunkSize: (_a = options.chunkSize) != null ? _a : 1e3,
4648
+ chunkSize: (_a2 = options.chunkSize) != null ? _a2 : 1e3,
4173
4649
  chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
4174
4650
  });
4175
4651
  const doc = new Document({ text, metadata: options.metadata || {} });
@@ -4278,7 +4754,7 @@ ${error instanceof Error ? error.message : String(error)}`
4278
4754
  * The agent returns `{ messages: [...] }` — the last message is the final answer.
4279
4755
  */
4280
4756
  async run(input, chatHistory = []) {
4281
- var _a, _b, _c;
4757
+ var _a2, _b, _c;
4282
4758
  if (!this.agent) {
4283
4759
  throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
4284
4760
  }
@@ -4289,14 +4765,445 @@ ${error instanceof Error ? error.message : String(error)}`
4289
4765
  const response = await this.agent.invoke({
4290
4766
  messages: [...historyMessages, new HumanMessage(input)]
4291
4767
  });
4292
- const lastMessage = (_a = response == null ? void 0 : response.messages) == null ? void 0 : _a.at(-1);
4293
- if (lastMessage && typeof lastMessage.content === "string") {
4294
- return lastMessage.content;
4295
- }
4296
- if (Array.isArray(lastMessage == null ? void 0 : lastMessage.content)) {
4297
- return lastMessage.content.filter((c) => c.type === "text").map((c) => c.text).join("");
4298
- }
4299
- return String((_c = (_b = response == null ? void 0 : response.output) != null ? _b : response) != null ? _c : "");
4768
+ const lastMessage = (_a2 = response == null ? void 0 : response.messages) == null ? void 0 : _a2.at(-1);
4769
+ if (lastMessage && typeof lastMessage.content === "string") {
4770
+ return lastMessage.content;
4771
+ }
4772
+ if (Array.isArray(lastMessage == null ? void 0 : lastMessage.content)) {
4773
+ return lastMessage.content.filter((c) => c.type === "text").map((c) => c.text).join("");
4774
+ }
4775
+ return String((_c = (_b = response == null ? void 0 : response.output) != null ? _b : response) != null ? _c : "");
4776
+ }
4777
+ };
4778
+
4779
+ // src/core/mcp.ts
4780
+ var import_child_process = require("child_process");
4781
+ var MCPClient = class {
4782
+ constructor(config) {
4783
+ this.config = config;
4784
+ this.messageIdCounter = 0;
4785
+ this.pendingRequests = /* @__PURE__ */ new Map();
4786
+ this.stdioBuffer = "";
4787
+ this.initialized = false;
4788
+ }
4789
+ getNextMessageId() {
4790
+ return ++this.messageIdCounter;
4791
+ }
4792
+ /**
4793
+ * Connect and initialize the MCP server connection.
4794
+ */
4795
+ async connect() {
4796
+ if (this.initialized) return;
4797
+ if (this.config.transport === "stdio") {
4798
+ await this.connectStdio();
4799
+ } else {
4800
+ await this.connectSSE();
4801
+ }
4802
+ try {
4803
+ const response = await this.sendJsonRpc("initialize", {
4804
+ protocolVersion: "2024-11-05",
4805
+ capabilities: {},
4806
+ clientInfo: {
4807
+ name: "retrivora-sdk",
4808
+ version: "1.0.0"
4809
+ }
4810
+ });
4811
+ await this.sendNotification("notifications/initialized");
4812
+ this.initialized = true;
4813
+ console.log(`[MCPClient] Connected and initialized server "${this.config.name}" successfully.`);
4814
+ } catch (err) {
4815
+ this.disconnect();
4816
+ throw new Error(`[MCPClient] Failed to initialize server "${this.config.name}": ${err.message}`);
4817
+ }
4818
+ }
4819
+ async connectStdio() {
4820
+ var _a2;
4821
+ const cmd = this.config.command;
4822
+ if (!cmd) {
4823
+ throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
4824
+ }
4825
+ const args = this.config.args || [];
4826
+ const env = __spreadValues(__spreadValues({}, process.env), this.config.env || {});
4827
+ this.childProcess = (0, import_child_process.spawn)(cmd, args, { env, shell: true });
4828
+ if (!this.childProcess || !this.childProcess.stdout || !this.childProcess.stdin) {
4829
+ throw new Error(`[MCPClient] Failed to spawn stdio child process for "${this.config.name}"`);
4830
+ }
4831
+ this.childProcess.stdout.on("data", (data) => {
4832
+ this.stdioBuffer += data.toString("utf-8");
4833
+ this.processStdioLines();
4834
+ });
4835
+ (_a2 = this.childProcess.stderr) == null ? void 0 : _a2.on("data", (data) => {
4836
+ console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
4837
+ });
4838
+ this.childProcess.on("close", (code) => {
4839
+ console.log(`[MCPClient] Connection closed for "${this.config.name}" with exit code: ${code}`);
4840
+ this.disconnect();
4841
+ });
4842
+ await new Promise((resolve) => setTimeout(resolve, 100));
4843
+ }
4844
+ processStdioLines() {
4845
+ let newlineIndex;
4846
+ while ((newlineIndex = this.stdioBuffer.indexOf("\n")) !== -1) {
4847
+ const line = this.stdioBuffer.substring(0, newlineIndex).trim();
4848
+ this.stdioBuffer = this.stdioBuffer.substring(newlineIndex + 1);
4849
+ if (!line) continue;
4850
+ try {
4851
+ const payload = JSON.parse(line);
4852
+ if (payload.id !== void 0) {
4853
+ const req = this.pendingRequests.get(Number(payload.id));
4854
+ if (req) {
4855
+ this.pendingRequests.delete(Number(payload.id));
4856
+ if (payload.error) {
4857
+ req.reject(new Error(payload.error.message || JSON.stringify(payload.error)));
4858
+ } else {
4859
+ req.resolve(payload.result);
4860
+ }
4861
+ }
4862
+ }
4863
+ } catch (e) {
4864
+ console.warn(`[MCPClient] Error parsing stdio JSON-RPC line from "${this.config.name}":`, e, "Line content:", line);
4865
+ }
4866
+ }
4867
+ }
4868
+ async connectSSE() {
4869
+ if (!this.config.url) {
4870
+ throw new Error(`[MCPClient] URL is required for sse transport on "${this.config.name}"`);
4871
+ }
4872
+ this.sseUrl = this.config.url;
4873
+ }
4874
+ async sendJsonRpc(method, params) {
4875
+ const id = this.getNextMessageId();
4876
+ const request = {
4877
+ jsonrpc: "2.0",
4878
+ id,
4879
+ method,
4880
+ params
4881
+ };
4882
+ if (this.config.transport === "stdio") {
4883
+ if (!this.childProcess || !this.childProcess.stdin) {
4884
+ throw new Error(`[MCPClient] Server "${this.config.name}" is not connected (stdio process missing)`);
4885
+ }
4886
+ return new Promise((resolve, reject) => {
4887
+ this.pendingRequests.set(id, { resolve, reject });
4888
+ this.childProcess.stdin.write(JSON.stringify(request) + "\n", "utf-8");
4889
+ });
4890
+ } else {
4891
+ if (!this.sseUrl) {
4892
+ throw new Error(`[MCPClient] Server "${this.config.name}" SSE URL is not initialized`);
4893
+ }
4894
+ const response = await fetch(this.sseUrl, {
4895
+ method: "POST",
4896
+ headers: { "Content-Type": "application/json" },
4897
+ body: JSON.stringify(request)
4898
+ });
4899
+ if (!response.ok) {
4900
+ throw new Error(`SSE JSON-RPC POST failed with status ${response.status}`);
4901
+ }
4902
+ const payload = await response.json();
4903
+ if (payload.error) {
4904
+ throw new Error(payload.error.message || JSON.stringify(payload.error));
4905
+ }
4906
+ return payload.result;
4907
+ }
4908
+ }
4909
+ async sendNotification(method, params) {
4910
+ var _a2;
4911
+ const notification = {
4912
+ jsonrpc: "2.0",
4913
+ method,
4914
+ params
4915
+ };
4916
+ if (this.config.transport === "stdio") {
4917
+ if ((_a2 = this.childProcess) == null ? void 0 : _a2.stdin) {
4918
+ this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
4919
+ }
4920
+ } else if (this.sseUrl) {
4921
+ await fetch(this.sseUrl, {
4922
+ method: "POST",
4923
+ headers: { "Content-Type": "application/json" },
4924
+ body: JSON.stringify(notification)
4925
+ }).catch((err) => console.warn("[MCPClient] Failed to send notification over SSE:", err));
4926
+ }
4927
+ }
4928
+ /**
4929
+ * List all tools offered by the MCP server.
4930
+ */
4931
+ async listTools() {
4932
+ await this.connect();
4933
+ const result = await this.sendJsonRpc("tools/list", {});
4934
+ return (result == null ? void 0 : result.tools) || [];
4935
+ }
4936
+ /**
4937
+ * Execute a tool on the MCP server.
4938
+ */
4939
+ async callTool(name, args = {}) {
4940
+ await this.connect();
4941
+ return await this.sendJsonRpc("tools/call", { name, arguments: args });
4942
+ }
4943
+ disconnect() {
4944
+ this.initialized = false;
4945
+ this.pendingRequests.forEach((req) => req.reject(new Error("MCPClient disconnected")));
4946
+ this.pendingRequests.clear();
4947
+ if (this.childProcess) {
4948
+ try {
4949
+ this.childProcess.kill();
4950
+ } catch (e) {
4951
+ }
4952
+ this.childProcess = void 0;
4953
+ }
4954
+ }
4955
+ };
4956
+ var MCPRegistry = class {
4957
+ constructor(servers = []) {
4958
+ this.clients = [];
4959
+ this.clients = servers.map((cfg) => new MCPClient(cfg));
4960
+ }
4961
+ async getAllTools() {
4962
+ const list = [];
4963
+ await Promise.all(
4964
+ this.clients.map(async (client) => {
4965
+ try {
4966
+ const tools = await client.listTools();
4967
+ tools.forEach((t) => list.push({ serverName: client["config"].name, tool: t }));
4968
+ } catch (e) {
4969
+ console.warn(`[MCPRegistry] Failed to fetch tools from server "${client["config"].name}":`, e);
4970
+ }
4971
+ })
4972
+ );
4973
+ return list;
4974
+ }
4975
+ async callTool(toolName, args = {}) {
4976
+ for (const client of this.clients) {
4977
+ try {
4978
+ const tools = await client.listTools();
4979
+ if (tools.some((t) => t.name === toolName)) {
4980
+ return await client.callTool(toolName, args);
4981
+ }
4982
+ } catch (e) {
4983
+ }
4984
+ }
4985
+ throw new Error(`[MCPRegistry] Tool "${toolName}" not found on any registered MCP server.`);
4986
+ }
4987
+ disconnectAll() {
4988
+ this.clients.forEach((c) => c.disconnect());
4989
+ }
4990
+ };
4991
+
4992
+ // src/core/MultiAgentCoordinator.ts
4993
+ var MultiAgentCoordinator = class {
4994
+ constructor(options) {
4995
+ var _a2;
4996
+ this.llmProvider = options.llmProvider;
4997
+ this.mcpRegistry = options.mcpRegistry;
4998
+ this.documentSearch = options.documentSearch;
4999
+ this.maxIterations = (_a2 = options.maxIterations) != null ? _a2 : 5;
5000
+ }
5001
+ /**
5002
+ * Run the multi-agent coordination loop synchronously and return the final response.
5003
+ */
5004
+ async run(question, history = []) {
5005
+ const generator = this.runStream(question, history);
5006
+ let finalReply = "";
5007
+ const sources = [];
5008
+ try {
5009
+ for (var iter = __forAwait(generator), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
5010
+ const chunk = temp.value;
5011
+ if (typeof chunk === "string") {
5012
+ finalReply += chunk;
5013
+ } else if (chunk && typeof chunk === "object") {
5014
+ if ("reply" in chunk && chunk.reply) {
5015
+ finalReply += chunk.reply;
5016
+ }
5017
+ if ("sources" in chunk && chunk.sources) {
5018
+ sources.push(...chunk.sources);
5019
+ }
5020
+ }
5021
+ }
5022
+ } catch (temp) {
5023
+ error = [temp];
5024
+ } finally {
5025
+ try {
5026
+ more && (temp = iter.return) && await temp.call(iter);
5027
+ } finally {
5028
+ if (error)
5029
+ throw error[0];
5030
+ }
5031
+ }
5032
+ return {
5033
+ reply: finalReply,
5034
+ sources
5035
+ };
5036
+ }
5037
+ /**
5038
+ * Run the multi-agent coordination loop as an async stream, yielding intermediate thought blocks and tool execution events.
5039
+ */
5040
+ runStream(_0) {
5041
+ return __asyncGenerator(this, arguments, function* (question, history = []) {
5042
+ const mcpTools = yield new __await(this.mcpRegistry.getAllTools());
5043
+ let systemPrompt = `You are a goal-driven supervisor agent coordinating a RAG search engine and external MCP servers to solve the user's task.
5044
+ You must think step-by-step before acting. Write your internal thinking process inside a \`<think>...</think>\` block first, then act or answer.
5045
+
5046
+ Available Tools:
5047
+ - document_search(query: string): Search the vector database and knowledge base for documents.
5048
+
5049
+ ${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
5050
+ ${mcpTools.map((mt) => {
5051
+ var _a2;
5052
+ return `- ${mt.tool.name}(${JSON.stringify(((_a2 = mt.tool.inputSchema) == null ? void 0 : _a2.properties) || {})}): ${mt.tool.description || "No description provided."}`;
5053
+ }).join("\n")}
5054
+
5055
+ Tool Calling Protocol:
5056
+ If you need to call a tool, write:
5057
+ TOOL_CALL: <toolName>({ "argName": "value" })
5058
+ And then STOP generating immediately.
5059
+
5060
+ Once you have gathered enough information to fully satisfy the user's query, write your final response directly after the closing \`</think>\` block.
5061
+ `;
5062
+ const supervisorHistory = [
5063
+ { role: "system", content: systemPrompt },
5064
+ ...history,
5065
+ { role: "user", content: question }
5066
+ ];
5067
+ let iteration = 0;
5068
+ const allSources = [];
5069
+ while (iteration < this.maxIterations) {
5070
+ iteration++;
5071
+ const context = "";
5072
+ let fullModelResponse = "";
5073
+ let textBuffer = "";
5074
+ let inThinking = false;
5075
+ let toolCallDetected = null;
5076
+ if (!this.llmProvider.chatStream) {
5077
+ const reply = yield new __await(this.llmProvider.chat(supervisorHistory, context));
5078
+ fullModelResponse = reply;
5079
+ const thinkIndex = reply.indexOf("<think>");
5080
+ const endThinkIndex = reply.indexOf("</think>");
5081
+ let thinkingText = "";
5082
+ let answerText = reply;
5083
+ if (thinkIndex !== -1 && endThinkIndex !== -1) {
5084
+ thinkingText = reply.substring(thinkIndex + 7, endThinkIndex);
5085
+ answerText = reply.substring(endThinkIndex + 8);
5086
+ yield { type: "thinking", text: thinkingText };
5087
+ }
5088
+ const toolMatch = answerText.match(/TOOL_CALL:\s*(\w+)\s*\(([\s\S]*)\)/);
5089
+ if (toolMatch) {
5090
+ const toolName = toolMatch[1];
5091
+ const toolArgsStr = toolMatch[2];
5092
+ try {
5093
+ const toolArgs = JSON.parse(toolArgsStr.trim());
5094
+ toolCallDetected = { name: toolName, args: toolArgs };
5095
+ } catch (e) {
5096
+ console.error("[MultiAgentCoordinator] Failed to parse tool args:", toolArgsStr, e);
5097
+ }
5098
+ } else {
5099
+ yield answerText;
5100
+ }
5101
+ } else {
5102
+ const stream = this.llmProvider.chatStream(supervisorHistory, context);
5103
+ try {
5104
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
5105
+ const chunk = temp.value;
5106
+ fullModelResponse += chunk;
5107
+ textBuffer += chunk;
5108
+ if (!inThinking && textBuffer.includes("<think>")) {
5109
+ inThinking = true;
5110
+ const idx = textBuffer.indexOf("<think>");
5111
+ textBuffer = textBuffer.slice(idx + 7);
5112
+ }
5113
+ if (inThinking && textBuffer.includes("</think>")) {
5114
+ inThinking = false;
5115
+ const idx = textBuffer.indexOf("</think>");
5116
+ const thinkingDelta = textBuffer.slice(0, idx);
5117
+ yield { type: "thinking", text: thinkingDelta };
5118
+ textBuffer = textBuffer.slice(idx + 8);
5119
+ }
5120
+ if (inThinking && textBuffer.length > 0) {
5121
+ yield { type: "thinking", text: textBuffer };
5122
+ textBuffer = "";
5123
+ }
5124
+ if (!inThinking && textBuffer.includes("TOOL_CALL:")) {
5125
+ const idx = textBuffer.indexOf("TOOL_CALL:");
5126
+ const precedingText = textBuffer.slice(0, idx);
5127
+ if (precedingText.trim()) {
5128
+ yield precedingText;
5129
+ }
5130
+ textBuffer = textBuffer.slice(idx);
5131
+ }
5132
+ if (!inThinking && !textBuffer.includes("TOOL_CALL:") && textBuffer.length > 0) {
5133
+ yield textBuffer;
5134
+ textBuffer = "";
5135
+ }
5136
+ }
5137
+ } catch (temp) {
5138
+ error = [temp];
5139
+ } finally {
5140
+ try {
5141
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
5142
+ } finally {
5143
+ if (error)
5144
+ throw error[0];
5145
+ }
5146
+ }
5147
+ if (textBuffer.trim()) {
5148
+ const toolMatch = textBuffer.match(/TOOL_CALL:\s*(\w+)\s*\(([\s\S]*)\)/);
5149
+ if (toolMatch) {
5150
+ const toolName = toolMatch[1];
5151
+ const toolArgsStr = toolMatch[2];
5152
+ try {
5153
+ const toolArgs = JSON.parse(toolArgsStr.trim());
5154
+ toolCallDetected = { name: toolName, args: toolArgs };
5155
+ } catch (e) {
5156
+ console.error("[MultiAgentCoordinator] Failed to parse tool args:", toolArgsStr, e);
5157
+ }
5158
+ } else {
5159
+ yield textBuffer;
5160
+ }
5161
+ }
5162
+ }
5163
+ supervisorHistory.push({ role: "assistant", content: fullModelResponse });
5164
+ if (toolCallDetected) {
5165
+ const { name: toolName, args: toolArgs } = toolCallDetected;
5166
+ yield {
5167
+ type: "thinking",
5168
+ text: `
5169
+ [Agent Call] Executing tool "${toolName}" with parameters ${JSON.stringify(toolArgs)}...
5170
+ `
5171
+ };
5172
+ let toolResultText = "";
5173
+ try {
5174
+ if (toolName === "document_search") {
5175
+ const searchRes = yield new __await(this.documentSearch(toolArgs.query || ""));
5176
+ toolResultText = `document_search returned:
5177
+ ${searchRes.reply}
5178
+
5179
+ Sources count: ${searchRes.sources.length}`;
5180
+ if (searchRes.sources && searchRes.sources.length > 0) {
5181
+ allSources.push(...searchRes.sources);
5182
+ yield { reply: "", sources: searchRes.sources };
5183
+ }
5184
+ } else {
5185
+ const mcpRes = yield new __await(this.mcpRegistry.callTool(toolName, toolArgs));
5186
+ toolResultText = `MCP Tool "${toolName}" returned:
5187
+ ${JSON.stringify(mcpRes.content)}`;
5188
+ }
5189
+ } catch (err) {
5190
+ toolResultText = `Error calling tool "${toolName}": ${err.message}`;
5191
+ }
5192
+ supervisorHistory.push({
5193
+ role: "user",
5194
+ content: `TOOL_RESULT for ${toolName}:
5195
+ ${toolResultText}`
5196
+ });
5197
+ yield {
5198
+ type: "thinking",
5199
+ text: `[Agent Output] Tool "${toolName}" executed. Continuing reasoning...
5200
+ `
5201
+ };
5202
+ } else {
5203
+ break;
5204
+ }
5205
+ }
5206
+ });
4300
5207
  }
4301
5208
  };
4302
5209
 
@@ -4626,7 +5533,7 @@ var QueryProcessor = class {
4626
5533
  * @param validFields Optional list of known filterable fields to look for
4627
5534
  */
4628
5535
  static extractQueryFieldHints(question, validFields = []) {
4629
- var _a, _b, _c, _d;
5536
+ var _a2, _b, _c, _d;
4630
5537
  if (!question.trim()) return [];
4631
5538
  const hints = /* @__PURE__ */ new Map();
4632
5539
  const addHint = (value, field) => {
@@ -4706,7 +5613,7 @@ var QueryProcessor = class {
4706
5613
  ];
4707
5614
  for (const p of universalPatterns) {
4708
5615
  for (const match of question.matchAll(p.regex)) {
4709
- const val = p.group ? (_a = match[p.group]) != null ? _a : match[0] : match[0];
5616
+ const val = p.group ? (_a2 = match[p.group]) != null ? _a2 : match[0] : match[0];
4710
5617
  if (!val) continue;
4711
5618
  if (p.field) addHint(val, p.field);
4712
5619
  else addHint(val);
@@ -4930,11 +5837,11 @@ var LLMRouter = class {
4930
5837
  * When provided it is used directly as the 'default' role without re-constructing.
4931
5838
  */
4932
5839
  async initialize(prebuiltDefault) {
4933
- var _a;
5840
+ var _a2;
4934
5841
  const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
4935
5842
  this.models.set("default", defaultModel);
4936
5843
  const envFastModel = process.env.FAST_LLM_MODEL;
4937
- const providerFastDefault = (_a = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a : "";
5844
+ const providerFastDefault = (_a2 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a2 : "";
4938
5845
  const fastModelName = envFastModel || providerFastDefault;
4939
5846
  if (fastModelName && fastModelName !== this.config.llm.model) {
4940
5847
  console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
@@ -4953,8 +5860,8 @@ var LLMRouter = class {
4953
5860
  * Falls back to 'default' if the requested role is not registered.
4954
5861
  */
4955
5862
  get(role) {
4956
- var _a;
4957
- const provider = (_a = this.models.get(role)) != null ? _a : this.models.get("default");
5863
+ var _a2;
5864
+ const provider = (_a2 = this.models.get(role)) != null ? _a2 : this.models.get("default");
4958
5865
  if (!provider) {
4959
5866
  throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
4960
5867
  }
@@ -4972,7 +5879,7 @@ var UITransformer = class _UITransformer {
4972
5879
  * Prefer `analyzeAndDecide()` in production.
4973
5880
  */
4974
5881
  static transform(userQuery, retrievedData, config, trainedSchema, intent) {
4975
- var _a, _b, _c;
5882
+ var _a2, _b, _c;
4976
5883
  if (!retrievedData || retrievedData.length === 0) {
4977
5884
  return this.createTextResponse("No data available", "No relevant data found for your query.");
4978
5885
  }
@@ -4992,7 +5899,7 @@ var UITransformer = class _UITransformer {
4992
5899
  return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
4993
5900
  }
4994
5901
  if (resolvedIntent.visualizationHint === "distribution") {
4995
- return (_a = this.transformToHistogram(profile, userQuery)) != null ? _a : this.transformToBarChart(filteredData, profile, userQuery);
5902
+ return (_a2 = this.transformToHistogram(profile, userQuery)) != null ? _a2 : this.transformToBarChart(filteredData, profile, userQuery);
4996
5903
  }
4997
5904
  if (resolvedIntent.visualizationHint === "correlation") {
4998
5905
  return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
@@ -5317,11 +6224,11 @@ ${schemaProfileText}` : ""}`;
5317
6224
  };
5318
6225
  }
5319
6226
  static transformToPieChart(data, profile, query = "") {
5320
- var _a;
6227
+ var _a2;
5321
6228
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
5322
6229
  const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
5323
- var _a2;
5324
- return String((_a2 = record.fields[dimension.key]) != null ? _a2 : "");
6230
+ var _a3;
6231
+ return String((_a3 = record.fields[dimension.key]) != null ? _a3 : "");
5325
6232
  }).filter(Boolean))) : this.detectCategories(data);
5326
6233
  if (categories.length === 0) return null;
5327
6234
  const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
@@ -5331,7 +6238,7 @@ ${schemaProfileText}` : ""}`;
5331
6238
  });
5332
6239
  return {
5333
6240
  type: "pie_chart",
5334
- title: `Distribution by ${(_a = dimension == null ? void 0 : dimension.label) != null ? _a : "Category"}`,
6241
+ title: `Distribution by ${(_a2 = dimension == null ? void 0 : dimension.label) != null ? _a2 : "Category"}`,
5335
6242
  description: `Showing breakdown across ${pieData.length} categories`,
5336
6243
  data: pieData
5337
6244
  };
@@ -5341,8 +6248,8 @@ ${schemaProfileText}` : ""}`;
5341
6248
  const valueField = profile.numericFields[0];
5342
6249
  const buckets = /* @__PURE__ */ new Map();
5343
6250
  profile.records.forEach((record) => {
5344
- var _a, _b, _c;
5345
- const timestamp = String((_a = record.fields[dateField.key]) != null ? _a : "");
6251
+ var _a2, _b, _c;
6252
+ const timestamp = String((_a2 = record.fields[dateField.key]) != null ? _a2 : "");
5346
6253
  const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
5347
6254
  buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
5348
6255
  });
@@ -5355,23 +6262,23 @@ ${schemaProfileText}` : ""}`;
5355
6262
  };
5356
6263
  }
5357
6264
  static transformToBarChart(data, profile, query = "", horizontal = false) {
5358
- var _a;
6265
+ var _a2;
5359
6266
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
5360
6267
  const measure = profile ? this.selectNumericField(profile, query) : void 0;
5361
6268
  const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
5362
6269
  const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
5363
6270
  const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
5364
- var _a2, _b, _c, _d, _e;
6271
+ var _a3, _b, _c, _d, _e;
5365
6272
  const meta = item.metadata || {};
5366
6273
  const label = String(
5367
- (_c = (_b = (_a2 = this.getDynamicVal(meta, "name")) != null ? _a2 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
6274
+ (_c = (_b = (_a3 = this.getDynamicVal(meta, "name")) != null ? _a3 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
5368
6275
  );
5369
6276
  const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
5370
6277
  return { category: label, value: Number(value) };
5371
6278
  });
5372
6279
  return {
5373
6280
  type: horizontal ? "horizontal_bar" : "bar_chart",
5374
- title: dimension ? `${(_a = measure == null ? void 0 : measure.label) != null ? _a : "Count"} by ${dimension.label}` : "Comparison",
6281
+ title: dimension ? `${(_a2 = measure == null ? void 0 : measure.label) != null ? _a2 : "Count"} by ${dimension.label}` : "Comparison",
5375
6282
  description: `Showing ${fallbackData.length} comparable values`,
5376
6283
  data: fallbackData
5377
6284
  };
@@ -5406,11 +6313,11 @@ ${schemaProfileText}` : ""}`;
5406
6313
  if (fields.length < 2) return null;
5407
6314
  const [xField, yField] = fields;
5408
6315
  const points = profile.records.map((record) => {
5409
- var _a;
6316
+ var _a2;
5410
6317
  const x = this.toFiniteNumber(record.fields[xField.key]);
5411
6318
  const y = this.toFiniteNumber(record.fields[yField.key]);
5412
6319
  if (x === null || y === null) return null;
5413
- return { x, y, label: String((_a = this.getRecordLabel(record)) != null ? _a : record.id) };
6320
+ return { x, y, label: String((_a2 = this.getRecordLabel(record)) != null ? _a2 : record.id) };
5414
6321
  }).filter((point) => point !== null).slice(0, 100);
5415
6322
  if (points.length === 0) return null;
5416
6323
  return {
@@ -5440,9 +6347,9 @@ ${schemaProfileText}` : ""}`;
5440
6347
  static transformToRadarChart(data) {
5441
6348
  const attributeMap = {};
5442
6349
  data.forEach((item) => {
5443
- var _a, _b, _c;
6350
+ var _a2, _b, _c;
5444
6351
  const meta = item.metadata || {};
5445
- const seriesName = String((_c = (_b = (_a = meta.name) != null ? _a : meta.product) != null ? _b : item.id) != null ? _c : "Item");
6352
+ const seriesName = String((_c = (_b = (_a2 = meta.name) != null ? _a2 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
5446
6353
  Object.entries(meta).forEach(([key, val]) => {
5447
6354
  if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
5448
6355
  if (!attributeMap[key]) attributeMap[key] = {};
@@ -5524,22 +6431,22 @@ ${schemaProfileText}` : ""}`;
5524
6431
  return null;
5525
6432
  }
5526
6433
  static normalizeTransformation(payload) {
5527
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
6434
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
5528
6435
  if (!payload || typeof payload !== "object") return null;
5529
6436
  const p = payload;
5530
6437
  const type = this.normalizeVisualizationType(
5531
- String((_c = (_b = (_a = p.type) != null ? _a : p.view) != null ? _b : p.chartType) != null ? _c : "")
6438
+ String((_c = (_b = (_a2 = p.type) != null ? _a2 : p.view) != null ? _b : p.chartType) != null ? _c : "")
5532
6439
  );
5533
6440
  if (!type) return null;
5534
6441
  const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
5535
6442
  const description = p.description ? String(p.description) : void 0;
5536
- const rawData = (_j = (_i = (_h = (_g = (_f = p.data) != null ? _f : p.table) != null ? _g : p.rows) != null ? _h : p.items) != null ? _i : p.content) != null ? _j : null;
6443
+ const rawData = (_j = (_i = (_h = (_g2 = (_f = p.data) != null ? _f : p.table) != null ? _g2 : p.rows) != null ? _h : p.items) != null ? _i : p.content) != null ? _j : null;
5537
6444
  const data = type === "text" && typeof rawData === "string" ? { content: rawData } : rawData;
5538
6445
  const transformation = { type, title, description, data };
5539
6446
  return this.validateTransformation(transformation) ? transformation : null;
5540
6447
  }
5541
6448
  static normalizeVisualizationType(type) {
5542
- var _a;
6449
+ var _a2;
5543
6450
  const mapping = {
5544
6451
  pie: "pie_chart",
5545
6452
  pie_chart: "pie_chart",
@@ -5567,7 +6474,7 @@ ${schemaProfileText}` : ""}`;
5567
6474
  product_carousel: "product_carousel",
5568
6475
  carousel: "carousel"
5569
6476
  };
5570
- return (_a = mapping[type.toLowerCase()]) != null ? _a : null;
6477
+ return (_a2 = mapping[type.toLowerCase()]) != null ? _a2 : null;
5571
6478
  }
5572
6479
  static validateTransformation(t) {
5573
6480
  const { type, data } = t;
@@ -5769,16 +6676,16 @@ ${schemaProfileText}` : ""}`;
5769
6676
  return null;
5770
6677
  }
5771
6678
  static selectDimensionField(profile, query) {
5772
- var _a, _b;
6679
+ var _a2, _b;
5773
6680
  const productCategory = profile.categoricalFields.find(
5774
6681
  (field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
5775
6682
  );
5776
6683
  const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
5777
- return (_b = (_a = ranked[0]) != null ? _a : productCategory) != null ? _b : profile.categoricalFields[0];
6684
+ return (_b = (_a2 = ranked[0]) != null ? _a2 : productCategory) != null ? _b : profile.categoricalFields[0];
5778
6685
  }
5779
6686
  static selectNumericField(profile, query) {
5780
- var _a;
5781
- return (_a = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a : profile.numericFields[0];
6687
+ var _a2;
6688
+ return (_a2 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a2 : profile.numericFields[0];
5782
6689
  }
5783
6690
  static rankFieldsByQuery(fields, query) {
5784
6691
  const q = query.toLowerCase();
@@ -5807,8 +6714,8 @@ ${schemaProfileText}` : ""}`;
5807
6714
  static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
5808
6715
  const result = {};
5809
6716
  profile.records.forEach((record) => {
5810
- var _a, _b, _c;
5811
- const category = String((_a = record.fields[dimensionKey]) != null ? _a : "Other").trim() || "Other";
6717
+ var _a2, _b, _c;
6718
+ const category = String((_a2 = record.fields[dimensionKey]) != null ? _a2 : "Other").trim() || "Other";
5812
6719
  const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
5813
6720
  result[category] = ((_c = result[category]) != null ? _c : 0) + value;
5814
6721
  });
@@ -5887,8 +6794,8 @@ ${schemaProfileText}` : ""}`;
5887
6794
  static aggregateByCategory(data, categories) {
5888
6795
  const result = Object.fromEntries(categories.map((c) => [c, 0]));
5889
6796
  data.forEach((item) => {
5890
- var _a;
5891
- const cat = (_a = this.getProductCategory(item)) != null ? _a : "Other";
6797
+ var _a2;
6798
+ const cat = (_a2 = this.getProductCategory(item)) != null ? _a2 : "Other";
5892
6799
  if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
5893
6800
  else result["Other"] = (result["Other"] || 0) + 1;
5894
6801
  });
@@ -5896,17 +6803,17 @@ ${schemaProfileText}` : ""}`;
5896
6803
  }
5897
6804
  static extractTimeSeriesData(data) {
5898
6805
  return data.map((item) => {
5899
- var _a, _b, _c, _d, _e;
6806
+ var _a2, _b, _c, _d, _e;
5900
6807
  const meta = item.metadata || {};
5901
6808
  return {
5902
- timestamp: (_b = (_a = meta.timestamp) != null ? _a : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
6809
+ timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
5903
6810
  value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
5904
6811
  label: (_e = meta.label) != null ? _e : item.content.substring(0, 50)
5905
6812
  };
5906
6813
  });
5907
6814
  }
5908
6815
  static extractNumericValue(meta) {
5909
- var _a;
6816
+ var _a2;
5910
6817
  const preferredKeys = [
5911
6818
  "value",
5912
6819
  "count",
@@ -5921,7 +6828,7 @@ ${schemaProfileText}` : ""}`;
5921
6828
  "price"
5922
6829
  ];
5923
6830
  for (const key of preferredKeys) {
5924
- const raw = (_a = resolveMetadataValue(meta, key)) != null ? _a : meta[key];
6831
+ const raw = (_a2 = resolveMetadataValue(meta, key)) != null ? _a2 : meta[key];
5925
6832
  const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
5926
6833
  if (Number.isFinite(value)) return value;
5927
6834
  }
@@ -6067,8 +6974,8 @@ ${schemaProfileText}` : ""}`;
6067
6974
  let inStock = 0;
6068
6975
  let outOfStock = 0;
6069
6976
  data.forEach((d) => {
6070
- var _a, _b;
6071
- const cat = (_a = this.getProductCategory(d)) != null ? _a : "Other";
6977
+ var _a2, _b;
6978
+ const cat = (_a2 = this.getProductCategory(d)) != null ? _a2 : "Other";
6072
6979
  if (cat === category) {
6073
6980
  const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
6074
6981
  if (this.determineStockStatus(d)) inStock += quantity;
@@ -6112,9 +7019,9 @@ ${schemaProfileText}` : ""}`;
6112
7019
  }
6113
7020
  // ─── Product Extraction ───────────────────────────────────────────────────
6114
7021
  static getDynamicVal(meta, uiKey, config, trainedSchema) {
6115
- var _a;
7022
+ var _a2;
6116
7023
  if (!meta) return void 0;
6117
- const mapping = (_a = config == null ? void 0 : config.rag) == null ? void 0 : _a.uiMapping;
7024
+ const mapping = (_a2 = config == null ? void 0 : config.rag) == null ? void 0 : _a2.uiMapping;
6118
7025
  if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
6119
7026
  if (trainedSchema && typeof trainedSchema === "object") {
6120
7027
  const trainedKey = trainedSchema[uiKey];
@@ -6123,13 +7030,13 @@ ${schemaProfileText}` : ""}`;
6123
7030
  return resolveMetadataValue(meta, uiKey);
6124
7031
  }
6125
7032
  static extractProductInfo(item, config, trainedSchema) {
6126
- var _a;
7033
+ var _a2;
6127
7034
  const meta = item.metadata || {};
6128
7035
  const name = this.getDynamicVal(meta, "name", config, trainedSchema);
6129
7036
  const price = this.getDynamicVal(meta, "price", config, trainedSchema);
6130
7037
  const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
6131
7038
  const description = this.cleanProductDescription(
6132
- (_a = this.extractProductDescriptionFromContent(item.content)) != null ? _a : this.getProductDescriptionValue(meta, config, trainedSchema)
7039
+ (_a2 = this.extractProductDescriptionFromContent(item.content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
6133
7040
  );
6134
7041
  if (name || this.isProductData(item)) {
6135
7042
  let finalName = name ? String(name) : void 0;
@@ -6237,10 +7144,10 @@ RULES:
6237
7144
  }
6238
7145
  static buildContextSummary(sources, maxChars = 6e3) {
6239
7146
  const items = sources.map((s, i) => {
6240
- var _a, _b, _c, _d;
7147
+ var _a2, _b, _c, _d;
6241
7148
  return {
6242
7149
  index: i + 1,
6243
- content: (_b = (_a = s.content) == null ? void 0 : _a.substring(0, 400)) != null ? _b : "",
7150
+ content: (_b = (_a2 = s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
6244
7151
  metadata: (_c = s.metadata) != null ? _c : {},
6245
7152
  score: (_d = s.score) != null ? _d : 0
6246
7153
  };
@@ -6433,9 +7340,11 @@ var Pipeline = class {
6433
7340
  /** LRU-bounded cache: avoids re-embedding identical queries within the same process. */
6434
7341
  this.embeddingCache = new LRUEmbeddingCache(500);
6435
7342
  this.initialised = false;
6436
- var _a, _b, _c, _d, _e;
7343
+ /** Namespace-specific static cold context cache for CAG */
7344
+ this.coldContexts = /* @__PURE__ */ new Map();
7345
+ var _a2, _b, _c, _d, _e;
6437
7346
  this.chunker = new DocumentChunker(
6438
- (_b = (_a = config.rag) == null ? void 0 : _a.chunkSize) != null ? _b : 1e3,
7347
+ (_b = (_a2 = config.rag) == null ? void 0 : _a2.chunkSize) != null ? _b : 1e3,
6439
7348
  (_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
6440
7349
  );
6441
7350
  if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
@@ -6451,7 +7360,7 @@ var Pipeline = class {
6451
7360
  return this.initialised ? this.llmProvider : void 0;
6452
7361
  }
6453
7362
  async initialize() {
6454
- var _a;
7363
+ var _a2, _b, _c;
6455
7364
  if (this.initialised) return;
6456
7365
  const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
6457
7366
 
@@ -6494,12 +7403,47 @@ var Pipeline = class {
6494
7403
  this.entityExtractor = new EntityExtractor(this.llmProvider);
6495
7404
  }
6496
7405
  await this.vectorDB.initialize();
6497
- if (((_a = this.config.rag) == null ? void 0 : _a.architecture) === "agentic") {
7406
+ if (((_a2 = this.config.rag) == null ? void 0 : _a2.architecture) === "agentic" || this.config.mcpServers && this.config.mcpServers.length > 0) {
7407
+ this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
7408
+ this.multiAgentCoordinator = new MultiAgentCoordinator({
7409
+ llmProvider: this.llmProvider,
7410
+ mcpRegistry: this.mcpRegistry,
7411
+ documentSearch: async (query) => {
7412
+ return this.runNormalQuery(query);
7413
+ }
7414
+ });
6498
7415
  this.agent = new LangChainAgent(this, this.config);
6499
7416
  await this.agent.initialize(this.llmProvider);
6500
7417
  }
7418
+ if ((_c = (_b = this.config.rag) == null ? void 0 : _b.cag) == null ? void 0 : _c.enabled) {
7419
+ await this.loadColdContext(this.config.projectId);
7420
+ }
6501
7421
  this.initialised = true;
6502
7422
  }
7423
+ async loadColdContext(ns) {
7424
+ var _a2, _b;
7425
+ const cagConfig = (_a2 = this.config.rag) == null ? void 0 : _a2.cag;
7426
+ if (!cagConfig || !cagConfig.enabled) return;
7427
+ try {
7428
+ const coldNs = cagConfig.coldNamespace || ns;
7429
+ const limit = (_b = cagConfig.coldLimit) != null ? _b : 20;
7430
+ const queryText = cagConfig.coldQuery || "documentation";
7431
+ const queryVector = await this.embeddingProvider.embed(queryText, { taskType: "query" });
7432
+ const coldMatches = await this.vectorDB.query(queryVector, limit, coldNs);
7433
+ if (coldMatches.length > 0) {
7434
+ const formatted = coldMatches.map((m, i) => `[Cold Source ${i + 1}]
7435
+ ${m.content}`).join("\n\n---\n\n");
7436
+ this.coldContexts.set(ns, formatted);
7437
+ console.log(`[Pipeline] Cold RAG (CAG) loaded ${coldMatches.length} documents into cached context for namespace: ${ns}`);
7438
+ } else {
7439
+ this.coldContexts.set(ns, "No cold context found.");
7440
+ console.warn(`[Pipeline] Cold RAG (CAG) initialized but no documents were found in namespace: ${coldNs}`);
7441
+ }
7442
+ } catch (err) {
7443
+ console.error(`[Pipeline] Failed to load Cold RAG (CAG) context for namespace ${ns}:`, err);
7444
+ this.coldContexts.set(ns, "Failed to load cold context.");
7445
+ }
7446
+ }
6503
7447
  /**
6504
7448
  * Ingest documents with automatic chunking, embedding, and batch upsert.
6505
7449
  */
@@ -6531,12 +7475,12 @@ var Pipeline = class {
6531
7475
  }
6532
7476
  /** Step 1: Chunk the document content. */
6533
7477
  async prepareChunks(doc) {
6534
- var _a, _b;
7478
+ var _a2, _b;
6535
7479
  if (this.llamaIngestor) {
6536
7480
  return this.llamaIngestor.chunk(doc.content, {
6537
7481
  docId: doc.docId,
6538
7482
  metadata: doc.metadata,
6539
- chunkSize: (_a = this.config.rag) == null ? void 0 : _a.chunkSize,
7483
+ chunkSize: (_a2 = this.config.rag) == null ? void 0 : _a2.chunkSize,
6540
7484
  chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
6541
7485
  });
6542
7486
  }
@@ -6607,12 +7551,37 @@ var Pipeline = class {
6607
7551
  extractionOptions
6608
7552
  );
6609
7553
  }
7554
+ async runNormalQuery(question, history = [], namespace) {
7555
+ const stream = this.askStreamInternal(question, history, namespace);
7556
+ let reply = "";
7557
+ let sources = [];
7558
+ try {
7559
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
7560
+ const chunk = temp.value;
7561
+ if (typeof chunk === "string") {
7562
+ reply += chunk;
7563
+ } else if (typeof chunk === "object" && chunk !== null) {
7564
+ if ("reply" in chunk && chunk.reply) reply += chunk.reply;
7565
+ if ("sources" in chunk && chunk.sources) sources = chunk.sources;
7566
+ }
7567
+ }
7568
+ } catch (temp) {
7569
+ error = [temp];
7570
+ } finally {
7571
+ try {
7572
+ more && (temp = iter.return) && await temp.call(iter);
7573
+ } finally {
7574
+ if (error)
7575
+ throw error[0];
7576
+ }
7577
+ }
7578
+ return { reply, sources };
7579
+ }
6610
7580
  async ask(question, history = [], namespace) {
6611
- var _a;
7581
+ var _a2;
6612
7582
  await this.initialize();
6613
- if (((_a = this.config.rag) == null ? void 0 : _a.architecture) === "agentic" && this.agent) {
6614
- const agentReply = await this.agent.run(question, history);
6615
- return { reply: agentReply, sources: [] };
7583
+ if ((((_a2 = this.config.rag) == null ? void 0 : _a2.architecture) === "agentic" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
7584
+ return await this.multiAgentCoordinator.run(question, history);
6616
7585
  }
6617
7586
  const stream = this.askStream(question, history, namespace);
6618
7587
  let reply = "";
@@ -6644,6 +7613,47 @@ var Pipeline = class {
6644
7613
  }
6645
7614
  return { reply, sources, graphData, ui_transformation: uiTransformation, trace };
6646
7615
  }
7616
+ askStream(_0) {
7617
+ return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
7618
+ var _a2;
7619
+ yield new __await(this.initialize());
7620
+ if ((((_a2 = this.config.rag) == null ? void 0 : _a2.architecture) === "agentic" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
7621
+ const stream2 = this.multiAgentCoordinator.runStream(question, history);
7622
+ try {
7623
+ for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
7624
+ const chunk = temp.value;
7625
+ yield chunk;
7626
+ }
7627
+ } catch (temp) {
7628
+ error = [temp];
7629
+ } finally {
7630
+ try {
7631
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
7632
+ } finally {
7633
+ if (error)
7634
+ throw error[0];
7635
+ }
7636
+ }
7637
+ return;
7638
+ }
7639
+ const stream = this.askStreamInternal(question, history, namespace);
7640
+ try {
7641
+ for (var iter2 = __forAwait(stream), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
7642
+ const chunk = temp2.value;
7643
+ yield chunk;
7644
+ }
7645
+ } catch (temp2) {
7646
+ error2 = [temp2];
7647
+ } finally {
7648
+ try {
7649
+ more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));
7650
+ } finally {
7651
+ if (error2)
7652
+ throw error2[0];
7653
+ }
7654
+ }
7655
+ });
7656
+ }
6647
7657
  /**
6648
7658
  * High-performance streaming RAG flow.
6649
7659
  * Yields text chunks first, then the retrieval metadata + observability trace at the end.
@@ -6654,12 +7664,12 @@ var Pipeline = class {
6654
7664
  * - UITransformation is computed after text streaming and emitted with metadata
6655
7665
  * - SchemaMapper.train runs while answer generation streams
6656
7666
  */
6657
- askStream(_0) {
7667
+ askStreamInternal(_0) {
6658
7668
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
6659
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
7669
+ 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;
6660
7670
  yield new __await(this.initialize());
6661
7671
  const ns = namespace != null ? namespace : this.config.projectId;
6662
- const topK = (_b = (_a = this.config.rag) == null ? void 0 : _a.topK) != null ? _b : 5;
7672
+ const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
6663
7673
  const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
6664
7674
  const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
6665
7675
  const requestStart = performance.now();
@@ -6672,7 +7682,7 @@ var Pipeline = class {
6672
7682
  }
6673
7683
  const hints = QueryProcessor.extractQueryFieldHints(question, (_f = this.config.rag) == null ? void 0 : _f.filterableFields);
6674
7684
  const filter = QueryProcessor.buildQueryFilter(question, hints);
6675
- const numericPredicates = QueryProcessor.extractNumericPredicates(question, (_g = this.config.rag) == null ? void 0 : _g.filterableFields);
7685
+ const numericPredicates = QueryProcessor.extractNumericPredicates(question, (_g2 = this.config.rag) == null ? void 0 : _g2.filterableFields);
6676
7686
  if (numericPredicates.length > 0) {
6677
7687
  filter.__numericPredicates = numericPredicates;
6678
7688
  }
@@ -6738,6 +7748,32 @@ ${graphContext}
6738
7748
  VECTOR CONTEXT:
6739
7749
  ${context}`;
6740
7750
  }
7751
+ if ((_n = (_m = this.config.rag) == null ? void 0 : _m.cag) == null ? void 0 : _n.enabled) {
7752
+ if (!this.coldContexts.has(ns)) {
7753
+ yield new __await(this.loadColdContext(ns));
7754
+ }
7755
+ const coldContext = this.coldContexts.get(ns);
7756
+ if (coldContext && coldContext !== "No cold context found." && coldContext !== "Failed to load cold context.") {
7757
+ context = `COLD CONTEXT (STATIC KNOWLEDGE):
7758
+ ${coldContext}
7759
+
7760
+ RETRIEVED HOT CONTEXT (REAL-TIME KNOWLEDGE):
7761
+ ${context}`;
7762
+ }
7763
+ }
7764
+ yield {
7765
+ reply: "",
7766
+ sources: sources.map((s) => {
7767
+ var _a3;
7768
+ return {
7769
+ id: s.id,
7770
+ score: s.score,
7771
+ content: s.content,
7772
+ metadata: (_a3 = s.metadata) != null ? _a3 : {},
7773
+ namespace: ns
7774
+ };
7775
+ })
7776
+ };
6741
7777
  const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
6742
7778
  const cachedSchema = allMetadataKeys.length > 0 ? SchemaMapper.getCached(ns, allMetadataKeys) : void 0;
6743
7779
  if (allMetadataKeys.length > 0 && !cachedSchema) {
@@ -6765,10 +7801,10 @@ ${context}`;
6765
7801
  let hallucinationScoringPromise = Promise.resolve(void 0);
6766
7802
  const restrictionSuffix = "\n\n(IMPORTANT: Format your response beautifully using rich Markdown! Use bolding for emphasis, headings (##) for structure, bullet points for lists, and proper line breaks between paragraphs to make it highly readable. However, NEVER generate Markdown tables, HTML figures, or text charts (the UI renders requested charts separately, so NEVER say you cannot create, display, draw, render, or provide a chart/visualization). If listing products, use simple markdown bullet points or comma-separated names. NEVER use plus signs (+) to separate product names, category names, or list items. For product description/detail questions, provide customer-facing prose only and do NOT list internal catalog fields such as Handle, Body (HTML), Vendor, Type, Tags, Published, Option, Variant, SKU, or raw metadata labels. You CAN use numbers for years/counts like 2006 or 5800, but NEVER put a dollar sign ($) before them.)";
6767
7803
  const isClaude37 = this.config.llm.model.includes("claude-3-7-sonnet");
6768
- const isNativeThinking = isClaude37 && (((_m = this.config.llm.options) == null ? void 0 : _m.thinking) === true || ((_n = this.config.llm.options) == null ? void 0 : _n.thinking) === "enabled" || ((_o = this.config.llm.options) == null ? void 0 : _o.thinking) !== false);
7804
+ const isNativeThinking = isClaude37 && (((_o = this.config.llm.options) == null ? void 0 : _o.thinking) === true || ((_p = this.config.llm.options) == null ? void 0 : _p.thinking) === "enabled" || ((_q = this.config.llm.options) == null ? void 0 : _q.thinking) !== false);
6769
7805
  const modelNameLower = this.config.llm.model.toLowerCase();
6770
7806
  const isReasoningModel = modelNameLower.includes("-r1") || modelNameLower.includes("deepseek-r1") || modelNameLower.includes("reasoning") || modelNameLower.includes("thinking");
6771
- const isSimulatedThinking = !isNativeThinking && (((_p = this.config.llm.options) == null ? void 0 : _p.thinking) === true || ((_q = this.config.llm.options) == null ? void 0 : _q.thinking) === "enabled" || isReasoningModel && ((_r = this.config.llm.options) == null ? void 0 : _r.thinking) !== false);
7807
+ const isSimulatedThinking = !isNativeThinking && (((_r = this.config.llm.options) == null ? void 0 : _r.thinking) === true || ((_s = this.config.llm.options) == null ? void 0 : _s.thinking) === "enabled" || isReasoningModel && ((_t = this.config.llm.options) == null ? void 0 : _t.thinking) !== false);
6772
7808
  let finalRestrictionSuffix = restrictionSuffix;
6773
7809
  if (isSimulatedThinking) {
6774
7810
  finalRestrictionSuffix += "\n\n(IMPORTANT: You must think step-by-step before answering. Write your thinking process inside a `<think>...</think>` block. Write the `<think>` block first, then follow it with your final response. Keep the thinking process thorough and detailed. Example: `<think>Thinking details here...</think>Final answer text here.`)";
@@ -6776,7 +7812,7 @@ ${context}`;
6776
7812
  const hardenedHistory = [...history];
6777
7813
  const userQuestion = { role: "user", content: question + finalRestrictionSuffix };
6778
7814
  const messages = [...hardenedHistory, userQuestion];
6779
- const systemPrompt = (_s = this.config.llm.systemPrompt) != null ? _s : "";
7815
+ const systemPrompt = (_u = this.config.llm.systemPrompt) != null ? _u : "";
6780
7816
  const userPrompt = messages.map((m) => `${m.role}: ${m.content}`).join("\n");
6781
7817
  let fullReply = "";
6782
7818
  let thinkingText = "";
@@ -6887,7 +7923,7 @@ ${context}`;
6887
7923
  }
6888
7924
  yield fullReply;
6889
7925
  }
6890
- const runHallucination = ((_t = this.config.llm.options) == null ? void 0 : _t.hallucinationScoring) === true || this.config.llm.provider !== "ollama" && ((_u = this.config.llm.options) == null ? void 0 : _u.hallucinationScoring) !== false;
7926
+ const runHallucination = ((_v = this.config.llm.options) == null ? void 0 : _v.hallucinationScoring) === true || this.config.llm.provider !== "ollama" && ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) !== false;
6891
7927
  if (runHallucination) {
6892
7928
  hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
6893
7929
  }
@@ -6896,7 +7932,7 @@ ${context}`;
6896
7932
  const latency = {
6897
7933
  embedMs: Math.round(embedMs),
6898
7934
  retrieveMs: Math.round(retrieveMs),
6899
- rerankMs: ((_v = this.config.rag) == null ? void 0 : _v.useReranking) ? Math.round(rerankMs) : void 0,
7935
+ rerankMs: ((_x = this.config.rag) == null ? void 0 : _x.useReranking) ? Math.round(rerankMs) : void 0,
6900
7936
  generateMs: Math.round(generateMs),
6901
7937
  totalMs: Math.round(totalMs)
6902
7938
  };
@@ -6909,33 +7945,63 @@ ${context}`;
6909
7945
  totalTokens: promptTokens + completionTokens,
6910
7946
  estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
6911
7947
  };
7948
+ const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
6912
7949
  const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
6913
7950
  uiTransformationPromise,
6914
- hallucinationScoringPromise
7951
+ awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
6915
7952
  ]));
6916
- const trace = __spreadValues({
7953
+ const buildTrace = (hScore) => __spreadValues({
6917
7954
  requestId,
6918
7955
  query: question,
6919
7956
  rewrittenQuery,
6920
7957
  systemPrompt,
6921
7958
  userPrompt: question + finalRestrictionSuffix,
6922
7959
  chunks: sources.map((s) => {
6923
- var _a2;
7960
+ var _a3;
6924
7961
  return {
6925
7962
  id: s.id,
6926
7963
  score: s.score,
6927
7964
  content: s.content,
6928
- metadata: (_a2 = s.metadata) != null ? _a2 : {},
7965
+ metadata: (_a3 = s.metadata) != null ? _a3 : {},
6929
7966
  namespace: ns
6930
7967
  };
6931
7968
  }),
6932
7969
  latency,
6933
7970
  tokens,
6934
7971
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
6935
- }, hallucinationResult ? {
6936
- hallucinationScore: hallucinationResult.score,
6937
- hallucinationReason: hallucinationResult.reason
7972
+ }, hScore ? {
7973
+ hallucinationScore: hScore.score,
7974
+ hallucinationReason: hScore.reason
6938
7975
  } : {});
7976
+ const trace = buildTrace(hallucinationResult);
7977
+ if ((_z = this.config.telemetry) == null ? void 0 : _z.enabled) {
7978
+ const telemetryUrl = this.config.telemetry.url || "/api/telemetry";
7979
+ const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
7980
+ (async () => {
7981
+ try {
7982
+ let finalTrace = trace;
7983
+ if (!awaitHallucination && runHallucination) {
7984
+ const backgroundScoreResult = await hallucinationScoringPromise;
7985
+ if (backgroundScoreResult) {
7986
+ finalTrace = buildTrace(backgroundScoreResult);
7987
+ }
7988
+ }
7989
+ await fetch(absoluteUrl, {
7990
+ method: "POST",
7991
+ headers: {
7992
+ "Content-Type": "application/json"
7993
+ },
7994
+ body: JSON.stringify({
7995
+ trace: finalTrace,
7996
+ licenseKey: this.config.licenseKey,
7997
+ projectId: ns
7998
+ })
7999
+ });
8000
+ } catch (err) {
8001
+ console.warn(`[Pipeline Telemetry] Failed to send trace async to ${absoluteUrl}:`, err.message);
8002
+ }
8003
+ })();
8004
+ }
6939
8005
  yield {
6940
8006
  reply: "",
6941
8007
  sources,
@@ -6955,7 +8021,7 @@ ${context}`;
6955
8021
  * Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
6956
8022
  */
6957
8023
  async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
6958
- var _a;
8024
+ var _a2;
6959
8025
  if (!sources || sources.length === 0) {
6960
8026
  return UITransformer.transform(question, sources, this.config, cachedSchema);
6961
8027
  }
@@ -6969,7 +8035,7 @@ ${context}`;
6969
8035
  );
6970
8036
  }
6971
8037
  const isLocalProvider = this.config.llm.provider === "ollama";
6972
- const disableLlmUiTransform = ((_a = this.config.llm.options) == null ? void 0 : _a.disableLlmUiTransform) === true;
8038
+ const disableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.disableLlmUiTransform) === true;
6973
8039
  if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
6974
8040
  return UITransformer.transform(question, sources, this.config, cachedSchema);
6975
8041
  }
@@ -6987,9 +8053,9 @@ ${context}`;
6987
8053
  const value = this.resolveNumericPredicateValue(source, predicate);
6988
8054
  return value !== null && this.matchesNumericPredicate(value, predicate);
6989
8055
  })).sort((a, b) => {
6990
- var _a, _b;
8056
+ var _a2, _b;
6991
8057
  const primary = predicates[0];
6992
- const aValue = (_a = this.resolveNumericPredicateValue(a, primary)) != null ? _a : 0;
8058
+ const aValue = (_a2 = this.resolveNumericPredicateValue(a, primary)) != null ? _a2 : 0;
6993
8059
  const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
6994
8060
  return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
6995
8061
  });
@@ -7061,8 +8127,8 @@ ${context}`;
7061
8127
  return Number.isFinite(numeric) ? numeric : null;
7062
8128
  }
7063
8129
  async retrieve(query, options) {
7064
- var _a, _b, _c, _d, _e, _f, _g;
7065
- const ns = (_a = options.namespace) != null ? _a : this.config.projectId;
8130
+ var _a2, _b, _c, _d, _e, _f, _g2;
8131
+ const ns = (_a2 = options.namespace) != null ? _a2 : this.config.projectId;
7066
8132
  const topK = (_b = options.topK) != null ? _b : 5;
7067
8133
  const cacheKey = `${ns}::${query}`;
7068
8134
  let queryVector = this.embeddingCache.get(cacheKey);
@@ -7094,7 +8160,7 @@ ${context}`;
7094
8160
  ) : [];
7095
8161
  const resolvedSources = [];
7096
8162
  for (const source of sources) {
7097
- const parentId = (_g = source.metadata) == null ? void 0 : _g.parent_id;
8163
+ const parentId = (_g2 = source.metadata) == null ? void 0 : _g2.parent_id;
7098
8164
  if (parentId) {
7099
8165
  console.log(`[Pipeline] Multi-Vector: Found child chunk. Parent ID: ${parentId}`);
7100
8166
  resolvedSources.push(source);
@@ -7176,8 +8242,14 @@ var Retrivora = class {
7176
8242
  this.pipeline = new Pipeline(this.config);
7177
8243
  }
7178
8244
  async initialize() {
8245
+ var _a2;
7179
8246
  try {
7180
8247
  await ConfigValidator.validateAndThrow(this.config);
8248
+ LicenseVerifier.verify(
8249
+ this.config.licenseKey,
8250
+ this.config.projectId,
8251
+ (_a2 = this.config.vectorDb) == null ? void 0 : _a2.provider
8252
+ );
7181
8253
  } catch (err) {
7182
8254
  throw wrapError(err, "CONFIGURATION_ERROR");
7183
8255
  }
@@ -7351,11 +8423,20 @@ var ProviderHealthCheck = class {
7351
8423
  // src/core/VectorPlugin.ts
7352
8424
  var VectorPlugin = class {
7353
8425
  constructor(hostConfig) {
7354
- this.config = ConfigResolver.resolve(hostConfig);
7355
- this.validationPromise = ConfigValidator.validateAndThrow(this.config);
8426
+ const resolvedConfig = ConfigResolver.resolve(hostConfig);
8427
+ this.config = resolvedConfig;
8428
+ this.validationPromise = (async () => {
8429
+ var _a2;
8430
+ await ConfigValidator.validateAndThrow(resolvedConfig);
8431
+ LicenseVerifier.verify(
8432
+ resolvedConfig.licenseKey,
8433
+ resolvedConfig.projectId,
8434
+ (_a2 = resolvedConfig.vectorDb) == null ? void 0 : _a2.provider
8435
+ );
8436
+ })();
7356
8437
  this.validationPromise.catch(() => {
7357
8438
  });
7358
- this.pipeline = new Pipeline(this.config);
8439
+ this.pipeline = new Pipeline(resolvedConfig);
7359
8440
  }
7360
8441
  /**
7361
8442
  * Get the current resolved configuration.
@@ -7491,13 +8572,13 @@ var ConfigBuilder = class {
7491
8572
  * Configure the vector database provider
7492
8573
  */
7493
8574
  vectorDb(provider, options) {
7494
- var _a;
8575
+ var _a2;
7495
8576
  if (provider === "auto") {
7496
8577
  this._vectorDb = this._autoDetectVectorDb();
7497
8578
  } else {
7498
8579
  this._vectorDb = {
7499
8580
  provider,
7500
- indexName: (_a = options == null ? void 0 : options.indexName) != null ? _a : "default",
8581
+ indexName: (_a2 = options == null ? void 0 : options.indexName) != null ? _a2 : "default",
7501
8582
  options: __spreadValues({}, options)
7502
8583
  };
7503
8584
  }
@@ -7507,7 +8588,7 @@ var ConfigBuilder = class {
7507
8588
  * Configure the LLM provider for chat
7508
8589
  */
7509
8590
  llm(provider, model, apiKey, options) {
7510
- var _a, _b;
8591
+ var _a2, _b;
7511
8592
  if (provider === "auto") {
7512
8593
  this._llm = this._autoDetectLLM();
7513
8594
  } else {
@@ -7516,7 +8597,7 @@ var ConfigBuilder = class {
7516
8597
  model: model != null ? model : "default-model",
7517
8598
  apiKey,
7518
8599
  systemPrompt: options == null ? void 0 : options.systemPrompt,
7519
- maxTokens: (_a = options == null ? void 0 : options.maxTokens) != null ? _a : 1024,
8600
+ maxTokens: (_a2 = options == null ? void 0 : options.maxTokens) != null ? _a2 : 1024,
7520
8601
  temperature: (_b = options == null ? void 0 : options.temperature) != null ? _b : 0.7,
7521
8602
  baseUrl: options == null ? void 0 : options.baseUrl,
7522
8603
  options
@@ -7559,8 +8640,8 @@ var ConfigBuilder = class {
7559
8640
  * Set RAG-specific pipeline parameters
7560
8641
  */
7561
8642
  rag(options) {
7562
- var _a;
7563
- this._rag = __spreadValues(__spreadValues({}, (_a = this._rag) != null ? _a : {}), options);
8643
+ var _a2;
8644
+ this._rag = __spreadValues(__spreadValues({}, (_a2 = this._rag) != null ? _a2 : {}), options);
7564
8645
  return this;
7565
8646
  }
7566
8647
  /**
@@ -7576,7 +8657,7 @@ var ConfigBuilder = class {
7576
8657
  * Throws if required fields (projectId, vectorDb, llm, embedding) are not set.
7577
8658
  */
7578
8659
  build() {
7579
- var _a;
8660
+ var _a2;
7580
8661
  const missing = [];
7581
8662
  if (!this._projectId) missing.push('projectId (call .projectId("my-app"))');
7582
8663
  if (!this._vectorDb) missing.push('vectorDb (call .vectorDb("pinecone", { ... }))');
@@ -7588,7 +8669,7 @@ var ConfigBuilder = class {
7588
8669
  ${missing.join("\n ")}`
7589
8670
  );
7590
8671
  }
7591
- const ragConfig = (_a = this._rag) != null ? _a : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
8672
+ const ragConfig = (_a2 = this._rag) != null ? _a2 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
7592
8673
  if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
7593
8674
  ragConfig.useGraphRetrieval = true;
7594
8675
  }
@@ -7684,8 +8765,8 @@ var DocumentParser = class {
7684
8765
  * Extract text from a File or Buffer based on its type.
7685
8766
  */
7686
8767
  static async parse(file, fileName, mimeType) {
7687
- var _a;
7688
- const extension = (_a = fileName.split(".").pop()) == null ? void 0 : _a.toLowerCase();
8768
+ var _a2;
8769
+ const extension = (_a2 = fileName.split(".").pop()) == null ? void 0 : _a2.toLowerCase();
7689
8770
  if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
7690
8771
  return this.readAsText(file);
7691
8772
  }
@@ -7752,6 +8833,497 @@ init_UniversalVectorProvider();
7752
8833
 
7753
8834
  // src/handlers/index.ts
7754
8835
  var import_server = require("next/server");
8836
+
8837
+ // src/core/DatabaseStorage.ts
8838
+ var fs = __toESM(require("fs"));
8839
+ var path = __toESM(require("path"));
8840
+ var DatabaseStorage = class {
8841
+ constructor(config) {
8842
+ // Dynamic PG Pool
8843
+ this.pgPool = null;
8844
+ // Dynamic MongoDB Client
8845
+ this.mongoClient = null;
8846
+ this.mongoDbName = "";
8847
+ // Filesystem fallback configuration
8848
+ this.fallbackDir = path.join(process.cwd(), ".retrivora");
8849
+ this.historyFile = path.join(this.fallbackDir, "history.json");
8850
+ this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
8851
+ var _a2, _b, _c, _d, _e;
8852
+ this.config = config;
8853
+ this.provider = ((_a2 = config.vectorDb) == null ? void 0 : _a2.provider) || "fs";
8854
+ const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
8855
+ const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
8856
+ this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
8857
+ this.feedbackTableName = rawFeedbackTable.replace(/[^a-zA-Z0-9_]/g, "_");
8858
+ }
8859
+ /**
8860
+ * Asserts the user is running a valid Premium/Enterprise license in production.
8861
+ * In non-production (development / test) environments this is a complete no-op —
8862
+ * all History and Feedback features are freely accessible for local development.
8863
+ */
8864
+ checkPremiumSubscription() {
8865
+ if (process.env.NODE_ENV !== "production") {
8866
+ return;
8867
+ }
8868
+ if (!this.config.licenseKey) {
8869
+ throw new Error(
8870
+ "[Retrivora SDK] Chat History and Feedback features require a Premium or Enterprise license key in production."
8871
+ );
8872
+ }
8873
+ try {
8874
+ const payload = LicenseVerifier.verify(this.config.licenseKey, this.config.projectId);
8875
+ const tier = (payload.tier || "").toLowerCase();
8876
+ if (tier !== "premium" && tier !== "enterprise" && tier !== "growth" && tier !== "pro" && tier !== "developer_pro") {
8877
+ throw new Error(
8878
+ `[Retrivora SDK] Chat History and Feedback features are not available on the "${tier}" tier. Please upgrade to a Developer Pro or Enterprise plan.`
8879
+ );
8880
+ }
8881
+ } catch (err) {
8882
+ throw new Error(
8883
+ `[Retrivora SDK] Subscription check failed: ${err instanceof Error ? err.message : String(err)}`
8884
+ );
8885
+ }
8886
+ }
8887
+ checkHistoryEnabled() {
8888
+ var _a2, _b;
8889
+ this.checkPremiumSubscription();
8890
+ if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.history) == null ? void 0 : _b.enabled) === false) {
8891
+ throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
8892
+ }
8893
+ }
8894
+ checkFeedbackEnabled() {
8895
+ var _a2, _b;
8896
+ this.checkPremiumSubscription();
8897
+ if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.feedback) == null ? void 0 : _b.enabled) === false) {
8898
+ throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
8899
+ }
8900
+ }
8901
+ async getPGPool() {
8902
+ const globalKey = `__retrivora_pg_pool_${this.config.projectId}`;
8903
+ const _g2 = global;
8904
+ if (_g2[globalKey]) {
8905
+ this.pgPool = _g2[globalKey];
8906
+ return this.pgPool;
8907
+ }
8908
+ const opts = this.config.vectorDb.options;
8909
+ if (!opts.connectionString) {
8910
+ throw new Error("[DatabaseStorage] pg connectionString option is missing.");
8911
+ }
8912
+ const { Pool: Pool3 } = await import("pg");
8913
+ this.pgPool = new Pool3({ connectionString: opts.connectionString });
8914
+ _g2[globalKey] = this.pgPool;
8915
+ const client = await this.pgPool.connect();
8916
+ try {
8917
+ await client.query(`
8918
+ CREATE TABLE IF NOT EXISTS ${this.historyTableName} (
8919
+ id TEXT PRIMARY KEY,
8920
+ session_id TEXT NOT NULL,
8921
+ role TEXT NOT NULL,
8922
+ content TEXT NOT NULL,
8923
+ sources JSONB,
8924
+ ui_transformation JSONB,
8925
+ trace JSONB,
8926
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
8927
+ )
8928
+ `);
8929
+ await client.query(`
8930
+ CREATE TABLE IF NOT EXISTS ${this.feedbackTableName} (
8931
+ id TEXT PRIMARY KEY,
8932
+ message_id TEXT NOT NULL UNIQUE,
8933
+ session_id TEXT NOT NULL,
8934
+ rating TEXT NOT NULL,
8935
+ comment TEXT,
8936
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
8937
+ )
8938
+ `);
8939
+ } finally {
8940
+ client.release();
8941
+ }
8942
+ return this.pgPool;
8943
+ }
8944
+ async getMongoClient() {
8945
+ const globalKey = `__retrivora_mongo_client_${this.config.projectId}`;
8946
+ const _g2 = global;
8947
+ if (_g2[globalKey]) {
8948
+ this.mongoClient = _g2[globalKey];
8949
+ this.mongoDbName = this.config.vectorDb.options.database;
8950
+ return this.mongoClient;
8951
+ }
8952
+ const opts = this.config.vectorDb.options;
8953
+ if (!opts.uri || !opts.database) {
8954
+ throw new Error("[DatabaseStorage] mongo uri and database options are missing.");
8955
+ }
8956
+ const { MongoClient: MongoClient2 } = await import("mongodb");
8957
+ this.mongoClient = new MongoClient2(opts.uri);
8958
+ await this.mongoClient.connect();
8959
+ _g2[globalKey] = this.mongoClient;
8960
+ this.mongoDbName = opts.database;
8961
+ return this.mongoClient;
8962
+ }
8963
+ getMongoDb() {
8964
+ return this.mongoClient.db(this.mongoDbName);
8965
+ }
8966
+ // Helper for FS fallback reads
8967
+ readLocalFile(filePath) {
8968
+ if (!fs.existsSync(filePath)) return [];
8969
+ try {
8970
+ const raw = fs.readFileSync(filePath, "utf-8");
8971
+ return JSON.parse(raw) || [];
8972
+ } catch (e) {
8973
+ return [];
8974
+ }
8975
+ }
8976
+ // Helper for FS fallback writes
8977
+ writeLocalFile(filePath, data) {
8978
+ if (!fs.existsSync(this.fallbackDir)) {
8979
+ fs.mkdirSync(this.fallbackDir, { recursive: true });
8980
+ }
8981
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
8982
+ }
8983
+ // ─── Message History Operations ──────────────────────────────────────────
8984
+ async saveMessage(sessionId, message) {
8985
+ this.checkHistoryEnabled();
8986
+ const createdAt = (/* @__PURE__ */ new Date()).toISOString();
8987
+ const msgId = message.id || `msg_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
8988
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
8989
+ const pool = await this.getPGPool();
8990
+ await pool.query(
8991
+ `INSERT INTO ${this.historyTableName} (id, session_id, role, content, sources, ui_transformation, trace, created_at)
8992
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
8993
+ ON CONFLICT (id) DO UPDATE
8994
+ SET content = EXCLUDED.content, sources = EXCLUDED.sources, ui_transformation = EXCLUDED.ui_transformation, trace = EXCLUDED.trace`,
8995
+ [
8996
+ msgId,
8997
+ sessionId,
8998
+ message.role,
8999
+ message.content,
9000
+ message.sources ? JSON.stringify(message.sources) : null,
9001
+ message.uiTransformation ? JSON.stringify(message.uiTransformation) : null,
9002
+ message.trace ? JSON.stringify(message.trace) : null,
9003
+ createdAt
9004
+ ]
9005
+ );
9006
+ } else if (this.provider === "mongodb") {
9007
+ await this.getMongoClient();
9008
+ const db = this.getMongoDb();
9009
+ const col = db.collection(this.historyTableName);
9010
+ await col.updateOne(
9011
+ { id: msgId },
9012
+ {
9013
+ $set: {
9014
+ id: msgId,
9015
+ session_id: sessionId,
9016
+ role: message.role,
9017
+ content: message.content,
9018
+ sources: message.sources || null,
9019
+ ui_transformation: message.uiTransformation || null,
9020
+ trace: message.trace || null,
9021
+ created_at: createdAt
9022
+ }
9023
+ },
9024
+ { upsert: true }
9025
+ );
9026
+ } else {
9027
+ const history = this.readLocalFile(this.historyFile);
9028
+ const index = history.findIndex((h) => h.id === msgId);
9029
+ const item = {
9030
+ id: msgId,
9031
+ session_id: sessionId,
9032
+ role: message.role,
9033
+ content: message.content,
9034
+ sources: message.sources || null,
9035
+ ui_transformation: message.uiTransformation || null,
9036
+ trace: message.trace || null,
9037
+ created_at: createdAt
9038
+ };
9039
+ if (index !== -1) {
9040
+ history[index] = item;
9041
+ } else {
9042
+ history.push(item);
9043
+ }
9044
+ this.writeLocalFile(this.historyFile, history);
9045
+ }
9046
+ }
9047
+ async getHistory(sessionId) {
9048
+ this.checkHistoryEnabled();
9049
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9050
+ const pool = await this.getPGPool();
9051
+ const res = await pool.query(
9052
+ `SELECT id, role, content, sources, ui_transformation as "uiTransformation", trace, created_at as "createdAt"
9053
+ FROM ${this.historyTableName}
9054
+ WHERE session_id = $1
9055
+ ORDER BY created_at ASC`,
9056
+ [sessionId]
9057
+ );
9058
+ return res.rows;
9059
+ } else if (this.provider === "mongodb") {
9060
+ await this.getMongoClient();
9061
+ const db = this.getMongoDb();
9062
+ const col = db.collection(this.historyTableName);
9063
+ const items = await col.find({ session_id: sessionId }).sort({ created_at: 1 }).toArray();
9064
+ return items.map((item) => ({
9065
+ id: item.id,
9066
+ role: item.role,
9067
+ content: item.content,
9068
+ sources: item.sources,
9069
+ uiTransformation: item.ui_transformation,
9070
+ trace: item.trace,
9071
+ createdAt: item.created_at
9072
+ }));
9073
+ } else {
9074
+ const history = this.readLocalFile(this.historyFile);
9075
+ return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
9076
+ }
9077
+ }
9078
+ async clearHistory(sessionId) {
9079
+ this.checkHistoryEnabled();
9080
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9081
+ const pool = await this.getPGPool();
9082
+ await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
9083
+ await pool.query(`DELETE FROM ${this.feedbackTableName} WHERE session_id = $1`, [sessionId]);
9084
+ } else if (this.provider === "mongodb") {
9085
+ await this.getMongoClient();
9086
+ const db = this.getMongoDb();
9087
+ await db.collection(this.historyTableName).deleteMany({ session_id: sessionId });
9088
+ await db.collection(this.feedbackTableName).deleteMany({ session_id: sessionId });
9089
+ } else {
9090
+ const history = this.readLocalFile(this.historyFile);
9091
+ const filteredHistory = history.filter((h) => h.session_id !== sessionId);
9092
+ this.writeLocalFile(this.historyFile, filteredHistory);
9093
+ const feedback = this.readLocalFile(this.feedbackFile);
9094
+ const filteredFeedback = feedback.filter((f) => f.session_id !== sessionId);
9095
+ this.writeLocalFile(this.feedbackFile, filteredFeedback);
9096
+ }
9097
+ }
9098
+ async listSessions() {
9099
+ this.checkHistoryEnabled();
9100
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9101
+ const pool = await this.getPGPool();
9102
+ const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
9103
+ return res.rows.map((r) => r.session_id);
9104
+ } else if (this.provider === "mongodb") {
9105
+ await this.getMongoClient();
9106
+ const db = this.getMongoDb();
9107
+ return db.collection(this.historyTableName).distinct("session_id");
9108
+ } else {
9109
+ const history = this.readLocalFile(this.historyFile);
9110
+ const sessions = new Set(history.map((h) => h.session_id));
9111
+ return Array.from(sessions);
9112
+ }
9113
+ }
9114
+ // ─── Feedback Operations ──────────────────────────────────────────────────
9115
+ async saveFeedback(feedback) {
9116
+ this.checkFeedbackEnabled();
9117
+ const id = `fb_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
9118
+ const createdAt = (/* @__PURE__ */ new Date()).toISOString();
9119
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9120
+ const pool = await this.getPGPool();
9121
+ await pool.query(
9122
+ `INSERT INTO ${this.feedbackTableName} (id, message_id, session_id, rating, comment, created_at)
9123
+ VALUES ($1, $2, $3, $4, $5, $6)
9124
+ ON CONFLICT (message_id) DO UPDATE
9125
+ SET rating = EXCLUDED.rating, comment = EXCLUDED.comment`,
9126
+ [id, feedback.messageId, feedback.sessionId, feedback.rating, feedback.comment || null, createdAt]
9127
+ );
9128
+ } else if (this.provider === "mongodb") {
9129
+ await this.getMongoClient();
9130
+ const db = this.getMongoDb();
9131
+ const col = db.collection(this.feedbackTableName);
9132
+ await col.updateOne(
9133
+ { message_id: feedback.messageId },
9134
+ {
9135
+ $set: {
9136
+ id,
9137
+ message_id: feedback.messageId,
9138
+ session_id: feedback.sessionId,
9139
+ rating: feedback.rating,
9140
+ comment: feedback.comment || null,
9141
+ created_at: createdAt
9142
+ }
9143
+ },
9144
+ { upsert: true }
9145
+ );
9146
+ } else {
9147
+ const list = this.readLocalFile(this.feedbackFile);
9148
+ const index = list.findIndex((f) => f.message_id === feedback.messageId);
9149
+ const item = {
9150
+ id,
9151
+ message_id: feedback.messageId,
9152
+ session_id: feedback.sessionId,
9153
+ rating: feedback.rating,
9154
+ comment: feedback.comment || null,
9155
+ created_at: createdAt
9156
+ };
9157
+ if (index !== -1) {
9158
+ list[index] = item;
9159
+ } else {
9160
+ list.push(item);
9161
+ }
9162
+ this.writeLocalFile(this.feedbackFile, list);
9163
+ }
9164
+ }
9165
+ async getFeedback(messageId) {
9166
+ this.checkFeedbackEnabled();
9167
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9168
+ const pool = await this.getPGPool();
9169
+ const res = await pool.query(
9170
+ `SELECT id, message_id as "messageId", session_id as "sessionId", rating, comment, created_at as "createdAt"
9171
+ FROM ${this.feedbackTableName}
9172
+ WHERE message_id = $1`,
9173
+ [messageId]
9174
+ );
9175
+ return res.rows[0] || null;
9176
+ } else if (this.provider === "mongodb") {
9177
+ await this.getMongoClient();
9178
+ const db = this.getMongoDb();
9179
+ const col = db.collection(this.feedbackTableName);
9180
+ const item = await col.findOne({ message_id: messageId });
9181
+ if (!item) return null;
9182
+ return {
9183
+ id: item.id,
9184
+ messageId: item.message_id,
9185
+ sessionId: item.session_id,
9186
+ rating: item.rating,
9187
+ comment: item.comment,
9188
+ createdAt: item.created_at
9189
+ };
9190
+ } else {
9191
+ const list = this.readLocalFile(this.feedbackFile);
9192
+ return list.find((f) => f.message_id === messageId) || null;
9193
+ }
9194
+ }
9195
+ async listFeedback() {
9196
+ this.checkFeedbackEnabled();
9197
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9198
+ const pool = await this.getPGPool();
9199
+ const res = await pool.query(
9200
+ `SELECT id, message_id as "messageId", session_id as "sessionId", rating, comment, created_at as "createdAt"
9201
+ FROM ${this.feedbackTableName}
9202
+ ORDER BY created_at DESC`
9203
+ );
9204
+ return res.rows;
9205
+ } else if (this.provider === "mongodb") {
9206
+ await this.getMongoClient();
9207
+ const db = this.getMongoDb();
9208
+ const col = db.collection(this.feedbackTableName);
9209
+ const items = await col.find({}).sort({ created_at: -1 }).toArray();
9210
+ return items.map((item) => ({
9211
+ id: item.id,
9212
+ messageId: item.message_id,
9213
+ sessionId: item.session_id,
9214
+ rating: item.rating,
9215
+ comment: item.comment,
9216
+ createdAt: item.created_at
9217
+ }));
9218
+ } else {
9219
+ const list = this.readLocalFile(this.feedbackFile);
9220
+ return [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
9221
+ }
9222
+ }
9223
+ async disconnect() {
9224
+ if (this.pgPool) {
9225
+ await this.pgPool.end();
9226
+ this.pgPool = null;
9227
+ }
9228
+ if (this.mongoClient) {
9229
+ await this.mongoClient.close();
9230
+ this.mongoClient = null;
9231
+ }
9232
+ }
9233
+ };
9234
+
9235
+ // src/handlers/index.ts
9236
+ async function checkAuth(req, onAuthorize) {
9237
+ if (!onAuthorize) return null;
9238
+ try {
9239
+ const res = await onAuthorize(req);
9240
+ if (res === false) {
9241
+ return import_server.NextResponse.json({ error: "Unauthorized" }, { status: 401 });
9242
+ }
9243
+ if (res instanceof Response) {
9244
+ return res;
9245
+ }
9246
+ return null;
9247
+ } catch (err) {
9248
+ const msg = err instanceof Error ? err.message : "Authorization check failed";
9249
+ return import_server.NextResponse.json({ error: msg }, { status: 401 });
9250
+ }
9251
+ }
9252
+ var RateLimiter = class {
9253
+ constructor(windowMs = 6e4, max = 30) {
9254
+ this.hits = /* @__PURE__ */ new Map();
9255
+ this.windowMs = windowMs;
9256
+ this.max = max;
9257
+ }
9258
+ /** Returns true if the request should be allowed, false if rate-limited. */
9259
+ allow(key) {
9260
+ const now = Date.now();
9261
+ const cutoff = now - this.windowMs;
9262
+ const existing = (this.hits.get(key) || []).filter((t) => t > cutoff);
9263
+ existing.push(now);
9264
+ this.hits.set(key, existing);
9265
+ if (this.hits.size > 5e3) {
9266
+ for (const [k, timestamps] of this.hits.entries()) {
9267
+ if (timestamps.every((t) => t <= cutoff)) this.hits.delete(k);
9268
+ }
9269
+ }
9270
+ return existing.length <= this.max;
9271
+ }
9272
+ retryAfterSec(key) {
9273
+ const now = Date.now();
9274
+ const cutoff = now - this.windowMs;
9275
+ const existing = (this.hits.get(key) || []).filter((t) => t > cutoff);
9276
+ if (existing.length === 0) return 0;
9277
+ return Math.ceil((existing[0] + this.windowMs - now) / 1e3);
9278
+ }
9279
+ };
9280
+ var _g = global;
9281
+ var _a;
9282
+ var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
9283
+ function getRateLimitKey(req) {
9284
+ var _a2, _b;
9285
+ 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";
9286
+ return `ip:${ip}`;
9287
+ }
9288
+ function checkRateLimit(req) {
9289
+ const key = getRateLimitKey(req);
9290
+ if (!rateLimiter.allow(key)) {
9291
+ const retryAfter = rateLimiter.retryAfterSec(key);
9292
+ return new Response(
9293
+ JSON.stringify({ error: { code: "RATE_LIMITED", message: "Too many requests. Please slow down." } }),
9294
+ {
9295
+ status: 429,
9296
+ headers: {
9297
+ "Content-Type": "application/json",
9298
+ "Retry-After": String(retryAfter),
9299
+ "X-RateLimit-Limit": "30",
9300
+ "X-RateLimit-Window": "60"
9301
+ }
9302
+ }
9303
+ );
9304
+ }
9305
+ return null;
9306
+ }
9307
+ var MAX_MESSAGE_LENGTH = 8e3;
9308
+ function sanitizeInput(raw) {
9309
+ const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
9310
+ const trimmed = stripped.trim();
9311
+ if (!trimmed) {
9312
+ return { ok: false, error: "message must not be empty" };
9313
+ }
9314
+ if (trimmed.length > MAX_MESSAGE_LENGTH) {
9315
+ return { ok: false, error: `message must be \u2264 ${MAX_MESSAGE_LENGTH} characters` };
9316
+ }
9317
+ return { ok: true, value: trimmed };
9318
+ }
9319
+ function getOrCreatePlugin(configOrPlugin) {
9320
+ if (configOrPlugin instanceof VectorPlugin) return configOrPlugin;
9321
+ const cacheKey = "__retrivoraPlugin_" + JSON.stringify(configOrPlugin != null ? configOrPlugin : {}).slice(0, 64);
9322
+ if (!_g[cacheKey]) {
9323
+ _g[cacheKey] = new VectorPlugin(configOrPlugin);
9324
+ }
9325
+ return _g[cacheKey];
9326
+ }
7755
9327
  function sseFrame(payload) {
7756
9328
  return `data: ${JSON.stringify(payload)}
7757
9329
 
@@ -7789,47 +9361,88 @@ var SSE_HEADERS = {
7789
9361
  "X-Accel-Buffering": "no"
7790
9362
  // Disable Nginx buffering for streaming
7791
9363
  };
7792
- function createChatHandler(configOrPlugin) {
7793
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
9364
+ function createChatHandler(configOrPlugin, options) {
9365
+ const plugin = getOrCreatePlugin(configOrPlugin);
9366
+ const storage = new DatabaseStorage(plugin.getConfig());
9367
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
7794
9368
  return async function POST(req) {
9369
+ const authResult = await checkAuth(req, onAuthorize);
9370
+ if (authResult) return authResult;
9371
+ const rateLimited = checkRateLimit(req);
9372
+ if (rateLimited) return rateLimited;
7795
9373
  try {
7796
9374
  const body = await req.json();
7797
- const { message, history = [], namespace } = body;
7798
- if (!(message == null ? void 0 : message.trim())) {
7799
- return import_server.NextResponse.json({ error: "message is required" }, { status: 400 });
7800
- }
9375
+ const { message: rawMessage, history = [], namespace, sessionId = "default", messageId, userMessageId } = body;
9376
+ const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
9377
+ if (!sanitized.ok) {
9378
+ return import_server.NextResponse.json({ error: { code: "INVALID_INPUT", message: sanitized.error } }, { status: 400 });
9379
+ }
9380
+ const message = sanitized.value;
9381
+ const userMsgId = userMessageId || `user_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
9382
+ await storage.saveMessage(sessionId, {
9383
+ id: userMsgId,
9384
+ role: "user",
9385
+ content: message
9386
+ }).catch((err) => console.warn("[createChatHandler] Failed to save user message:", err));
7801
9387
  const result = await plugin.chat(message, history, namespace);
7802
- return import_server.NextResponse.json(result);
9388
+ const assistantMsgId = messageId || `assistant_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
9389
+ await storage.saveMessage(sessionId, {
9390
+ id: assistantMsgId,
9391
+ role: "assistant",
9392
+ content: result.reply,
9393
+ sources: result.sources,
9394
+ uiTransformation: result.ui_transformation,
9395
+ trace: result.trace
9396
+ }).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
9397
+ return import_server.NextResponse.json(__spreadProps(__spreadValues({}, result), {
9398
+ messageId: assistantMsgId,
9399
+ userMessageId: userMsgId
9400
+ }));
7803
9401
  } catch (err) {
7804
9402
  const message = err instanceof Error ? err.message : "Internal server error";
7805
9403
  return import_server.NextResponse.json({ error: message }, { status: 500 });
7806
9404
  }
7807
9405
  };
7808
9406
  }
7809
- function createStreamHandler(configOrPlugin) {
7810
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
9407
+ function createStreamHandler(configOrPlugin, options) {
9408
+ const plugin = getOrCreatePlugin(configOrPlugin);
9409
+ const storage = new DatabaseStorage(plugin.getConfig());
9410
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
7811
9411
  return async function POST(req) {
9412
+ const authResult = await checkAuth(req, onAuthorize);
9413
+ if (authResult) return authResult;
9414
+ const rateLimited = checkRateLimit(req);
9415
+ if (rateLimited) return rateLimited;
7812
9416
  let body;
7813
9417
  try {
7814
9418
  body = await req.json();
7815
9419
  } catch (e) {
7816
- return new Response(JSON.stringify({ error: "Invalid JSON body" }), {
9420
+ return new Response(JSON.stringify({ error: { code: "INVALID_JSON", message: "Invalid JSON body" } }), {
7817
9421
  status: 400,
7818
9422
  headers: { "Content-Type": "application/json" }
7819
9423
  });
7820
9424
  }
7821
- const { message, history = [], namespace } = body;
7822
- if (!(message == null ? void 0 : message.trim())) {
7823
- return new Response(JSON.stringify({ error: "message is required" }), {
7824
- status: 400,
7825
- headers: { "Content-Type": "application/json" }
7826
- });
9425
+ const { message: rawMessage, history = [], namespace, sessionId = "default", messageId, userMessageId } = body;
9426
+ const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
9427
+ if (!sanitized.ok) {
9428
+ return new Response(
9429
+ JSON.stringify({ error: { code: "INVALID_INPUT", message: sanitized.error } }),
9430
+ { status: 400, headers: { "Content-Type": "application/json" } }
9431
+ );
7827
9432
  }
9433
+ const message = sanitized.value;
9434
+ const userMsgId = userMessageId || `user_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
9435
+ await storage.saveMessage(sessionId, {
9436
+ id: userMsgId,
9437
+ role: "user",
9438
+ content: message
9439
+ }).catch((err) => console.warn("[createStreamHandler] Failed to save user message:", err));
9440
+ const assistantMsgId = messageId || `assistant_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
7828
9441
  const encoder = new TextEncoder();
7829
9442
  let isActive = true;
7830
9443
  const stream = new ReadableStream({
7831
9444
  async start(controller) {
7832
- var _a;
9445
+ var _a2;
7833
9446
  const enqueue = (text) => {
7834
9447
  if (!isActive) return;
7835
9448
  try {
@@ -7840,11 +9453,13 @@ function createStreamHandler(configOrPlugin) {
7840
9453
  };
7841
9454
  try {
7842
9455
  const pipelineStream = plugin.chatStream(message, history, namespace);
9456
+ let fullReply = "";
7843
9457
  try {
7844
9458
  for (var iter = __forAwait(pipelineStream), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
7845
9459
  const chunk = temp.value;
7846
9460
  if (!isActive) break;
7847
9461
  if (typeof chunk === "string") {
9462
+ fullReply += chunk;
7848
9463
  enqueue(sseTextFrame(chunk));
7849
9464
  } else if (chunk && typeof chunk === "object" && "type" in chunk && chunk.type === "thinking") {
7850
9465
  enqueue(`data: ${JSON.stringify(chunk)}
@@ -7857,9 +9472,10 @@ function createStreamHandler(configOrPlugin) {
7857
9472
  if (responseChunk == null ? void 0 : responseChunk.trace) {
7858
9473
  enqueue(sseObservabilityFrame(responseChunk.trace));
7859
9474
  }
9475
+ let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
7860
9476
  if (sources.length > 0) {
7861
9477
  try {
7862
- const uiTransformation = (_a = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a : UITransformer.transform(message, sources, plugin.getConfig());
9478
+ uiTransformation = (_a2 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a2 : UITransformer.transform(message, sources, plugin.getConfig());
7863
9479
  if (uiTransformation) {
7864
9480
  enqueue(sseUIFrame(uiTransformation));
7865
9481
  }
@@ -7867,11 +9483,22 @@ function createStreamHandler(configOrPlugin) {
7867
9483
  console.warn("[createStreamHandler] UI transformation warning:", transformError);
7868
9484
  try {
7869
9485
  const fallback = UITransformer.transform(message, sources, plugin.getConfig());
7870
- if (fallback) enqueue(sseUIFrame(fallback));
9486
+ if (fallback) {
9487
+ uiTransformation = fallback;
9488
+ enqueue(sseUIFrame(fallback));
9489
+ }
7871
9490
  } catch (e) {
7872
9491
  }
7873
9492
  }
7874
9493
  }
9494
+ await storage.saveMessage(sessionId, {
9495
+ id: assistantMsgId,
9496
+ role: "assistant",
9497
+ content: fullReply,
9498
+ sources,
9499
+ uiTransformation,
9500
+ trace: responseChunk == null ? void 0 : responseChunk.trace
9501
+ }).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
7875
9502
  }
7876
9503
  }
7877
9504
  } catch (temp) {
@@ -7908,12 +9535,15 @@ function createStreamHandler(configOrPlugin) {
7908
9535
  console.log("[createStreamHandler] Stream connection closed by client:", reason);
7909
9536
  }
7910
9537
  });
7911
- return new Response(stream, { headers: SSE_HEADERS });
9538
+ return new Response(stream, { headers: __spreadProps(__spreadValues({}, SSE_HEADERS), { "x-message-id": assistantMsgId, "x-user-message-id": userMsgId }) });
7912
9539
  };
7913
9540
  }
7914
- function createIngestHandler(configOrPlugin) {
7915
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
9541
+ function createIngestHandler(configOrPlugin, options) {
9542
+ const plugin = getOrCreatePlugin(configOrPlugin);
9543
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
7916
9544
  return async function POST(req) {
9545
+ const authResult = await checkAuth(req, onAuthorize);
9546
+ if (authResult) return authResult;
7917
9547
  try {
7918
9548
  const body = await req.json();
7919
9549
  const { documents, namespace } = body;
@@ -7928,9 +9558,14 @@ function createIngestHandler(configOrPlugin) {
7928
9558
  }
7929
9559
  };
7930
9560
  }
7931
- function createHealthHandler(configOrPlugin) {
7932
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
7933
- return async function GET() {
9561
+ function createHealthHandler(configOrPlugin, options) {
9562
+ const plugin = getOrCreatePlugin(configOrPlugin);
9563
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
9564
+ return async function GET(req) {
9565
+ if (req) {
9566
+ const authResult = await checkAuth(req, onAuthorize);
9567
+ if (authResult) return authResult;
9568
+ }
7934
9569
  try {
7935
9570
  const health = await plugin.checkHealth();
7936
9571
  const status = health.allHealthy ? "ok" : "degraded";
@@ -7945,9 +9580,12 @@ function createHealthHandler(configOrPlugin) {
7945
9580
  }
7946
9581
  };
7947
9582
  }
7948
- function createUploadHandler(configOrPlugin) {
7949
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
9583
+ function createUploadHandler(configOrPlugin, options) {
9584
+ const plugin = getOrCreatePlugin(configOrPlugin);
9585
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
7950
9586
  return async function POST(req) {
9587
+ const authResult = await checkAuth(req, onAuthorize);
9588
+ if (authResult) return authResult;
7951
9589
  try {
7952
9590
  const formData = await req.formData();
7953
9591
  const files = formData.getAll("files");
@@ -8021,9 +9659,12 @@ function createUploadHandler(configOrPlugin) {
8021
9659
  }
8022
9660
  };
8023
9661
  }
8024
- function createSuggestionsHandler(configOrPlugin) {
8025
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
9662
+ function createSuggestionsHandler(configOrPlugin, options) {
9663
+ const plugin = getOrCreatePlugin(configOrPlugin);
9664
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
8026
9665
  return async function POST(req) {
9666
+ const authResult = await checkAuth(req, onAuthorize);
9667
+ if (authResult) return authResult;
8027
9668
  try {
8028
9669
  const body = await req.json();
8029
9670
  const { query, namespace } = body;
@@ -8038,13 +9679,108 @@ function createSuggestionsHandler(configOrPlugin) {
8038
9679
  }
8039
9680
  };
8040
9681
  }
8041
- function createRagHandler(configOrPlugin) {
8042
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
8043
- const chatHandler = createChatHandler(plugin);
8044
- const streamHandler = createStreamHandler(plugin);
8045
- const uploadHandler = createUploadHandler(plugin);
8046
- const healthHandler = createHealthHandler(plugin);
8047
- const suggestionsHandler = createSuggestionsHandler(plugin);
9682
+ function createHistoryHandler(configOrPlugin, options) {
9683
+ const plugin = getOrCreatePlugin(configOrPlugin);
9684
+ const storage = new DatabaseStorage(plugin.getConfig());
9685
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
9686
+ return async function handler(req) {
9687
+ const authResult = await checkAuth(req, onAuthorize);
9688
+ if (authResult) return authResult;
9689
+ const url = new URL(req.url);
9690
+ const sessionId = url.searchParams.get("sessionId") || "default";
9691
+ if (req.method === "GET") {
9692
+ try {
9693
+ const history = await storage.getHistory(sessionId);
9694
+ return import_server.NextResponse.json({ history });
9695
+ } catch (err) {
9696
+ const message = err instanceof Error ? err.message : "Failed to fetch history";
9697
+ return import_server.NextResponse.json({ error: message }, { status: 500 });
9698
+ }
9699
+ } else if (req.method === "POST") {
9700
+ try {
9701
+ const body = await req.json().catch(() => ({}));
9702
+ const sid = body.sessionId || sessionId;
9703
+ await storage.clearHistory(sid);
9704
+ return import_server.NextResponse.json({ success: true });
9705
+ } catch (err) {
9706
+ const message = err instanceof Error ? err.message : "Failed to clear history";
9707
+ return import_server.NextResponse.json({ error: message }, { status: 500 });
9708
+ }
9709
+ }
9710
+ return import_server.NextResponse.json({ error: "Method Not Allowed" }, { status: 405 });
9711
+ };
9712
+ }
9713
+ function createFeedbackHandler(configOrPlugin, options) {
9714
+ const plugin = getOrCreatePlugin(configOrPlugin);
9715
+ const storage = new DatabaseStorage(plugin.getConfig());
9716
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
9717
+ return async function handler(req) {
9718
+ const authResult = await checkAuth(req, onAuthorize);
9719
+ if (authResult) return authResult;
9720
+ if (req.method === "GET") {
9721
+ try {
9722
+ const url = new URL(req.url);
9723
+ const messageId = url.searchParams.get("messageId");
9724
+ if (!messageId) {
9725
+ const feedbackList = await storage.listFeedback();
9726
+ return import_server.NextResponse.json({ feedback: feedbackList });
9727
+ }
9728
+ const feedback = await storage.getFeedback(messageId);
9729
+ return import_server.NextResponse.json({ feedback });
9730
+ } catch (err) {
9731
+ const message = err instanceof Error ? err.message : "Failed to fetch feedback";
9732
+ return import_server.NextResponse.json({ error: message }, { status: 500 });
9733
+ }
9734
+ } else if (req.method === "POST") {
9735
+ try {
9736
+ const body = await req.json();
9737
+ const { messageId, sessionId = "default", rating, comment } = body;
9738
+ if (!messageId) {
9739
+ return import_server.NextResponse.json({ error: "messageId is required" }, { status: 400 });
9740
+ }
9741
+ if (!rating) {
9742
+ return import_server.NextResponse.json({ error: "rating is required" }, { status: 400 });
9743
+ }
9744
+ await storage.saveFeedback({ messageId, sessionId, rating, comment });
9745
+ return import_server.NextResponse.json({ success: true });
9746
+ } catch (err) {
9747
+ const message = err instanceof Error ? err.message : "Failed to save feedback";
9748
+ return import_server.NextResponse.json({ error: message }, { status: 500 });
9749
+ }
9750
+ }
9751
+ return import_server.NextResponse.json({ error: "Method Not Allowed" }, { status: 405 });
9752
+ };
9753
+ }
9754
+ function createSessionsHandler(configOrPlugin, options) {
9755
+ const plugin = getOrCreatePlugin(configOrPlugin);
9756
+ const storage = new DatabaseStorage(plugin.getConfig());
9757
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
9758
+ return async function GET(req) {
9759
+ if (req) {
9760
+ const authResult = await checkAuth(req, onAuthorize);
9761
+ if (authResult) return authResult;
9762
+ }
9763
+ void req;
9764
+ try {
9765
+ const sessions = await storage.listSessions();
9766
+ return import_server.NextResponse.json({ sessions });
9767
+ } catch (err) {
9768
+ const message = err instanceof Error ? err.message : "Failed to list sessions";
9769
+ return import_server.NextResponse.json({ error: message }, { status: 500 });
9770
+ }
9771
+ };
9772
+ }
9773
+ function createRagHandler(configOrPlugin, options) {
9774
+ const plugin = getOrCreatePlugin(configOrPlugin);
9775
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
9776
+ const chatHandler = createChatHandler(plugin, { onAuthorize });
9777
+ const streamHandler = createStreamHandler(plugin, { onAuthorize });
9778
+ const uploadHandler = createUploadHandler(plugin, { onAuthorize });
9779
+ const healthHandler = createHealthHandler(plugin, { onAuthorize });
9780
+ const suggestionsHandler = createSuggestionsHandler(plugin, { onAuthorize });
9781
+ const historyHandler = createHistoryHandler(plugin, { onAuthorize });
9782
+ const feedbackHandler = createFeedbackHandler(plugin, { onAuthorize });
9783
+ const sessionsHandler = createSessionsHandler(plugin, { onAuthorize });
8048
9784
  async function routePostRequest(req, segment) {
8049
9785
  switch (segment) {
8050
9786
  case "chat":
@@ -8056,22 +9792,35 @@ function createRagHandler(configOrPlugin) {
8056
9792
  case "suggestions":
8057
9793
  return suggestionsHandler(req);
8058
9794
  case "health":
8059
- return healthHandler();
9795
+ return healthHandler(req);
9796
+ case "history":
9797
+ case "history/clear":
9798
+ return historyHandler(req);
9799
+ case "feedback":
9800
+ return feedbackHandler(req);
8060
9801
  default:
8061
9802
  return import_server.NextResponse.json({ error: `Not Found: POST segment "${segment}" not supported.` }, { status: 404 });
8062
9803
  }
8063
9804
  }
8064
9805
  async function routeGetRequest(req, segment) {
8065
- if (segment === "health") {
8066
- return healthHandler();
9806
+ switch (segment) {
9807
+ case "health":
9808
+ return healthHandler(req);
9809
+ case "history":
9810
+ return historyHandler(req);
9811
+ case "feedback":
9812
+ return feedbackHandler(req);
9813
+ case "sessions":
9814
+ return sessionsHandler(req);
9815
+ default:
9816
+ return import_server.NextResponse.json({ error: `Method Not Allowed: GET segment "${segment}" not supported.` }, { status: 405 });
8067
9817
  }
8068
- return import_server.NextResponse.json({ error: `Method Not Allowed: GET is only supported for "health" segment.` }, { status: 405 });
8069
9818
  }
8070
9819
  async function getSegment(context) {
8071
- var _a;
8072
- const resolvedParams = typeof ((_a = context == null ? void 0 : context.params) == null ? void 0 : _a.then) === "function" ? await context.params : context == null ? void 0 : context.params;
9820
+ var _a2;
9821
+ 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;
8073
9822
  const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || [];
8074
- return segments[0] || "chat";
9823
+ return segments.join("/") || "chat";
8075
9824
  }
8076
9825
  return {
8077
9826
  GET: async (req, context) => {
@@ -8110,8 +9859,10 @@ function createRagHandler(configOrPlugin) {
8110
9859
  EmbeddingFailedException,
8111
9860
  EmbeddingStrategy,
8112
9861
  EmbeddingStrategyResolver,
9862
+ GroqProvider,
8113
9863
  LLMFactory,
8114
9864
  LLM_PROFILES,
9865
+ LicenseVerifier,
8115
9866
  MilvusProvider,
8116
9867
  MongoDBProvider,
8117
9868
  MultiTablePostgresProvider,
@@ -8125,6 +9876,7 @@ function createRagHandler(configOrPlugin) {
8125
9876
  ProviderNotFoundException,
8126
9877
  ProviderRegistry,
8127
9878
  QdrantProvider,
9879
+ QwenProvider,
8128
9880
  RateLimitException,
8129
9881
  RedisProvider,
8130
9882
  RetrievalException,
@@ -8136,10 +9888,13 @@ function createRagHandler(configOrPlugin) {
8136
9888
  VectorPlugin,
8137
9889
  WeaviateProvider,
8138
9890
  createChatHandler,
9891
+ createFeedbackHandler,
8139
9892
  createFromPreset,
8140
9893
  createHealthHandler,
9894
+ createHistoryHandler,
8141
9895
  createIngestHandler,
8142
9896
  createRagHandler,
9897
+ createSessionsHandler,
8143
9898
  createStreamHandler,
8144
9899
  createUploadHandler,
8145
9900
  getRagConfig,