@retrivora-ai/rag-engine 2.0.5 → 2.0.7

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.
@@ -3907,7 +3907,7 @@ var UniversalLLMAdapter = class {
3907
3907
  });
3908
3908
  }
3909
3909
  async chat(messages, context) {
3910
- var _a2, _b;
3910
+ var _a2, _b, _c, _d, _e, _f;
3911
3911
  const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
3912
3912
  const formattedMessages = [
3913
3913
  { role: "system", content: `${this.systemPrompt}
@@ -3932,8 +3932,27 @@ ${context != null ? context : "None"}` },
3932
3932
  temperature: this.temperature
3933
3933
  };
3934
3934
  }
3935
+ const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
3936
+ if (isSelfHost || Boolean(process.env.VERCEL)) {
3937
+ const _g2 = globalThis;
3938
+ if (typeof _g2.__retrivoraDispatchChat === "function") {
3939
+ try {
3940
+ const res = await _g2.__retrivoraDispatchChat({
3941
+ model: this.model,
3942
+ messages: formattedMessages,
3943
+ max_tokens: this.maxTokens,
3944
+ temperature: this.temperature
3945
+ }, this.apiKey);
3946
+ if ((_e = (_d = (_c = (_b = res == null ? void 0 : res.response) == null ? void 0 : _b.choices) == null ? void 0 : _c[0]) == null ? void 0 : _d.message) == null ? void 0 : _e.content) {
3947
+ return res.response.choices[0].message.content;
3948
+ }
3949
+ } catch (dispatchErr) {
3950
+ throw dispatchErr;
3951
+ }
3952
+ }
3953
+ }
3935
3954
  const { data } = await this.http.post(path2, payload);
3936
- const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
3955
+ const extractPath = (_f = this.opts.responseExtractPath) != null ? _f : "choices[0].message.content";
3937
3956
  const result = resolvePath(data, extractPath);
3938
3957
  if (result === void 0) {
3939
3958
  throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
@@ -3947,7 +3966,7 @@ ${context != null ? context : "None"}` },
3947
3966
  */
3948
3967
  chatStream(messages, context) {
3949
3968
  return __asyncGenerator(this, null, function* () {
3950
- var _a2, _b, _c;
3969
+ var _a2, _b, _c, _d, _e, _f, _g2;
3951
3970
  const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
3952
3971
  const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
3953
3972
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
@@ -3978,19 +3997,46 @@ ${context != null ? context : "None"}` },
3978
3997
  stream: true
3979
3998
  };
3980
3999
  }
