@retrivora-ai/rag-engine 1.9.7 → 1.9.9

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 (60) hide show
  1. package/README.md +136 -136
  2. package/dist/{ILLMProvider-Bhk6zJOK.d.mts → ILLMProvider-DMxLyTdq.d.mts} +59 -4
  3. package/dist/{ILLMProvider-Bhk6zJOK.d.ts → ILLMProvider-DMxLyTdq.d.ts} +59 -4
  4. package/dist/handlers/index.d.mts +2 -2
  5. package/dist/handlers/index.d.ts +2 -2
  6. package/dist/handlers/index.js +2327 -474
  7. package/dist/handlers/index.mjs +2329 -473
  8. package/dist/{index-B9J_XEh0.d.ts → index-CfkqZd2Y.d.ts} +12 -2
  9. package/dist/{index-C3SVtPYg.d.mts → index-DXd29KMq.d.mts} +27 -52
  10. package/dist/{index-Bu7T6xgr.d.ts → index-D_bOdJML.d.ts} +27 -52
  11. package/dist/{index-BJ4cd-t5.d.mts → index-xygonxpW.d.mts} +12 -2
  12. package/dist/index.css +783 -550
  13. package/dist/index.d.mts +35 -7
  14. package/dist/index.d.ts +35 -7
  15. package/dist/index.js +419 -282
  16. package/dist/index.mjs +426 -292
  17. package/dist/server.d.mts +65 -6
  18. package/dist/server.d.ts +65 -6
  19. package/dist/server.js +2185 -317
  20. package/dist/server.mjs +2185 -317
  21. package/package.json +13 -8
  22. package/src/app/constants.tsx +37 -7
  23. package/src/app/page.tsx +2 -0
  24. package/src/components/ChatWidget.tsx +2 -1
  25. package/src/components/ChatWindow.tsx +4 -1
  26. package/src/components/CodeViewer.tsx +19 -14
  27. package/src/components/MarkdownComponents.tsx +44 -1
  28. package/src/components/MessageBubble.tsx +162 -50
  29. package/src/components/constants.tsx +228 -0
  30. package/src/config/RagConfig.ts +48 -2
  31. package/src/config/constants.ts +4 -0
  32. package/src/config/serverConfig.ts +15 -0
  33. package/src/core/ConfigResolver.ts +38 -6
  34. package/src/core/DatabaseStorage.ts +469 -0
  35. package/src/core/LicenseVerifier.ts +260 -0
  36. package/src/core/MultiAgentCoordinator.ts +239 -0
  37. package/src/core/Pipeline.ts +151 -18
  38. package/src/core/Retrivora.ts +7 -0
  39. package/src/core/VectorPlugin.ts +12 -3
  40. package/src/core/mcp.ts +261 -0
  41. package/src/handlers/index.ts +449 -63
  42. package/src/hooks/useRagChat.ts +96 -42
  43. package/src/hooks/useStoredMessages.ts +15 -4
  44. package/src/index.ts +3 -0
  45. package/src/llm/LLMFactory.ts +9 -1
  46. package/src/llm/providers/GroqProvider.ts +176 -0
  47. package/src/llm/providers/QwenProvider.ts +191 -0
  48. package/src/server.ts +7 -0
  49. package/src/types/chat.ts +14 -0
  50. package/src/types/props.ts +12 -0
  51. package/.env.example +0 -80
  52. package/LICENSE.txt +0 -21
  53. package/src/components/AmbientBackground.tsx +0 -29
  54. package/src/components/ArchitectureCard.tsx +0 -17
  55. package/src/components/ArchitectureCardsSection.tsx +0 -15
  56. package/src/components/DocViewer.tsx +0 -103
  57. package/src/components/Documentation.tsx +0 -121
  58. package/src/components/Hero.tsx +0 -59
  59. package/src/components/Lifecycle.tsx +0 -37
  60. package/src/components/Navbar.tsx +0 -55
package/dist/server.mjs CHANGED
@@ -19,6 +19,12 @@ var __spreadValues = (a, b) => {
19
19
  return a;
20
20
  };