3981
- const response = yield new __await(fetch(url, {
3982
- method: "POST",
3983
- headers: this.resolvedHeaders,
3984
- body: JSON.stringify(payload)
3985
- }));
3986
- if (!response.ok) {
3987
- const errorText = yield new __await(response.text().catch(() => response.statusText));
3988
- throw new Error(`[UniversalLLMAdapter] Streaming request failed (${response.status}): ${errorText}`);
4000
+ const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4001
+ let streamBody = null;
4002
+ if (isSelfHost || Boolean(process.env.VERCEL)) {
4003
+ const _g3 = globalThis;
4004
+ if (typeof _g3.__retrivoraDispatchChat === "function") {
4005
+ try {
4006
+ const res = yield new __await(_g3.__retrivoraDispatchChat({
4007
+ model: this.model,
4008
+ messages: formattedMessages,
4009
+ max_tokens: this.maxTokens,
4010
+ temperature: this.temperature,
4011
+ stream: true
4012
+ }, this.apiKey));
4013
+ if (res == null ? void 0 : res.stream) {
4014
+ streamBody = res.stream;
4015
+ } else if ((_f = (_e = (_d = (_c = res == null ? void 0 : res.response) == null ? void 0 : _c.choices) == null ? void 0 : _d[0]) == null ? void 0 : _e.message) == null ? void 0 : _f.content) {
4016
+ yield res.response.choices[0].message.content;
4017
+ return;
4018
+ }
4019
+ } catch (dispatchErr) {
4020
+ throw dispatchErr;
4021
+ }
4022
+ }
3989
4023
  }
3990
- if (!response.body) {
3991
- throw new Error("[UniversalLLMAdapter] Response body is null \u2014 server did not send a streaming response.");
4024
+ if (!streamBody) {
4025
+ const response = yield new __await(fetch(url, {
4026
+ method: "POST",
4027
+ headers: this.resolvedHeaders,
4028
+ body: JSON.stringify(payload)
4029
+ }));
4030
+ if (!response.ok) {
4031
+ const errorText = yield new __await(response.text().catch(() => response.statusText));
4032
+ throw new Error(`[UniversalLLMAdapter] Streaming request failed (${response.status}): ${errorText}`);
4033
+ }
4034
+ if (!response.body) {
4035
+ throw new Error("[UniversalLLMAdapter] Response body is null \u2014 server did not send a streaming response.");
4036
+ }
4037
+ streamBody = response.body;
3992
4038
  }
3993
- const reader = response.body.getReader();
4039
+ const reader = streamBody.getReader();
3994
4040
  const decoder = new TextDecoder("utf-8");
3995
4041
  let buffer = "";
3996
4042
  try {
@@ -3999,7 +4045,7 @@ ${context != null ? context : "None"}` },
3999
4045
  if (done) break;
4000
4046
  buffer += decoder.decode(value, { stream: true });
4001
4047
  const lines = buffer.split("\n");
4002
- buffer = (_c = lines.pop()) != null ? _c : "";
4048
+ buffer = (_g2 = lines.pop()) != null ? _g2 : "";
4003
4049
  for (const line of lines) {
4004
4050
  const trimmed = line.trim();
4005
4051
  if (!trimmed || trimmed === "data: [DONE]") continue;
@@ -4027,7 +4073,7 @@ ${context != null ? context : "None"}` },
4027
4073
  });
4028
4074
  }
4029
4075
  async embed(text) {
4030
- var _a2, _b;
4076
+ var _a2, _b, _c, _d;
4031
4077
  const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
4032
4078
  let payload;
4033
4079
  if (this.opts.embedPayloadTemplate) {
@@ -4041,8 +4087,25 @@ ${context != null ? context : "None"}` },
4041
4087
  input: text
4042
4088
  };
4043
4089
  }
4090
+ const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4091
+ if (isSelfHost || Boolean(process.env.VERCEL)) {
4092
+ const _g2 = globalThis;
4093
+ if (typeof _g2.__retrivoraDispatchEmbedding === "function") {
4094
+ try {
4095
+ const res = await _g2.__retrivoraDispatchEmbedding({
4096
+ model: this.model,
4097
+ input: text
4098
+ }, this.apiKey);
4099
+ if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
4100
+ return res.data[0].embedding;
4101
+ }
4102
+ } catch (dispatchErr) {
4103
+ throw dispatchErr;
4104
+ }
4105
+ }
4106
+ }
4044
4107
  const { data } = await this.http.post(path2, payload);
4045
- const extractPath = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
4108
+ const extractPath = (_d = this.opts.embedExtractPath) != null ? _d : "data[0].embedding";
4046
4109
  const vector = resolvePath(data, extractPath);
4047
4110
  if (!Array.isArray(vector)) {
4048
4111
  throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
@@ -4631,7 +4694,8 @@ var Reranker = class {
4631
4694
  return matches.sort((a, b) => b.score - a.score).slice(0, limit);
4632
4695
  }
4633
4696
  const scoredMatches = matches.map((match) => {
4634
- const contentLower = match.content.toLowerCase();
4697
+ var _a2;
4698
+ const contentLower = ((_a2 = match == null ? void 0 : match.content) != null ? _a2 : "").toLowerCase();
4635
4699
  let keywordScore = 0;
4636
4700
  keywords.forEach((keyword) => {
4637
4701
  if (contentLower.includes(keyword)) {
@@ -4652,7 +4716,10 @@ var Reranker = class {
4652
4716
  [{ role: "user", content: `Query: "${query}"
4653
4717
 
4654
4718
  Documents:
4655
- ${topN.map((m, i) => `[${i}] ${m.content.replace(/\n/g, " ")}`).join("\n")}` }],
4719
+ ${topN.map((m, i) => {
4720
+ var _a2;
4721
+ return `[${i}] ${((_a2 = m == null ? void 0 : m.content) != null ? _a2 : "").replace(/\n/g, " ")}`;
4722
+ }).join("\n")}` }],
4656
4723
  "",