21
21
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
22
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
23
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
24
+ }) : x)(function(x) {
25
+ if (typeof require !== "undefined") return require.apply(this, arguments);
26
+ throw Error('Dynamic require of "' + x + '" is not supported');
27
+ });
22
28
  var __objRest = (source, exclude) => {
23
29
  var target = {};
24
30
  for (var prop in source)
@@ -59,9 +65,9 @@ var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")])
59
65
  function isRecord(value) {
60
66
  return typeof value === "object" && value !== null;
61
67
  }
62
- function resolvePath(obj, path) {
63
- if (!path || !obj) return void 0;
64
- return path.replace(/\[(\w+)\]/g, ".$1").replace(/^\./, "").split(".").reduce((current, segment) => {
68
+ function resolvePath(obj, path2) {
69
+ if (!path2 || !obj) return void 0;
70
+ return path2.replace(/\[(\w+)\]/g, ".$1").replace(/^\./, "").split(".").reduce((current, segment) => {
65
71
  if (!isRecord(current) && !Array.isArray(current)) {
66
72
  return void 0;
67
73
  }
@@ -171,7 +177,7 @@ var init_PineconeProvider = __esm({
171
177
  static getHealthChecker() {
172
178
  return {
173
179
  async check(config) {
174
- var _a, _b;
180
+ var _a2, _b;
175
181
  const opts = config.options || {};
176
182
  const indexName = config.indexName;
177
183
  const timestamp = Date.now();
@@ -179,7 +185,7 @@ var init_PineconeProvider = __esm({
179
185
  const { Pinecone: Pinecone2 } = await import("@pinecone-database/pinecone");
180
186
  const client = new Pinecone2({ apiKey: opts.apiKey });
181
187
  const indexes = await client.listIndexes();
182
- const indexNames = (_b = (_a = indexes.indexes) == null ? void 0 : _a.map((i) => i.name)) != null ? _b : [];
188
+ const indexNames = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
183
189
  if (!indexNames.includes(indexName)) {
184
190
  return {
185
191
  healthy: false,
@@ -206,10 +212,10 @@ var init_PineconeProvider = __esm({
206
212
  };
207
213
  }
208
214
  async initialize() {
209
- var _a, _b;
215
+ var _a2, _b;
210
216
  this.client = new Pinecone({ apiKey: this.apiKey });
211
217
  const indexes = await this.client.listIndexes();
212
- const names = (_b = (_a = indexes.indexes) == null ? void 0 : _a.map((i) => i.name)) != null ? _b : [];
218
+ const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
213
219
  if (!names.includes(this.indexName)) {
214
220
  throw new Error(
215
221
  `[PineconeProvider] Index "${this.indexName}" not found. Available: ${names.join(", ")}`
@@ -221,12 +227,12 @@ var init_PineconeProvider = __esm({
221
227
  return namespace ? idx.namespace(namespace) : idx.namespace("");
222
228
  }
223
229
  async upsert(doc, namespace) {
224
- var _a;
230
+ var _a2;
225
231
  await this.index(namespace).upsert({
226
232
  records: [{
227
233
  id: String(doc.id),
228
234
  values: doc.vector,
229
- metadata: __spreadValues({ content: doc.content }, (_a = doc.metadata) != null ? _a : {})
235
+ metadata: __spreadValues({ content: doc.content }, (_a2 = doc.metadata) != null ? _a2 : {})
230
236
  }]
231
237
  });
232
238
  }
@@ -234,29 +240,29 @@ var init_PineconeProvider = __esm({
234
240
  const BATCH = 100;
235
241
  for (let i = 0; i < docs.length; i += BATCH) {
236
242
  const records = docs.slice(i, i + BATCH).map((d) => {
237
- var _a;
243
+ var _a2;
238
244
  return {
239
245
  id: String(d.id),
240
246
  values: d.vector,
241
- metadata: __spreadValues({ content: d.content }, (_a = d.metadata) != null ? _a : {})
247
+ metadata: __spreadValues({ content: d.content }, (_a2 = d.metadata) != null ? _a2 : {})
242
248
  };
243
249
  });
244
250
  await this.index(namespace).upsert({ records });
245
251
  }
246
252
  }
247
253
  async query(vector, topK, namespace, filter) {
248
- var _a;
254
+ var _a2;
249
255
  const pineconeFilter = this.sanitizeFilter(filter);
250
256
  const result = await this.index(namespace).query(__spreadValues({
251
257
  vector,
252
258
  topK,
253
259
  includeMetadata: true
254
260
  }, Object.keys(pineconeFilter).length > 0 ? { filter: pineconeFilter } : {}));
255
- return ((_a = result.matches) != null ? _a : []).map((m) => {
256
- var _a2, _b;
261
+ return ((_a2 = result.matches) != null ? _a2 : []).map((m) => {
262
+ var _a3, _b;
257
263
  return {
258
264
  id: m.id,
259
- score: (_a2 = m.score) != null ? _a2 : 0,
265
+ score: (_a3 = m.score) != null ? _a3 : 0,
260
266
  content: ((_b = m.metadata) == null ? void 0 : _b.content) || "",
261
267
  metadata: m.metadata
262
268
  };
@@ -295,13 +301,13 @@ var init_PostgreSQLProvider = __esm({
295
301
  init_BaseVectorProvider();
296
302
  PostgreSQLProvider = class extends BaseVectorProvider {
297
303
  constructor(config) {
298
- var _a;
304
+ var _a2;
299
305
  super(config);
300
306
  this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
301
307
  const opts = config.options;
302
308
  if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
303
309
  this.connectionString = opts.connectionString;
304
- this.dimensions = (_a = opts.dimensions) != null ? _a : 1536;
310
+ this.dimensions = (_a2 = opts.dimensions) != null ? _a2 : 1536;
305
311
  }
306
312
  static getValidator() {
307
313
  return {
@@ -382,7 +388,7 @@ var init_PostgreSQLProvider = __esm({
382
388
  }
383
389
  }
384
390
  async upsert(doc, namespace = "") {
385
- var _a;
391
+ var _a2;
386
392
  const vectorLiteral = `[${doc.vector.join(",")}]`;
387
393
  await this.pool.query(
388
394
  `INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
@@ -392,7 +398,7 @@ var init_PostgreSQLProvider = __esm({
392
398
  content = EXCLUDED.content,
393
399
  metadata = EXCLUDED.metadata,
394
400
  embedding = EXCLUDED.embedding`,
395
- [doc.id, namespace, doc.content, JSON.stringify((_a = doc.metadata) != null ? _a : {}), vectorLiteral]
401
+ [doc.id, namespace, doc.content, JSON.stringify((_a2 = doc.metadata) != null ? _a2 : {}), vectorLiteral]
396
402
  );
397
403
  }
398
404
  async batchUpsert(docs, namespace = "") {
@@ -405,9 +411,9 @@ var init_PostgreSQLProvider = __esm({
405
411
  const batch = docs.slice(i, i + BATCH_SIZE);
406
412
  const values = [];
407
413
  const valuePlaceholders = batch.map((doc, idx) => {
408
- var _a;
414
+ var _a2;
409
415
  const offset = idx * 5;
410
- values.push(doc.id, namespace, doc.content, JSON.stringify((_a = doc.metadata) != null ? _a : {}), `[${doc.vector.join(",")}]`);
416
+ values.push(doc.id, namespace, doc.content, JSON.stringify((_a2 = doc.metadata) != null ? _a2 : {}), `[${doc.vector.join(",")}]`);
411
417
  return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
412
418
  }).join(", ");
413
419
  const query = `
@@ -490,8 +496,8 @@ var init_PostgreSQLProvider = __esm({
490
496
 
491
497
  // src/utils/synonyms.ts
492
498
  function resolveMetadataValue(meta, uiKey) {
493
- var _a;
494
- const synonyms = (_a = FIELD_SYNONYMS[uiKey]) != null ? _a : [];
499
+ var _a2;
500
+ const synonyms = (_a2 = FIELD_SYNONYMS[uiKey]) != null ? _a2 : [];
495
501
  const keys = Object.keys(meta);
496
502
  const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
497
503
  let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
@@ -578,14 +584,14 @@ var init_MultiTablePostgresProvider = __esm({
578
584
  init_synonyms();
579
585
  MultiTablePostgresProvider = class extends BaseVectorProvider {
580
586
  constructor(config) {
581
- var _a, _b, _c;
587
+ var _a2, _b, _c;
582
588
  super(config);
583
589
  const opts = config.options || {};
584
590
  if (!opts.connectionString) {
585
591
  throw new Error("[MultiTablePostgresProvider] options.connectionString is required");
586
592
  }
587
593
  this.connectionString = opts.connectionString;
588
- this.dimensions = (_a = opts.dimensions) != null ? _a : 768;
594
+ this.dimensions = (_a2 = opts.dimensions) != null ? _a2 : 768;
589
595
  this.tables = [];
590
596
  const rawSearchFields = (_c = (_b = opts.searchFields) != null ? _b : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _c : ["name", "product_name", "productname", "title"];
591
597
  this.searchFields = typeof rawSearchFields === "string" ? rawSearchFields.split(",").map((f) => f.trim()).filter(Boolean) : rawSearchFields;
@@ -643,11 +649,11 @@ var init_MultiTablePostgresProvider = __esm({
643
649
  * Batch upsert documents by dynamically provisioning tables and columns based on CSV headers.
644
650
  */
645
651
  async batchUpsert(docs, namespace = "") {
646
- var _a;
652
+ var _a2;
647
653
  if (docs.length === 0) return;
648
654
  const docsByFile = {};
649
655
  for (const doc of docs) {
650
- const fileName = ((_a = doc.metadata) == null ? void 0 : _a.fileName) || this.uploadTable;
656
+ const fileName = ((_a2 = doc.metadata) == null ? void 0 : _a2.fileName) || this.uploadTable;
651
657
  if (!docsByFile[fileName]) docsByFile[fileName] = [];
652
658
  docsByFile[fileName].push(doc);
653
659
  }
@@ -700,11 +706,11 @@ var init_MultiTablePostgresProvider = __esm({
700
706
  const headerColumns = csvHeaders.map((h) => `"${h}"`).join(", ");
701
707
  const allColumns = `id, ${headerColumns ? headerColumns + ", " : ""}namespace, content, metadata, embedding`;
702
708
  const valuePlaceholders = batch.map((doc, idx) => {
703
- var _a2, _b;
709
+ var _a3, _b;
704
710
  const offset = idx * (5 + csvHeaders.length);
705
711
  values.push(doc.id);
706
712
  for (const h of csvHeaders) {
707
- values.push(String(((_a2 = doc.metadata) == null ? void 0 : _a2[h]) || ""));
713
+ values.push(String(((_a3 = doc.metadata) == null ? void 0 : _a3[h]) || ""));
708
714
  }
709
715
  values.push(namespace, doc.content, JSON.stringify((_b = doc.metadata) != null ? _b : {}), `[${doc.vector.join(",")}]`);
710
716
  const docPlaceholders = [];
@@ -743,7 +749,7 @@ var init_MultiTablePostgresProvider = __esm({
743
749
  * Query all configured tables and merge results, sorted by cosine similarity score.
744
750
  */
745
751
  async query(vector, topK, _namespace, _filter) {
746
- var _a;
752
+ var _a2;
747
753
  if (!this.pool) {
748
754
  throw new Error("[MultiTablePostgresProvider] Provider not initialized. Call initialize() first.");
749
755
  }
@@ -774,11 +780,11 @@ var init_MultiTablePostgresProvider = __esm({
774
780
  const filterParams = [];
775
781
  if (metadataFilters && Object.keys(metadataFilters).length > 0) {
776
782
  const conditions = Object.entries(metadataFilters).map(([key, val]) => {
777
- var _a3;
783
+ var _a4;
778
784
  filterParams.push(String(val));
779
785
  const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
780
786
  const paramIdx = baseOffset + filterParams.length;
781
- const synonyms = (_a3 = FIELD_SYNONYMS[key]) != null ? _a3 : [];
787
+ const synonyms = (_a4 = FIELD_SYNONYMS[key]) != null ? _a4 : [];
782
788
  const keysToCheck = [key, ...synonyms];
783
789
  const coalesceExprs = keysToCheck.flatMap((k) => [
784
790
  `metadata->>'${k}'`,
@@ -847,7 +853,7 @@ var init_MultiTablePostgresProvider = __esm({
847
853
  }
848
854
  const tableResults = [];
849
855
  for (const row of result.rows) {
850
- const _a2 = row, { hybrid_score, id } = _a2, rest = __objRest(_a2, ["hybrid_score", "id"]);
856
+ const _a3 = row, { hybrid_score, id } = _a3, rest = __objRest(_a3, ["hybrid_score", "id"]);
851
857
  delete rest.embedding;
852
858
  delete rest.vector_score;
853
859
  delete rest.keyword_score;
@@ -876,10 +882,10 @@ var init_MultiTablePostgresProvider = __esm({
876
882
  }
877
883
  allResults.sort((a, b) => b.score - a.score);
878
884
  if (allResults.length === 0) return [];
879
- const bestMatchTable = (_a = allResults[0].metadata) == null ? void 0 : _a.source_table;
885
+ const bestMatchTable = (_a2 = allResults[0].metadata) == null ? void 0 : _a2.source_table;
880
886
  const finalSorted = allResults.filter((res) => {
881
- var _a2;
882
- return ((_a2 = res.metadata) == null ? void 0 : _a2.source_table) === bestMatchTable;
887
+ var _a3;
888
+ return ((_a3 = res.metadata) == null ? void 0 : _a3.source_table) === bestMatchTable;
883
889
  });
884
890
  console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
885
891
  console.log(`[MultiTablePostgresProvider] Final top match from "${bestMatchTable}" with score ${finalSorted[0].score.toFixed(4)}`);
@@ -1284,14 +1290,14 @@ var init_QdrantProvider = __esm({
1284
1290
  * Samples points from the collection to discover available payload fields.
1285
1291
  */
1286
1292
  async discoverSchema() {
1287
- var _a;
1293
+ var _a2;
1288
1294
  try {
1289
1295
  const { data } = await this.http.post(`/collections/${this.indexName}/points/scroll`, {
1290
1296
  limit: 20,
1291
1297
  with_payload: true,
1292
1298
  with_vector: false
1293
1299
  });
1294
- const points = ((_a = data.result) == null ? void 0 : _a.points) || [];
1300
+ const points = ((_a2 = data.result) == null ? void 0 : _a2.points) || [];
1295
1301
  const keys = /* @__PURE__ */ new Set();
1296
1302
  for (const point of points) {
1297
1303
  const payload = point.payload || {};
@@ -1317,12 +1323,12 @@ var init_QdrantProvider = __esm({
1317
1323
  * Ensures the collection exists. Creates it if missing.
1318
1324
  */
1319
1325
  async ensureCollection() {
1320
- var _a;
1326
+ var _a2;
1321
1327
  try {
1322
1328
  await this.http.get(`/collections/${this.indexName}`);
1323
1329
  console.log(`[QdrantProvider] \u2705 Collection "${this.indexName}" already exists.`);
1324
1330
  } catch (err) {
1325
- if (axios4.isAxiosError(err) && ((_a = err.response) == null ? void 0 : _a.status) === 404) {
1331
+ if (axios4.isAxiosError(err) && ((_a2 = err.response) == null ? void 0 : _a2.status) === 404) {
1326
1332
  const opts = this.config.options;
1327
1333
  const dimensionsForCreate = opts.dimensions || 1536;
1328
1334
  console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
@@ -1342,7 +1348,7 @@ var init_QdrantProvider = __esm({
1342
1348
  * Ensures that a payload field has an index.
1343
1349
  */
1344
1350
  async ensureIndex(fieldName, schema = "keyword") {
1345
- var _a;
1351
+ var _a2;
1346
1352
  let fullPath = fieldName;
1347
1353
  if (!this.isFlatPayload && !fieldName.includes(".") && fieldName !== "namespace" && fieldName !== this.contentField) {
1348
1354
  fullPath = `${this.metadataField}.${fieldName}`;
@@ -1355,7 +1361,7 @@ var init_QdrantProvider = __esm({
1355
1361
  console.log(`[QdrantProvider] \u2705 Ensured ${schema} index for "${fullPath}"`);
1356
1362
  } catch (err) {
1357
1363
  let status;
1358
- if (axios4.isAxiosError(err)) status = (_a = err.response) == null ? void 0 : _a.status;
1364
+ if (axios4.isAxiosError(err)) status = (_a2 = err.response) == null ? void 0 : _a2.status;
1359
1365
  if (status === 409) return;
1360
1366
  console.warn(`[QdrantProvider] \u26A0\uFE0F Could not ensure index for "${fullPath}":`, err instanceof Error ? err.message : String(err));
1361
1367
  }
@@ -1384,7 +1390,7 @@ var init_QdrantProvider = __esm({
1384
1390
  await this.http.put(`/collections/${this.indexName}/points`, payload);
1385
1391
  }
1386
1392
  async query(vector, topK, namespace, _filter) {
1387
- var _a;
1393
+ var _a2;
1388
1394
  const must = [];
1389
1395
  if (namespace) {
1390
1396
  must.push({ key: "namespace", match: { value: namespace } });
@@ -1406,7 +1412,7 @@ var init_QdrantProvider = __esm({
1406
1412
  limit: topK,
1407
1413
  with_payload: true,
1408
1414
  params: {
1409
- hnsw_ef: ((_a = this.config.options) == null ? void 0 : _a.efSearch) || Math.max(topK * 20, 128),
1415
+ hnsw_ef: ((_a2 = this.config.options) == null ? void 0 : _a2.efSearch) || Math.max(topK * 20, 128),
1410
1416
  exact: false
1411
1417
  },
1412
1418
  filter: must.length > 0 ? { must } : void 0
@@ -1501,13 +1507,13 @@ var init_ChromaDBProvider = __esm({
1501
1507
  * Get or create the ChromaDB collection.
1502
1508
  */
1503
1509
  async initialize() {
1504
- var _a;
1510
+ var _a2;
1505
1511
  try {
1506
1512
  const { data } = await this.http.get(`/api/v1/collections/${this.indexName}`);
1507
1513
  this.collectionId = data.id;
1508
1514
  console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
1509
1515
  } catch (err) {
1510
- if (axios5.isAxiosError(err) && ((_a = err.response) == null ? void 0 : _a.status) === 404) {
1516
+ if (axios5.isAxiosError(err) && ((_a2 = err.response) == null ? void 0 : _a2.status) === 404) {
1511
1517
  console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
1512
1518
  const { data } = await this.http.post("/api/v1/collections", {
1513
1519
  name: this.indexName
@@ -1728,7 +1734,7 @@ var init_WeaviateProvider = __esm({
1728
1734
  await this.http.post("/v1/batch/objects", payload);
1729
1735
  }
1730
1736
  async query(vector, topK, namespace, _filter) {
1731
- var _a, _b;
1737
+ var _a2, _b;
1732
1738
  const queryText = _filter == null ? void 0 : _filter.queryText;
1733
1739
  const sanitizedFilter = this.sanitizeFilter(_filter);
1734
1740
  const searchParams = queryText ? `hybrid: { query: ${JSON.stringify(queryText)}, alpha: 0.5 }` : `nearVector: { vector: ${JSON.stringify(vector)} }`;
@@ -1754,7 +1760,7 @@ var init_WeaviateProvider = __esm({
1754
1760
  `
1755
1761
  };
1756
1762
  const { data } = await this.http.post("/v1/graphql", graphqlQuery);
1757
- const results = ((_b = (_a = data.data) == null ? void 0 : _a.Get) == null ? void 0 : _b[this.indexName]) || [];
1763
+ const results = ((_b = (_a2 = data.data) == null ? void 0 : _a2.Get) == null ? void 0 : _b[this.indexName]) || [];
1758
1764
  return results.map((res) => ({
1759
1765
  id: res["_additional"].id,
1760
1766
  score: 1 - res["_additional"].distance,
@@ -1807,10 +1813,10 @@ var init_WeaviateProvider = __esm({
1807
1813
  return `{ operator: And, operands: [${operands.join(", ")}] }`;
1808
1814
  }
1809
1815
  weaviateOperand(key, value) {
1810
- const path = `path: [${JSON.stringify(key)}], operator: Equal`;
1811
- if (typeof value === "number") return `{ ${path}, valueNumber: ${value} }`;
1812
- if (typeof value === "boolean") return `{ ${path}, valueBoolean: ${value} }`;
1813
- return `{ ${path}, valueString: ${JSON.stringify(value)} }`;
1816
+ const path2 = `path: [${JSON.stringify(key)}], operator: Equal`;
1817
+ if (typeof value === "number") return `{ ${path2}, valueNumber: ${value} }`;
1818
+ if (typeof value === "boolean") return `{ ${path2}, valueBoolean: ${value} }`;
1819
+ return `{ ${path2}, valueString: ${JSON.stringify(value)} }`;
1814
1820
  }
1815
1821
  };
1816
1822
  }
@@ -1837,21 +1843,21 @@ var init_UniversalVectorProvider = __esm({
1837
1843
  }
1838
1844
  }
1839
1845
  async initialize() {
1840
- var _a;
1846
+ var _a2;
1841
1847
  this.http = axios8.create({
1842
1848
  baseURL: this.opts.baseUrl,
1843
1849
  headers: __spreadValues({
1844
1850
  "Content-Type": "application/json"
1845
1851
  }, this.opts.headers),
1846
- timeout: (_a = this.opts.timeout) != null ? _a : 3e4
1852
+ timeout: (_a2 = this.opts.timeout) != null ? _a2 : 3e4
1847
1853
  });
1848
1854
  if (!await this.ping()) {
1849
1855
  throw new Error(`[UniversalVectorProvider] Failed to connect to ${this.opts.baseUrl}`);
1850
1856
  }
1851
1857
  }
1852
1858
  async upsert(doc, namespace) {
1853
- var _a, _b, _c;
1854
- const endpoint = (_a = this.opts.upsertEndpoint) != null ? _a : "/upsert";
1859
+ var _a2, _b, _c;
1860
+ const endpoint = (_a2 = this.opts.upsertEndpoint) != null ? _a2 : "/upsert";
1855
1861
  const template = (_b = this.opts.upsertTemplate) != null ? _b : JSON.stringify({
1856
1862
  id: "{{id}}",
1857
1863
  vector: "{{vector}}",
@@ -1884,8 +1890,8 @@ var init_UniversalVectorProvider = __esm({
1884
1890
  }
1885
1891
  }
1886
1892
  async query(vector, topK, namespace, filter) {
1887
- var _a, _b;
1888
- const endpoint = (_a = this.opts.queryEndpoint) != null ? _a : "/query";
1893
+ var _a2, _b;
1894
+ const endpoint = (_a2 = this.opts.queryEndpoint) != null ? _a2 : "/query";
1889
1895
  const template = (_b = this.opts.queryTemplate) != null ? _b : JSON.stringify({
1890
1896
  vector: "{{vector}}",
1891
1897
  limit: "{{topK}}",
@@ -1911,12 +1917,12 @@ var init_UniversalVectorProvider = __esm({
1911
1917
  );
1912
1918
  }
1913
1919
  return results.map((item) => {
1914
- var _a2, _b2, _c, _d, _e, _f, _g;
1920
+ var _a3, _b2, _c, _d, _e, _f, _g2;
1915
1921
  return {
1916
- id: item[(_a2 = this.opts.queryIdField) != null ? _a2 : "id"],
1922
+ id: item[(_a3 = this.opts.queryIdField) != null ? _a3 : "id"],
1917
1923
  score: (_c = item[(_b2 = this.opts.queryScoreField) != null ? _b2 : "score"]) != null ? _c : 0,
1918
1924
  content: (_e = item[(_d = this.opts.queryContentField) != null ? _d : "content"]) != null ? _e : "",
1919
- metadata: (_g = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g : {}
1925
+ metadata: (_g2 = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g2 : {}
1920
1926
  };
1921
1927
  });
1922
1928
  } catch (error) {
@@ -1926,8 +1932,8 @@ var init_UniversalVectorProvider = __esm({
1926
1932
  }
1927
1933
  }
1928
1934
  async delete(id, namespace) {
1929
- var _a, _b;
1930
- const endpoint = (_a = this.opts.deleteEndpoint) != null ? _a : "/delete";
1935
+ var _a2, _b;
1936
+ const endpoint = (_a2 = this.opts.deleteEndpoint) != null ? _a2 : "/delete";
1931
1937
  const template = (_b = this.opts.deleteTemplate) != null ? _b : JSON.stringify({
1932
1938
  id: "{{id}}",
1933
1939
  namespace: "{{namespace}}"
@@ -1945,8 +1951,8 @@ var init_UniversalVectorProvider = __esm({
1945
1951
  }
1946
1952
  }
1947
1953
  async deleteNamespace(namespace) {
1948
- var _a;
1949
- const endpoint = (_a = this.opts.deleteNamespaceEndpoint) != null ? _a : "/delete-namespace";
1954
+ var _a2;
1955
+ const endpoint = (_a2 = this.opts.deleteNamespaceEndpoint) != null ? _a2 : "/delete-namespace";
1950
1956
  try {
1951
1957
  await this.http.post(endpoint, { namespace });
1952
1958
  } catch (error) {
@@ -1956,9 +1962,9 @@ var init_UniversalVectorProvider = __esm({
1956
1962
  }
1957
1963
  }
1958
1964
  async ping() {
1959
- var _a;
1965
+ var _a2;
1960
1966
  try {
1961
- const endpoint = (_a = this.opts.pingEndpoint) != null ? _a : "/health";
1967
+ const endpoint = (_a2 = this.opts.pingEndpoint) != null ? _a2 : "/health";
1962
1968
  const response = await this.http.get(endpoint, { timeout: 5e3 });
1963
1969
  return response.status >= 200 && response.status < 300;
1964
1970
  } catch (e) {
@@ -2069,6 +2075,8 @@ var LLM_PROVIDERS = [
2069
2075
  "anthropic",
2070
2076
  "ollama",
2071
2077
  "gemini",
2078
+ "groq",
2079
+ "qwen",
2072
2080
  "rest",
2073
2081
  "universal_rest",
2074
2082
  "custom"
@@ -2077,6 +2085,7 @@ var EMBEDDING_PROVIDERS = [
2077
2085
  "openai",
2078
2086
  "ollama",
2079
2087
  "gemini",
2088
+ "qwen",
2080
2089
  "rest",
2081
2090
  "universal_rest",
2082
2091
  "custom"
@@ -2085,6 +2094,7 @@ var PROVIDERS_WITH_EMBEDDINGS = [
2085
2094
  "openai",
2086
2095
  "ollama",
2087
2096
  "gemini",
2097
+ "qwen",
2088
2098
  "rest",
2089
2099
  "universal_rest"
2090
2100
  ];
@@ -2092,8 +2102,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
2092
2102
 
2093
2103
  // src/config/serverConfig.ts
2094
2104
  function readString(env, name) {
2095
- var _a;
2096
- const value = (_a = env[name]) == null ? void 0 : _a.trim();
2105
+ var _a2;
2106
+ const value = (_a2 = env[name]) == null ? void 0 : _a2.trim();
2097
2107
  return value ? value : void 0;
2098
2108
  }
2099
2109
  function readNumber(env, name, fallback) {
@@ -2106,8 +2116,8 @@ function readNumber(env, name, fallback) {
2106
2116
  return parsed;
2107
2117
  }
2108
2118
  function readEnum(env, name, fallback, allowed) {
2109
- var _a;
2110
- const value = (_a = readString(env, name)) != null ? _a : fallback;
2119
+ var _a2;
2120
+ const value = (_a2 = readString(env, name)) != null ? _a2 : fallback;
2111
2121
  if (allowed.includes(value)) {
2112
2122
  return value;
2113
2123
  }
@@ -2117,15 +2127,15 @@ function getRagConfig(baseConfig, env = process.env) {
2117
2127
  return getEnvConfig(env, baseConfig);
2118
2128
  }
2119
2129
  function getEnvConfig(env = process.env, base) {
2120
- 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;
2121
- 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__";
2130
+ 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;
2131
+ 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__";
2122
2132
  const vectorProvider = readEnum(env, "VECTOR_DB_PROVIDER", "pinecone", VECTOR_DB_PROVIDERS);
2123
2133
  const llmProvider = readEnum(env, "LLM_PROVIDER", "openai", LLM_PROVIDERS);
2124
2134
  const embeddingProvider = readEnum(env, "EMBEDDING_PROVIDER", "openai", EMBEDDING_PROVIDERS);
2125
2135
  const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 1536);
2126
2136
  const vectorDbOptions = {};
2127
2137
  if (vectorProvider === "pinecone") {
2128
- 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 : "";
2138
+ 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 : "";
2129
2139
  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;
2130
2140
  } else if (vectorProvider === "pgvector" || vectorProvider === "postgresql") {
2131
2141
  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 : "";
@@ -2187,17 +2197,18 @@ function getEnvConfig(env = process.env, base) {
2187
2197
  rest: "default",
2188
2198
  custom: "default"
2189
2199
  };
2190
- return __spreadValues({
2200
+ return __spreadProps(__spreadValues({
2191
2201
  projectId,
2202
+ licenseKey: (_ha = (_ga = readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _ga : readString(env, "LICENSE_KEY")) != null ? _ha : base == null ? void 0 : base.licenseKey,
2192
2203
  vectorDb: {
2193
2204
  provider: vectorProvider,
2194
- indexName: (_ha = (_ga = readString(env, "VECTOR_DB_INDEX")) != null ? _ga : vectorDbOptions.indexName) != null ? _ha : "rag-index",
2205
+ indexName: (_ja = (_ia = readString(env, "VECTOR_DB_INDEX")) != null ? _ia : vectorDbOptions.indexName) != null ? _ja : "rag-index",
2195
2206
  options: vectorDbOptions
2196
2207
  },
2197
2208
  llm: {
2198
2209
  provider: llmProvider,
2199
- model: (_ja = (_ia = readString(env, "LLM_MODEL")) != null ? _ia : DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _ja : "gpt-4o",
2200
- apiKey: (_ka = llmApiKeyByProvider[llmProvider]) != null ? _ka : "",
2210
+ model: (_la = (_ka = readString(env, "LLM_MODEL")) != null ? _ka : DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _la : "gpt-4o",
2211
+ apiKey: (_ma = llmApiKeyByProvider[llmProvider]) != null ? _ma : "",
2201
2212
  baseUrl: readString(env, "LLM_BASE_URL"),
2202
2213
  systemPrompt: readString(env, "LLM_SYSTEM_PROMPT"),
2203
2214
  maxTokens: readNumber(env, "LLM_MAX_TOKENS", 4096),
@@ -2210,7 +2221,7 @@ function getEnvConfig(env = process.env, base) {
2210
2221
  },
2211
2222
  embedding: {
2212
2223
  provider: embeddingProvider,
2213
- model: (_la = readString(env, "EMBEDDING_MODEL")) != null ? _la : "text-embedding-3-small",
2224
+ model: (_na = readString(env, "EMBEDDING_MODEL")) != null ? _na : "text-embedding-3-small",
2214
2225
  apiKey: embeddingApiKeyByProvider[embeddingProvider],
2215
2226
  baseUrl: readString(env, "EMBEDDING_BASE_URL"),
2216
2227
  dimensions: embeddingDimensions,
@@ -2221,30 +2232,30 @@ function getEnvConfig(env = process.env, base) {
2221
2232
  }
2222
2233
  },
2223
2234
  ui: {
2224
- title: (_na = (_ma = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _ma : readString(env, "UI_TITLE")) != null ? _na : "AI Assistant",
2225
- subtitle: (_pa = (_oa = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _oa : readString(env, "UI_SUBTITLE")) != null ? _pa : "Powered by RAG",
2226
- primaryColor: (_ra = (_qa = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _qa : readString(env, "UI_PRIMARY_COLOR")) != null ? _ra : "#10b981",
2227
- accentColor: (_ta = (_sa = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _sa : readString(env, "UI_ACCENT_COLOR")) != null ? _ta : "#3b82f6",
2228
- logoUrl: (_ua = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _ua : readString(env, "UI_LOGO_URL"),
2229
- placeholder: (_wa = (_va = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _va : readString(env, "UI_PLACEHOLDER")) != null ? _wa : "Ask me anything\u2026",
2230
- showSources: ((_ya = (_xa = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _xa : readString(env, "UI_SHOW_SOURCES")) != null ? _ya : "true") !== "false",
2231
- 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.",
2232
- visualStyle: (_Ca = (_Ba = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _Ba : readString(env, "UI_VISUAL_STYLE")) != null ? _Ca : "glass",
2233
- borderRadius: (_Ea = (_Da = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _Da : readString(env, "UI_BORDER_RADIUS")) != null ? _Ea : "xl",
2234
- allowUpload: ((_Ga = (_Fa = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _Fa : readString(env, "UI_ALLOW_UPLOAD")) != null ? _Ga : "false") === "true"
2235
+ title: (_pa = (_oa = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _oa : readString(env, "UI_TITLE")) != null ? _pa : "AI Assistant",
2236
+ subtitle: (_ra = (_qa = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _qa : readString(env, "UI_SUBTITLE")) != null ? _ra : "Powered by RAG",
2237
+ primaryColor: (_ta = (_sa = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _sa : readString(env, "UI_PRIMARY_COLOR")) != null ? _ta : "#10b981",
2238
+ accentColor: (_va = (_ua = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _ua : readString(env, "UI_ACCENT_COLOR")) != null ? _va : "#3b82f6",
2239
+ logoUrl: (_wa = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _wa : readString(env, "UI_LOGO_URL"),
2240
+ placeholder: (_ya = (_xa = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _xa : readString(env, "UI_PLACEHOLDER")) != null ? _ya : "Ask me anything\u2026",
2241
+ showSources: ((_Aa = (_za = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _za : readString(env, "UI_SHOW_SOURCES")) != null ? _Aa : "true") !== "false",
2242
+ 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.",
2243
+ visualStyle: (_Ea = (_Da = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _Da : readString(env, "UI_VISUAL_STYLE")) != null ? _Ea : "glass",
2244
+ borderRadius: (_Ga = (_Fa = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _Fa : readString(env, "UI_BORDER_RADIUS")) != null ? _Ga : "xl",
2245
+ allowUpload: ((_Ia = (_Ha = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _Ha : readString(env, "UI_ALLOW_UPLOAD")) != null ? _Ia : "false") === "true"
2235
2246
  },
2236
2247
  rag: {
2237
2248
  topK: readNumber(env, "RAG_TOP_K", 5),
2238
2249
  scoreThreshold: readNumber(env, "RAG_SCORE_THRESHOLD", 0),
2239
2250
  chunkSize: readNumber(env, "RAG_CHUNK_SIZE", 1e3),
2240
2251
  chunkOverlap: readNumber(env, "RAG_CHUNK_OVERLAP", 200),
2241
- filterableFields: (_Ha = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _Ha.split(",").map((f) => f.trim()),
2252
+ filterableFields: (_Ja = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _Ja.split(",").map((f) => f.trim()),
2242
2253
  // Query pipeline toggles — read from .env.local
2243
2254
  useQueryTransformation: readString(env, "RAG_USE_QUERY_TRANSFORMATION") === "true",
2244
2255
  useReranking: readString(env, "RAG_USE_RERANKING") === "true",
2245
2256
  useGraphRetrieval: readString(env, "RAG_USE_GRAPH_RETRIEVAL") === "true",
2246
- architecture: (_Ia = readString(env, "RAG_ARCHITECTURE")) != null ? _Ia : "simple",
2247
- chunkingStrategy: (_Ja = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _Ja : "recursive",
2257
+ architecture: (_Ka = readString(env, "RAG_ARCHITECTURE")) != null ? _Ka : "simple",
2258
+ chunkingStrategy: (_La = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _La : "recursive",
2248
2259
  uiMapping: (() => {
2249
2260
  const raw = readString(env, "RAG_UI_MAPPING");
2250
2261
  if (!raw) return void 0;
@@ -2254,6 +2265,10 @@ function getEnvConfig(env = process.env, base) {
2254
2265
  return void 0;
2255
2266
  }
2256
2267
  })()
2268
+ },
2269
+ telemetry: {
2270
+ 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,
2271
+ 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"
2257
2272
  }
2258
2273
  }, readString(env, "GRAPH_DB_PROVIDER") ? {
2259
2274
  graphDb: {
@@ -2264,7 +2279,19 @@ function getEnvConfig(env = process.env, base) {
2264
2279
  password: readString(env, "GRAPH_DB_PASSWORD")
2265
2280
  }
2266
2281
  }
2267
- } : {});
2282
+ } : {}), {
2283
+ mcpServers: (() => {
2284
+ var _a3;
2285
+ const raw = (_a3 = readString(env, "MCP_SERVERS")) != null ? _a3 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
2286
+ if (!raw) return void 0;
2287
+ try {
2288
+ return JSON.parse(raw);
2289
+ } catch (e) {
2290
+ console.warn("[serverConfig] Failed to parse MCP_SERVERS env:", e);
2291
+ return void 0;
2292
+ }
2293
+ })()
2294
+ });
2268
2295
  }
2269
2296
 
2270
2297
  // src/core/ConfigResolver.ts
@@ -2290,7 +2317,8 @@ var ConfigResolver = class {
2290
2317
  options: __spreadValues(__spreadValues({}, envConfig.embedding.options || {}), hostConfig.embedding.options || {})
2291
2318
  }) : envConfig.embedding,
2292
2319
  ui: hostConfig.ui ? mergeDefined(envConfig.ui, hostConfig.ui) : envConfig.ui,
2293
- rag: hostConfig.rag ? __spreadValues(__spreadValues({}, envConfig.rag), hostConfig.rag) : envConfig.rag
2320
+ rag: hostConfig.rag ? __spreadValues(__spreadValues({}, envConfig.rag), hostConfig.rag) : envConfig.rag,
2321
+ telemetry: hostConfig.telemetry ? __spreadValues(__spreadValues({}, envConfig.telemetry), hostConfig.telemetry) : envConfig.telemetry
2294
2322
  });
2295
2323
  }
2296
2324
  /**
@@ -2299,10 +2327,10 @@ var ConfigResolver = class {
2299
2327
  * fallback behavior.
2300
2328
  */
2301
2329
  static resolveUniversal(hostConfig, env = process.env) {
2302
- var _a;
2330
+ var _a2;
2303
2331
  if (!hostConfig) return this.resolve(void 0, env);
2304
2332
  const normalized = __spreadProps(__spreadValues({}, hostConfig), {
2305
- vectorDb: (_a = hostConfig.vectorDb) != null ? _a : hostConfig.vectorDatabase,
2333
+ vectorDb: (_a2 = hostConfig.vectorDb) != null ? _a2 : hostConfig.vectorDatabase,
2306
2334
  rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
2307
2335
  });
2308
2336
  return this.resolve(normalized, env);
@@ -2322,28 +2350,52 @@ var ConfigResolver = class {
2322
2350
  }
2323
2351
  }
2324
2352
  static mergeRetrievalWorkflow(rag, retrieval, workflow) {
2325
- var _a, _b, _c, _d, _e;
2353
+ var _a2, _b, _c, _d, _e, _f;
2326
2354
  if (!rag && !retrieval && !workflow) return void 0;
2327
2355
  const normalized = __spreadValues({}, rag != null ? rag : {});
2328
2356
  if (retrieval) {
2329
- normalized.topK = (_a = retrieval.topK) != null ? _a : normalized.topK;
2357
+ normalized.topK = (_a2 = retrieval.topK) != null ? _a2 : normalized.topK;
2330
2358
  normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
2331
2359
  normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
2332
2360
  if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
2333
- if (retrieval.strategy === "agentic") normalized.architecture = "agentic";
2334
- if (retrieval.strategy === "contextual-compression") normalized.useReranking = true;
2361
+ if (retrieval.strategy === "agentic") normalized.architecture = "multi-agent";
2362
+ if (retrieval.strategy === "contextual-compression") {
2363
+ normalized.useReranking = true;
2364
+ normalized.architecture = (_e = normalized.architecture) != null ? _e : "retrieve-and-rerank";
2365
+ }
2335
2366
  }
2336
2367
  if (workflow == null ? void 0 : workflow.type) {
2337
2368
  const type = workflow.type;
2338
- if (type === "agentic" || type === "agentic-rag") normalized.architecture = "agentic";
2339
- else if (type === "hybrid-rag") normalized.architecture = "hybrid";
2340
- else if (type === "graph-rag") {
2369
+ if (type === "naive-rag") {
2370
+ normalized.architecture = "naive";
2371
+ normalized.useReranking = false;
2372
+ normalized.useGraphRetrieval = false;
2373
+ } else if (type === "retrieve-and-rerank") {
2374
+ normalized.architecture = "retrieve-and-rerank";
2375
+ normalized.useReranking = true;
2376
+ } else if (type === "multimodal-rag") {
2377
+ normalized.architecture = "multimodal";
2378
+ } else if (type === "graph-rag") {
2341
2379
  normalized.architecture = "graph";
2342
2380
  normalized.useGraphRetrieval = true;
2381
+ } else if (type === "hybrid-rag") {
2382
+ normalized.architecture = "hybrid";
2383
+ } else if (type === "agentic-router") {
2384
+ normalized.architecture = "agentic-router";
2385
+ } else if (type === "multi-agent-rag" || type === "multi-agent" || type === "agentic" || type === "agentic-rag") {
2386
+ normalized.architecture = "multi-agent";
2343
2387
  } else if (type === "simple-rag" || type === "rag") {
2344
- normalized.architecture = (_e = normalized.architecture) != null ? _e : "simple";
2388
+ normalized.architecture = (_f = normalized.architecture) != null ? _f : "naive";
2345
2389
  }
2346
2390
  }
2391
+ if (normalized.architecture === "retrieve-and-rerank") {
2392
+ normalized.useReranking = true;
2393
+ } else if (normalized.architecture === "graph") {
2394
+ normalized.useGraphRetrieval = true;
2395
+ } else if (normalized.architecture === "naive") {
2396
+ normalized.useReranking = false;
2397
+ normalized.useGraphRetrieval = false;
2398
+ }
2347
2399
  return normalized;
2348
2400
  }
2349
2401
  };
@@ -2408,8 +2460,8 @@ var OpenAIProvider = class {
2408
2460
  const apiKey = config.apiKey;
2409
2461
  const modelName = config.model;
2410
2462
  try {
2411
- const OpenAI2 = await import("openai");
2412
- const client = new OpenAI2.default({ apiKey });
2463
+ const OpenAI4 = await import("openai");
2464
+ const client = new OpenAI4.default({ apiKey });
2413
2465
  const models = await client.models.list();
2414
2466
  const hasModel = models.data.some((m) => m.id === modelName);
2415
2467
  return {
@@ -2430,8 +2482,8 @@ var OpenAIProvider = class {
2430
2482
  };
2431
2483
  }
2432
2484
  async chat(messages, context, options) {
2433
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2434
- 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.";
2485
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
2486
+ 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.";
2435
2487
  const systemMessage = {
2436
2488
  role: "system",
2437
2489
  content: buildSystemContent(basePrompt, context)
@@ -2450,12 +2502,12 @@ var OpenAIProvider = class {
2450
2502
  temperature: (_f = (_e = options == null ? void 0 : options.temperature) != null ? _e : this.llmConfig.temperature) != null ? _f : 0.7,
2451
2503
  stop: options == null ? void 0 : options.stop
2452
2504
  });
2453
- return (_i = (_h = (_g = completion.choices[0]) == null ? void 0 : _g.message) == null ? void 0 : _h.content) != null ? _i : "";
2505
+ return (_i = (_h = (_g2 = completion.choices[0]) == null ? void 0 : _g2.message) == null ? void 0 : _h.content) != null ? _i : "";
2454
2506
  }
2455
2507
  chatStream(messages, context, options) {
2456
2508
  return __asyncGenerator(this, null, function* () {
2457
- var _a, _b, _c, _d, _e, _f, _g, _h;
2458
- 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.";
2509
+ var _a2, _b, _c, _d, _e, _f, _g2, _h;
2510
+ 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.";
2459
2511
  const systemMessage = {
2460
2512
  role: "system",
2461
2513
  content: buildSystemContent(basePrompt, context)
@@ -2481,7 +2533,7 @@ var OpenAIProvider = class {
2481
2533
  try {
2482
2534
  for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
2483
2535
  const chunk = temp.value;
2484
- const content = ((_h = (_g = chunk.choices[0]) == null ? void 0 : _g.delta) == null ? void 0 : _h.content) || "";
2536
+ const content = ((_h = (_g2 = chunk.choices[0]) == null ? void 0 : _g2.delta) == null ? void 0 : _h.content) || "";
2485
2537
  if (content) yield content;
2486
2538
  }
2487
2539
  } catch (temp) {
@@ -2501,8 +2553,8 @@ var OpenAIProvider = class {
2501
2553
  return results[0];
2502
2554
  }
2503
2555
  async batchEmbed(texts, options) {
2504
- var _a, _b, _c, _d, _e;
2505
- 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";
2556
+ var _a2, _b, _c, _d, _e;
2557
+ 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";
2506
2558
  const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
2507
2559
  const client = apiKey !== this.llmConfig.apiKey ? new OpenAI({ apiKey }) : this.client;
2508
2560
  const response = await client.embeddings.create({ model, input: texts });
@@ -2579,8 +2631,8 @@ var AnthropicProvider = class {
2579
2631
  };
2580
2632
  }
2581
2633
  async chat(messages, context, options) {
2582
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2583
- 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.";
2634
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
2635
+ 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.";
2584
2636
  const system = buildSystemContent(basePrompt, context);
2585
2637
  const anthropicMessages = messages.map((m) => ({
2586
2638
  role: m.role === "assistant" ? "assistant" : "user",
@@ -2591,7 +2643,7 @@ var AnthropicProvider = class {
2591
2643
  const extraParams = {};
2592
2644
  if (isThinkingEnabled && isClaude37) {
2593
2645
  extraParams.betas = ["interleaved-thinking-2025-05-14"];
2594
- const maxTokens = (_g = (_f = options == null ? void 0 : options.maxTokens) != null ? _f : this.llmConfig.maxTokens) != null ? _g : 4096;
2646
+ const maxTokens = (_g2 = (_f = options == null ? void 0 : options.maxTokens) != null ? _f : this.llmConfig.maxTokens) != null ? _g2 : 4096;
2595
2647
  const budget = Math.min(
2596
2648
  typeof ((_h = this.llmConfig.options) == null ? void 0 : _h.thinkingBudget) === "number" ? (_i = this.llmConfig.options) == null ? void 0 : _i.thinkingBudget : 2048,
2597
2649
  maxTokens - 1
@@ -2618,8 +2670,8 @@ var AnthropicProvider = class {
2618
2670
  }
2619
2671
  chatStream(messages, context, options) {
2620
2672
  return __asyncGenerator(this, null, function* () {
2621
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2622
- 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.";
2673
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
2674
+ 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.";
2623
2675
  const system = buildSystemContent(basePrompt, context);
2624
2676
  const anthropicMessages = messages.map((m) => ({
2625
2677
  role: m.role === "assistant" ? "assistant" : "user",
@@ -2630,7 +2682,7 @@ var AnthropicProvider = class {
2630
2682
  const extraParams = {};
2631
2683
  if (isThinkingEnabled && isClaude37) {
2632
2684
  extraParams.betas = ["interleaved-thinking-2025-05-14"];
2633
- const maxTokens = (_g = (_f = options == null ? void 0 : options.maxTokens) != null ? _f : this.llmConfig.maxTokens) != null ? _g : 4096;
2685
+ const maxTokens = (_g2 = (_f = options == null ? void 0 : options.maxTokens) != null ? _f : this.llmConfig.maxTokens) != null ? _g2 : 4096;
2634
2686
  const budget = Math.min(
2635
2687
  typeof ((_h = this.llmConfig.options) == null ? void 0 : _h.thinkingBudget) === "number" ? (_i = this.llmConfig.options) == null ? void 0 : _i.thinkingBudget : 2048,
2636
2688
  maxTokens - 1
@@ -2703,8 +2755,8 @@ var AnthropicProvider = class {
2703
2755
  import axios from "axios";
2704
2756
  var OllamaProvider = class {
2705
2757
  constructor(llmConfig, embeddingConfig) {
2706
- var _a, _b;
2707
- const baseURL = (_a = llmConfig.baseUrl) != null ? _a : "http://localhost:11434";
2758
+ var _a2, _b;
2759
+ const baseURL = (_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434";
2708
2760
  const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
2709
2761
  this.http = axios.create({ baseURL, timeout });
2710
2762
  this.llmConfig = llmConfig;
@@ -2762,8 +2814,8 @@ var OllamaProvider = class {
2762
2814
  };
2763
2815
  }
2764
2816
  async chat(messages, context, options) {
2765
- var _a, _b, _c, _d, _e, _f;
2766
- 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.";
2817
+ var _a2, _b, _c, _d, _e, _f;
2818
+ 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.";
2767
2819
  const system = buildSystemContent(basePrompt, context);
2768
2820
  const { data } = await this.http.post("/api/chat", {
2769
2821
  model: this.llmConfig.model,
@@ -2781,8 +2833,8 @@ var OllamaProvider = class {
2781
2833
  }
2782
2834
  chatStream(messages, context, options) {
2783
2835
  return __asyncGenerator(this, null, function* () {
2784
- var _a, _b, _c, _d, _e, _f, _g, _h;
2785
- 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.";
2836
+ var _a2, _b, _c, _d, _e, _f, _g2, _h;
2837
+ 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.";
2786
2838
  const system = buildSystemContent(basePrompt, context);
2787
2839
  const response = yield new __await(this.http.post("/api/chat", {
2788
2840
  model: this.llmConfig.model,
@@ -2811,7 +2863,7 @@ var OllamaProvider = class {
2811
2863
  if (!line.trim()) continue;
2812
2864
  try {
2813
2865
  const json = JSON.parse(line);
2814
- if ((_g = json.message) == null ? void 0 : _g.content) {
2866
+ if ((_g2 = json.message) == null ? void 0 : _g2.content) {
2815
2867
  yield json.message.content;
2816
2868
  }
2817
2869
  if (json.done) return;
@@ -2840,10 +2892,10 @@ var OllamaProvider = class {
2840
2892
  });
2841
2893
  }
2842
2894
  async embed(text, options) {
2843
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2844
- 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";
2895
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
2896
+ 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";
2845
2897
  const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
2846
- const client = baseURL !== ((_g = this.llmConfig.baseUrl) != null ? _g : "http://localhost:11434") ? axios.create({ baseURL, timeout: 6e4 }) : this.http;
2898
+ const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? axios.create({ baseURL, timeout: 6e4 }) : this.http;
2847
2899
  let prompt = text;
2848
2900
  const queryPrefix = (_i = (_h = this.embeddingConfig) == null ? void 0 : _h.queryPrefix) != null ? _i : model.includes("nomic") ? "search_query: " : "";
2849
2901
  const docPrefix = (_k = (_j = this.embeddingConfig) == null ? void 0 : _j.documentPrefix) != null ? _k : model.includes("nomic") ? "search_document: " : "";
@@ -2942,9 +2994,9 @@ var GeminiProvider = class {
2942
2994
  static getHealthChecker() {
2943
2995
  return {
2944
2996
  async check(config) {
2945
- var _a, _b;
2997
+ var _a2, _b;
2946
2998
  const timestamp = Date.now();
2947
- const apiKey = (_b = (_a = config.apiKey) != null ? _a : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
2999
+ const apiKey = (_b = (_a2 = config.apiKey) != null ? _a2 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
2948
3000
  const modelName = sanitizeModel(config.model);
2949
3001
  try {
2950
3002
  const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
@@ -2974,16 +3026,16 @@ var GeminiProvider = class {
2974
3026
  /** Resolve the embedding client — uses a separate client when the embedding
2975
3027
  * API key differs from the LLM API key. */
2976
3028
  get embeddingClient() {
2977
- var _a;
2978
- if (((_a = this.embeddingConfig) == null ? void 0 : _a.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
3029
+ var _a2;
3030
+ if (((_a2 = this.embeddingConfig) == null ? void 0 : _a2.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
2979
3031
  return buildClient(this.embeddingConfig.apiKey);
2980
3032
  }
2981
3033
  return this.client;
2982
3034
  }
2983
3035
  /** Resolve the embedding model to use, in order of specificity. */
2984
3036
  resolveEmbeddingModel(optionsModel) {
2985
- var _a, _b;
2986
- return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a = this.embeddingConfig) == null ? void 0 : _a.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
3037
+ var _a2, _b;
3038
+ return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a2 = this.embeddingConfig) == null ? void 0 : _a2.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
2987
3039
  }
2988
3040
  /**
2989
3041
  * Convert ChatMessage[] to the Gemini contents format.
@@ -3003,8 +3055,8 @@ var GeminiProvider = class {
3003
3055
  // ILLMProvider — chat
3004
3056
  // -------------------------------------------------------------------------
3005
3057
  async chat(messages, context, options) {
3006
- var _a, _b, _c, _d, _e, _f;
3007
- 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.";
3058
+ var _a2, _b, _c, _d, _e, _f;
3059
+ 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.";
3008
3060
  const model = this.client.getGenerativeModel({
3009
3061
  model: this.llmConfig.model,
3010
3062
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3021,8 +3073,8 @@ var GeminiProvider = class {
3021
3073
  }
3022
3074
  chatStream(messages, context, options) {
3023
3075
  return __asyncGenerator(this, null, function* () {
3024
- var _a, _b, _c, _d, _e, _f;
3025
- 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.";
3076
+ var _a2, _b, _c, _d, _e, _f;
3077
+ 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.";
3026
3078
  const model = this.client.getGenerativeModel({
3027
3079
  model: this.llmConfig.model,
3028
3080
  systemInstruction: buildSystemContent(basePrompt, context)
@@ -3057,11 +3109,11 @@ var GeminiProvider = class {
3057
3109
  // ILLMProvider — embeddings
3058
3110
  // -------------------------------------------------------------------------
3059
3111
  async embed(text, options) {
3060
- var _a, _b;
3112
+ var _a2, _b;
3061
3113
  const content = applyPrefix(
3062
3114
  text,
3063
3115
  options == null ? void 0 : options.taskType,
3064
- (_a = this.embeddingConfig) == null ? void 0 : _a.queryPrefix,
3116
+ (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3065
3117
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3066
3118
  );
3067
3119
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
@@ -3078,7 +3130,7 @@ var GeminiProvider = class {
3078
3130
  const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
3079
3131
  const model = this.embeddingClient.getGenerativeModel({ model: modelName });
3080
3132
  const requests = texts.map((text) => {
3081
- var _a, _b;
3133
+ var _a2, _b;
3082
3134
  return {
3083
3135
  content: {
3084
3136
  role: "user",
@@ -3086,7 +3138,7 @@ var GeminiProvider = class {
3086
3138
  text: applyPrefix(
3087
3139
  text,
3088
3140
  options == null ? void 0 : options.taskType,
3089
- (_a = this.embeddingConfig) == null ? void 0 : _a.queryPrefix,
3141
+ (_a2 = this.embeddingConfig) == null ? void 0 : _a2.queryPrefix,
3090
3142
  (_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
3091
3143
  )
3092
3144
  }]
@@ -3103,8 +3155,8 @@ var GeminiProvider = class {
3103
3155
  throw err;
3104
3156
  });
3105
3157
  return response.embeddings.map((e) => {
3106
- var _a;
3107
- return (_a = e.values) != null ? _a : [];
3158
+ var _a2;
3159
+ return (_a2 = e.values) != null ? _a2 : [];
3108
3160
  });
3109
3161
  }
3110
3162
  // -------------------------------------------------------------------------
@@ -3124,6 +3176,325 @@ var GeminiProvider = class {
3124
3176
  }
3125
3177
  };
3126
3178
 
3179
+ // src/llm/providers/GroqProvider.ts
3180
+ import OpenAI2 from "openai";
3181
+ var GroqProvider = class {
3182
+ constructor(llmConfig, embeddingConfig) {
3183
+ void embeddingConfig;
3184
+ const apiKey = llmConfig.apiKey || process.env.GROQ_API_KEY;
3185
+ if (!apiKey) throw new Error("[GroqProvider] llmConfig.apiKey or GROQ_API_KEY environment variable is required");
3186
+ this.client = new OpenAI2({
3187
+ apiKey,
3188
+ baseURL: llmConfig.baseUrl || "https://api.groq.com/openai/v1"
3189
+ });
3190
+ this.llmConfig = llmConfig;
3191
+ }
3192
+ static getValidator() {
3193
+ return {
3194
+ validate(config) {
3195
+ const errors = [];
3196
+ if (!config.apiKey && !process.env.GROQ_API_KEY) {
3197
+ errors.push({
3198
+ field: "llm.apiKey",
3199
+ message: "Groq API key is required",
3200
+ suggestion: "Set GROQ_API_KEY environment variable",
3201
+ severity: "error"
3202
+ });
3203
+ }
3204
+ if (!config.model) {
3205
+ errors.push({
3206
+ field: "llm.model",
3207
+ message: "Groq model name is required",
3208
+ suggestion: 'e.g., "llama-3.3-70b-versatile"',
3209
+ severity: "error"
3210
+ });
3211
+ }
3212
+ return errors;
3213
+ }
3214
+ };
3215
+ }
3216
+ static getHealthChecker() {
3217
+ return {
3218
+ async check(config) {
3219
+ const timestamp = Date.now();
3220
+ const apiKey = config.apiKey || process.env.GROQ_API_KEY || "";
3221
+ const modelName = config.model;
3222
+ try {
3223
+ const OpenAI4 = await import("openai");
3224
+ const client = new OpenAI4.default({
3225
+ apiKey,
3226
+ baseURL: config.baseUrl || "https://api.groq.com/openai/v1"
3227
+ });
3228
+ const models = await client.models.list();
3229
+ const hasModel = models.data.some((m) => m.id === modelName);
3230
+ return {
3231
+ healthy: true,
3232
+ provider: "groq",
3233
+ capabilities: { model: modelName, available: hasModel, totalModels: models.data.length },
3234
+ timestamp
3235
+ };
3236
+ } catch (error) {
3237
+ return {
3238
+ healthy: false,
3239
+ provider: "groq",
3240
+ error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
3241
+ timestamp
3242
+ };
3243
+ }
3244
+ }
3245
+ };
3246
+ }
3247
+ async chat(messages, context, options) {
3248
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3249
+ 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.";
3250
+ const systemMessage = {
3251
+ role: "system",
3252
+ content: buildSystemContent(basePrompt, context)
3253
+ };
3254
+ const formattedMessages = [
3255
+ systemMessage,
3256
+ ...messages.map((m) => ({
3257
+ role: m.role,
3258
+ content: m.content
3259
+ }))
3260
+ ];
3261
+ const completion = await this.client.chat.completions.create({
3262
+ model: this.llmConfig.model,
3263
+ messages: formattedMessages,
3264
+ max_tokens: (_d = (_c = options == null ? void 0 : options.maxTokens) != null ? _c : this.llmConfig.maxTokens) != null ? _d : 1024,
3265
+ temperature: (_f = (_e = options == null ? void 0 : options.temperature) != null ? _e : this.llmConfig.temperature) != null ? _f : 0.7,
3266
+ stop: options == null ? void 0 : options.stop
3267
+ });
3268
+ return (_i = (_h = (_g2 = completion.choices[0]) == null ? void 0 : _g2.message) == null ? void 0 : _h.content) != null ? _i : "";
3269
+ }
3270
+ chatStream(messages, context, options) {
3271
+ return __asyncGenerator(this, null, function* () {
3272
+ var _a2, _b, _c, _d, _e, _f, _g2, _h;
3273
+ 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.";
3274
+ const systemMessage = {
3275
+ role: "system",
3276
+ content: buildSystemContent(basePrompt, context)
3277
+ };
3278
+ const formattedMessages = [
3279
+ systemMessage,
3280
+ ...messages.map((m) => ({
3281
+ role: m.role,
3282
+ content: m.content
3283
+ }))
3284
+ ];
3285
+ const stream = yield new __await(this.client.chat.completions.create({
3286
+ model: this.llmConfig.model,
3287
+ messages: formattedMessages,
3288
+ max_tokens: (_d = (_c = options == null ? void 0 : options.maxTokens) != null ? _c : this.llmConfig.maxTokens) != null ? _d : 1024,
3289
+ temperature: (_f = (_e = options == null ? void 0 : options.temperature) != null ? _e : this.llmConfig.temperature) != null ? _f : 0.7,
3290
+ stop: options == null ? void 0 : options.stop,
3291
+ stream: true
3292
+ }));
3293
+ if (!stream) {
3294
+ throw new Error("[GroqProvider] completions.create stream is undefined");
3295
+ }
3296
+ try {
3297
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
3298
+ const chunk = temp.value;
3299
+ const content = ((_h = (_g2 = chunk.choices[0]) == null ? void 0 : _g2.delta) == null ? void 0 : _h.content) || "";
3300
+ if (content) yield content;
3301
+ }
3302
+ } catch (temp) {
3303
+ error = [temp];
3304
+ } finally {
3305
+ try {
3306
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
3307
+ } finally {
3308
+ if (error)
3309
+ throw error[0];
3310
+ }
3311
+ }
3312
+ });
3313
+ }
3314
+ async embed(text, options) {
3315
+ void text;
3316
+ void options;
3317
+ throw new Error('[GroqProvider] Groq does not provide a native embedding API. Please configure "openai" or "gemini" for embeddings in RagConfig.');
3318
+ }
3319
+ async batchEmbed(texts, options) {
3320
+ void texts;
3321
+ void options;
3322
+ throw new Error('[GroqProvider] Groq does not provide a native embedding API. Please configure "openai" or "gemini" for embeddings in RagConfig.');
3323
+ }
3324
+ async ping() {
3325
+ try {
3326
+ await this.client.models.list();
3327
+ return true;
3328
+ } catch (err) {
3329
+ console.error("[GroqProvider] Ping failed:", err);
3330
+ return false;
3331
+ }
3332
+ }
3333
+ };
3334
+
3335
+ // src/llm/providers/QwenProvider.ts
3336
+ import OpenAI3 from "openai";
3337
+ var QwenProvider = class {
3338
+ constructor(llmConfig, embeddingConfig) {
3339
+ const apiKey = llmConfig.apiKey || process.env.DASHSCOPE_API_KEY || process.env.QWEN_API_KEY;
3340
+ if (!apiKey) throw new Error("[QwenProvider] llmConfig.apiKey, DASHSCOPE_API_KEY, or QWEN_API_KEY environment variable is required");
3341
+ this.client = new OpenAI3({
3342
+ apiKey,
3343
+ baseURL: llmConfig.baseUrl || "https://dashscope.aliyuncs.com/compatible-mode/v1"
3344
+ });
3345
+ this.llmConfig = llmConfig;
3346
+ this.embeddingConfig = embeddingConfig;
3347
+ }
3348
+ static getValidator() {
3349
+ return {
3350
+ validate(config) {
3351
+ const errors = [];
3352
+ const isEmbedding = config.provider === "qwen" && "dimensions" in config;
3353
+ const prefix = isEmbedding ? "embedding" : "llm";
3354
+ if (!config.apiKey && !process.env.DASHSCOPE_API_KEY && !process.env.QWEN_API_KEY) {
3355
+ errors.push({
3356
+ field: `${prefix}.apiKey`,
3357
+ message: "Qwen API key is required",
3358
+ suggestion: "Set DASHSCOPE_API_KEY or QWEN_API_KEY environment variable",
3359
+ severity: "error"
3360
+ });
3361
+ }
3362
+ if (!config.model) {
3363
+ errors.push({
3364
+ field: `${prefix}.model`,
3365
+ message: "Qwen model name is required",
3366
+ suggestion: isEmbedding ? 'e.g., "text-embedding-v3"' : 'e.g., "qwen-plus" or "qwen-max"',
3367
+ severity: "error"
3368
+ });
3369
+ }
3370
+ return errors;
3371
+ }
3372
+ };
3373
+ }
3374
+ static getHealthChecker() {
3375
+ return {
3376
+ async check(config) {
3377
+ const timestamp = Date.now();
3378
+ const apiKey = config.apiKey || process.env.DASHSCOPE_API_KEY || process.env.QWEN_API_KEY || "";
3379
+ const modelName = config.model;
3380
+ try {
3381
+ const OpenAI4 = await import("openai");
3382
+ const client = new OpenAI4.default({
3383
+ apiKey,
3384
+ baseURL: config.baseUrl || "https://dashscope.aliyuncs.com/compatible-mode/v1"
3385
+ });
3386
+ const models = await client.models.list();
3387
+ const hasModel = models.data.some((m) => m.id === modelName);
3388
+ return {
3389
+ healthy: true,
3390
+ provider: "qwen",
3391
+ capabilities: { model: modelName, available: hasModel, totalModels: models.data.length },
3392
+ timestamp
3393
+ };
3394
+ } catch (error) {
3395
+ return {
3396
+ healthy: false,
3397
+ provider: "qwen",
3398
+ error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
3399
+ timestamp
3400
+ };
3401
+ }
3402
+ }
3403
+ };
3404
+ }
3405
+ async chat(messages, context, options) {
3406
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i;
3407
+ 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.";
3408
+ const systemMessage = {
3409
+ role: "system",
3410
+ content: buildSystemContent(basePrompt, context)
3411
+ };
3412
+ const formattedMessages = [
3413
+ systemMessage,
3414
+ ...messages.map((m) => ({
3415
+ role: m.role,
3416
+ content: m.content
3417
+ }))
3418
+ ];
3419
+ const completion = await this.client.chat.completions.create({
3420
+ model: this.llmConfig.model,
3421
+ messages: formattedMessages,
3422
+ max_tokens: (_d = (_c = options == null ? void 0 : options.maxTokens) != null ? _c : this.llmConfig.maxTokens) != null ? _d : 1024,
3423
+ temperature: (_f = (_e = options == null ? void 0 : options.temperature) != null ? _e : this.llmConfig.temperature) != null ? _f : 0.7,
3424
+ stop: options == null ? void 0 : options.stop
3425
+ });
3426
+ return (_i = (_h = (_g2 = completion.choices[0]) == null ? void 0 : _g2.message) == null ? void 0 : _h.content) != null ? _i : "";
3427
+ }
3428
+ chatStream(messages, context, options) {
3429
+ return __asyncGenerator(this, null, function* () {
3430
+ var _a2, _b, _c, _d, _e, _f, _g2, _h;
3431
+ 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.";
3432
+ const systemMessage = {
3433
+ role: "system",
3434
+ content: buildSystemContent(basePrompt, context)
3435
+ };
3436
+ const formattedMessages = [
3437
+ systemMessage,
3438
+ ...messages.map((m) => ({
3439
+ role: m.role,
3440
+ content: m.content
3441
+ }))
3442
+ ];
3443
+ const stream = yield new __await(this.client.chat.completions.create({
3444
+ model: this.llmConfig.model,
3445
+ messages: formattedMessages,
3446
+ max_tokens: (_d = (_c = options == null ? void 0 : options.maxTokens) != null ? _c : this.llmConfig.maxTokens) != null ? _d : 1024,
3447
+ temperature: (_f = (_e = options == null ? void 0 : options.temperature) != null ? _e : this.llmConfig.temperature) != null ? _f : 0.7,
3448
+ stop: options == null ? void 0 : options.stop,
3449
+ stream: true
3450
+ }));
3451
+ if (!stream) {
3452
+ throw new Error("[QwenProvider] completions.create stream is undefined");
3453
+ }
3454
+ try {
3455
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
3456
+ const chunk = temp.value;
3457
+ const content = ((_h = (_g2 = chunk.choices[0]) == null ? void 0 : _g2.delta) == null ? void 0 : _h.content) || "";
3458
+ if (content) yield content;
3459
+ }
3460
+ } catch (temp) {
3461
+ error = [temp];
3462
+ } finally {
3463
+ try {
3464
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
3465
+ } finally {
3466
+ if (error)
3467
+ throw error[0];
3468
+ }
3469
+ }
3470
+ });
3471
+ }
3472
+ async embed(text, options) {
3473
+ const results = await this.batchEmbed([text], options);
3474
+ return results[0];
3475
+ }
3476
+ async batchEmbed(texts, options) {
3477
+ var _a2, _b, _c, _d, _e, _f;
3478
+ 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";
3479
+ const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
3480
+ const client = apiKey !== this.llmConfig.apiKey ? new OpenAI3({
3481
+ apiKey,
3482
+ baseURL: ((_f = this.embeddingConfig) == null ? void 0 : _f.baseUrl) || "https://dashscope.aliyuncs.com/compatible-mode/v1"
3483
+ }) : this.client;
3484
+ const response = await client.embeddings.create({ model, input: texts });
3485
+ return response.data.map((d) => d.embedding);
3486
+ }
3487
+ async ping() {
3488
+ try {
3489
+ await this.client.models.list();
3490
+ return true;
3491
+ } catch (err) {
3492
+ console.error("[QwenProvider] Ping failed:", err);
3493
+ return false;
3494
+ }
3495
+ }
3496
+ };
3497
+
3127
3498
  // src/llm/providers/UniversalLLMAdapter.ts
3128
3499
  init_templateUtils();
3129
3500
  import axios2 from "axios";
@@ -3207,10 +3578,10 @@ var VECTOR_PROFILES = {
3207
3578
  // src/llm/providers/UniversalLLMAdapter.ts
3208
3579
  var UniversalLLMAdapter = class {
3209
3580
  constructor(config) {
3210
- var _a, _b, _c, _d, _e, _f, _g, _h;
3581
+ var _a2, _b, _c, _d, _e, _f, _g2, _h;
3211
3582
  this.model = config.model;
3212
3583
  const llmConfig = config;
3213
- const options = (_a = llmConfig.options) != null ? _a : {};
3584
+ const options = (_a2 = llmConfig.options) != null ? _a2 : {};
3214
3585
  let profile = {};
3215
3586
  if (typeof options.profile === "string") {
3216
3587
  profile = LLM_PROFILES[options.profile] || {};
@@ -3222,7 +3593,7 @@ var UniversalLLMAdapter = class {
3222
3593
  this.maxTokens = (_d = llmConfig.maxTokens) != null ? _d : 1024;
3223
3594
  this.temperature = (_e = llmConfig.temperature) != null ? _e : 0;
3224
3595
  this.apiKey = config.apiKey;
3225
- this.baseUrl = (_g = (_f = llmConfig.baseUrl) != null ? _f : this.opts.baseUrl) != null ? _g : "";
3596
+ this.baseUrl = (_g2 = (_f = llmConfig.baseUrl) != null ? _f : this.opts.baseUrl) != null ? _g2 : "";
3226
3597
  if (!this.baseUrl) {
3227
3598
  throw new Error("[UniversalLLMAdapter] baseUrl is required in config or config.options");
3228
3599
  }
@@ -3236,8 +3607,8 @@ var UniversalLLMAdapter = class {
3236
3607
  });
3237
3608
  }
3238
3609
  async chat(messages, context) {
3239
- var _a, _b;
3240
- const path = (_a = this.opts.chatPath) != null ? _a : "/chat/completions";
3610
+ var _a2, _b;
3611
+ const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
3241
3612
  const formattedMessages = [
3242
3613
  { role: "system", content: `${this.systemPrompt}
3243
3614
 
@@ -3261,7 +3632,7 @@ ${context != null ? context : "None"}` },
3261
3632
  temperature: this.temperature
3262
3633
  };
3263
3634
  }
3264
- const { data } = await this.http.post(path, payload);
3635
+ const { data } = await this.http.post(path2, payload);
3265
3636
  const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
3266
3637
  const result = resolvePath(data, extractPath);
3267
3638
  if (result === void 0) {
@@ -3276,9 +3647,9 @@ ${context != null ? context : "None"}` },
3276
3647
  */
3277
3648
  chatStream(messages, context) {
3278
3649
  return __asyncGenerator(this, null, function* () {
3279
- var _a, _b, _c;
3280
- const path = (_a = this.opts.chatPath) != null ? _a : "/chat/completions";
3281
- const url = `${this.baseUrl.replace(/\/$/, "")}${path}`;
3650
+ var _a2, _b, _c;
3651
+ const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
3652
+ const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
3282
3653
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
3283
3654
  const formattedMessages = [
3284
3655
  { role: "system", content: `${this.systemPrompt}
@@ -3356,8 +3727,8 @@ ${context != null ? context : "None"}` },
3356
3727
  });
3357
3728
  }
3358
3729
  async embed(text) {
3359
- var _a, _b;
3360
- const path = (_a = this.opts.embedPath) != null ? _a : "/embeddings";
3730
+ var _a2, _b;
3731
+ const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
3361
3732
  let payload;
3362
3733
  if (this.opts.embedPayloadTemplate) {
3363
3734
  payload = buildPayload(this.opts.embedPayloadTemplate, {
@@ -3370,7 +3741,7 @@ ${context != null ? context : "None"}` },
3370
3741
  input: text
3371
3742
  };
3372
3743
  }
3373
- const { data } = await this.http.post(path, payload);
3744
+ const { data } = await this.http.post(path2, payload);
3374
3745
  const extractPath = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
3375
3746
  const vector = resolvePath(data, extractPath);
3376
3747
  if (!Array.isArray(vector)) {
@@ -3438,13 +3809,13 @@ var AuthenticationException = class extends RetrivoraError {
3438
3809
  }
3439
3810
  };
3440
3811
  function wrapError(err, defaultCode, defaultMessage) {
3441
- var _a;
3812
+ var _a2;
3442
3813
  if (err instanceof RetrivoraError) {
3443
3814
  return err;
3444
3815
  }
3445
3816
  const error = err;
3446
3817
  const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
3447
- 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);
3818
+ 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);
3448
3819
  const code = error == null ? void 0 : error.code;
3449
3820
  if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
3450
3821
  return new RateLimitException(message, err);
@@ -3508,6 +3879,8 @@ var LLMFactory = class _LLMFactory {
3508
3879
  "anthropic",
3509
3880
  "ollama",
3510
3881
  "gemini",
3882
+ "groq",
3883
+ "qwen",
3511
3884
  "rest",
3512
3885
  "universal_rest",
3513
3886
  "custom",
@@ -3515,7 +3888,7 @@ var LLMFactory = class _LLMFactory {
3515
3888
  ];
3516
3889
  }
3517
3890
  static create(llmConfig, embeddingConfig) {
3518
- var _a, _b, _c;
3891
+ var _a2, _b, _c;
3519
3892
  switch (llmConfig.provider) {
3520
3893
  case "openai":
3521
3894
  return new OpenAIProvider(llmConfig, embeddingConfig);
@@ -3525,12 +3898,16 @@ var LLMFactory = class _LLMFactory {
3525
3898
  return new OllamaProvider(llmConfig, embeddingConfig);
3526
3899
  case "gemini":
3527
3900
  return new GeminiProvider(llmConfig, embeddingConfig);
3901
+ case "groq":
3902
+ return new GroqProvider(llmConfig, embeddingConfig);
3903
+ case "qwen":
3904
+ return new QwenProvider(llmConfig, embeddingConfig);
3528
3905
  case "rest":
3529
3906
  case "universal_rest":
3530
3907
  case "custom":
3531
3908
  return new UniversalLLMAdapter(llmConfig);
3532
3909
  default: {
3533
- const providerName = String((_a = llmConfig.provider) != null ? _a : "").toLowerCase();
3910
+ const providerName = String((_a2 = llmConfig.provider) != null ? _a2 : "").toLowerCase();
3534
3911
  const customFactory = customProviders.get(providerName);
3535
3912
  if (customFactory) {
3536
3913
  return customFactory(llmConfig);
@@ -3567,6 +3944,10 @@ var LLMFactory = class _LLMFactory {
3567
3944
  return OllamaProvider;
3568
3945
  case "gemini":
3569
3946
  return GeminiProvider;
3947
+ case "groq":
3948
+ return GroqProvider;
3949
+ case "qwen":
3950
+ return QwenProvider;
3570
3951
  case "rest":
3571
3952
  case "universal_rest":
3572
3953
  case "custom":
@@ -3628,7 +4009,7 @@ var ProviderRegistry = class {
3628
4009
  return null;
3629
4010
  }
3630
4011
  static async loadVectorProviderClass(provider) {
3631
- var _a;
4012
+ var _a2;
3632
4013
  if (this.vectorProviders[provider]) return this.vectorProviders[provider];
3633
4014
  switch (provider) {
3634
4015
  case "pinecone": {
@@ -3637,7 +4018,7 @@ var ProviderRegistry = class {
3637
4018
  }
3638
4019
  case "pgvector":
3639
4020
  case "postgresql": {
3640
- const postgresMode = ((_a = process.env.POSTGRES_MODE) != null ? _a : "multi").toLowerCase();
4021
+ const postgresMode = ((_a2 = process.env.POSTGRES_MODE) != null ? _a2 : "multi").toLowerCase();
3641
4022
  if (postgresMode === "single") {
3642
4023
  const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
3643
4024
  return PostgreSQLProvider2;
@@ -3857,6 +4238,211 @@ var ConfigValidator = class {
3857
4238
  }
3858
4239
  };
3859
4240
 
4241
+ // src/core/LicenseVerifier.ts
4242
+ import * as crypto2 from "crypto";
4243
+ var LicenseVerifier = class {
4244
+ /**
4245
+ * Decodes, verifies signature, and checks metadata of a license key.
4246
+ *
4247
+ * @param licenseKey - Base64url signed JWT license key.
4248
+ * @param currentProjectId - Project namespace ID.
4249
+ * @param publicKeyOverride - Optional override for unit/integration tests.
4250
+ */
4251
+ static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
4252
+ const isProduction = process.env.NODE_ENV === "production";
4253
+ const now = Date.now();
4254
+ if (licenseKey) {
4255
+ const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
4256
+ const cached = this.cache.get(cacheKey);
4257
+ if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
4258
+ const currentTimestampSec = Math.floor(now / 1e3);
4259
+ if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
4260
+ this.cache.delete(cacheKey);
4261
+ } else {
4262
+ return cached.payload;
4263
+ }
4264
+ }
4265
+ }
4266
+ if (!licenseKey) {
4267
+ if (isProduction) {
4268
+ throw new ConfigurationException(
4269
+ "[Retrivora SDK] License key (licenseKey) is required in production environments."
4270
+ );
4271
+ }
4272
+ console.warn(
4273
+ `\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
4274
+ );
4275
+ return {
4276
+ projectId: currentProjectId,
4277
+ expiresAt: Math.floor(Date.now() / 1e3) + 86400,
4278
+ // Valid for 24h
4279
+ tier: "hobby"
4280
+ };
4281
+ }
4282
+ try {
4283
+ const parts = licenseKey.split(".");
4284
+ if (parts.length !== 3) {
4285
+ throw new Error("Malformed token structure (expected 3 parts).");
4286
+ }
4287
+ const [headerB64, payloadB64, signatureB64] = parts;
4288
+ const dataToVerify = `${headerB64}.${payloadB64}`;
4289
+ const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
4290
+ const signature = Buffer.from(signatureB64, "base64url");
4291
+ const data = Buffer.from(dataToVerify);
4292
+ const isValid = crypto2.verify(
4293
+ "sha256",
4294
+ data,
4295
+ publicKey,
4296
+ signature
4297
+ );
4298
+ if (!isValid) {
4299
+ throw new Error("Signature verification failed.");
4300
+ }
4301
+ const payload = JSON.parse(
4302
+ Buffer.from(payloadB64, "base64url").toString("utf8")
4303
+ );
4304
+ if (!payload.projectId) {
4305
+ throw new Error('License payload is missing "projectId".');
4306
+ }
4307
+ if (payload.projectId !== currentProjectId) {
4308
+ throw new Error(
4309
+ `Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
4310
+ );
4311
+ }
4312
+ if (!payload.expiresAt) {
4313
+ throw new Error('License payload is missing expiration ("expiresAt").');
4314
+ }
4315
+ const currentTimestampSec = Math.floor(Date.now() / 1e3);
4316
+ if (currentTimestampSec > payload.expiresAt) {
4317
+ throw new Error(
4318
+ `License key has expired. Expiration: ${new Date(
4319
+ payload.expiresAt * 1e3
4320
+ ).toDateString()}`
4321
+ );
4322
+ }
4323
+ if (isProduction && provider) {
4324
+ const tier = (payload.tier || "").toLowerCase();
4325
+ const normalizedProvider = provider.toLowerCase();
4326
+ if (tier === "hobby") {
4327
+ const allowedHobby = ["postgresql", "pgvector", "supabase"];
4328
+ if (!allowedHobby.includes(normalizedProvider)) {
4329
+ throw new Error(
4330
+ `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.`
4331
+ );
4332
+ }
4333
+ } else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth") {
4334
+ const allowedPro = [
4335
+ "postgresql",
4336
+ "pgvector",
4337
+ "supabase",
4338
+ "pinecone",
4339
+ "qdrant",
4340
+ "mongodb",
4341
+ "milvus",
4342
+ "chroma",
4343
+ "chromadb"
4344
+ ];
4345
+ if (!allowedPro.includes(normalizedProvider)) {
4346
+ throw new Error(
4347
+ `The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
4348
+ );
4349
+ }
4350
+ }
4351
+ }
4352
+ if (licenseKey) {
4353
+ const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
4354
+ this.cache.set(cacheKey, { payload, cachedAt: now });
4355
+ }
4356
+ return payload;
4357
+ } catch (err) {
4358
+ const message = err instanceof Error ? err.message : String(err);
4359
+ throw new ConfigurationException(
4360
+ `[Retrivora SDK] License key validation failed: ${message}`
4361
+ );
4362
+ }
4363
+ }
4364
+ static async verifyIP(licenseKey) {
4365
+ if (!licenseKey) return;
4366
+ try {
4367
+ const parts = licenseKey.split(".");
4368
+ if (parts.length !== 3) return;
4369
+ const [, payloadB64] = parts;
4370
+ const payload = JSON.parse(
4371
+ Buffer.from(payloadB64, "base64url").toString("utf8")
4372
+ );
4373
+ const tier = (payload.tier || "").toLowerCase();
4374
+ if (tier === "enterprise" || tier === "custom") {
4375
+ return;
4376
+ }
4377
+ if (payload.ipv4 || payload.ipv6) {
4378
+ let currentIpv4 = "";
4379
+ let currentIpv6 = "";
4380
+ try {
4381
+ const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
4382
+ const data = await res.json();
4383
+ currentIpv4 = data.ip;
4384
+ } catch (e) {
4385
+ }
4386
+ try {
4387
+ const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
4388
+ const data = await res.json();
4389
+ currentIpv6 = data.ip;
4390
+ } catch (e) {
4391
+ }
4392
+ const localIps = [];
4393
+ try {
4394
+ const osModule = __require("os");
4395
+ const interfaces = osModule.networkInterfaces();
4396
+ for (const name of Object.keys(interfaces)) {
4397
+ for (const iface of interfaces[name] || []) {
4398
+ if (!iface.internal) {
4399
+ localIps.push(iface.address);
4400
+ }
4401
+ }
4402
+ }
4403
+ } catch (e) {
4404
+ }
4405
+ const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
4406
+ const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
4407
+ if (payload.ipv4 && payload.ipv6) {
4408
+ if (!isIpv4Match && !isIpv6Match) {
4409
+ throw new Error(
4410
+ `License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}, IPv6: ${payload.ipv6}) and cannot be used on this machine.`
4411
+ );
4412
+ }
4413
+ } else if (payload.ipv4 && !isIpv4Match) {
4414
+ throw new Error(
4415
+ `License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
4416
+ );
4417
+ } else if (payload.ipv6 && !isIpv6Match) {
4418
+ throw new Error(
4419
+ `License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
4420
+ );
4421
+ }
4422
+ }
4423
+ } catch (err) {
4424
+ if (err.message.includes("License key access restricted")) {
4425
+ throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
4426
+ }
4427
+ }
4428
+ }
4429
+ };
4430
+ // A simple in-memory cache to save CPU overhead of cryptographic signature checks.
4431
+ LicenseVerifier.cache = /* @__PURE__ */ new Map();
4432
+ LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
4433
+ // Cache verified license for 60 seconds
4434
+ // Retrivora's Public Key used to verify the license key signature.
4435
+ // In production, this matches the private key held by Retrivora SaaS.
4436
+ LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
4437
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
4438
+ XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
4439
+ xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
4440
+ NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
4441
+ iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
4442
+ +Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
4443
+ MwIDAQAB
4444
+ -----END PUBLIC KEY-----`;
4445
+
3860
4446
  // src/rag/DocumentChunker.ts
3861
4447
  var DocumentChunker = class {
3862
4448
  constructor(chunkSize = 1e3, chunkOverlap = 200, separators = ["\n# ", "\n## ", "\n### ", "\n#### ", "\n\n", "\n", " ", ""]) {
@@ -4086,11 +4672,11 @@ var LlamaIndexIngestor = class {
4086
4672
  * than standard character-count splitting.
4087
4673
  */
4088
4674
  async chunk(text, options = {}) {
4089
- var _a, _b;
4675
+ var _a2, _b;
4090
4676
  try {
4091
4677
  const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
4092
4678
  const splitter = new SentenceSplitter({
4093
- chunkSize: (_a = options.chunkSize) != null ? _a : 1e3,
4679
+ chunkSize: (_a2 = options.chunkSize) != null ? _a2 : 1e3,
4094
4680
  chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
4095
4681
  });
4096
4682
  const doc = new Document({ text, metadata: options.metadata || {} });
@@ -4199,7 +4785,7 @@ ${error instanceof Error ? error.message : String(error)}`
4199
4785
  * The agent returns `{ messages: [...] }` — the last message is the final answer.
4200
4786
  */
4201
4787
  async run(input, chatHistory = []) {
4202
- var _a, _b, _c;
4788
+ var _a2, _b, _c;
4203
4789
  if (!this.agent) {
4204
4790
  throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
4205
4791
  }
@@ -4210,14 +4796,445 @@ ${error instanceof Error ? error.message : String(error)}`
4210
4796
  const response = await this.agent.invoke({
4211
4797
  messages: [...historyMessages, new HumanMessage(input)]
4212
4798
  });
4213
- const lastMessage = (_a = response == null ? void 0 : response.messages) == null ? void 0 : _a.at(-1);
4214
- if (lastMessage && typeof lastMessage.content === "string") {
4215
- return lastMessage.content;
4216
- }
4217
- if (Array.isArray(lastMessage == null ? void 0 : lastMessage.content)) {
4218
- return lastMessage.content.filter((c) => c.type === "text").map((c) => c.text).join("");
4219
- }
4220
- return String((_c = (_b = response == null ? void 0 : response.output) != null ? _b : response) != null ? _c : "");
4799
+ const lastMessage = (_a2 = response == null ? void 0 : response.messages) == null ? void 0 : _a2.at(-1);
4800
+ if (lastMessage && typeof lastMessage.content === "string") {
4801
+ return lastMessage.content;
4802
+ }
4803
+ if (Array.isArray(lastMessage == null ? void 0 : lastMessage.content)) {
4804
+ return lastMessage.content.filter((c) => c.type === "text").map((c) => c.text).join("");
4805
+ }
4806
+ return String((_c = (_b = response == null ? void 0 : response.output) != null ? _b : response) != null ? _c : "");
4807
+ }
4808
+ };
4809
+
4810
+ // src/core/mcp.ts
4811
+ import { spawn } from "child_process";
4812
+ var MCPClient = class {
4813
+ constructor(config) {
4814
+ this.config = config;
4815
+ this.messageIdCounter = 0;
4816
+ this.pendingRequests = /* @__PURE__ */ new Map();
4817
+ this.stdioBuffer = "";
4818
+ this.initialized = false;
4819
+ }
4820
+ getNextMessageId() {
4821
+ return ++this.messageIdCounter;
4822
+ }
4823
+ /**
4824
+ * Connect and initialize the MCP server connection.
4825
+ */
4826
+ async connect() {
4827
+ if (this.initialized) return;
4828
+ if (this.config.transport === "stdio") {
4829
+ await this.connectStdio();
4830
+ } else {
4831
+ await this.connectSSE();
4832
+ }
4833
+ try {
4834
+ const response = await this.sendJsonRpc("initialize", {
4835
+ protocolVersion: "2024-11-05",
4836
+ capabilities: {},
4837
+ clientInfo: {
4838
+ name: "retrivora-sdk",
4839
+ version: "1.0.0"
4840
+ }
4841
+ });
4842
+ await this.sendNotification("notifications/initialized");
4843
+ this.initialized = true;
4844
+ console.log(`[MCPClient] Connected and initialized server "${this.config.name}" successfully.`);
4845
+ } catch (err) {
4846
+ this.disconnect();
4847
+ throw new Error(`[MCPClient] Failed to initialize server "${this.config.name}": ${err.message}`);
4848
+ }
4849
+ }
4850
+ async connectStdio() {
4851
+ var _a2;
4852
+ const cmd = this.config.command;
4853
+ if (!cmd) {
4854
+ throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
4855
+ }
4856
+ const args = this.config.args || [];
4857
+ const env = __spreadValues(__spreadValues({}, process.env), this.config.env || {});
4858
+ this.childProcess = spawn(cmd, args, { env, shell: true });
4859
+ if (!this.childProcess || !this.childProcess.stdout || !this.childProcess.stdin) {
4860
+ throw new Error(`[MCPClient] Failed to spawn stdio child process for "${this.config.name}"`);
4861
+ }
4862
+ this.childProcess.stdout.on("data", (data) => {
4863
+ this.stdioBuffer += data.toString("utf-8");
4864
+ this.processStdioLines();
4865
+ });
4866
+ (_a2 = this.childProcess.stderr) == null ? void 0 : _a2.on("data", (data) => {
4867
+ console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
4868
+ });
4869
+ this.childProcess.on("close", (code) => {
4870
+ console.log(`[MCPClient] Connection closed for "${this.config.name}" with exit code: ${code}`);
4871
+ this.disconnect();
4872
+ });
4873
+ await new Promise((resolve) => setTimeout(resolve, 100));
4874
+ }
4875
+ processStdioLines() {
4876
+ let newlineIndex;
4877
+ while ((newlineIndex = this.stdioBuffer.indexOf("\n")) !== -1) {
4878
+ const line = this.stdioBuffer.substring(0, newlineIndex).trim();
4879
+ this.stdioBuffer = this.stdioBuffer.substring(newlineIndex + 1);
4880
+ if (!line) continue;
4881
+ try {
4882
+ const payload = JSON.parse(line);
4883
+ if (payload.id !== void 0) {
4884
+ const req = this.pendingRequests.get(Number(payload.id));
4885
+ if (req) {
4886
+ this.pendingRequests.delete(Number(payload.id));
4887
+ if (payload.error) {
4888
+ req.reject(new Error(payload.error.message || JSON.stringify(payload.error)));
4889
+ } else {
4890
+ req.resolve(payload.result);
4891
+ }
4892
+ }
4893
+ }
4894
+ } catch (e) {
4895
+ console.warn(`[MCPClient] Error parsing stdio JSON-RPC line from "${this.config.name}":`, e, "Line content:", line);
4896
+ }
4897
+ }
4898
+ }
4899
+ async connectSSE() {
4900
+ if (!this.config.url) {
4901
+ throw new Error(`[MCPClient] URL is required for sse transport on "${this.config.name}"`);
4902
+ }
4903
+ this.sseUrl = this.config.url;
4904
+ }
4905
+ async sendJsonRpc(method, params) {
4906
+ const id = this.getNextMessageId();
4907
+ const request = {
4908
+ jsonrpc: "2.0",
4909
+ id,
4910
+ method,
4911
+ params
4912
+ };
4913
+ if (this.config.transport === "stdio") {
4914
+ if (!this.childProcess || !this.childProcess.stdin) {
4915
+ throw new Error(`[MCPClient] Server "${this.config.name}" is not connected (stdio process missing)`);
4916
+ }
4917
+ return new Promise((resolve, reject) => {
4918
+ this.pendingRequests.set(id, { resolve, reject });
4919
+ this.childProcess.stdin.write(JSON.stringify(request) + "\n", "utf-8");
4920
+ });
4921
+ } else {
4922
+ if (!this.sseUrl) {
4923
+ throw new Error(`[MCPClient] Server "${this.config.name}" SSE URL is not initialized`);
4924
+ }
4925
+ const response = await fetch(this.sseUrl, {
4926
+ method: "POST",
4927
+ headers: { "Content-Type": "application/json" },
4928
+ body: JSON.stringify(request)
4929
+ });
4930
+ if (!response.ok) {
4931
+ throw new Error(`SSE JSON-RPC POST failed with status ${response.status}`);
4932
+ }
4933
+ const payload = await response.json();
4934
+ if (payload.error) {
4935
+ throw new Error(payload.error.message || JSON.stringify(payload.error));
4936
+ }
4937
+ return payload.result;
4938
+ }
4939
+ }
4940
+ async sendNotification(method, params) {
4941
+ var _a2;
4942
+ const notification = {
4943
+ jsonrpc: "2.0",
4944
+ method,
4945
+ params
4946
+ };
4947
+ if (this.config.transport === "stdio") {
4948
+ if ((_a2 = this.childProcess) == null ? void 0 : _a2.stdin) {
4949
+ this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
4950
+ }
4951
+ } else if (this.sseUrl) {
4952
+ await fetch(this.sseUrl, {
4953
+ method: "POST",
4954
+ headers: { "Content-Type": "application/json" },
4955
+ body: JSON.stringify(notification)
4956
+ }).catch((err) => console.warn("[MCPClient] Failed to send notification over SSE:", err));
4957
+ }
4958
+ }
4959
+ /**
4960
+ * List all tools offered by the MCP server.
4961
+ */
4962
+ async listTools() {
4963
+ await this.connect();
4964
+ const result = await this.sendJsonRpc("tools/list", {});
4965
+ return (result == null ? void 0 : result.tools) || [];
4966
+ }
4967
+ /**
4968
+ * Execute a tool on the MCP server.
4969
+ */
4970
+ async callTool(name, args = {}) {
4971
+ await this.connect();
4972
+ return await this.sendJsonRpc("tools/call", { name, arguments: args });
4973
+ }
4974
+ disconnect() {
4975
+ this.initialized = false;
4976
+ this.pendingRequests.forEach((req) => req.reject(new Error("MCPClient disconnected")));
4977
+ this.pendingRequests.clear();
4978
+ if (this.childProcess) {
4979
+ try {
4980
+ this.childProcess.kill();
4981
+ } catch (e) {
4982
+ }
4983
+ this.childProcess = void 0;
4984
+ }
4985
+ }
4986
+ };
4987
+ var MCPRegistry = class {
4988
+ constructor(servers = []) {
4989
+ this.clients = [];
4990
+ this.clients = servers.map((cfg) => new MCPClient(cfg));
4991
+ }
4992
+ async getAllTools() {
4993
+ const list = [];
4994
+ await Promise.all(
4995
+ this.clients.map(async (client) => {
4996
+ try {
4997
+ const tools = await client.listTools();
4998
+ tools.forEach((t) => list.push({ serverName: client["config"].name, tool: t }));
4999
+ } catch (e) {
5000
+ console.warn(`[MCPRegistry] Failed to fetch tools from server "${client["config"].name}":`, e);
5001
+ }
5002
+ })
5003
+ );
5004
+ return list;
5005
+ }
5006
+ async callTool(toolName, args = {}) {
5007
+ for (const client of this.clients) {
5008
+ try {
5009
+ const tools = await client.listTools();
5010
+ if (tools.some((t) => t.name === toolName)) {
5011
+ return await client.callTool(toolName, args);
5012
+ }
5013
+ } catch (e) {
5014
+ }
5015
+ }
5016
+ throw new Error(`[MCPRegistry] Tool "${toolName}" not found on any registered MCP server.`);
5017
+ }
5018
+ disconnectAll() {
5019
+ this.clients.forEach((c) => c.disconnect());
5020
+ }
5021
+ };
5022
+
5023
+ // src/core/MultiAgentCoordinator.ts
5024
+ var MultiAgentCoordinator = class {
5025
+ constructor(options) {
5026
+ var _a2;
5027
+ this.llmProvider = options.llmProvider;
5028
+ this.mcpRegistry = options.mcpRegistry;
5029
+ this.documentSearch = options.documentSearch;
5030
+ this.maxIterations = (_a2 = options.maxIterations) != null ? _a2 : 5;
5031
+ }
5032
+ /**
5033
+ * Run the multi-agent coordination loop synchronously and return the final response.
5034
+ */
5035
+ async run(question, history = []) {
5036
+ const generator = this.runStream(question, history);
5037
+ let finalReply = "";
5038
+ const sources = [];
5039
+ try {
5040
+ for (var iter = __forAwait(generator), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
5041
+ const chunk = temp.value;
5042
+ if (typeof chunk === "string") {
5043
+ finalReply += chunk;
5044
+ } else if (chunk && typeof chunk === "object") {
5045
+ if ("reply" in chunk && chunk.reply) {
5046
+ finalReply += chunk.reply;
5047
+ }
5048
+ if ("sources" in chunk && chunk.sources) {
5049
+ sources.push(...chunk.sources);
5050
+ }
5051
+ }
5052
+ }
5053
+ } catch (temp) {
5054
+ error = [temp];
5055
+ } finally {
5056
+ try {
5057
+ more && (temp = iter.return) && await temp.call(iter);
5058
+ } finally {
5059
+ if (error)
5060
+ throw error[0];
5061
+ }
5062
+ }
5063
+ return {
5064
+ reply: finalReply,
5065
+ sources
5066
+ };
5067
+ }
5068
+ /**
5069
+ * Run the multi-agent coordination loop as an async stream, yielding intermediate thought blocks and tool execution events.
5070
+ */
5071
+ runStream(_0) {
5072
+ return __asyncGenerator(this, arguments, function* (question, history = []) {
5073
+ const mcpTools = yield new __await(this.mcpRegistry.getAllTools());
5074
+ let systemPrompt = `You are a goal-driven supervisor agent coordinating a RAG search engine and external MCP servers to solve the user's task.
5075
+ You must think step-by-step before acting. Write your internal thinking process inside a \`<think>...</think>\` block first, then act or answer.
5076
+
5077
+ Available Tools:
5078
+ - document_search(query: string): Search the vector database and knowledge base for documents.
5079
+
5080
+ ${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
5081
+ ${mcpTools.map((mt) => {
5082
+ var _a2;
5083
+ return `- ${mt.tool.name}(${JSON.stringify(((_a2 = mt.tool.inputSchema) == null ? void 0 : _a2.properties) || {})}): ${mt.tool.description || "No description provided."}`;
5084
+ }).join("\n")}
5085
+
5086
+ Tool Calling Protocol:
5087
+ If you need to call a tool, write:
5088
+ TOOL_CALL: <toolName>({ "argName": "value" })
5089
+ And then STOP generating immediately.
5090
+
5091
+ Once you have gathered enough information to fully satisfy the user's query, write your final response directly after the closing \`</think>\` block.
5092
+ `;
5093
+ const supervisorHistory = [
5094
+ { role: "system", content: systemPrompt },
5095
+ ...history,
5096
+ { role: "user", content: question }
5097
+ ];
5098
+ let iteration = 0;
5099
+ const allSources = [];
5100
+ while (iteration < this.maxIterations) {
5101
+ iteration++;
5102
+ const context = "";
5103
+ let fullModelResponse = "";
5104
+ let textBuffer = "";
5105
+ let inThinking = false;
5106
+ let toolCallDetected = null;
5107
+ if (!this.llmProvider.chatStream) {
5108
+ const reply = yield new __await(this.llmProvider.chat(supervisorHistory, context));
5109
+ fullModelResponse = reply;
5110
+ const thinkIndex = reply.indexOf("<think>");
5111
+ const endThinkIndex = reply.indexOf("</think>");
5112
+ let thinkingText = "";
5113
+ let answerText = reply;
5114
+ if (thinkIndex !== -1 && endThinkIndex !== -1) {
5115
+ thinkingText = reply.substring(thinkIndex + 7, endThinkIndex);
5116
+ answerText = reply.substring(endThinkIndex + 8);
5117
+ yield { type: "thinking", text: thinkingText };
5118
+ }
5119
+ const toolMatch = answerText.match(/TOOL_CALL:\s*(\w+)\s*\(([\s\S]*)\)/);
5120
+ if (toolMatch) {
5121
+ const toolName = toolMatch[1];
5122
+ const toolArgsStr = toolMatch[2];
5123
+ try {
5124
+ const toolArgs = JSON.parse(toolArgsStr.trim());
5125
+ toolCallDetected = { name: toolName, args: toolArgs };
5126
+ } catch (e) {
5127
+ console.error("[MultiAgentCoordinator] Failed to parse tool args:", toolArgsStr, e);
5128
+ }
5129
+ } else {
5130
+ yield answerText;
5131
+ }
5132
+ } else {
5133
+ const stream = this.llmProvider.chatStream(supervisorHistory, context);
5134
+ try {
5135
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
5136
+ const chunk = temp.value;
5137
+ fullModelResponse += chunk;
5138
+ textBuffer += chunk;
5139
+ if (!inThinking && textBuffer.includes("<think>")) {
5140
+ inThinking = true;
5141
+ const idx = textBuffer.indexOf("<think>");
5142
+ textBuffer = textBuffer.slice(idx + 7);
5143
+ }
5144
+ if (inThinking && textBuffer.includes("</think>")) {
5145
+ inThinking = false;
5146
+ const idx = textBuffer.indexOf("</think>");
5147
+ const thinkingDelta = textBuffer.slice(0, idx);
5148
+ yield { type: "thinking", text: thinkingDelta };
5149
+ textBuffer = textBuffer.slice(idx + 8);
5150
+ }
5151
+ if (inThinking && textBuffer.length > 0) {
5152
+ yield { type: "thinking", text: textBuffer };
5153
+ textBuffer = "";
5154
+ }
5155
+ if (!inThinking && textBuffer.includes("TOOL_CALL:")) {
5156
+ const idx = textBuffer.indexOf("TOOL_CALL:");
5157
+ const precedingText = textBuffer.slice(0, idx);
5158
+ if (precedingText.trim()) {
5159
+ yield precedingText;
5160
+ }
5161
+ textBuffer = textBuffer.slice(idx);
5162
+ }
5163
+ if (!inThinking && !textBuffer.includes("TOOL_CALL:") && textBuffer.length > 0) {
5164
+ yield textBuffer;
5165
+ textBuffer = "";
5166
+ }
5167
+ }
5168
+ } catch (temp) {
5169
+ error = [temp];
5170
+ } finally {
5171
+ try {
5172
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
5173
+ } finally {
5174
+ if (error)
5175
+ throw error[0];
5176
+ }
5177
+ }
5178
+ if (textBuffer.trim()) {
5179
+ const toolMatch = textBuffer.match(/TOOL_CALL:\s*(\w+)\s*\(([\s\S]*)\)/);
5180
+ if (toolMatch) {
5181
+ const toolName = toolMatch[1];
5182
+ const toolArgsStr = toolMatch[2];
5183
+ try {
5184
+ const toolArgs = JSON.parse(toolArgsStr.trim());
5185
+ toolCallDetected = { name: toolName, args: toolArgs };
5186
+ } catch (e) {
5187
+ console.error("[MultiAgentCoordinator] Failed to parse tool args:", toolArgsStr, e);
5188
+ }
5189
+ } else {
5190
+ yield textBuffer;
5191
+ }
5192
+ }
5193
+ }
5194
+ supervisorHistory.push({ role: "assistant", content: fullModelResponse });
5195
+ if (toolCallDetected) {
5196
+ const { name: toolName, args: toolArgs } = toolCallDetected;
5197
+ yield {
5198
+ type: "thinking",
5199
+ text: `
5200
+ [Agent Call] Executing tool "${toolName}" with parameters ${JSON.stringify(toolArgs)}...
5201
+ `
5202
+ };
5203
+ let toolResultText = "";
5204
+ try {
5205
+ if (toolName === "document_search") {
5206
+ const searchRes = yield new __await(this.documentSearch(toolArgs.query || ""));
5207
+ toolResultText = `document_search returned:
5208
+ ${searchRes.reply}
5209
+
5210
+ Sources count: ${searchRes.sources.length}`;
5211
+ if (searchRes.sources && searchRes.sources.length > 0) {
5212
+ allSources.push(...searchRes.sources);
5213
+ yield { reply: "", sources: searchRes.sources };
5214
+ }
5215
+ } else {
5216
+ const mcpRes = yield new __await(this.mcpRegistry.callTool(toolName, toolArgs));
5217
+ toolResultText = `MCP Tool "${toolName}" returned:
5218
+ ${JSON.stringify(mcpRes.content)}`;
5219
+ }
5220
+ } catch (err) {
5221
+ toolResultText = `Error calling tool "${toolName}": ${err.message}`;
5222
+ }
5223
+ supervisorHistory.push({
5224
+ role: "user",
5225
+ content: `TOOL_RESULT for ${toolName}:
5226
+ ${toolResultText}`
5227
+ });
5228
+ yield {
5229
+ type: "thinking",
5230
+ text: `[Agent Output] Tool "${toolName}" executed. Continuing reasoning...
5231
+ `
5232
+ };
5233
+ } else {
5234
+ break;
5235
+ }
5236
+ }
5237
+ });
4221
5238
  }
4222
5239
  };
4223
5240
 
@@ -4547,7 +5564,7 @@ var QueryProcessor = class {
4547
5564
  * @param validFields Optional list of known filterable fields to look for
4548
5565
  */
4549
5566
  static extractQueryFieldHints(question, validFields = []) {
4550
- var _a, _b, _c, _d;
5567
+ var _a2, _b, _c, _d;
4551
5568
  if (!question.trim()) return [];
4552
5569
  const hints = /* @__PURE__ */ new Map();
4553
5570
  const addHint = (value, field) => {
@@ -4627,7 +5644,7 @@ var QueryProcessor = class {
4627
5644
  ];
4628
5645
  for (const p of universalPatterns) {
4629
5646
  for (const match of question.matchAll(p.regex)) {
4630
- const val = p.group ? (_a = match[p.group]) != null ? _a : match[0] : match[0];
5647
+ const val = p.group ? (_a2 = match[p.group]) != null ? _a2 : match[0] : match[0];
4631
5648
  if (!val) continue;
4632
5649
  if (p.field) addHint(val, p.field);
4633
5650
  else addHint(val);
@@ -4851,11 +5868,11 @@ var LLMRouter = class {
4851
5868
  * When provided it is used directly as the 'default' role without re-constructing.
4852
5869
  */
4853
5870
  async initialize(prebuiltDefault) {
4854
- var _a;
5871
+ var _a2;
4855
5872
  const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
4856
5873
  this.models.set("default", defaultModel);
4857
5874
  const envFastModel = process.env.FAST_LLM_MODEL;
4858
- const providerFastDefault = (_a = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a : "";
5875
+ const providerFastDefault = (_a2 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a2 : "";
4859
5876
  const fastModelName = envFastModel || providerFastDefault;
4860
5877
  if (fastModelName && fastModelName !== this.config.llm.model) {
4861
5878
  console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
@@ -4874,8 +5891,8 @@ var LLMRouter = class {
4874
5891
  * Falls back to 'default' if the requested role is not registered.
4875
5892
  */
4876
5893
  get(role) {
4877
- var _a;
4878
- const provider = (_a = this.models.get(role)) != null ? _a : this.models.get("default");
5894
+ var _a2;
5895
+ const provider = (_a2 = this.models.get(role)) != null ? _a2 : this.models.get("default");
4879
5896
  if (!provider) {
4880
5897
  throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
4881
5898
  }
@@ -4893,7 +5910,7 @@ var UITransformer = class _UITransformer {
4893
5910
  * Prefer `analyzeAndDecide()` in production.
4894
5911
  */
4895
5912
  static transform(userQuery, retrievedData, config, trainedSchema, intent) {
4896
- var _a, _b, _c;
5913
+ var _a2, _b, _c;
4897
5914
  if (!retrievedData || retrievedData.length === 0) {
4898
5915
  return this.createTextResponse("No data available", "No relevant data found for your query.");
4899
5916
  }
@@ -4913,7 +5930,7 @@ var UITransformer = class _UITransformer {
4913
5930
  return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
4914
5931
  }
4915
5932
  if (resolvedIntent.visualizationHint === "distribution") {
4916
- return (_a = this.transformToHistogram(profile, userQuery)) != null ? _a : this.transformToBarChart(filteredData, profile, userQuery);
5933
+ return (_a2 = this.transformToHistogram(profile, userQuery)) != null ? _a2 : this.transformToBarChart(filteredData, profile, userQuery);
4917
5934
  }
4918
5935
  if (resolvedIntent.visualizationHint === "correlation") {
4919
5936
  return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
@@ -5238,11 +6255,11 @@ ${schemaProfileText}` : ""}`;
5238
6255
  };
5239
6256
  }
5240
6257
  static transformToPieChart(data, profile, query = "") {
5241
- var _a;
6258
+ var _a2;
5242
6259
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
5243
6260
  const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
5244
- var _a2;
5245
- return String((_a2 = record.fields[dimension.key]) != null ? _a2 : "");
6261
+ var _a3;
6262
+ return String((_a3 = record.fields[dimension.key]) != null ? _a3 : "");
5246
6263
  }).filter(Boolean))) : this.detectCategories(data);
5247
6264
  if (categories.length === 0) return null;
5248
6265
  const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
@@ -5252,7 +6269,7 @@ ${schemaProfileText}` : ""}`;
5252
6269
  });
5253
6270
  return {
5254
6271
  type: "pie_chart",
5255
- title: `Distribution by ${(_a = dimension == null ? void 0 : dimension.label) != null ? _a : "Category"}`,
6272
+ title: `Distribution by ${(_a2 = dimension == null ? void 0 : dimension.label) != null ? _a2 : "Category"}`,
5256
6273
  description: `Showing breakdown across ${pieData.length} categories`,
5257
6274
  data: pieData
5258
6275
  };
@@ -5262,8 +6279,8 @@ ${schemaProfileText}` : ""}`;
5262
6279
  const valueField = profile.numericFields[0];
5263
6280
  const buckets = /* @__PURE__ */ new Map();
5264
6281
  profile.records.forEach((record) => {
5265
- var _a, _b, _c;
5266
- const timestamp = String((_a = record.fields[dateField.key]) != null ? _a : "");
6282
+ var _a2, _b, _c;
6283
+ const timestamp = String((_a2 = record.fields[dateField.key]) != null ? _a2 : "");
5267
6284
  const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
5268
6285
  buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
5269
6286
  });
@@ -5276,23 +6293,23 @@ ${schemaProfileText}` : ""}`;
5276
6293
  };
5277
6294
  }
5278
6295
  static transformToBarChart(data, profile, query = "", horizontal = false) {
5279
- var _a;
6296
+ var _a2;
5280
6297
  const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
5281
6298
  const measure = profile ? this.selectNumericField(profile, query) : void 0;
5282
6299
  const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
5283
6300
  const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
5284
6301
  const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
5285
- var _a2, _b, _c, _d, _e;
6302
+ var _a3, _b, _c, _d, _e;
5286
6303
  const meta = item.metadata || {};
5287
6304
  const label = String(
5288
- (_c = (_b = (_a2 = this.getDynamicVal(meta, "name")) != null ? _a2 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
6305
+ (_c = (_b = (_a3 = this.getDynamicVal(meta, "name")) != null ? _a3 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
5289
6306
  );
5290
6307
  const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
5291
6308
  return { category: label, value: Number(value) };
5292
6309
  });
5293
6310
  return {
5294
6311
  type: horizontal ? "horizontal_bar" : "bar_chart",
5295
- title: dimension ? `${(_a = measure == null ? void 0 : measure.label) != null ? _a : "Count"} by ${dimension.label}` : "Comparison",
6312
+ title: dimension ? `${(_a2 = measure == null ? void 0 : measure.label) != null ? _a2 : "Count"} by ${dimension.label}` : "Comparison",
5296
6313
  description: `Showing ${fallbackData.length} comparable values`,
5297
6314
  data: fallbackData
5298
6315
  };
@@ -5327,11 +6344,11 @@ ${schemaProfileText}` : ""}`;
5327
6344
  if (fields.length < 2) return null;
5328
6345
  const [xField, yField] = fields;
5329
6346
  const points = profile.records.map((record) => {
5330
- var _a;
6347
+ var _a2;
5331
6348
  const x = this.toFiniteNumber(record.fields[xField.key]);
5332
6349
  const y = this.toFiniteNumber(record.fields[yField.key]);
5333
6350
  if (x === null || y === null) return null;
5334
- return { x, y, label: String((_a = this.getRecordLabel(record)) != null ? _a : record.id) };
6351
+ return { x, y, label: String((_a2 = this.getRecordLabel(record)) != null ? _a2 : record.id) };
5335
6352
  }).filter((point) => point !== null).slice(0, 100);
5336
6353
  if (points.length === 0) return null;
5337
6354
  return {
@@ -5361,9 +6378,9 @@ ${schemaProfileText}` : ""}`;
5361
6378
  static transformToRadarChart(data) {
5362
6379
  const attributeMap = {};
5363
6380
  data.forEach((item) => {
5364
- var _a, _b, _c;
6381
+ var _a2, _b, _c;
5365
6382
  const meta = item.metadata || {};
5366
- const seriesName = String((_c = (_b = (_a = meta.name) != null ? _a : meta.product) != null ? _b : item.id) != null ? _c : "Item");
6383
+ const seriesName = String((_c = (_b = (_a2 = meta.name) != null ? _a2 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
5367
6384
  Object.entries(meta).forEach(([key, val]) => {
5368
6385
  if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
5369
6386
  if (!attributeMap[key]) attributeMap[key] = {};
@@ -5445,22 +6462,22 @@ ${schemaProfileText}` : ""}`;
5445
6462
  return null;
5446
6463
  }
5447
6464
  static normalizeTransformation(payload) {
5448
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
6465
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
5449
6466
  if (!payload || typeof payload !== "object") return null;
5450
6467
  const p = payload;
5451
6468
  const type = this.normalizeVisualizationType(
5452
- String((_c = (_b = (_a = p.type) != null ? _a : p.view) != null ? _b : p.chartType) != null ? _c : "")
6469
+ String((_c = (_b = (_a2 = p.type) != null ? _a2 : p.view) != null ? _b : p.chartType) != null ? _c : "")
5453
6470
  );
5454
6471
  if (!type) return null;
5455
6472
  const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
5456
6473
  const description = p.description ? String(p.description) : void 0;
5457
- 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;
6474
+ 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;
5458
6475
  const data = type === "text" && typeof rawData === "string" ? { content: rawData } : rawData;
5459
6476
  const transformation = { type, title, description, data };
5460
6477
  return this.validateTransformation(transformation) ? transformation : null;
5461
6478
  }
5462
6479
  static normalizeVisualizationType(type) {
5463
- var _a;
6480
+ var _a2;
5464
6481
  const mapping = {
5465
6482
  pie: "pie_chart",
5466
6483
  pie_chart: "pie_chart",
@@ -5488,7 +6505,7 @@ ${schemaProfileText}` : ""}`;
5488
6505
  product_carousel: "product_carousel",
5489
6506
  carousel: "carousel"
5490
6507
  };
5491
- return (_a = mapping[type.toLowerCase()]) != null ? _a : null;
6508
+ return (_a2 = mapping[type.toLowerCase()]) != null ? _a2 : null;
5492
6509
  }
5493
6510
  static validateTransformation(t) {
5494
6511
  const { type, data } = t;
@@ -5690,16 +6707,16 @@ ${schemaProfileText}` : ""}`;
5690
6707
  return null;
5691
6708
  }
5692
6709
  static selectDimensionField(profile, query) {
5693
- var _a, _b;
6710
+ var _a2, _b;
5694
6711
  const productCategory = profile.categoricalFields.find(
5695
6712
  (field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
5696
6713
  );
5697
6714
  const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
5698
- return (_b = (_a = ranked[0]) != null ? _a : productCategory) != null ? _b : profile.categoricalFields[0];
6715
+ return (_b = (_a2 = ranked[0]) != null ? _a2 : productCategory) != null ? _b : profile.categoricalFields[0];
5699
6716
  }
5700
6717
  static selectNumericField(profile, query) {
5701
- var _a;
5702
- return (_a = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a : profile.numericFields[0];
6718
+ var _a2;
6719
+ return (_a2 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a2 : profile.numericFields[0];
5703
6720
  }
5704
6721
  static rankFieldsByQuery(fields, query) {
5705
6722
  const q = query.toLowerCase();
@@ -5728,8 +6745,8 @@ ${schemaProfileText}` : ""}`;
5728
6745
  static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
5729
6746
  const result = {};
5730
6747
  profile.records.forEach((record) => {
5731
- var _a, _b, _c;
5732
- const category = String((_a = record.fields[dimensionKey]) != null ? _a : "Other").trim() || "Other";
6748
+ var _a2, _b, _c;
6749
+ const category = String((_a2 = record.fields[dimensionKey]) != null ? _a2 : "Other").trim() || "Other";
5733
6750
  const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
5734
6751
  result[category] = ((_c = result[category]) != null ? _c : 0) + value;
5735
6752
  });
@@ -5808,8 +6825,8 @@ ${schemaProfileText}` : ""}`;
5808
6825
  static aggregateByCategory(data, categories) {
5809
6826
  const result = Object.fromEntries(categories.map((c) => [c, 0]));
5810
6827
  data.forEach((item) => {
5811
- var _a;
5812
- const cat = (_a = this.getProductCategory(item)) != null ? _a : "Other";
6828
+ var _a2;
6829
+ const cat = (_a2 = this.getProductCategory(item)) != null ? _a2 : "Other";
5813
6830
  if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
5814
6831
  else result["Other"] = (result["Other"] || 0) + 1;
5815
6832
  });
@@ -5817,17 +6834,17 @@ ${schemaProfileText}` : ""}`;
5817
6834
  }
5818
6835
  static extractTimeSeriesData(data) {
5819
6836
  return data.map((item) => {
5820
- var _a, _b, _c, _d, _e;
6837
+ var _a2, _b, _c, _d, _e;
5821
6838
  const meta = item.metadata || {};
5822
6839
  return {
5823
- timestamp: (_b = (_a = meta.timestamp) != null ? _a : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
6840
+ timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
5824
6841
  value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
5825
6842
  label: (_e = meta.label) != null ? _e : item.content.substring(0, 50)
5826
6843
  };
5827
6844
  });
5828
6845
  }
5829
6846
  static extractNumericValue(meta) {
5830
- var _a;
6847
+ var _a2;
5831
6848
  const preferredKeys = [
5832
6849
  "value",
5833
6850
  "count",
@@ -5842,7 +6859,7 @@ ${schemaProfileText}` : ""}`;
5842
6859
  "price"
5843
6860
  ];
5844
6861
  for (const key of preferredKeys) {
5845
- const raw = (_a = resolveMetadataValue(meta, key)) != null ? _a : meta[key];
6862
+ const raw = (_a2 = resolveMetadataValue(meta, key)) != null ? _a2 : meta[key];
5846
6863
  const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
5847
6864
  if (Number.isFinite(value)) return value;
5848
6865
  }
@@ -5988,8 +7005,8 @@ ${schemaProfileText}` : ""}`;
5988
7005
  let inStock = 0;
5989
7006
  let outOfStock = 0;
5990
7007
  data.forEach((d) => {
5991
- var _a, _b;
5992
- const cat = (_a = this.getProductCategory(d)) != null ? _a : "Other";
7008
+ var _a2, _b;
7009
+ const cat = (_a2 = this.getProductCategory(d)) != null ? _a2 : "Other";
5993
7010
  if (cat === category) {
5994
7011
  const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
5995
7012
  if (this.determineStockStatus(d)) inStock += quantity;
@@ -6033,9 +7050,9 @@ ${schemaProfileText}` : ""}`;
6033
7050
  }
6034
7051
  // ─── Product Extraction ───────────────────────────────────────────────────
6035
7052
  static getDynamicVal(meta, uiKey, config, trainedSchema) {
6036
- var _a;
7053
+ var _a2;
6037
7054
  if (!meta) return void 0;
6038
- const mapping = (_a = config == null ? void 0 : config.rag) == null ? void 0 : _a.uiMapping;
7055
+ const mapping = (_a2 = config == null ? void 0 : config.rag) == null ? void 0 : _a2.uiMapping;
6039
7056
  if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
6040
7057
  if (trainedSchema && typeof trainedSchema === "object") {
6041
7058
  const trainedKey = trainedSchema[uiKey];
@@ -6044,13 +7061,13 @@ ${schemaProfileText}` : ""}`;
6044
7061
  return resolveMetadataValue(meta, uiKey);
6045
7062
  }
6046
7063
  static extractProductInfo(item, config, trainedSchema) {
6047
- var _a;
7064
+ var _a2;
6048
7065
  const meta = item.metadata || {};
6049
7066
  const name = this.getDynamicVal(meta, "name", config, trainedSchema);
6050
7067
  const price = this.getDynamicVal(meta, "price", config, trainedSchema);
6051
7068
  const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
6052
7069
  const description = this.cleanProductDescription(
6053
- (_a = this.extractProductDescriptionFromContent(item.content)) != null ? _a : this.getProductDescriptionValue(meta, config, trainedSchema)
7070
+ (_a2 = this.extractProductDescriptionFromContent(item.content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
6054
7071
  );
6055
7072
  if (name || this.isProductData(item)) {
6056
7073
  let finalName = name ? String(name) : void 0;
@@ -6158,10 +7175,10 @@ RULES:
6158
7175
  }
6159
7176
  static buildContextSummary(sources, maxChars = 6e3) {
6160
7177
  const items = sources.map((s, i) => {
6161
- var _a, _b, _c, _d;
7178
+ var _a2, _b, _c, _d;
6162
7179
  return {
6163
7180
  index: i + 1,
6164
- content: (_b = (_a = s.content) == null ? void 0 : _a.substring(0, 400)) != null ? _b : "",
7181
+ content: (_b = (_a2 = s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
6165
7182
  metadata: (_c = s.metadata) != null ? _c : {},
6166
7183
  score: (_d = s.score) != null ? _d : 0
6167
7184
  };
@@ -6354,9 +7371,11 @@ var Pipeline = class {
6354
7371
  /** LRU-bounded cache: avoids re-embedding identical queries within the same process. */
6355
7372
  this.embeddingCache = new LRUEmbeddingCache(500);
6356
7373
  this.initialised = false;
6357
- var _a, _b, _c, _d, _e;
7374
+ /** Namespace-specific static cold context cache for CAG */
7375
+ this.coldContexts = /* @__PURE__ */ new Map();
7376
+ var _a2, _b, _c, _d, _e;
6358
7377
  this.chunker = new DocumentChunker(
6359
- (_b = (_a = config.rag) == null ? void 0 : _a.chunkSize) != null ? _b : 1e3,
7378
+ (_b = (_a2 = config.rag) == null ? void 0 : _a2.chunkSize) != null ? _b : 1e3,
6360
7379
  (_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
6361
7380
  );
6362
7381
  if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
@@ -6372,7 +7391,7 @@ var Pipeline = class {
6372
7391
  return this.initialised ? this.llmProvider : void 0;
6373
7392
  }
6374
7393
  async initialize() {
6375
- var _a;
7394
+ var _a2, _b, _c, _d;
6376
7395
  if (this.initialised) return;
6377
7396
  const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
6378
7397
 
@@ -6415,12 +7434,47 @@ var Pipeline = class {
6415
7434
  this.entityExtractor = new EntityExtractor(this.llmProvider);
6416
7435
  }
6417
7436
  await this.vectorDB.initialize();
6418
- if (((_a = this.config.rag) == null ? void 0 : _a.architecture) === "agentic") {
7437
+ if (((_a2 = this.config.rag) == null ? void 0 : _a2.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) {
7438
+ this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
7439
+ this.multiAgentCoordinator = new MultiAgentCoordinator({
7440
+ llmProvider: this.llmProvider,
7441
+ mcpRegistry: this.mcpRegistry,
7442
+ documentSearch: async (query) => {
7443
+ return this.runNormalQuery(query);
7444
+ }
7445
+ });
6419
7446
  this.agent = new LangChainAgent(this, this.config);
6420
7447
  await this.agent.initialize(this.llmProvider);
6421
7448
  }
7449
+ if ((_d = (_c = this.config.rag) == null ? void 0 : _c.cag) == null ? void 0 : _d.enabled) {
7450
+ await this.loadColdContext(this.config.projectId);
7451
+ }
6422
7452
  this.initialised = true;
6423
7453
  }
7454
+ async loadColdContext(ns) {
7455
+ var _a2, _b;
7456
+ const cagConfig = (_a2 = this.config.rag) == null ? void 0 : _a2.cag;
7457
+ if (!cagConfig || !cagConfig.enabled) return;
7458
+ try {
7459
+ const coldNs = cagConfig.coldNamespace || ns;
7460
+ const limit = (_b = cagConfig.coldLimit) != null ? _b : 20;
7461
+ const queryText = cagConfig.coldQuery || "documentation";
7462
+ const queryVector = await this.embeddingProvider.embed(queryText, { taskType: "query" });
7463
+ const coldMatches = await this.vectorDB.query(queryVector, limit, coldNs);
7464
+ if (coldMatches.length > 0) {
7465
+ const formatted = coldMatches.map((m, i) => `[Cold Source ${i + 1}]
7466
+ ${m.content}`).join("\n\n---\n\n");
7467
+ this.coldContexts.set(ns, formatted);
7468
+ console.log(`[Pipeline] Cold RAG (CAG) loaded ${coldMatches.length} documents into cached context for namespace: ${ns}`);
7469
+ } else {
7470
+ this.coldContexts.set(ns, "No cold context found.");
7471
+ console.warn(`[Pipeline] Cold RAG (CAG) initialized but no documents were found in namespace: ${coldNs}`);
7472
+ }
7473
+ } catch (err) {
7474
+ console.error(`[Pipeline] Failed to load Cold RAG (CAG) context for namespace ${ns}:`, err);
7475
+ this.coldContexts.set(ns, "Failed to load cold context.");
7476
+ }
7477
+ }
6424
7478
  /**
6425
7479
  * Ingest documents with automatic chunking, embedding, and batch upsert.
6426
7480
  */
@@ -6452,12 +7506,12 @@ var Pipeline = class {
6452
7506
  }
6453
7507
  /** Step 1: Chunk the document content. */
6454
7508
  async prepareChunks(doc) {
6455
- var _a, _b;
7509
+ var _a2, _b;
6456
7510
  if (this.llamaIngestor) {
6457
7511
  return this.llamaIngestor.chunk(doc.content, {
6458
7512
  docId: doc.docId,
6459
7513
  metadata: doc.metadata,
6460
- chunkSize: (_a = this.config.rag) == null ? void 0 : _a.chunkSize,
7514
+ chunkSize: (_a2 = this.config.rag) == null ? void 0 : _a2.chunkSize,
6461
7515
  chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
6462
7516
  });
6463
7517
  }
@@ -6528,12 +7582,37 @@ var Pipeline = class {
6528
7582
  extractionOptions
6529
7583
  );
6530
7584
  }
7585
+ async runNormalQuery(question, history = [], namespace) {
7586
+ const stream = this.askStreamInternal(question, history, namespace);
7587
+ let reply = "";
7588
+ let sources = [];
7589
+ try {
7590
+ for (var iter = __forAwait(stream), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
7591
+ const chunk = temp.value;
7592
+ if (typeof chunk === "string") {
7593
+ reply += chunk;
7594
+ } else if (typeof chunk === "object" && chunk !== null) {
7595
+ if ("reply" in chunk && chunk.reply) reply += chunk.reply;
7596
+ if ("sources" in chunk && chunk.sources) sources = chunk.sources;
7597
+ }
7598
+ }
7599
+ } catch (temp) {
7600
+ error = [temp];
7601
+ } finally {
7602
+ try {
7603
+ more && (temp = iter.return) && await temp.call(iter);
7604
+ } finally {
7605
+ if (error)
7606
+ throw error[0];
7607
+ }
7608
+ }
7609
+ return { reply, sources };
7610
+ }
6531
7611
  async ask(question, history = [], namespace) {
6532
- var _a;
7612
+ var _a2, _b;
6533
7613
  await this.initialize();
6534
- if (((_a = this.config.rag) == null ? void 0 : _a.architecture) === "agentic" && this.agent) {
6535
- const agentReply = await this.agent.run(question, history);
6536
- return { reply: agentReply, sources: [] };
7614
+ if ((((_a2 = this.config.rag) == null ? void 0 : _a2.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
7615
+ return await this.multiAgentCoordinator.run(question, history);
6537
7616
  }
6538
7617
  const stream = this.askStream(question, history, namespace);
6539
7618
  let reply = "";
@@ -6565,6 +7644,47 @@ var Pipeline = class {
6565
7644
  }
6566
7645
  return { reply, sources, graphData, ui_transformation: uiTransformation, trace };
6567
7646
  }
7647
+ askStream(_0) {
7648
+ return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
7649
+ var _a2, _b;
7650
+ yield new __await(this.initialize());
7651
+ if ((((_a2 = this.config.rag) == null ? void 0 : _a2.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
7652
+ const stream2 = this.multiAgentCoordinator.runStream(question, history);
7653
+ try {
7654
+ for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
7655
+ const chunk = temp.value;
7656
+ yield chunk;
7657
+ }
7658
+ } catch (temp) {
7659
+ error = [temp];
7660
+ } finally {
7661
+ try {
7662
+ more && (temp = iter.return) && (yield new __await(temp.call(iter)));
7663
+ } finally {
7664
+ if (error)
7665
+ throw error[0];
7666
+ }
7667
+ }
7668
+ return;
7669
+ }
7670
+ const stream = this.askStreamInternal(question, history, namespace);
7671
+ try {
7672
+ for (var iter2 = __forAwait(stream), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {
7673
+ const chunk = temp2.value;
7674
+ yield chunk;
7675
+ }
7676
+ } catch (temp2) {
7677
+ error2 = [temp2];
7678
+ } finally {
7679
+ try {
7680
+ more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));
7681
+ } finally {
7682
+ if (error2)
7683
+ throw error2[0];
7684
+ }
7685
+ }
7686
+ });
7687
+ }
6568
7688
  /**
6569
7689
  * High-performance streaming RAG flow.
6570
7690
  * Yields text chunks first, then the retrieval metadata + observability trace at the end.
@@ -6575,12 +7695,12 @@ var Pipeline = class {
6575
7695
  * - UITransformation is computed after text streaming and emitted with metadata
6576
7696
  * - SchemaMapper.train runs while answer generation streams
6577
7697
  */
6578
- askStream(_0) {
7698
+ askStreamInternal(_0) {
6579
7699
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
6580
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
7700
+ 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;
6581
7701
  yield new __await(this.initialize());
6582
7702
  const ns = namespace != null ? namespace : this.config.projectId;
6583
- const topK = (_b = (_a = this.config.rag) == null ? void 0 : _a.topK) != null ? _b : 5;
7703
+ const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
6584
7704
  const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
6585
7705
  const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
6586
7706
  const requestStart = performance.now();
@@ -6593,20 +7713,21 @@ var Pipeline = class {
6593
7713
  }
6594
7714
  const hints = QueryProcessor.extractQueryFieldHints(question, (_f = this.config.rag) == null ? void 0 : _f.filterableFields);
6595
7715
  const filter = QueryProcessor.buildQueryFilter(question, hints);
6596
- const numericPredicates = QueryProcessor.extractNumericPredicates(question, (_g = this.config.rag) == null ? void 0 : _g.filterableFields);
7716
+ const numericPredicates = QueryProcessor.extractNumericPredicates(question, (_g2 = this.config.rag) == null ? void 0 : _g2.filterableFields);
6597
7717
  if (numericPredicates.length > 0) {
6598
7718
  filter.__numericPredicates = numericPredicates;
6599
7719
  }
6600
7720
  const embedStart = performance.now();
6601
7721
  const cacheKey = `${ns}::${searchQuery}`;
6602
7722
  const cachedVector = this.embeddingCache.get(cacheKey);
6603
- const useGraph = this.graphDB && ((_h = this.config.rag) == null ? void 0 : _h.useGraphRetrieval);
7723
+ const arch = (_h = this.config.rag) == null ? void 0 : _h.architecture;
7724
+ const useGraph = arch !== "naive" && arch !== "retrieve-and-rerank" && this.graphDB && ((_i = this.config.rag) == null ? void 0 : _i.useGraphRetrieval);
6604
7725
  const [strategyResult, embeddedVector] = yield new __await(Promise.all([
6605
7726
  QueryProcessor.determineRetrievalStrategy(
6606
7727
  searchQuery,
6607
7728
  useGraph ? this.llmRouter.get("fast") : void 0,
6608
- (_i = this.config.rag) == null ? void 0 : _i.graphKeywords,
6609
- (_j = this.config.rag) == null ? void 0 : _j.vectorKeywords
7729
+ (_j = this.config.rag) == null ? void 0 : _j.graphKeywords,
7730
+ (_k = this.config.rag) == null ? void 0 : _k.vectorKeywords
6610
7731
  ),
6611
7732
  // Embed immediately regardless of strategy — costs nothing if cached.
6612
7733
  // If strategy turns out to be 'graph'-only we just won't use the vector.
@@ -6616,7 +7737,7 @@ var Pipeline = class {
6616
7737
  if (!cachedVector && queryVector.length > 0) {
6617
7738
  this.embeddingCache.set(cacheKey, queryVector);
6618
7739
  }
6619
- const graphData = (strategyResult === "graph" || strategyResult === "both") && this.graphDB && ((_k = this.config.rag) == null ? void 0 : _k.useGraphRetrieval) ? yield new __await(this.graphDB.query(searchQuery)) : void 0;
7740
+ const graphData = (strategyResult === "graph" || strategyResult === "both") && this.graphDB && ((_l = this.config.rag) == null ? void 0 : _l.useGraphRetrieval) ? yield new __await(this.graphDB.query(searchQuery)) : void 0;
6620
7741
  const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
6621
7742
  const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
6622
7743
  const wantsExhaustiveList = hasNumericPredicates || hasMetadataFilter || /\b(list|all|show|provide|give|get|browse|find|search|display)\b/i.test(question);
@@ -6629,7 +7750,8 @@ var Pipeline = class {
6629
7750
  const structuredSources = this.applyStructuredFilters(rawSources, filter);
6630
7751
  let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => m.score >= scoreThreshold);
6631
7752
  const rerankLimit = wantsExhaustiveList ? retrievalLimit : topK;
6632
- if (!hasNumericPredicates && ((_l = this.config.rag) == null ? void 0 : _l.useReranking)) {
7753
+ const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
7754
+ if (!hasNumericPredicates && useReranking) {
6633
7755
  fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
6634
7756
  } else if (!wantsExhaustiveList) {
6635
7757
  fullSources = fullSources.slice(0, topK);
@@ -6659,6 +7781,32 @@ ${graphContext}
6659
7781
  VECTOR CONTEXT:
6660
7782
  ${context}`;
6661
7783
  }
7784
+ if ((_o = (_n = this.config.rag) == null ? void 0 : _n.cag) == null ? void 0 : _o.enabled) {
7785
+ if (!this.coldContexts.has(ns)) {
7786
+ yield new __await(this.loadColdContext(ns));
7787
+ }
7788
+ const coldContext = this.coldContexts.get(ns);
7789
+ if (coldContext && coldContext !== "No cold context found." && coldContext !== "Failed to load cold context.") {
7790
+ context = `COLD CONTEXT (STATIC KNOWLEDGE):
7791
+ ${coldContext}
7792
+
7793
+ RETRIEVED HOT CONTEXT (REAL-TIME KNOWLEDGE):
7794
+ ${context}`;
7795
+ }
7796
+ }
7797
+ yield {
7798
+ reply: "",
7799
+ sources: sources.map((s) => {
7800
+ var _a3;
7801
+ return {
7802
+ id: s.id,
7803
+ score: s.score,
7804
+ content: s.content,
7805
+ metadata: (_a3 = s.metadata) != null ? _a3 : {},
7806
+ namespace: ns
7807
+ };
7808
+ })
7809
+ };
6662
7810
  const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
6663
7811
  const cachedSchema = allMetadataKeys.length > 0 ? SchemaMapper.getCached(ns, allMetadataKeys) : void 0;
6664
7812
  if (allMetadataKeys.length > 0 && !cachedSchema) {
@@ -6686,10 +7834,10 @@ ${context}`;
6686
7834
  let hallucinationScoringPromise = Promise.resolve(void 0);
6687
7835
  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.)";
6688
7836
  const isClaude37 = this.config.llm.model.includes("claude-3-7-sonnet");
6689
- 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);
7837
+ const isNativeThinking = isClaude37 && (((_p = this.config.llm.options) == null ? void 0 : _p.thinking) === true || ((_q = this.config.llm.options) == null ? void 0 : _q.thinking) === "enabled" || ((_r = this.config.llm.options) == null ? void 0 : _r.thinking) !== false);
6690
7838
  const modelNameLower = this.config.llm.model.toLowerCase();
6691
7839
  const isReasoningModel = modelNameLower.includes("-r1") || modelNameLower.includes("deepseek-r1") || modelNameLower.includes("reasoning") || modelNameLower.includes("thinking");
6692
- 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);
7840
+ const isSimulatedThinking = !isNativeThinking && (((_s = this.config.llm.options) == null ? void 0 : _s.thinking) === true || ((_t = this.config.llm.options) == null ? void 0 : _t.thinking) === "enabled" || isReasoningModel && ((_u = this.config.llm.options) == null ? void 0 : _u.thinking) !== false);
6693
7841
  let finalRestrictionSuffix = restrictionSuffix;
6694
7842
  if (isSimulatedThinking) {
6695
7843
  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.`)";
@@ -6697,7 +7845,7 @@ ${context}`;
6697
7845
  const hardenedHistory = [...history];
6698
7846
  const userQuestion = { role: "user", content: question + finalRestrictionSuffix };
6699
7847
  const messages = [...hardenedHistory, userQuestion];
6700
- const systemPrompt = (_s = this.config.llm.systemPrompt) != null ? _s : "";
7848
+ const systemPrompt = (_v = this.config.llm.systemPrompt) != null ? _v : "";
6701
7849
  const userPrompt = messages.map((m) => `${m.role}: ${m.content}`).join("\n");
6702
7850
  let fullReply = "";
6703
7851
  let thinkingText = "";
@@ -6808,7 +7956,7 @@ ${context}`;
6808
7956
  }
6809
7957
  yield fullReply;
6810
7958
  }
6811
- 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;
7959
+ const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true || this.config.llm.provider !== "ollama" && ((_x = this.config.llm.options) == null ? void 0 : _x.hallucinationScoring) !== false;
6812
7960
  if (runHallucination) {
6813
7961
  hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
6814
7962
  }
@@ -6817,7 +7965,7 @@ ${context}`;
6817
7965
  const latency = {
6818
7966
  embedMs: Math.round(embedMs),
6819
7967
  retrieveMs: Math.round(retrieveMs),
6820
- rerankMs: ((_v = this.config.rag) == null ? void 0 : _v.useReranking) ? Math.round(rerankMs) : void 0,
7968
+ rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_y = this.config.rag) == null ? void 0 : _y.useReranking)) ? Math.round(rerankMs) : void 0,
6821
7969
  generateMs: Math.round(generateMs),
6822
7970
  totalMs: Math.round(totalMs)
6823
7971
  };
@@ -6830,33 +7978,63 @@ ${context}`;
6830
7978
  totalTokens: promptTokens + completionTokens,
6831
7979
  estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
6832
7980
  };
7981
+ const awaitHallucination = ((_z = this.config.llm.options) == null ? void 0 : _z.awaitHallucination) === true;
6833
7982
  const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
6834
7983
  uiTransformationPromise,
6835
- hallucinationScoringPromise
7984
+ awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
6836
7985
  ]));
6837
- const trace = __spreadValues({
7986
+ const buildTrace = (hScore) => __spreadValues({
6838
7987
  requestId,
6839
7988
  query: question,
6840
7989
  rewrittenQuery,
6841
7990
  systemPrompt,
6842
7991
  userPrompt: question + finalRestrictionSuffix,
6843
7992
  chunks: sources.map((s) => {
6844
- var _a2;
7993
+ var _a3;
6845
7994
  return {
6846
7995
  id: s.id,
6847
7996
  score: s.score,
6848
7997
  content: s.content,
6849
- metadata: (_a2 = s.metadata) != null ? _a2 : {},
7998
+ metadata: (_a3 = s.metadata) != null ? _a3 : {},
6850
7999
  namespace: ns
6851
8000
  };
6852
8001
  }),
6853
8002
  latency,
6854
8003
  tokens,
6855
8004
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
6856
- }, hallucinationResult ? {
6857
- hallucinationScore: hallucinationResult.score,
6858
- hallucinationReason: hallucinationResult.reason
8005
+ }, hScore ? {
8006
+ hallucinationScore: hScore.score,
8007
+ hallucinationReason: hScore.reason
6859
8008
  } : {});
8009
+ const trace = buildTrace(hallucinationResult);
8010
+ if ((_A = this.config.telemetry) == null ? void 0 : _A.enabled) {
8011
+ const telemetryUrl = this.config.telemetry.url || "/api/telemetry";
8012
+ const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
8013
+ (async () => {
8014
+ try {
8015
+ let finalTrace = trace;
8016
+ if (!awaitHallucination && runHallucination) {
8017
+ const backgroundScoreResult = await hallucinationScoringPromise;
8018
+ if (backgroundScoreResult) {
8019
+ finalTrace = buildTrace(backgroundScoreResult);
8020
+ }
8021
+ }
8022
+ await fetch(absoluteUrl, {
8023
+ method: "POST",
8024
+ headers: {
8025
+ "Content-Type": "application/json"
8026
+ },
8027
+ body: JSON.stringify({
8028
+ trace: finalTrace,
8029
+ licenseKey: this.config.licenseKey,
8030
+ projectId: ns
8031
+ })
8032
+ });
8033
+ } catch (err) {
8034
+ console.warn(`[Pipeline Telemetry] Failed to send trace async to ${absoluteUrl}:`, err.message);
8035
+ }
8036
+ })();
8037
+ }
6860
8038
  yield {
6861
8039
  reply: "",
6862
8040
  sources,
@@ -6876,7 +8054,7 @@ ${context}`;
6876
8054
  * Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
6877
8055
  */
6878
8056
  async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
6879
- var _a;
8057
+ var _a2;
6880
8058
  if (!sources || sources.length === 0) {
6881
8059
  return UITransformer.transform(question, sources, this.config, cachedSchema);
6882
8060
  }
@@ -6890,7 +8068,7 @@ ${context}`;
6890
8068
  );
6891
8069
  }
6892
8070
  const isLocalProvider = this.config.llm.provider === "ollama";
6893
- const disableLlmUiTransform = ((_a = this.config.llm.options) == null ? void 0 : _a.disableLlmUiTransform) === true;
8071
+ const disableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.disableLlmUiTransform) === true;
6894
8072
  if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
6895
8073
  return UITransformer.transform(question, sources, this.config, cachedSchema);
6896
8074
  }
@@ -6908,9 +8086,9 @@ ${context}`;
6908
8086
  const value = this.resolveNumericPredicateValue(source, predicate);
6909
8087
  return value !== null && this.matchesNumericPredicate(value, predicate);
6910
8088
  })).sort((a, b) => {
6911
- var _a, _b;
8089
+ var _a2, _b;
6912
8090
  const primary = predicates[0];
6913
- const aValue = (_a = this.resolveNumericPredicateValue(a, primary)) != null ? _a : 0;
8091
+ const aValue = (_a2 = this.resolveNumericPredicateValue(a, primary)) != null ? _a2 : 0;
6914
8092
  const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
6915
8093
  return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
6916
8094
  });
@@ -6982,8 +8160,8 @@ ${context}`;
6982
8160
  return Number.isFinite(numeric) ? numeric : null;
6983
8161
  }
6984
8162
  async retrieve(query, options) {
6985
- var _a, _b, _c, _d, _e, _f, _g;
6986
- const ns = (_a = options.namespace) != null ? _a : this.config.projectId;
8163
+ var _a2, _b, _c, _d, _e, _f, _g2;
8164
+ const ns = (_a2 = options.namespace) != null ? _a2 : this.config.projectId;
6987
8165
  const topK = (_b = options.topK) != null ? _b : 5;
6988
8166
  const cacheKey = `${ns}::${query}`;
6989
8167
  let queryVector = this.embeddingCache.get(cacheKey);
@@ -7015,7 +8193,7 @@ ${context}`;
7015
8193
  ) : [];
7016
8194
  const resolvedSources = [];
7017
8195
  for (const source of sources) {
7018
- const parentId = (_g = source.metadata) == null ? void 0 : _g.parent_id;
8196
+ const parentId = (_g2 = source.metadata) == null ? void 0 : _g2.parent_id;
7019
8197
  if (parentId) {
7020
8198
  console.log(`[Pipeline] Multi-Vector: Found child chunk. Parent ID: ${parentId}`);
7021
8199
  resolvedSources.push(source);
@@ -7097,8 +8275,15 @@ var Retrivora = class {
7097
8275
  this.pipeline = new Pipeline(this.config);
7098
8276
  }
7099
8277
  async initialize() {
8278
+ var _a2;
7100
8279
  try {
7101
8280
  await ConfigValidator.validateAndThrow(this.config);
8281
+ LicenseVerifier.verify(
8282
+ this.config.licenseKey,
8283
+ this.config.projectId,
8284
+ (_a2 = this.config.vectorDb) == null ? void 0 : _a2.provider
8285
+ );
8286
+ await LicenseVerifier.verifyIP(this.config.licenseKey);
7102
8287
  } catch (err) {
7103
8288
  throw wrapError(err, "CONFIGURATION_ERROR");
7104
8289
  }
@@ -7272,11 +8457,20 @@ var ProviderHealthCheck = class {
7272
8457
  // src/core/VectorPlugin.ts
7273
8458
  var VectorPlugin = class {
7274
8459
  constructor(hostConfig) {
7275
- this.config = ConfigResolver.resolve(hostConfig);
7276
- this.validationPromise = ConfigValidator.validateAndThrow(this.config);
8460
+ const resolvedConfig = ConfigResolver.resolve(hostConfig);
8461
+ this.config = resolvedConfig;
8462
+ this.validationPromise = (async () => {
8463
+ var _a2;
8464
+ await ConfigValidator.validateAndThrow(resolvedConfig);
8465
+ LicenseVerifier.verify(
8466
+ resolvedConfig.licenseKey,
8467
+ resolvedConfig.projectId,
8468
+ (_a2 = resolvedConfig.vectorDb) == null ? void 0 : _a2.provider
8469
+ );
8470
+ })();
7277
8471
  this.validationPromise.catch(() => {
7278
8472
  });
7279
- this.pipeline = new Pipeline(this.config);
8473
+ this.pipeline = new Pipeline(resolvedConfig);
7280
8474
  }
7281
8475
  /**
7282
8476
  * Get the current resolved configuration.
@@ -7412,13 +8606,13 @@ var ConfigBuilder = class {
7412
8606
  * Configure the vector database provider
7413
8607
  */
7414
8608
  vectorDb(provider, options) {
7415
- var _a;
8609
+ var _a2;
7416
8610
  if (provider === "auto") {
7417
8611
  this._vectorDb = this._autoDetectVectorDb();
7418
8612
  } else {
7419
8613
  this._vectorDb = {
7420
8614
  provider,
7421
- indexName: (_a = options == null ? void 0 : options.indexName) != null ? _a : "default",
8615
+ indexName: (_a2 = options == null ? void 0 : options.indexName) != null ? _a2 : "default",
7422
8616
  options: __spreadValues({}, options)
7423
8617
  };
7424
8618
  }
@@ -7428,7 +8622,7 @@ var ConfigBuilder = class {
7428
8622
  * Configure the LLM provider for chat
7429
8623
  */
7430
8624
  llm(provider, model, apiKey, options) {
7431
- var _a, _b;
8625
+ var _a2, _b;
7432
8626
  if (provider === "auto") {
7433
8627
  this._llm = this._autoDetectLLM();
7434
8628
  } else {
@@ -7437,7 +8631,7 @@ var ConfigBuilder = class {
7437
8631
  model: model != null ? model : "default-model",
7438
8632
  apiKey,
7439
8633
  systemPrompt: options == null ? void 0 : options.systemPrompt,
7440
- maxTokens: (_a = options == null ? void 0 : options.maxTokens) != null ? _a : 1024,
8634
+ maxTokens: (_a2 = options == null ? void 0 : options.maxTokens) != null ? _a2 : 1024,
7441
8635
  temperature: (_b = options == null ? void 0 : options.temperature) != null ? _b : 0.7,
7442
8636
  baseUrl: options == null ? void 0 : options.baseUrl,
7443
8637
  options
@@ -7480,8 +8674,8 @@ var ConfigBuilder = class {
7480
8674
  * Set RAG-specific pipeline parameters
7481
8675
  */
7482
8676
  rag(options) {
7483
- var _a;
7484
- this._rag = __spreadValues(__spreadValues({}, (_a = this._rag) != null ? _a : {}), options);
8677
+ var _a2;
8678
+ this._rag = __spreadValues(__spreadValues({}, (_a2 = this._rag) != null ? _a2 : {}), options);
7485
8679
  return this;
7486
8680
  }
7487
8681
  /**
@@ -7497,7 +8691,7 @@ var ConfigBuilder = class {
7497
8691
  * Throws if required fields (projectId, vectorDb, llm, embedding) are not set.
7498
8692
  */
7499
8693
  build() {
7500
- var _a;
8694
+ var _a2;
7501
8695
  const missing = [];
7502
8696
  if (!this._projectId) missing.push('projectId (call .projectId("my-app"))');
7503
8697
  if (!this._vectorDb) missing.push('vectorDb (call .vectorDb("pinecone", { ... }))');
@@ -7509,7 +8703,7 @@ var ConfigBuilder = class {
7509
8703
  ${missing.join("\n ")}`
7510
8704
  );
7511
8705
  }
7512
- const ragConfig = (_a = this._rag) != null ? _a : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
8706
+ const ragConfig = (_a2 = this._rag) != null ? _a2 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
7513
8707
  if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
7514
8708
  ragConfig.useGraphRetrieval = true;
7515
8709
  }
@@ -7605,8 +8799,8 @@ var DocumentParser = class {
7605
8799
  * Extract text from a File or Buffer based on its type.
7606
8800
  */
7607
8801
  static async parse(file, fileName, mimeType) {
7608
- var _a;
7609
- const extension = (_a = fileName.split(".").pop()) == null ? void 0 : _a.toLowerCase();
8802
+ var _a2;
8803
+ const extension = (_a2 = fileName.split(".").pop()) == null ? void 0 : _a2.toLowerCase();
7610
8804
  if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
7611
8805
  return this.readAsText(file);
7612
8806
  }
@@ -7673,6 +8867,497 @@ init_UniversalVectorProvider();
7673
8867
 
7674
8868
  // src/handlers/index.ts
7675
8869
  import { NextResponse } from "next/server";
8870
+
8871
+ // src/core/DatabaseStorage.ts
8872
+ import * as fs from "fs";
8873
+ import * as path from "path";
8874
+ var DatabaseStorage = class {
8875
+ constructor(config) {
8876
+ // Dynamic PG Pool
8877
+ this.pgPool = null;
8878
+ // Dynamic MongoDB Client
8879
+ this.mongoClient = null;
8880
+ this.mongoDbName = "";
8881
+ // Filesystem fallback configuration
8882
+ this.fallbackDir = path.join(process.cwd(), ".retrivora");
8883
+ this.historyFile = path.join(this.fallbackDir, "history.json");
8884
+ this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
8885
+ var _a2, _b, _c, _d, _e;
8886
+ this.config = config;
8887
+ this.provider = ((_a2 = config.vectorDb) == null ? void 0 : _a2.provider) || "fs";
8888
+ const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
8889
+ const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
8890
+ this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
8891
+ this.feedbackTableName = rawFeedbackTable.replace(/[^a-zA-Z0-9_]/g, "_");
8892
+ }
8893
+ /**
8894
+ * Asserts the user is running a valid Premium/Enterprise license in production.
8895
+ * In non-production (development / test) environments this is a complete no-op —
8896
+ * all History and Feedback features are freely accessible for local development.
8897
+ */
8898
+ checkPremiumSubscription() {
8899
+ if (process.env.NODE_ENV !== "production") {
8900
+ return;
8901
+ }
8902
+ if (!this.config.licenseKey) {
8903
+ throw new Error(
8904
+ "[Retrivora SDK] Chat History and Feedback features require a Premium or Enterprise license key in production."
8905
+ );
8906
+ }
8907
+ try {
8908
+ const payload = LicenseVerifier.verify(this.config.licenseKey, this.config.projectId);
8909
+ const tier = (payload.tier || "").toLowerCase();
8910
+ if (tier !== "premium" && tier !== "enterprise" && tier !== "growth" && tier !== "pro" && tier !== "developer_pro") {
8911
+ throw new Error(
8912
+ `[Retrivora SDK] Chat History and Feedback features are not available on the "${tier}" tier. Please upgrade to a Developer Pro or Enterprise plan.`
8913
+ );
8914
+ }
8915
+ } catch (err) {
8916
+ throw new Error(
8917
+ `[Retrivora SDK] Subscription check failed: ${err instanceof Error ? err.message : String(err)}`
8918
+ );
8919
+ }
8920
+ }
8921
+ checkHistoryEnabled() {
8922
+ var _a2, _b;
8923
+ this.checkPremiumSubscription();
8924
+ if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.history) == null ? void 0 : _b.enabled) === false) {
8925
+ throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
8926
+ }
8927
+ }
8928
+ checkFeedbackEnabled() {
8929
+ var _a2, _b;
8930
+ this.checkPremiumSubscription();
8931
+ if (((_b = (_a2 = this.config.rag) == null ? void 0 : _a2.feedback) == null ? void 0 : _b.enabled) === false) {
8932
+ throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
8933
+ }
8934
+ }
8935
+ async getPGPool() {
8936
+ const globalKey = `__retrivora_pg_pool_${this.config.projectId}`;
8937
+ const _g2 = global;
8938
+ if (_g2[globalKey]) {
8939
+ this.pgPool = _g2[globalKey];
8940
+ return this.pgPool;
8941
+ }
8942
+ const opts = this.config.vectorDb.options;
8943
+ if (!opts.connectionString) {
8944
+ throw new Error("[DatabaseStorage] pg connectionString option is missing.");
8945
+ }
8946
+ const { Pool: Pool3 } = await import("pg");
8947
+ this.pgPool = new Pool3({ connectionString: opts.connectionString });
8948
+ _g2[globalKey] = this.pgPool;
8949
+ const client = await this.pgPool.connect();
8950
+ try {
8951
+ await client.query(`
8952
+ CREATE TABLE IF NOT EXISTS ${this.historyTableName} (
8953
+ id TEXT PRIMARY KEY,
8954
+ session_id TEXT NOT NULL,
8955
+ role TEXT NOT NULL,
8956
+ content TEXT NOT NULL,
8957
+ sources JSONB,
8958
+ ui_transformation JSONB,
8959
+ trace JSONB,
8960
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
8961
+ )
8962
+ `);
8963
+ await client.query(`
8964
+ CREATE TABLE IF NOT EXISTS ${this.feedbackTableName} (
8965
+ id TEXT PRIMARY KEY,
8966
+ message_id TEXT NOT NULL UNIQUE,
8967
+ session_id TEXT NOT NULL,
8968
+ rating TEXT NOT NULL,
8969
+ comment TEXT,
8970
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
8971
+ )
8972
+ `);
8973
+ } finally {
8974
+ client.release();
8975
+ }
8976
+ return this.pgPool;
8977
+ }
8978
+ async getMongoClient() {
8979
+ const globalKey = `__retrivora_mongo_client_${this.config.projectId}`;
8980
+ const _g2 = global;
8981
+ if (_g2[globalKey]) {
8982
+ this.mongoClient = _g2[globalKey];
8983
+ this.mongoDbName = this.config.vectorDb.options.database;
8984
+ return this.mongoClient;
8985
+ }
8986
+ const opts = this.config.vectorDb.options;
8987
+ if (!opts.uri || !opts.database) {
8988
+ throw new Error("[DatabaseStorage] mongo uri and database options are missing.");
8989
+ }
8990
+ const { MongoClient: MongoClient2 } = await import("mongodb");
8991
+ this.mongoClient = new MongoClient2(opts.uri);
8992
+ await this.mongoClient.connect();
8993
+ _g2[globalKey] = this.mongoClient;
8994
+ this.mongoDbName = opts.database;
8995
+ return this.mongoClient;
8996
+ }
8997
+ getMongoDb() {
8998
+ return this.mongoClient.db(this.mongoDbName);
8999
+ }
9000
+ // Helper for FS fallback reads
9001
+ readLocalFile(filePath) {
9002
+ if (!fs.existsSync(filePath)) return [];
9003
+ try {
9004
+ const raw = fs.readFileSync(filePath, "utf-8");
9005
+ return JSON.parse(raw) || [];
9006
+ } catch (e) {
9007
+ return [];
9008
+ }
9009
+ }
9010
+ // Helper for FS fallback writes
9011
+ writeLocalFile(filePath, data) {
9012
+ if (!fs.existsSync(this.fallbackDir)) {
9013
+ fs.mkdirSync(this.fallbackDir, { recursive: true });
9014
+ }
9015
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
9016
+ }
9017
+ // ─── Message History Operations ──────────────────────────────────────────
9018
+ async saveMessage(sessionId, message) {
9019
+ this.checkHistoryEnabled();
9020
+ const createdAt = (/* @__PURE__ */ new Date()).toISOString();
9021
+ const msgId = message.id || `msg_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
9022
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9023
+ const pool = await this.getPGPool();
9024
+ await pool.query(
9025
+ `INSERT INTO ${this.historyTableName} (id, session_id, role, content, sources, ui_transformation, trace, created_at)
9026
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
9027
+ ON CONFLICT (id) DO UPDATE
9028
+ SET content = EXCLUDED.content, sources = EXCLUDED.sources, ui_transformation = EXCLUDED.ui_transformation, trace = EXCLUDED.trace`,
9029
+ [
9030
+ msgId,
9031
+ sessionId,
9032
+ message.role,
9033
+ message.content,
9034
+ message.sources ? JSON.stringify(message.sources) : null,
9035
+ message.uiTransformation ? JSON.stringify(message.uiTransformation) : null,
9036
+ message.trace ? JSON.stringify(message.trace) : null,
9037
+ createdAt
9038
+ ]
9039
+ );
9040
+ } else if (this.provider === "mongodb") {
9041
+ await this.getMongoClient();
9042
+ const db = this.getMongoDb();
9043
+ const col = db.collection(this.historyTableName);
9044
+ await col.updateOne(
9045
+ { id: msgId },
9046
+ {
9047
+ $set: {
9048
+ id: msgId,
9049
+ session_id: sessionId,
9050
+ role: message.role,
9051
+ content: message.content,
9052
+ sources: message.sources || null,
9053
+ ui_transformation: message.uiTransformation || null,
9054
+ trace: message.trace || null,
9055
+ created_at: createdAt
9056
+ }
9057
+ },
9058
+ { upsert: true }
9059
+ );
9060
+ } else {
9061
+ const history = this.readLocalFile(this.historyFile);
9062
+ const index = history.findIndex((h) => h.id === msgId);
9063
+ const item = {
9064
+ id: msgId,
9065
+ session_id: sessionId,
9066
+ role: message.role,
9067
+ content: message.content,
9068
+ sources: message.sources || null,
9069
+ ui_transformation: message.uiTransformation || null,
9070
+ trace: message.trace || null,
9071
+ created_at: createdAt
9072
+ };
9073
+ if (index !== -1) {
9074
+ history[index] = item;
9075
+ } else {
9076
+ history.push(item);
9077
+ }
9078
+ this.writeLocalFile(this.historyFile, history);
9079
+ }
9080
+ }
9081
+ async getHistory(sessionId) {
9082
+ this.checkHistoryEnabled();
9083
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9084
+ const pool = await this.getPGPool();
9085
+ const res = await pool.query(
9086
+ `SELECT id, role, content, sources, ui_transformation as "uiTransformation", trace, created_at as "createdAt"
9087
+ FROM ${this.historyTableName}
9088
+ WHERE session_id = $1
9089
+ ORDER BY created_at ASC`,
9090
+ [sessionId]
9091
+ );
9092
+ return res.rows;
9093
+ } else if (this.provider === "mongodb") {
9094
+ await this.getMongoClient();
9095
+ const db = this.getMongoDb();
9096
+ const col = db.collection(this.historyTableName);
9097
+ const items = await col.find({ session_id: sessionId }).sort({ created_at: 1 }).toArray();
9098
+ return items.map((item) => ({
9099
+ id: item.id,
9100
+ role: item.role,
9101
+ content: item.content,
9102
+ sources: item.sources,
9103
+ uiTransformation: item.ui_transformation,
9104
+ trace: item.trace,
9105
+ createdAt: item.created_at
9106
+ }));
9107
+ } else {
9108
+ const history = this.readLocalFile(this.historyFile);
9109
+ return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
9110
+ }
9111
+ }
9112
+ async clearHistory(sessionId) {
9113
+ this.checkHistoryEnabled();
9114
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9115
+ const pool = await this.getPGPool();
9116
+ await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
9117
+ await pool.query(`DELETE FROM ${this.feedbackTableName} WHERE session_id = $1`, [sessionId]);
9118
+ } else if (this.provider === "mongodb") {
9119
+ await this.getMongoClient();
9120
+ const db = this.getMongoDb();
9121
+ await db.collection(this.historyTableName).deleteMany({ session_id: sessionId });
9122
+ await db.collection(this.feedbackTableName).deleteMany({ session_id: sessionId });
9123
+ } else {
9124
+ const history = this.readLocalFile(this.historyFile);
9125
+ const filteredHistory = history.filter((h) => h.session_id !== sessionId);
9126
+ this.writeLocalFile(this.historyFile, filteredHistory);
9127
+ const feedback = this.readLocalFile(this.feedbackFile);
9128
+ const filteredFeedback = feedback.filter((f) => f.session_id !== sessionId);
9129
+ this.writeLocalFile(this.feedbackFile, filteredFeedback);
9130
+ }
9131
+ }
9132
+ async listSessions() {
9133
+ this.checkHistoryEnabled();
9134
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9135
+ const pool = await this.getPGPool();
9136
+ const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
9137
+ return res.rows.map((r) => r.session_id);
9138
+ } else if (this.provider === "mongodb") {
9139
+ await this.getMongoClient();
9140
+ const db = this.getMongoDb();
9141
+ return db.collection(this.historyTableName).distinct("session_id");
9142
+ } else {
9143
+ const history = this.readLocalFile(this.historyFile);
9144
+ const sessions = new Set(history.map((h) => h.session_id));
9145
+ return Array.from(sessions);
9146
+ }
9147
+ }
9148
+ // ─── Feedback Operations ──────────────────────────────────────────────────
9149
+ async saveFeedback(feedback) {
9150
+ this.checkFeedbackEnabled();
9151
+ const id = `fb_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
9152
+ const createdAt = (/* @__PURE__ */ new Date()).toISOString();
9153
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9154
+ const pool = await this.getPGPool();
9155
+ await pool.query(
9156
+ `INSERT INTO ${this.feedbackTableName} (id, message_id, session_id, rating, comment, created_at)
9157
+ VALUES ($1, $2, $3, $4, $5, $6)
9158
+ ON CONFLICT (message_id) DO UPDATE
9159
+ SET rating = EXCLUDED.rating, comment = EXCLUDED.comment`,
9160
+ [id, feedback.messageId, feedback.sessionId, feedback.rating, feedback.comment || null, createdAt]
9161
+ );
9162
+ } else if (this.provider === "mongodb") {
9163
+ await this.getMongoClient();
9164
+ const db = this.getMongoDb();
9165
+ const col = db.collection(this.feedbackTableName);
9166
+ await col.updateOne(
9167
+ { message_id: feedback.messageId },
9168
+ {
9169
+ $set: {
9170
+ id,
9171
+ message_id: feedback.messageId,
9172
+ session_id: feedback.sessionId,
9173
+ rating: feedback.rating,
9174
+ comment: feedback.comment || null,
9175
+ created_at: createdAt
9176
+ }
9177
+ },
9178
+ { upsert: true }
9179
+ );
9180
+ } else {
9181
+ const list = this.readLocalFile(this.feedbackFile);
9182
+ const index = list.findIndex((f) => f.message_id === feedback.messageId);
9183
+ const item = {
9184
+ id,
9185
+ message_id: feedback.messageId,
9186
+ session_id: feedback.sessionId,
9187
+ rating: feedback.rating,
9188
+ comment: feedback.comment || null,
9189
+ created_at: createdAt
9190
+ };
9191
+ if (index !== -1) {
9192
+ list[index] = item;
9193
+ } else {
9194
+ list.push(item);
9195
+ }
9196
+ this.writeLocalFile(this.feedbackFile, list);
9197
+ }
9198
+ }
9199
+ async getFeedback(messageId) {
9200
+ this.checkFeedbackEnabled();
9201
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9202
+ const pool = await this.getPGPool();
9203
+ const res = await pool.query(
9204
+ `SELECT id, message_id as "messageId", session_id as "sessionId", rating, comment, created_at as "createdAt"
9205
+ FROM ${this.feedbackTableName}
9206
+ WHERE message_id = $1`,
9207
+ [messageId]
9208
+ );
9209
+ return res.rows[0] || null;
9210
+ } else if (this.provider === "mongodb") {
9211
+ await this.getMongoClient();
9212
+ const db = this.getMongoDb();
9213
+ const col = db.collection(this.feedbackTableName);
9214
+ const item = await col.findOne({ message_id: messageId });
9215
+ if (!item) return null;
9216
+ return {
9217
+ id: item.id,
9218
+ messageId: item.message_id,
9219
+ sessionId: item.session_id,
9220
+ rating: item.rating,
9221
+ comment: item.comment,
9222
+ createdAt: item.created_at
9223
+ };
9224
+ } else {
9225
+ const list = this.readLocalFile(this.feedbackFile);
9226
+ return list.find((f) => f.message_id === messageId) || null;
9227
+ }
9228
+ }
9229
+ async listFeedback() {
9230
+ this.checkFeedbackEnabled();
9231
+ if (this.provider === "postgresql" || this.provider === "pgvector") {
9232
+ const pool = await this.getPGPool();
9233
+ const res = await pool.query(
9234
+ `SELECT id, message_id as "messageId", session_id as "sessionId", rating, comment, created_at as "createdAt"
9235
+ FROM ${this.feedbackTableName}
9236
+ ORDER BY created_at DESC`
9237
+ );
9238
+ return res.rows;
9239
+ } else if (this.provider === "mongodb") {
9240
+ await this.getMongoClient();
9241
+ const db = this.getMongoDb();
9242
+ const col = db.collection(this.feedbackTableName);
9243
+ const items = await col.find({}).sort({ created_at: -1 }).toArray();
9244
+ return items.map((item) => ({
9245
+ id: item.id,
9246
+ messageId: item.message_id,
9247
+ sessionId: item.session_id,
9248
+ rating: item.rating,
9249
+ comment: item.comment,
9250
+ createdAt: item.created_at
9251
+ }));
9252
+ } else {
9253
+ const list = this.readLocalFile(this.feedbackFile);
9254
+ return [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
9255
+ }
9256
+ }
9257
+ async disconnect() {
9258
+ if (this.pgPool) {
9259
+ await this.pgPool.end();
9260
+ this.pgPool = null;
9261
+ }
9262
+ if (this.mongoClient) {
9263
+ await this.mongoClient.close();
9264
+ this.mongoClient = null;
9265
+ }
9266
+ }
9267
+ };
9268
+
9269
+ // src/handlers/index.ts
9270
+ async function checkAuth(req, onAuthorize) {
9271
+ if (!onAuthorize) return null;
9272
+ try {
9273
+ const res = await onAuthorize(req);
9274
+ if (res === false) {
9275
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
9276
+ }
9277
+ if (res instanceof Response) {
9278
+ return res;
9279
+ }
9280
+ return null;
9281
+ } catch (err) {
9282
+ const msg = err instanceof Error ? err.message : "Authorization check failed";
9283
+ return NextResponse.json({ error: msg }, { status: 401 });
9284
+ }
9285
+ }
9286
+ var RateLimiter = class {
9287
+ constructor(windowMs = 6e4, max = 30) {
9288
+ this.hits = /* @__PURE__ */ new Map();
9289
+ this.windowMs = windowMs;
9290
+ this.max = max;
9291
+ }
9292
+ /** Returns true if the request should be allowed, false if rate-limited. */
9293
+ allow(key) {
9294
+ const now = Date.now();
9295
+ const cutoff = now - this.windowMs;
9296
+ const existing = (this.hits.get(key) || []).filter((t) => t > cutoff);
9297
+ existing.push(now);
9298
+ this.hits.set(key, existing);
9299
+ if (this.hits.size > 5e3) {
9300
+ for (const [k, timestamps] of this.hits.entries()) {
9301
+ if (timestamps.every((t) => t <= cutoff)) this.hits.delete(k);
9302
+ }
9303
+ }
9304
+ return existing.length <= this.max;
9305
+ }
9306
+ retryAfterSec(key) {
9307
+ const now = Date.now();
9308
+ const cutoff = now - this.windowMs;
9309
+ const existing = (this.hits.get(key) || []).filter((t) => t > cutoff);
9310
+ if (existing.length === 0) return 0;
9311
+ return Math.ceil((existing[0] + this.windowMs - now) / 1e3);
9312
+ }
9313
+ };
9314
+ var _g = global;
9315
+ var _a;
9316
+ var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
9317
+ function getRateLimitKey(req) {
9318
+ var _a2, _b;
9319
+ 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";
9320
+ return `ip:${ip}`;
9321
+ }
9322
+ function checkRateLimit(req) {
9323
+ const key = getRateLimitKey(req);
9324
+ if (!rateLimiter.allow(key)) {
9325
+ const retryAfter = rateLimiter.retryAfterSec(key);
9326
+ return new Response(
9327
+ JSON.stringify({ error: { code: "RATE_LIMITED", message: "Too many requests. Please slow down." } }),
9328
+ {
9329
+ status: 429,
9330
+ headers: {
9331
+ "Content-Type": "application/json",
9332
+ "Retry-After": String(retryAfter),
9333
+ "X-RateLimit-Limit": "30",
9334
+ "X-RateLimit-Window": "60"
9335
+ }
9336
+ }
9337
+ );
9338
+ }
9339
+ return null;
9340
+ }
9341
+ var MAX_MESSAGE_LENGTH = 8e3;
9342
+ function sanitizeInput(raw) {
9343
+ const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
9344
+ const trimmed = stripped.trim();
9345
+ if (!trimmed) {
9346
+ return { ok: false, error: "message must not be empty" };
9347
+ }
9348
+ if (trimmed.length > MAX_MESSAGE_LENGTH) {
9349
+ return { ok: false, error: `message must be \u2264 ${MAX_MESSAGE_LENGTH} characters` };
9350
+ }
9351
+ return { ok: true, value: trimmed };
9352
+ }
9353
+ function getOrCreatePlugin(configOrPlugin) {
9354
+ if (configOrPlugin instanceof VectorPlugin) return configOrPlugin;
9355
+ const cacheKey = "__retrivoraPlugin_" + JSON.stringify(configOrPlugin != null ? configOrPlugin : {}).slice(0, 64);
9356
+ if (!_g[cacheKey]) {
9357
+ _g[cacheKey] = new VectorPlugin(configOrPlugin);
9358
+ }
9359
+ return _g[cacheKey];
9360
+ }
7676
9361
  function sseFrame(payload) {
7677
9362
  return `data: ${JSON.stringify(payload)}
7678
9363
 
@@ -7710,47 +9395,88 @@ var SSE_HEADERS = {
7710
9395
  "X-Accel-Buffering": "no"
7711
9396
  // Disable Nginx buffering for streaming
7712
9397
  };
7713
- function createChatHandler(configOrPlugin) {
7714
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
9398
+ function createChatHandler(configOrPlugin, options) {
9399
+ const plugin = getOrCreatePlugin(configOrPlugin);
9400
+ const storage = new DatabaseStorage(plugin.getConfig());
9401
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
7715
9402
  return async function POST(req) {
9403
+ const authResult = await checkAuth(req, onAuthorize);
9404
+ if (authResult) return authResult;
9405
+ const rateLimited = checkRateLimit(req);
9406
+ if (rateLimited) return rateLimited;
7716
9407
  try {
7717
9408
  const body = await req.json();
7718
- const { message, history = [], namespace } = body;
7719
- if (!(message == null ? void 0 : message.trim())) {
7720
- return NextResponse.json({ error: "message is required" }, { status: 400 });
7721
- }
9409
+ const { message: rawMessage, history = [], namespace, sessionId = "default", messageId, userMessageId } = body;
9410
+ const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
9411
+ if (!sanitized.ok) {
9412
+ return NextResponse.json({ error: { code: "INVALID_INPUT", message: sanitized.error } }, { status: 400 });
9413
+ }
9414
+ const message = sanitized.value;
9415
+ const userMsgId = userMessageId || `user_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
9416
+ await storage.saveMessage(sessionId, {
9417
+ id: userMsgId,
9418
+ role: "user",
9419
+ content: message
9420
+ }).catch((err) => console.warn("[createChatHandler] Failed to save user message:", err));
7722
9421
  const result = await plugin.chat(message, history, namespace);
7723
- return NextResponse.json(result);
9422
+ const assistantMsgId = messageId || `assistant_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
9423
+ await storage.saveMessage(sessionId, {
9424
+ id: assistantMsgId,
9425
+ role: "assistant",
9426
+ content: result.reply,
9427
+ sources: result.sources,
9428
+ uiTransformation: result.ui_transformation,
9429
+ trace: result.trace
9430
+ }).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
9431
+ return NextResponse.json(__spreadProps(__spreadValues({}, result), {
9432
+ messageId: assistantMsgId,
9433
+ userMessageId: userMsgId
9434
+ }));
7724
9435
  } catch (err) {
7725
9436
  const message = err instanceof Error ? err.message : "Internal server error";
7726
9437
  return NextResponse.json({ error: message }, { status: 500 });
7727
9438
  }
7728
9439
  };
7729
9440
  }
7730
- function createStreamHandler(configOrPlugin) {
7731
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
9441
+ function createStreamHandler(configOrPlugin, options) {
9442
+ const plugin = getOrCreatePlugin(configOrPlugin);
9443
+ const storage = new DatabaseStorage(plugin.getConfig());
9444
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
7732
9445
  return async function POST(req) {
9446
+ const authResult = await checkAuth(req, onAuthorize);
9447
+ if (authResult) return authResult;
9448
+ const rateLimited = checkRateLimit(req);
9449
+ if (rateLimited) return rateLimited;
7733
9450
  let body;
7734
9451
  try {
7735
9452
  body = await req.json();
7736
9453
  } catch (e) {
7737
- return new Response(JSON.stringify({ error: "Invalid JSON body" }), {
9454
+ return new Response(JSON.stringify({ error: { code: "INVALID_JSON", message: "Invalid JSON body" } }), {
7738
9455
  status: 400,
7739
9456
  headers: { "Content-Type": "application/json" }
7740
9457
  });
7741
9458
  }
7742
- const { message, history = [], namespace } = body;
7743
- if (!(message == null ? void 0 : message.trim())) {
7744
- return new Response(JSON.stringify({ error: "message is required" }), {
7745
- status: 400,
7746
- headers: { "Content-Type": "application/json" }
7747
- });
9459
+ const { message: rawMessage, history = [], namespace, sessionId = "default", messageId, userMessageId } = body;
9460
+ const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
9461
+ if (!sanitized.ok) {
9462
+ return new Response(
9463
+ JSON.stringify({ error: { code: "INVALID_INPUT", message: sanitized.error } }),
9464
+ { status: 400, headers: { "Content-Type": "application/json" } }
9465
+ );
7748
9466
  }
9467
+ const message = sanitized.value;
9468
+ const userMsgId = userMessageId || `user_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
9469
+ await storage.saveMessage(sessionId, {
9470
+ id: userMsgId,
9471
+ role: "user",
9472
+ content: message
9473
+ }).catch((err) => console.warn("[createStreamHandler] Failed to save user message:", err));
9474
+ const assistantMsgId = messageId || `assistant_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
7749
9475
  const encoder = new TextEncoder();
7750
9476
  let isActive = true;
7751
9477
  const stream = new ReadableStream({
7752
9478
  async start(controller) {
7753
- var _a;
9479
+ var _a2;
7754
9480
  const enqueue = (text) => {
7755
9481
  if (!isActive) return;
7756
9482
  try {
@@ -7761,11 +9487,13 @@ function createStreamHandler(configOrPlugin) {
7761
9487
  };
7762
9488
  try {
7763
9489
  const pipelineStream = plugin.chatStream(message, history, namespace);
9490
+ let fullReply = "";
7764
9491
  try {
7765
9492
  for (var iter = __forAwait(pipelineStream), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
7766
9493
  const chunk = temp.value;
7767
9494
  if (!isActive) break;
7768
9495
  if (typeof chunk === "string") {
9496
+ fullReply += chunk;
7769
9497
  enqueue(sseTextFrame(chunk));
7770
9498
  } else if (chunk && typeof chunk === "object" && "type" in chunk && chunk.type === "thinking") {
7771
9499
  enqueue(`data: ${JSON.stringify(chunk)}
@@ -7778,9 +9506,10 @@ function createStreamHandler(configOrPlugin) {
7778
9506
  if (responseChunk == null ? void 0 : responseChunk.trace) {
7779
9507
  enqueue(sseObservabilityFrame(responseChunk.trace));
7780
9508
  }
9509
+ let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
7781
9510
  if (sources.length > 0) {
7782
9511
  try {
7783
- const uiTransformation = (_a = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a : UITransformer.transform(message, sources, plugin.getConfig());
9512
+ uiTransformation = (_a2 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a2 : UITransformer.transform(message, sources, plugin.getConfig());
7784
9513
  if (uiTransformation) {
7785
9514
  enqueue(sseUIFrame(uiTransformation));
7786
9515
  }
@@ -7788,11 +9517,22 @@ function createStreamHandler(configOrPlugin) {
7788
9517
  console.warn("[createStreamHandler] UI transformation warning:", transformError);
7789
9518
  try {
7790
9519
  const fallback = UITransformer.transform(message, sources, plugin.getConfig());
7791
- if (fallback) enqueue(sseUIFrame(fallback));
9520
+ if (fallback) {
9521
+ uiTransformation = fallback;
9522
+ enqueue(sseUIFrame(fallback));
9523
+ }
7792
9524
  } catch (e) {
7793
9525
  }
7794
9526
  }
7795
9527
  }
9528
+ await storage.saveMessage(sessionId, {
9529
+ id: assistantMsgId,
9530
+ role: "assistant",
9531
+ content: fullReply,
9532
+ sources,
9533
+ uiTransformation,
9534
+ trace: responseChunk == null ? void 0 : responseChunk.trace
9535
+ }).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
7796
9536
  }
7797
9537
  }
7798
9538
  } catch (temp) {
@@ -7829,12 +9569,15 @@ function createStreamHandler(configOrPlugin) {
7829
9569
  console.log("[createStreamHandler] Stream connection closed by client:", reason);
7830
9570
  }
7831
9571
  });
7832
- return new Response(stream, { headers: SSE_HEADERS });
9572
+ return new Response(stream, { headers: __spreadProps(__spreadValues({}, SSE_HEADERS), { "x-message-id": assistantMsgId, "x-user-message-id": userMsgId }) });
7833
9573
  };
7834
9574
  }
7835
- function createIngestHandler(configOrPlugin) {
7836
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
9575
+ function createIngestHandler(configOrPlugin, options) {
9576
+ const plugin = getOrCreatePlugin(configOrPlugin);
9577
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
7837
9578
  return async function POST(req) {
9579
+ const authResult = await checkAuth(req, onAuthorize);
9580
+ if (authResult) return authResult;
7838
9581
  try {
7839
9582
  const body = await req.json();
7840
9583
  const { documents, namespace } = body;
@@ -7849,9 +9592,14 @@ function createIngestHandler(configOrPlugin) {
7849
9592
  }
7850
9593
  };
7851
9594
  }
7852
- function createHealthHandler(configOrPlugin) {
7853
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
7854
- return async function GET() {
9595
+ function createHealthHandler(configOrPlugin, options) {
9596
+ const plugin = getOrCreatePlugin(configOrPlugin);
9597
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
9598
+ return async function GET(req) {
9599
+ if (req) {
9600
+ const authResult = await checkAuth(req, onAuthorize);
9601
+ if (authResult) return authResult;
9602
+ }
7855
9603
  try {
7856
9604
  const health = await plugin.checkHealth();
7857
9605
  const status = health.allHealthy ? "ok" : "degraded";
@@ -7866,9 +9614,12 @@ function createHealthHandler(configOrPlugin) {
7866
9614
  }
7867
9615
  };
7868
9616
  }
7869
- function createUploadHandler(configOrPlugin) {
7870
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
9617
+ function createUploadHandler(configOrPlugin, options) {
9618
+ const plugin = getOrCreatePlugin(configOrPlugin);
9619
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
7871
9620
  return async function POST(req) {
9621
+ const authResult = await checkAuth(req, onAuthorize);
9622
+ if (authResult) return authResult;
7872
9623
  try {
7873
9624
  const formData = await req.formData();
7874
9625
  const files = formData.getAll("files");
@@ -7942,9 +9693,12 @@ function createUploadHandler(configOrPlugin) {
7942
9693
  }
7943
9694
  };
7944
9695
  }
7945
- function createSuggestionsHandler(configOrPlugin) {
7946
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
9696
+ function createSuggestionsHandler(configOrPlugin, options) {
9697
+ const plugin = getOrCreatePlugin(configOrPlugin);
9698
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
7947
9699
  return async function POST(req) {
9700
+ const authResult = await checkAuth(req, onAuthorize);
9701
+ if (authResult) return authResult;
7948
9702
  try {
7949
9703
  const body = await req.json();
7950
9704
  const { query, namespace } = body;
@@ -7959,13 +9713,108 @@ function createSuggestionsHandler(configOrPlugin) {
7959
9713
  }
7960
9714
  };
7961
9715
  }
7962
- function createRagHandler(configOrPlugin) {
7963
- const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
7964
- const chatHandler = createChatHandler(plugin);
7965
- const streamHandler = createStreamHandler(plugin);
7966
- const uploadHandler = createUploadHandler(plugin);
7967
- const healthHandler = createHealthHandler(plugin);
7968
- const suggestionsHandler = createSuggestionsHandler(plugin);
9716
+ function createHistoryHandler(configOrPlugin, options) {
9717
+ const plugin = getOrCreatePlugin(configOrPlugin);
9718
+ const storage = new DatabaseStorage(plugin.getConfig());
9719
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
9720
+ return async function handler(req) {
9721
+ const authResult = await checkAuth(req, onAuthorize);
9722
+ if (authResult) return authResult;
9723
+ const url = new URL(req.url);
9724
+ const sessionId = url.searchParams.get("sessionId") || "default";
9725
+ if (req.method === "GET") {
9726
+ try {
9727
+ const history = await storage.getHistory(sessionId);
9728
+ return NextResponse.json({ history });
9729
+ } catch (err) {
9730
+ const message = err instanceof Error ? err.message : "Failed to fetch history";
9731
+ return NextResponse.json({ error: message }, { status: 500 });
9732
+ }
9733
+ } else if (req.method === "POST") {
9734
+ try {
9735
+ const body = await req.json().catch(() => ({}));
9736
+ const sid = body.sessionId || sessionId;
9737
+ await storage.clearHistory(sid);
9738
+ return NextResponse.json({ success: true });
9739
+ } catch (err) {
9740
+ const message = err instanceof Error ? err.message : "Failed to clear history";
9741
+ return NextResponse.json({ error: message }, { status: 500 });
9742
+ }
9743
+ }
9744
+ return NextResponse.json({ error: "Method Not Allowed" }, { status: 405 });
9745
+ };
9746
+ }
9747
+ function createFeedbackHandler(configOrPlugin, options) {
9748
+ const plugin = getOrCreatePlugin(configOrPlugin);
9749
+ const storage = new DatabaseStorage(plugin.getConfig());
9750
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
9751
+ return async function handler(req) {
9752
+ const authResult = await checkAuth(req, onAuthorize);
9753
+ if (authResult) return authResult;
9754
+ if (req.method === "GET") {
9755
+ try {
9756
+ const url = new URL(req.url);
9757
+ const messageId = url.searchParams.get("messageId");
9758
+ if (!messageId) {
9759
+ const feedbackList = await storage.listFeedback();
9760
+ return NextResponse.json({ feedback: feedbackList });
9761
+ }
9762
+ const feedback = await storage.getFeedback(messageId);
9763
+ return NextResponse.json({ feedback });
9764
+ } catch (err) {
9765
+ const message = err instanceof Error ? err.message : "Failed to fetch feedback";
9766
+ return NextResponse.json({ error: message }, { status: 500 });
9767
+ }
9768
+ } else if (req.method === "POST") {
9769
+ try {
9770
+ const body = await req.json();
9771
+ const { messageId, sessionId = "default", rating, comment } = body;
9772
+ if (!messageId) {
9773
+ return NextResponse.json({ error: "messageId is required" }, { status: 400 });
9774
+ }
9775
+ if (!rating) {
9776
+ return NextResponse.json({ error: "rating is required" }, { status: 400 });
9777
+ }
9778
+ await storage.saveFeedback({ messageId, sessionId, rating, comment });
9779
+ return NextResponse.json({ success: true });
9780
+ } catch (err) {
9781
+ const message = err instanceof Error ? err.message : "Failed to save feedback";
9782
+ return NextResponse.json({ error: message }, { status: 500 });
9783
+ }
9784
+ }
9785
+ return NextResponse.json({ error: "Method Not Allowed" }, { status: 405 });
9786
+ };
9787
+ }
9788
+ function createSessionsHandler(configOrPlugin, options) {
9789
+ const plugin = getOrCreatePlugin(configOrPlugin);
9790
+ const storage = new DatabaseStorage(plugin.getConfig());
9791
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
9792
+ return async function GET(req) {
9793
+ if (req) {
9794
+ const authResult = await checkAuth(req, onAuthorize);
9795
+ if (authResult) return authResult;
9796
+ }
9797
+ void req;
9798
+ try {
9799
+ const sessions = await storage.listSessions();
9800
+ return NextResponse.json({ sessions });
9801
+ } catch (err) {
9802
+ const message = err instanceof Error ? err.message : "Failed to list sessions";
9803
+ return NextResponse.json({ error: message }, { status: 500 });
9804
+ }
9805
+ };
9806
+ }
9807
+ function createRagHandler(configOrPlugin, options) {
9808
+ const plugin = getOrCreatePlugin(configOrPlugin);
9809
+ const onAuthorize = options == null ? void 0 : options.onAuthorize;
9810
+ const chatHandler = createChatHandler(plugin, { onAuthorize });
9811
+ const streamHandler = createStreamHandler(plugin, { onAuthorize });
9812
+ const uploadHandler = createUploadHandler(plugin, { onAuthorize });
9813
+ const healthHandler = createHealthHandler(plugin, { onAuthorize });
9814
+ const suggestionsHandler = createSuggestionsHandler(plugin, { onAuthorize });
9815
+ const historyHandler = createHistoryHandler(plugin, { onAuthorize });
9816
+ const feedbackHandler = createFeedbackHandler(plugin, { onAuthorize });
9817
+ const sessionsHandler = createSessionsHandler(plugin, { onAuthorize });
7969
9818
  async function routePostRequest(req, segment) {
7970
9819
  switch (segment) {
7971
9820
  case "chat":
@@ -7977,22 +9826,35 @@ function createRagHandler(configOrPlugin) {
7977
9826
  case "suggestions":
7978
9827
  return suggestionsHandler(req);
7979
9828
  case "health":
7980
- return healthHandler();
9829
+ return healthHandler(req);
9830
+ case "history":
9831
+ case "history/clear":
9832
+ return historyHandler(req);
9833
+ case "feedback":
9834
+ return feedbackHandler(req);
7981
9835
  default:
7982
9836
  return NextResponse.json({ error: `Not Found: POST segment "${segment}" not supported.` }, { status: 404 });
7983
9837
  }
7984
9838
  }
7985
9839
  async function routeGetRequest(req, segment) {
7986
- if (segment === "health") {
7987
- return healthHandler();
9840
+ switch (segment) {
9841
+ case "health":
9842
+ return healthHandler(req);
9843
+ case "history":
9844
+ return historyHandler(req);
9845
+ case "feedback":
9846
+ return feedbackHandler(req);
9847
+ case "sessions":
9848
+ return sessionsHandler(req);
9849
+ default:
9850
+ return NextResponse.json({ error: `Method Not Allowed: GET segment "${segment}" not supported.` }, { status: 405 });
7988
9851
  }
7989
- return NextResponse.json({ error: `Method Not Allowed: GET is only supported for "health" segment.` }, { status: 405 });
7990
9852
  }
7991
9853
  async function getSegment(context) {
7992
- var _a;
7993
- 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;
9854
+ var _a2;
9855
+ 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;
7994
9856
  const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || [];
7995
- return segments[0] || "chat";
9857
+ return segments.join("/") || "chat";
7996
9858
  }
7997
9859
  return {
7998
9860
  GET: async (req, context) => {
@@ -8030,8 +9892,10 @@ export {
8030
9892
  EmbeddingFailedException,
8031
9893
  EmbeddingStrategy,
8032
9894
  EmbeddingStrategyResolver,
9895
+ GroqProvider,
8033
9896
  LLMFactory,
8034
9897
  LLM_PROFILES,
9898
+ LicenseVerifier,
8035
9899
  MilvusProvider,
8036
9900
  MongoDBProvider,
8037
9901
  MultiTablePostgresProvider,
@@ -8045,6 +9909,7 @@ export {
8045
9909
  ProviderNotFoundException,
8046
9910
  ProviderRegistry,
8047
9911
  QdrantProvider,
9912
+ QwenProvider,
8048
9913
  RateLimitException,
8049
9914
  RedisProvider,
8050
9915
  RetrievalException,
@@ -8056,10 +9921,13 @@ export {
8056
9921
  VectorPlugin,
8057
9922
  WeaviateProvider,
8058
9923
  createChatHandler,
9924
+ createFeedbackHandler,
8059
9925
  createFromPreset,
8060
9926
  createHealthHandler,
9927
+ createHistoryHandler,
8061
9928
  createIngestHandler,
8062
9929
  createRagHandler,
9930
+ createSessionsHandler,
8063
9931
  createStreamHandler,
8064
9932
  createUploadHandler,
8065
9933
  getRagConfig,