4657
4724
  {
4658
4725
  systemPrompt: 'You are a relevance ranking expert. Given the user query and a list of retrieved document chunks, rank the chunks by relevance to the query. Return the result as a comma-separated list of document indices in order of relevance, from most relevant to least relevant. Use the indices provided in brackets like [0], [1], etc. Only return the indices (e.g., "2,0,1"), nothing else. Do not include brackets in the output.',
@@ -5817,10 +5884,10 @@ Return ONLY 'vector', 'graph', or 'both'. No explanation.`;
5817
5884
  "",
5818
5885
  { temperature: 0, maxTokens: 10 }
5819
5886
  );
5820
- const cleanResponse = response.trim().toLowerCase();
5821
- if (cleanResponse.includes("vector")) return "vector";
5822
- if (cleanResponse.includes("graph")) return "graph";
5887
+ const cleanResponse = (response != null ? response : "").trim().toLowerCase();
5823
5888
  if (cleanResponse.includes("both")) return "both";
5889
+ if (cleanResponse.includes("graph")) return "graph";
5890
+ if (cleanResponse.includes("vector")) return "vector";
5824
5891
  } catch (error) {
5825
5892
  console.warn("[QueryProcessor] LLM strategy classification failed, falling back to keywords:", error);
5826
5893
  }
@@ -5994,7 +6061,10 @@ var IntentClassifier = class {
5994
6061
  hasCategoricalFields = catKeys.size > 0;
5995
6062
  numericFieldCount = numericKeys.size;
5996
6063
  categoricalFieldCount = catKeys.size;
5997
- if (productKeyMatches >= 2 || docs.some((d) => d.content.toLowerCase().includes("price") || d.content.toLowerCase().includes("brand"))) {
6064
+ if (productKeyMatches >= 2 || docs.some((d) => {
6065
+ var _a2, _b;
6066
+ return ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").toLowerCase().includes("price") || ((_b = d == null ? void 0 : d.content) != null ? _b : "").toLowerCase().includes("brand");
6067
+ })) {
5998
6068
  isProductLike = true;
5999
6069
  }
6000
6070
  }
@@ -6274,7 +6344,10 @@ var TextRendererStrategy = class {
6274
6344
  return { type: "text", title, data: { content: data } };
6275
6345
  }
6276
6346
  const docs = Array.isArray(data) ? data : [];
6277
- const text = docs.map((d) => d.content).join("\n\n");
6347
+ const text = docs.map((d) => {
6348
+ var _a2;
6349
+ return (_a2 = d == null ? void 0 : d.content) != null ? _a2 : "";
6350
+ }).join("\n\n");
6278
6351
  return { type: "text", title, data: { content: text || "No detailed content available." } };
6279
6352
  }
6280
6353
  };
@@ -6523,6 +6596,19 @@ var UITransformer = class _UITransformer {
6523
6596
  if (!retrievedData || retrievedData.length === 0) {
6524
6597
  return this.createTextResponse("No data available", "No relevant data found for your query.");
6525
6598
  }
6599
+ console.log("[UITransformer.transform] Processing retrievedData:", {
6600
+ userQuery,
6601
+ retrievedCount: retrievedData.length,
6602
+ sample: retrievedData.slice(0, 2).map((item) => {
6603
+ var _a3;
6604
+ return {
6605
+ id: item == null ? void 0 : item.id,
6606
+ contentType: typeof (item == null ? void 0 : item.content),
6607
+ contentSnippet: String((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 150),
6608
+ metadataKeys: Object.keys((item == null ? void 0 : item.metadata) || {})
6609
+ };
6610
+ })
6611
+ });
6526
6612
  const resolvedIntent = intent != null ? intent : this.detectIntentHeuristic(userQuery);
6527
6613
  const filteredData = resolvedIntent.filterInStockOnly ? retrievedData.filter((item) => this.determineStockStatus(item)) : retrievedData;
6528
6614
  const profile = this.profileData(filteredData);
@@ -7012,7 +7098,10 @@ ${schemaProfileText}` : ""}`;
7012
7098
  type: "radar_chart",
7013
7099
  title: "Product Comparison",
7014
7100
  description: `Comparing ${data.length} items across ${radarData.length} attributes`,
7015
- data: radarData.length > 0 ? radarData : data.map((d) => ({ attribute: d.content.substring(0, 40) }))
7101
+ data: radarData.length > 0 ? radarData : data.map((d) => {
7102
+ var _a2;
7103
+ return { attribute: ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").substring(0, 40) };
7104
+ })
7016
7105
  };
7017
7106
  }
7018
7107
  static transformToTable(data, query = "") {
@@ -7029,7 +7118,10 @@ ${schemaProfileText}` : ""}`;
7029
7118
  static transformToText(data) {
7030
7119
  return this.createTextResponse(
7031
7120
  "Retrieved Context",
7032
- data.map((item) => item.content).join("\n\n"),
7121
+ data.map((item) => {
7122
+ var _a2;
7123
+ return (_a2 = item == null ? void 0 : item.content) != null ? _a2 : "";
7124
+ }).join("\n\n"),
7033
7125
  `Found ${data.length} relevant results`
7034
7126
  );
7035
7127
  }
@@ -7190,6 +7282,7 @@ ${schemaProfileText}` : ""}`;
7190
7282
  return productTerms && productAction && !nonProductEntityTerms;
7191
7283
  }
7192
7284
  static isProductData(item) {
7285
+ if (!item) return false;
7193
7286
  const content = (item.content || "").toLowerCase();
7194
7287
  const productKeywords = [
7195
7288
  "product",
@@ -7448,12 +7541,12 @@ ${schemaProfileText}` : ""}`;
7448
7541
  }
7449
7542
  static extractTimeSeriesData(data) {
7450
7543
  return data.map((item) => {
7451
- var _a2, _b, _c, _d, _e;
7544
+ var _a2, _b, _c, _d, _e, _f;
7452
7545
  const meta = item.metadata || {};
7453
7546
  return {
7454
7547
  timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
7455
7548
  value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
7456
- label: (_e = meta.label) != null ? _e : item.content.substring(0, 50)
7549
+ label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
7457
7550
  };
7458
7551
  });
7459
7552
  }
@@ -7567,7 +7660,8 @@ ${schemaProfileText}` : ""}`;
7567
7660
  }, query.includes(normalizedField) ? 3 : 0);
7568
7661
  }
7569
7662
  static resolveTableCellValue(item, column) {
7570
- if (column === "Content") return item.content.substring(0, 100);
7663
+ var _a2, _b, _c;
7664
+ if (column === "Content") return ((_a2 = item == null ? void 0 : item.content) != null ? _a2 : "").substring(0, 100);
7571
7665
  const meta = item.metadata || {};
7572
7666
  const normalizedColumn = this.normalizeComparableField(column);
7573
7667
  const exactMetadata = Object.entries(meta).find(
@@ -7578,9 +7672,9 @@ ${schemaProfileText}` : ""}`;
7578
7672
  }
7579
7673
  const aliasValue = this.resolveAliasedTableCell(meta, column);
7580
7674
  if (aliasValue !== void 0) return this.toDisplayValue(aliasValue);
7581
- const contentValue = this.extractContentFieldValue(item.content, column);
7675
+ const contentValue = this.extractContentFieldValue((_b = item == null ? void 0 : item.content) != null ? _b : "", column);
7582
7676
  if (contentValue !== null) return contentValue;
7583
- const aliasContentValue = this.extractAliasedContentFieldValue(item.content, column);
7677
+ const aliasContentValue = this.extractAliasedContentFieldValue((_c = item == null ? void 0 : item.content) != null ? _c : "", column);
7584
7678
  return aliasContentValue != null ? aliasContentValue : "";
7585
7679
  }
7586
7680
  static resolveAliasedTableCell(meta, column) {
@@ -7630,6 +7724,7 @@ ${schemaProfileText}` : ""}`;
7630
7724
  return { inStockCount: inStock, outOfStockCount: outOfStock };
7631
7725
  }
7632
7726
  static determineStockStatus(item) {
7727
+ if (!item) return true;
7633
7728
  const meta = item.metadata || {};
7634
7729
  const stockValue = resolveMetadataValue(meta, "stock");
7635
7730
  if (stockValue !== void 0) {
@@ -7675,35 +7770,64 @@ ${schemaProfileText}` : ""}`;
7675
7770
  return resolveMetadataValue(meta, uiKey);
7676
7771
  }
7677
7772
  static extractProductInfo(item, config, trainedSchema) {
7678
- var _a2;
7773
+ var _a2, _b;
7774
+ if (!item) return null;
7679
7775
  const meta = item.metadata || {};
7776
+ const content = item.content || "";
7680
7777
  const name = this.getDynamicVal(meta, "name", config, trainedSchema);
7681
7778
  const price = this.getDynamicVal(meta, "price", config, trainedSchema);
7682
7779
  const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
7683
7780
  const description = this.cleanProductDescription(
7684
- (_a2 = this.extractProductDescriptionFromContent(item.content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
7781
+ (_a2 = this.extractProductDescriptionFromContent(content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
7685
7782
  );
7686
7783
  if (name || this.isProductData(item)) {
7687
7784
  let finalName = name ? String(name) : void 0;
7785
+ if (!finalName && content) {
7786
+ const nameMatch = content.match(/(?:Product|Item|Name):\s*([^\n]+)/i);
7787
+ finalName = nameMatch ? nameMatch[1].trim() : (_b = content.split("\n")[0]) == null ? void 0 : _b.substring(0, 60);
7788
+ }
7688
7789
  if (!finalName) {
7689
- const nameMatch = item.content.match(/(?:Product|Item|Name):\s*([^\n]+)/i);
7690
- finalName = nameMatch ? nameMatch[1].trim() : item.content.split("\n")[0].substring(0, 60);
7790
+ console.warn(
7791
+ `[UITransformer] Unable to read product name from metadata or content for item ${item.id}. Defaulting to 'Unnamed Product'.`,
7792
+ { metadataKeys: Object.keys(meta), contentLength: content.length }
7793
+ );
7691
7794
  }
7692
7795
  let finalPrice = typeof price === "number" || typeof price === "string" ? price : void 0;
7693
- if (!finalPrice) {
7694
- const priceMatch = item.content.match(/(?:Price|Cost):\s*\$?([\d,.]+)/i) || item.content.match(/\$\s*([\d,.]+)/);
7796
+ if (!finalPrice && content) {
7797
+ const priceMatch = content.match(/(?:Price|Cost):\s*\$?([\d,.]+)/i) || content.match(/\$\s*([\d,.]+)/);
7695
7798
  if (priceMatch) finalPrice = priceMatch[1].replace(/,/g, "");
7696
7799
  }
7800
+ if (finalPrice === void 0) {
7801
+ console.warn(
7802
+ `[UITransformer] Unable to read product price from metadata or content for item ${item.id}.`,
7803
+ { metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
7804
+ );
7805
+ }
7697
7806
  const imageValue = this.getDynamicVal(meta, "image", config, trainedSchema);
7807
+ if (!imageValue) {
7808
+ console.debug(
7809
+ `[UITransformer] Unable to read product image URL from metadata for item ${item.id}.`
7810
+ );
7811
+ }
7812
+ if (!description) {
7813
+ console.debug(
7814
+ `[UITransformer] Unable to read product description from metadata or content for item ${item.id}.`
7815
+ );
7816
+ }
7698
7817
  return {
7699
7818
  id: item.id,
7700
- name: finalName,
7819
+ name: finalName || "Unnamed Product",
7701
7820
  price: finalPrice,
7702
7821
  image: typeof imageValue === "string" ? imageValue : void 0,
7703
7822
  brand: brand ? String(brand) : void 0,
7704
7823
  description,
7705
7824
  inStock: this.determineStockStatus(item)
7706
7825
  };
7826
+ } else {
7827
+ console.warn(
7828
+ `[UITransformer] Item ${item.id} skipped: unable to read name or identify as product data from metadata/content.`,
7829
+ { metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
7830
+ );
7707
7831
  }
7708
7832
  return null;
7709
7833
  }
@@ -7788,13 +7912,13 @@ RULES:
7788
7912
  5. If no relevant data is found, return text: "I cannot answer this question based on the available information."`;
7789
7913
  }
7790
7914
  static buildContextSummary(sources, maxChars = 6e3) {
7791
- const items = sources.map((s, i) => {
7915
+ const items = (sources || []).filter(Boolean).map((s, i) => {
7792
7916
  var _a2, _b, _c, _d;
7793
7917
  return {
7794
7918
  index: i + 1,
7795
- content: (_b = (_a2 = s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
7796
- metadata: (_c = s.metadata) != null ? _c : {},
7797
- score: (_d = s.score) != null ? _d : 0
7919
+ content: (_b = (_a2 = s == null ? void 0 : s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
7920
+ metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
7921
+ score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
7798
7922
  };
7799
7923
  });
7800
7924
  const full = JSON.stringify(items, null, 2);
@@ -8363,35 +8487,74 @@ ${m.content}`).join("\n\n---\n\n");
8363
8487
  const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
8364
8488
  const wantsExhaustiveList = hasNumericPredicates || hasMetadataFilter || /\b(list|all|show|provide|give|get|browse|find|search|display)\b/i.test(question);
8365
8489
  const retrievalLimit = wantsExhaustiveList ? Math.max(topK * 20, 100) : topK * 2;
8366
- const rawSources = (strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : [];
8490
+ const rawSources = ((strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : []).filter((s) => Boolean(s && typeof s === "object"));
8491
+ console.log("[Pipeline] Raw vectorDB.query response:", {
8492
+ rawCount: rawSources.length,
8493
+ sample: rawSources.slice(0, 2).map((s) => {
8494
+ var _a3;
8495
+ return {
8496
+ id: s == null ? void 0 : s.id,
8497
+ score: s == null ? void 0 : s.score,
8498
+ contentType: typeof (s == null ? void 0 : s.content),
8499
+ contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
8500
+ metadataKeys: Object.keys((s == null ? void 0 : s.metadata) || {})
8501
+ };
8502
+ })
8503
+ });
8367
8504
  const retrieveEnd = performance.now();
8368
8505
  const embedMs = retrieveEnd - embedStart;
8369
8506
  const retrieveMs = retrieveEnd - embedStart;
8370
8507
  const rerankStart = performance.now();
8371
- const structuredSources = this.applyStructuredFilters(rawSources, filter);
8372
- let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => m.score >= scoreThreshold);
8508
+ const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
8509
+ let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
8510
+ var _a3;
8511
+ return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
8512
+ });
8373
8513
  const rerankLimit = wantsExhaustiveList ? retrievalLimit : topK;
8374
8514
  const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
8375
8515
  if (!hasNumericPredicates && useReranking) {
8376
- fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
8516
+ fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
8377
8517
  } else if (!wantsExhaustiveList) {
8378
8518
  fullSources = fullSources.slice(0, topK);
8379
8519
  }
8380
8520
  const rerankMs = performance.now() - rerankStart;
8381
- let context = fullSources.length ? fullSources.map((m, i) => `[Source ${i + 1}]
8382
- ${m.content}`).join("\n\n---\n\n") : "No relevant context found.";
8521
+ let context = fullSources.length ? fullSources.map((m, i) => {
8522
+ var _a3;
8523
+ return `[Source ${i + 1}]
8524
+ ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
8525
+ }).join("\n\n---\n\n") : "No relevant context found.";
8383
8526
  let displayCount = 15;
8384
8527
  if (hasMetadataFilter) {
8385
8528
  displayCount = fullSources.length;
8386
8529
  } else {
8387
8530
  const baseThreshold = Math.max(scoreThreshold, 0.4);
8388
- const highlyRelevant = fullSources.filter((m) => m.score >= baseThreshold);
8531
+ const highlyRelevant = fullSources.filter((m) => {
8532
+ var _a3;
8533
+ return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= baseThreshold;
8534
+ });
8389
8535
  displayCount = Math.max(highlyRelevant.length, topK);
8390
8536
  if (displayCount > 15) {
8391
8537
  displayCount = 15;
8392
8538
  }
8393
8539
  }
8394
- const sources = [...fullSources].sort((a, b) => b.score - a.score).slice(0, displayCount);
8540
+ const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
8541
+ var _a3, _b2;
8542
+ return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
8543
+ }).slice(0, displayCount);
8544
+ console.log("[Pipeline] Final sources for prompt & UI:", {
8545
+ count: sources.length,
8546
+ sources: sources.map((s, idx) => {
8547
+ var _a3;
8548
+ return {
8549
+ rank: idx + 1,
8550
+ id: s == null ? void 0 : s.id,
8551
+ score: s == null ? void 0 : s.score,
8552
+ contentType: typeof (s == null ? void 0 : s.content),
8553
+ contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
8554
+ metadata: s == null ? void 0 : s.metadata
8555
+ };
8556
+ })
8557
+ });
8395
8558
  if (graphData && graphData.nodes.length > 0) {
8396
8559
  const graphContext = graphData.nodes.map(
8397
8560
  (n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
@@ -8417,18 +8580,18 @@ ${context}`;
8417
8580
  }
8418
8581
  yield {
8419
8582
  reply: "",
8420
- sources: sources.map((s) => {
8421
- var _a3;
8583
+ sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
8584
+ var _a3, _b2, _c2;
8422
8585
  return {
8423
8586
  id: s.id,
8424
- score: s.score,
8425
- content: s.content,
8426
- metadata: (_a3 = s.metadata) != null ? _a3 : {},
8587
+ score: (_a3 = s.score) != null ? _a3 : 0,
8588
+ content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
8589
+ metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
8427
8590
  namespace: ns
8428
8591
  };
8429
8592
  })
8430
8593
  };
8431
- const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
8594
+ const allMetadataKeys = Array.from(new Set(sources.filter(Boolean).flatMap((s) => Object.keys((s == null ? void 0 : s.metadata) || {}))));
8432
8595
  const cachedSchema = allMetadataKeys.length > 0 ? SchemaMapper.getCached(ns, allMetadataKeys) : void 0;
8433
8596
  if (allMetadataKeys.length > 0 && !cachedSchema) {
8434
8597
  SchemaMapper.train(this.llmProvider, ns, allMetadataKeys).catch(() => {
@@ -8463,7 +8626,10 @@ ${context}`;
8463
8626
  if (isSimulatedThinking) {
8464
8627
  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.`)";
8465
8628
  }
8466
- const hardenedHistory = [...history];
8629
+ const hardenedHistory = (Array.isArray(history) ? history : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
8630
+ role: m.role || "user",
8631
+ content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
8632
+ }));
8467
8633
  const userQuestion = { role: "user", content: question + finalRestrictionSuffix };
8468
8634
  const messages = [...hardenedHistory, userQuestion];
8469
8635
  const systemPrompt = (_v = this.config.llm.systemPrompt) != null ? _v : "";
@@ -8610,13 +8776,13 @@ ${context}`;
8610
8776
  rewrittenQuery,
8611
8777
  systemPrompt,
8612
8778
  userPrompt: question + finalRestrictionSuffix,
8613
- chunks: sources.map((s) => {
8614
- var _a3;
8779
+ chunks: (sources || []).filter(Boolean).map((s) => {
8780
+ var _a3, _b2;
8615
8781
  return {
8616
8782
  id: s.id,
8617
8783
  score: s.score,
8618
- content: s.content,
8619
- metadata: (_a3 = s.metadata) != null ? _a3 : {},
8784
+ content: (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "",
8785
+ metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
8620
8786
  namespace: ns
8621
8787
  };
8622
8788
  }),
@@ -8717,6 +8883,8 @@ ${context}`;
8717
8883
  });
8718
8884
  }
8719
8885
  resolveNumericPredicateValue(source, predicate) {
8886
+ var _a2;
8887
+ if (!source) return null;
8720
8888
  const meta = source.metadata || {};
8721
8889
  const field = predicate.field;
8722
8890
  const entries = Object.entries(meta).filter(([, value]) => value !== null && value !== void 0 && typeof value !== "object");
@@ -8728,7 +8896,7 @@ ${context}`;
8728
8896
  const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
8729
8897
  if (value !== null) return value;
8730
8898
  }
8731
- const contentValue = this.extractNumericValueFromContent(source.content, field);
8899
+ const contentValue = this.extractNumericValueFromContent((_a2 = source.content) != null ? _a2 : "", field);
8732
8900
  if (contentValue !== null) return contentValue;
8733
8901
  }
8734
8902
  for (const [key, value] of entries) {
@@ -8739,6 +8907,7 @@ ${context}`;
8739
8907
  return null;
8740
8908
  }
8741
8909
  extractNumericValueFromContent(content, field) {
8910
+ if (!content || typeof content !== "string") return null;
8742
8911
  const escapedWords = field.split(/\s+|_+|-+/).filter(Boolean).map((word) => word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
8743
8912
  if (escapedWords.length === 0) return null;
8744
8913
  const pattern = new RegExp(`(?:${escapedWords.join("[\\\\s_:-]*")})\\s*[:\\-\u2013]?\\s*([\\d,]+(?:\\.\\d+)?)`, "i");
@@ -8824,6 +8993,20 @@ ${context}`;
8824
8993
  resolvedSources.push(source);
8825
8994
  }
8826
8995
  }
8996
+ console.log("[Pipeline] retrieve() response:", {
8997
+ query,
8998
+ namespace: ns,
8999
+ count: resolvedSources.length,
9000
+ sample: resolvedSources.slice(0, 2).map((s) => {
9001
+ var _a3;
9002
+ return {
9003
+ id: s == null ? void 0 : s.id,
9004
+ score: s == null ? void 0 : s.score,
9005
+ contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9006
+ metadata: s == null ? void 0 : s.metadata
9007
+ };
9008
+ })
9009
+ });
8827
9010
  return { sources: resolvedSources, graphData };
8828
9011
  }
8829
9012
  /** Rewrite the user query for better retrieval performance. */
@@ -9218,6 +9401,7 @@ ${csv.trim()}`);
9218
9401
  // src/core/DatabaseStorage.ts
9219
9402
  var fs = __toESM(require("fs"));
9220
9403
  var path = __toESM(require("path"));
9404
+ var os = __toESM(require("os"));
9221
9405
  var DatabaseStorage = class {
9222
9406
  constructor(config) {
9223
9407
  // Dynamic PG Pool
@@ -9226,7 +9410,8 @@ var DatabaseStorage = class {
9226
9410
  this.mongoClient = null;
9227
9411
  this.mongoDbName = "";
9228
9412
  // Filesystem fallback configuration
9229
- this.fallbackDir = path.join(process.cwd(), ".retrivora");
9413
+ this.isServerless = Boolean(process.env.VERCEL || process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.LAMBDA_TASK_ROOT);
9414
+ this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
9230
9415
  this.historyFile = path.join(this.fallbackDir, "history.json");
9231
9416
  this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
9232
9417
  var _a2, _b, _c, _d, _e;
@@ -9356,10 +9541,27 @@ var DatabaseStorage = class {
9356
9541
  }
9357
9542
  // Helper for FS fallback writes
9358
9543
  writeLocalFile(filePath, data) {
9359
- if (!fs.existsSync(this.fallbackDir)) {
9360
- fs.mkdirSync(this.fallbackDir, { recursive: true });
9544
+ try {
9545
+ const dir = path.dirname(filePath);
9546
+ if (!fs.existsSync(dir)) {
9547
+ fs.mkdirSync(dir, { recursive: true });
9548
+ }
9549
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
9550
+ } catch (err) {
9551
+ if (err.code === "EROFS") {
9552
+ try {
9553
+ const tmpDir = path.join(os.tmpdir(), ".retrivora");
9554
+ if (!fs.existsSync(tmpDir)) {
9555
+ fs.mkdirSync(tmpDir, { recursive: true });
9556
+ }
9557
+ const tmpFilePath = path.join(tmpDir, path.basename(filePath));
9558
+ fs.writeFileSync(tmpFilePath, JSON.stringify(data, null, 2), "utf-8");
9559
+ } catch (e) {
9560
+ }
9561
+ } else {
9562
+ console.warn(`[DatabaseStorage] Failed to write local fallback file: ${err.message}`);
9563
+ }
9361
9564
  }
9362
- fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
9363
9565
  }
9364
9566
  // ─── Message History Operations ──────────────────────────────────────────
9365
9567
  async saveMessage(sessionId, message) {