@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.
package/dist/server.js CHANGED
@@ -4007,7 +4007,7 @@ var UniversalLLMAdapter = class {
4007
4007
  });
4008
4008
  }
4009
4009
  async chat(messages, context) {
4010
- var _a2, _b;
4010
+ var _a2, _b, _c, _d, _e, _f;
4011
4011
  const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4012
4012
  const formattedMessages = [
4013
4013
  { role: "system", content: `${this.systemPrompt}
@@ -4032,8 +4032,27 @@ ${context != null ? context : "None"}` },
4032
4032
  temperature: this.temperature
4033
4033
  };
4034
4034
  }
4035
+ const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4036
+ if (isSelfHost || Boolean(process.env.VERCEL)) {
4037
+ const _g2 = globalThis;
4038
+ if (typeof _g2.__retrivoraDispatchChat === "function") {
4039
+ try {
4040
+ const res = await _g2.__retrivoraDispatchChat({
4041
+ model: this.model,
4042
+ messages: formattedMessages,
4043
+ max_tokens: this.maxTokens,
4044
+ temperature: this.temperature
4045
+ }, this.apiKey);
4046
+ 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) {
4047
+ return res.response.choices[0].message.content;
4048
+ }
4049
+ } catch (dispatchErr) {
4050
+ throw dispatchErr;
4051
+ }
4052
+ }
4053
+ }
4035
4054
  const { data } = await this.http.post(path2, payload);
4036
- const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
4055
+ const extractPath = (_f = this.opts.responseExtractPath) != null ? _f : "choices[0].message.content";
4037
4056
  const result = resolvePath(data, extractPath);
4038
4057
  if (result === void 0) {
4039
4058
  throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
@@ -4047,7 +4066,7 @@ ${context != null ? context : "None"}` },
4047
4066
  */
4048
4067
  chatStream(messages, context) {
4049
4068
  return __asyncGenerator(this, null, function* () {
4050
- var _a2, _b, _c;
4069
+ var _a2, _b, _c, _d, _e, _f, _g2;
4051
4070
  const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4052
4071
  const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
4053
4072
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
@@ -4078,19 +4097,46 @@ ${context != null ? context : "None"}` },
4078
4097
  stream: true
4079
4098
  };
4080
4099
  }
4081
- const response = yield new __await(fetch(url, {
4082
- method: "POST",
4083
- headers: this.resolvedHeaders,
4084
- body: JSON.stringify(payload)
4085
- }));
4086
- if (!response.ok) {
4087
- const errorText = yield new __await(response.text().catch(() => response.statusText));
4088
- throw new Error(`[UniversalLLMAdapter] Streaming request failed (${response.status}): ${errorText}`);
4100
+ const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4101
+ let streamBody = null;
4102
+ if (isSelfHost || Boolean(process.env.VERCEL)) {
4103
+ const _g3 = globalThis;
4104
+ if (typeof _g3.__retrivoraDispatchChat === "function") {
4105
+ try {
4106
+ const res = yield new __await(_g3.__retrivoraDispatchChat({
4107
+ model: this.model,
4108
+ messages: formattedMessages,
4109
+ max_tokens: this.maxTokens,
4110
+ temperature: this.temperature,
4111
+ stream: true
4112
+ }, this.apiKey));
4113
+ if (res == null ? void 0 : res.stream) {
4114
+ streamBody = res.stream;
4115
+ } 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) {
4116
+ yield res.response.choices[0].message.content;
4117
+ return;
4118
+ }
4119
+ } catch (dispatchErr) {
4120
+ throw dispatchErr;
4121
+ }
4122
+ }
4089
4123
  }
4090
- if (!response.body) {
4091
- throw new Error("[UniversalLLMAdapter] Response body is null \u2014 server did not send a streaming response.");
4124
+ if (!streamBody) {
4125
+ const response = yield new __await(fetch(url, {
4126
+ method: "POST",
4127
+ headers: this.resolvedHeaders,
4128
+ body: JSON.stringify(payload)
4129
+ }));
4130
+ if (!response.ok) {
4131
+ const errorText = yield new __await(response.text().catch(() => response.statusText));
4132
+ throw new Error(`[UniversalLLMAdapter] Streaming request failed (${response.status}): ${errorText}`);
4133
+ }
4134
+ if (!response.body) {
4135
+ throw new Error("[UniversalLLMAdapter] Response body is null \u2014 server did not send a streaming response.");
4136
+ }
4137
+ streamBody = response.body;
4092
4138
  }
4093
- const reader = response.body.getReader();
4139
+ const reader = streamBody.getReader();
4094
4140
  const decoder = new TextDecoder("utf-8");
4095
4141
  let buffer = "";
4096
4142
  try {
@@ -4099,7 +4145,7 @@ ${context != null ? context : "None"}` },
4099
4145
  if (done) break;
4100
4146
  buffer += decoder.decode(value, { stream: true });
4101
4147
  const lines = buffer.split("\n");
4102
- buffer = (_c = lines.pop()) != null ? _c : "";
4148
+ buffer = (_g2 = lines.pop()) != null ? _g2 : "";
4103
4149
  for (const line of lines) {
4104
4150
  const trimmed = line.trim();
4105
4151
  if (!trimmed || trimmed === "data: [DONE]") continue;
@@ -4127,7 +4173,7 @@ ${context != null ? context : "None"}` },
4127
4173
  });
4128
4174
  }
4129
4175
  async embed(text) {
4130
- var _a2, _b;
4176
+ var _a2, _b, _c, _d;
4131
4177
  const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
4132
4178
  let payload;
4133
4179
  if (this.opts.embedPayloadTemplate) {
@@ -4141,8 +4187,25 @@ ${context != null ? context : "None"}` },
4141
4187
  input: text
4142
4188
  };
4143
4189
  }
4190
+ const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4191
+ if (isSelfHost || Boolean(process.env.VERCEL)) {
4192
+ const _g2 = globalThis;
4193
+ if (typeof _g2.__retrivoraDispatchEmbedding === "function") {
4194
+ try {
4195
+ const res = await _g2.__retrivoraDispatchEmbedding({
4196
+ model: this.model,
4197
+ input: text
4198
+ }, this.apiKey);
4199
+ if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
4200
+ return res.data[0].embedding;
4201
+ }
4202
+ } catch (dispatchErr) {
4203
+ throw dispatchErr;
4204
+ }
4205
+ }
4206
+ }
4144
4207
  const { data } = await this.http.post(path2, payload);
4145
- const extractPath = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
4208
+ const extractPath = (_d = this.opts.embedExtractPath) != null ? _d : "data[0].embedding";
4146
4209
  const vector = resolvePath(data, extractPath);
4147
4210
  if (!Array.isArray(vector)) {
4148
4211
  throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
@@ -4731,7 +4794,8 @@ var Reranker = class {
4731
4794
  return matches.sort((a, b) => b.score - a.score).slice(0, limit);
4732
4795
  }
4733
4796
  const scoredMatches = matches.map((match) => {
4734
- const contentLower = match.content.toLowerCase();
4797
+ var _a2;
4798
+ const contentLower = ((_a2 = match == null ? void 0 : match.content) != null ? _a2 : "").toLowerCase();
4735
4799
  let keywordScore = 0;
4736
4800
  keywords.forEach((keyword) => {
4737
4801
  if (contentLower.includes(keyword)) {
@@ -4752,7 +4816,10 @@ var Reranker = class {
4752
4816
  [{ role: "user", content: `Query: "${query}"
4753
4817
 
4754
4818
  Documents:
4755
- ${topN.map((m, i) => `[${i}] ${m.content.replace(/\n/g, " ")}`).join("\n")}` }],
4819
+ ${topN.map((m, i) => {
4820
+ var _a2;
4821
+ return `[${i}] ${((_a2 = m == null ? void 0 : m.content) != null ? _a2 : "").replace(/\n/g, " ")}`;
4822
+ }).join("\n")}` }],
4756
4823
  "",
4757
4824
  {
4758
4825
  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.',
@@ -5923,10 +5990,10 @@ Return ONLY 'vector', 'graph', or 'both'. No explanation.`;
5923
5990
  "",
5924
5991
  { temperature: 0, maxTokens: 10 }
5925
5992
  );
5926
- const cleanResponse = response.trim().toLowerCase();
5927
- if (cleanResponse.includes("vector")) return "vector";
5928
- if (cleanResponse.includes("graph")) return "graph";
5993
+ const cleanResponse = (response != null ? response : "").trim().toLowerCase();
5929
5994
  if (cleanResponse.includes("both")) return "both";
5995
+ if (cleanResponse.includes("graph")) return "graph";
5996
+ if (cleanResponse.includes("vector")) return "vector";
5930
5997
  } catch (error) {
5931
5998
  console.warn("[QueryProcessor] LLM strategy classification failed, falling back to keywords:", error);
5932
5999
  }
@@ -6100,7 +6167,10 @@ var IntentClassifier = class {
6100
6167
  hasCategoricalFields = catKeys.size > 0;
6101
6168
  numericFieldCount = numericKeys.size;
6102
6169
  categoricalFieldCount = catKeys.size;
6103
- if (productKeyMatches >= 2 || docs.some((d) => d.content.toLowerCase().includes("price") || d.content.toLowerCase().includes("brand"))) {
6170
+ if (productKeyMatches >= 2 || docs.some((d) => {
6171
+ var _a2, _b;
6172
+ 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");
6173
+ })) {
6104
6174
  isProductLike = true;
6105
6175
  }
6106
6176
  }
@@ -6380,7 +6450,10 @@ var TextRendererStrategy = class {
6380
6450
  return { type: "text", title, data: { content: data } };
6381
6451
  }
6382
6452
  const docs = Array.isArray(data) ? data : [];
6383
- const text = docs.map((d) => d.content).join("\n\n");
6453
+ const text = docs.map((d) => {
6454
+ var _a2;
6455
+ return (_a2 = d == null ? void 0 : d.content) != null ? _a2 : "";
6456
+ }).join("\n\n");
6384
6457
  return { type: "text", title, data: { content: text || "No detailed content available." } };
6385
6458
  }
6386
6459
  };
@@ -6637,6 +6710,19 @@ var UITransformer = class _UITransformer {
6637
6710
  if (!retrievedData || retrievedData.length === 0) {
6638
6711
  return this.createTextResponse("No data available", "No relevant data found for your query.");
6639
6712
  }
6713
+ console.log("[UITransformer.transform] Processing retrievedData:", {
6714
+ userQuery,
6715
+ retrievedCount: retrievedData.length,
6716
+ sample: retrievedData.slice(0, 2).map((item) => {
6717
+ var _a3;
6718
+ return {
6719
+ id: item == null ? void 0 : item.id,
6720
+ contentType: typeof (item == null ? void 0 : item.content),
6721
+ contentSnippet: String((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 150),
6722
+ metadataKeys: Object.keys((item == null ? void 0 : item.metadata) || {})
6723
+ };
6724
+ })
6725
+ });
6640
6726
  const resolvedIntent = intent != null ? intent : this.detectIntentHeuristic(userQuery);
6641
6727
  const filteredData = resolvedIntent.filterInStockOnly ? retrievedData.filter((item) => this.determineStockStatus(item)) : retrievedData;
6642
6728
  const profile = this.profileData(filteredData);
@@ -7126,7 +7212,10 @@ ${schemaProfileText}` : ""}`;
7126
7212
  type: "radar_chart",
7127
7213
  title: "Product Comparison",
7128
7214
  description: `Comparing ${data.length} items across ${radarData.length} attributes`,
7129
- data: radarData.length > 0 ? radarData : data.map((d) => ({ attribute: d.content.substring(0, 40) }))
7215
+ data: radarData.length > 0 ? radarData : data.map((d) => {
7216
+ var _a2;
7217
+ return { attribute: ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").substring(0, 40) };
7218
+ })
7130
7219
  };
7131
7220
  }
7132
7221
  static transformToTable(data, query = "") {
@@ -7143,7 +7232,10 @@ ${schemaProfileText}` : ""}`;
7143
7232
  static transformToText(data) {
7144
7233
  return this.createTextResponse(
7145
7234
  "Retrieved Context",
7146
- data.map((item) => item.content).join("\n\n"),
7235
+ data.map((item) => {
7236
+ var _a2;
7237
+ return (_a2 = item == null ? void 0 : item.content) != null ? _a2 : "";
7238
+ }).join("\n\n"),
7147
7239
  `Found ${data.length} relevant results`
7148
7240
  );
7149
7241
  }
@@ -7304,6 +7396,7 @@ ${schemaProfileText}` : ""}`;
7304
7396
  return productTerms && productAction && !nonProductEntityTerms;
7305
7397
  }
7306
7398
  static isProductData(item) {
7399
+ if (!item) return false;
7307
7400
  const content = (item.content || "").toLowerCase();
7308
7401
  const productKeywords = [
7309
7402
  "product",
@@ -7562,12 +7655,12 @@ ${schemaProfileText}` : ""}`;
7562
7655
  }
7563
7656
  static extractTimeSeriesData(data) {
7564
7657
  return data.map((item) => {
7565
- var _a2, _b, _c, _d, _e;
7658
+ var _a2, _b, _c, _d, _e, _f;
7566
7659
  const meta = item.metadata || {};
7567
7660
  return {
7568
7661
  timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
7569
7662
  value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
7570
- label: (_e = meta.label) != null ? _e : item.content.substring(0, 50)
7663
+ label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
7571
7664
  };
7572
7665
  });
7573
7666
  }
@@ -7681,7 +7774,8 @@ ${schemaProfileText}` : ""}`;
7681
7774
  }, query.includes(normalizedField) ? 3 : 0);
7682
7775
  }
7683
7776
  static resolveTableCellValue(item, column) {
7684
- if (column === "Content") return item.content.substring(0, 100);
7777
+ var _a2, _b, _c;
7778
+ if (column === "Content") return ((_a2 = item == null ? void 0 : item.content) != null ? _a2 : "").substring(0, 100);
7685
7779
  const meta = item.metadata || {};
7686
7780
  const normalizedColumn = this.normalizeComparableField(column);
7687
7781
  const exactMetadata = Object.entries(meta).find(
@@ -7692,9 +7786,9 @@ ${schemaProfileText}` : ""}`;
7692
7786
  }
7693
7787
  const aliasValue = this.resolveAliasedTableCell(meta, column);
7694
7788
  if (aliasValue !== void 0) return this.toDisplayValue(aliasValue);
7695
- const contentValue = this.extractContentFieldValue(item.content, column);
7789
+ const contentValue = this.extractContentFieldValue((_b = item == null ? void 0 : item.content) != null ? _b : "", column);
7696
7790
  if (contentValue !== null) return contentValue;
7697
- const aliasContentValue = this.extractAliasedContentFieldValue(item.content, column);
7791
+ const aliasContentValue = this.extractAliasedContentFieldValue((_c = item == null ? void 0 : item.content) != null ? _c : "", column);
7698
7792
  return aliasContentValue != null ? aliasContentValue : "";
7699
7793
  }
7700
7794
  static resolveAliasedTableCell(meta, column) {
@@ -7744,6 +7838,7 @@ ${schemaProfileText}` : ""}`;
7744
7838
  return { inStockCount: inStock, outOfStockCount: outOfStock };
7745
7839
  }
7746
7840
  static determineStockStatus(item) {
7841
+ if (!item) return true;
7747
7842
  const meta = item.metadata || {};
7748
7843
  const stockValue = resolveMetadataValue(meta, "stock");
7749
7844
  if (stockValue !== void 0) {
@@ -7789,35 +7884,64 @@ ${schemaProfileText}` : ""}`;
7789
7884
  return resolveMetadataValue(meta, uiKey);
7790
7885
  }
7791
7886
  static extractProductInfo(item, config, trainedSchema) {
7792
- var _a2;
7887
+ var _a2, _b;
7888
+ if (!item) return null;
7793
7889
  const meta = item.metadata || {};
7890
+ const content = item.content || "";
7794
7891
  const name = this.getDynamicVal(meta, "name", config, trainedSchema);
7795
7892
  const price = this.getDynamicVal(meta, "price", config, trainedSchema);
7796
7893
  const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
7797
7894
  const description = this.cleanProductDescription(
7798
- (_a2 = this.extractProductDescriptionFromContent(item.content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
7895
+ (_a2 = this.extractProductDescriptionFromContent(content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
7799
7896
  );
7800
7897
  if (name || this.isProductData(item)) {
7801
7898
  let finalName = name ? String(name) : void 0;
7899
+ if (!finalName && content) {
7900
+ const nameMatch = content.match(/(?:Product|Item|Name):\s*([^\n]+)/i);
7901
+ finalName = nameMatch ? nameMatch[1].trim() : (_b = content.split("\n")[0]) == null ? void 0 : _b.substring(0, 60);
7902
+ }
7802
7903
  if (!finalName) {
7803
- const nameMatch = item.content.match(/(?:Product|Item|Name):\s*([^\n]+)/i);
7804
- finalName = nameMatch ? nameMatch[1].trim() : item.content.split("\n")[0].substring(0, 60);
7904
+ console.warn(
7905
+ `[UITransformer] Unable to read product name from metadata or content for item ${item.id}. Defaulting to 'Unnamed Product'.`,
7906
+ { metadataKeys: Object.keys(meta), contentLength: content.length }
7907
+ );
7805
7908
  }
7806
7909
  let finalPrice = typeof price === "number" || typeof price === "string" ? price : void 0;
7807
- if (!finalPrice) {
7808
- const priceMatch = item.content.match(/(?:Price|Cost):\s*\$?([\d,.]+)/i) || item.content.match(/\$\s*([\d,.]+)/);
7910
+ if (!finalPrice && content) {
7911
+ const priceMatch = content.match(/(?:Price|Cost):\s*\$?([\d,.]+)/i) || content.match(/\$\s*([\d,.]+)/);
7809
7912
  if (priceMatch) finalPrice = priceMatch[1].replace(/,/g, "");
7810
7913
  }
7914
+ if (finalPrice === void 0) {
7915
+ console.warn(
7916
+ `[UITransformer] Unable to read product price from metadata or content for item ${item.id}.`,
7917
+ { metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
7918
+ );
7919
+ }
7811
7920
  const imageValue = this.getDynamicVal(meta, "image", config, trainedSchema);
7921
+ if (!imageValue) {
7922
+ console.debug(
7923
+ `[UITransformer] Unable to read product image URL from metadata for item ${item.id}.`
7924
+ );
7925
+ }
7926
+ if (!description) {
7927
+ console.debug(
7928
+ `[UITransformer] Unable to read product description from metadata or content for item ${item.id}.`
7929
+ );
7930
+ }
7812
7931
  return {
7813
7932
  id: item.id,
7814
- name: finalName,
7933
+ name: finalName || "Unnamed Product",
7815
7934
  price: finalPrice,
7816
7935
  image: typeof imageValue === "string" ? imageValue : void 0,
7817
7936
  brand: brand ? String(brand) : void 0,
7818
7937
  description,
7819
7938
  inStock: this.determineStockStatus(item)
7820
7939
  };
7940
+ } else {
7941
+ console.warn(
7942
+ `[UITransformer] Item ${item.id} skipped: unable to read name or identify as product data from metadata/content.`,
7943
+ { metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
7944
+ );
7821
7945
  }
7822
7946
  return null;
7823
7947
  }
@@ -7902,13 +8026,13 @@ RULES:
7902
8026
  5. If no relevant data is found, return text: "I cannot answer this question based on the available information."`;
7903
8027
  }
7904
8028
  static buildContextSummary(sources, maxChars = 6e3) {
7905
- const items = sources.map((s, i) => {
8029
+ const items = (sources || []).filter(Boolean).map((s, i) => {
7906
8030
  var _a2, _b, _c, _d;
7907
8031
  return {
7908
8032
  index: i + 1,
7909
- content: (_b = (_a2 = s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
7910
- metadata: (_c = s.metadata) != null ? _c : {},
7911
- score: (_d = s.score) != null ? _d : 0
8033
+ content: (_b = (_a2 = s == null ? void 0 : s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
8034
+ metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
8035
+ score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
7912
8036
  };
7913
8037
  });
7914
8038
  const full = JSON.stringify(items, null, 2);
@@ -8477,35 +8601,74 @@ ${m.content}`).join("\n\n---\n\n");
8477
8601
  const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
8478
8602
  const wantsExhaustiveList = hasNumericPredicates || hasMetadataFilter || /\b(list|all|show|provide|give|get|browse|find|search|display)\b/i.test(question);
8479
8603
  const retrievalLimit = wantsExhaustiveList ? Math.max(topK * 20, 100) : topK * 2;
8480
- const rawSources = (strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : [];
8604
+ 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"));
8605
+ console.log("[Pipeline] Raw vectorDB.query response:", {
8606
+ rawCount: rawSources.length,
8607
+ sample: rawSources.slice(0, 2).map((s) => {
8608
+ var _a3;
8609
+ return {
8610
+ id: s == null ? void 0 : s.id,
8611
+ score: s == null ? void 0 : s.score,
8612
+ contentType: typeof (s == null ? void 0 : s.content),
8613
+ contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
8614
+ metadataKeys: Object.keys((s == null ? void 0 : s.metadata) || {})
8615
+ };
8616
+ })
8617
+ });
8481
8618
  const retrieveEnd = performance.now();
8482
8619
  const embedMs = retrieveEnd - embedStart;
8483
8620
  const retrieveMs = retrieveEnd - embedStart;
8484
8621
  const rerankStart = performance.now();
8485
- const structuredSources = this.applyStructuredFilters(rawSources, filter);
8486
- let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => m.score >= scoreThreshold);
8622
+ const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
8623
+ let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
8624
+ var _a3;
8625
+ return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
8626
+ });
8487
8627
  const rerankLimit = wantsExhaustiveList ? retrievalLimit : topK;
8488
8628
  const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
8489
8629
  if (!hasNumericPredicates && useReranking) {
8490
- fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
8630
+ fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
8491
8631
  } else if (!wantsExhaustiveList) {
8492
8632
  fullSources = fullSources.slice(0, topK);
8493
8633
  }
8494
8634
  const rerankMs = performance.now() - rerankStart;
8495
- let context = fullSources.length ? fullSources.map((m, i) => `[Source ${i + 1}]
8496
- ${m.content}`).join("\n\n---\n\n") : "No relevant context found.";
8635
+ let context = fullSources.length ? fullSources.map((m, i) => {
8636
+ var _a3;
8637
+ return `[Source ${i + 1}]
8638
+ ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
8639
+ }).join("\n\n---\n\n") : "No relevant context found.";
8497
8640
  let displayCount = 15;
8498
8641
  if (hasMetadataFilter) {
8499
8642
  displayCount = fullSources.length;
8500
8643
  } else {
8501
8644
  const baseThreshold = Math.max(scoreThreshold, 0.4);
8502
- const highlyRelevant = fullSources.filter((m) => m.score >= baseThreshold);
8645
+ const highlyRelevant = fullSources.filter((m) => {
8646
+ var _a3;
8647
+ return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= baseThreshold;
8648
+ });
8503
8649
  displayCount = Math.max(highlyRelevant.length, topK);
8504
8650
  if (displayCount > 15) {
8505
8651
  displayCount = 15;
8506
8652
  }
8507
8653
  }
8508
- const sources = [...fullSources].sort((a, b) => b.score - a.score).slice(0, displayCount);
8654
+ const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
8655
+ var _a3, _b2;
8656
+ return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
8657
+ }).slice(0, displayCount);
8658
+ console.log("[Pipeline] Final sources for prompt & UI:", {
8659
+ count: sources.length,
8660
+ sources: sources.map((s, idx) => {
8661
+ var _a3;
8662
+ return {
8663
+ rank: idx + 1,
8664
+ id: s == null ? void 0 : s.id,
8665
+ score: s == null ? void 0 : s.score,
8666
+ contentType: typeof (s == null ? void 0 : s.content),
8667
+ contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
8668
+ metadata: s == null ? void 0 : s.metadata
8669
+ };
8670
+ })
8671
+ });
8509
8672
  if (graphData && graphData.nodes.length > 0) {
8510
8673
  const graphContext = graphData.nodes.map(
8511
8674
  (n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
@@ -8531,18 +8694,18 @@ ${context}`;
8531
8694
  }
8532
8695
  yield {
8533
8696
  reply: "",
8534
- sources: sources.map((s) => {
8535
- var _a3;
8697
+ sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
8698
+ var _a3, _b2, _c2;
8536
8699
  return {
8537
8700
  id: s.id,
8538
- score: s.score,
8539
- content: s.content,
8540
- metadata: (_a3 = s.metadata) != null ? _a3 : {},
8701
+ score: (_a3 = s.score) != null ? _a3 : 0,
8702
+ content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
8703
+ metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
8541
8704
  namespace: ns
8542
8705
  };
8543
8706
  })
8544
8707
  };
8545
- const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
8708
+ const allMetadataKeys = Array.from(new Set(sources.filter(Boolean).flatMap((s) => Object.keys((s == null ? void 0 : s.metadata) || {}))));
8546
8709
  const cachedSchema = allMetadataKeys.length > 0 ? SchemaMapper.getCached(ns, allMetadataKeys) : void 0;
8547
8710
  if (allMetadataKeys.length > 0 && !cachedSchema) {
8548
8711
  SchemaMapper.train(this.llmProvider, ns, allMetadataKeys).catch(() => {
@@ -8577,7 +8740,10 @@ ${context}`;
8577
8740
  if (isSimulatedThinking) {
8578
8741
  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.`)";
8579
8742
  }
8580
- const hardenedHistory = [...history];
8743
+ const hardenedHistory = (Array.isArray(history) ? history : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
8744
+ role: m.role || "user",
8745
+ content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
8746
+ }));
8581
8747
  const userQuestion = { role: "user", content: question + finalRestrictionSuffix };
8582
8748
  const messages = [...hardenedHistory, userQuestion];
8583
8749
  const systemPrompt = (_v = this.config.llm.systemPrompt) != null ? _v : "";
@@ -8724,13 +8890,13 @@ ${context}`;
8724
8890
  rewrittenQuery,
8725
8891
  systemPrompt,
8726
8892
  userPrompt: question + finalRestrictionSuffix,
8727
- chunks: sources.map((s) => {
8728
- var _a3;
8893
+ chunks: (sources || []).filter(Boolean).map((s) => {
8894
+ var _a3, _b2;
8729
8895
  return {
8730
8896
  id: s.id,
8731
8897
  score: s.score,
8732
- content: s.content,
8733
- metadata: (_a3 = s.metadata) != null ? _a3 : {},
8898
+ content: (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "",
8899
+ metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
8734
8900
  namespace: ns
8735
8901
  };
8736
8902
  }),
@@ -8831,6 +8997,8 @@ ${context}`;
8831
8997
  });
8832
8998
  }
8833
8999
  resolveNumericPredicateValue(source, predicate) {
9000
+ var _a2;
9001
+ if (!source) return null;
8834
9002
  const meta = source.metadata || {};
8835
9003
  const field = predicate.field;
8836
9004
  const entries = Object.entries(meta).filter(([, value]) => value !== null && value !== void 0 && typeof value !== "object");
@@ -8842,7 +9010,7 @@ ${context}`;
8842
9010
  const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
8843
9011
  if (value !== null) return value;
8844
9012
  }
8845
- const contentValue = this.extractNumericValueFromContent(source.content, field);
9013
+ const contentValue = this.extractNumericValueFromContent((_a2 = source.content) != null ? _a2 : "", field);
8846
9014
  if (contentValue !== null) return contentValue;
8847
9015
  }
8848
9016
  for (const [key, value] of entries) {
@@ -8853,6 +9021,7 @@ ${context}`;
8853
9021
  return null;
8854
9022
  }
8855
9023
  extractNumericValueFromContent(content, field) {
9024
+ if (!content || typeof content !== "string") return null;
8856
9025
  const escapedWords = field.split(/\s+|_+|-+/).filter(Boolean).map((word) => word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
8857
9026
  if (escapedWords.length === 0) return null;
8858
9027
  const pattern = new RegExp(`(?:${escapedWords.join("[\\\\s_:-]*")})\\s*[:\\-\u2013]?\\s*([\\d,]+(?:\\.\\d+)?)`, "i");
@@ -8938,6 +9107,20 @@ ${context}`;
8938
9107
  resolvedSources.push(source);
8939
9108
  }
8940
9109
  }
9110
+ console.log("[Pipeline] retrieve() response:", {
9111
+ query,
9112
+ namespace: ns,
9113
+ count: resolvedSources.length,
9114
+ sample: resolvedSources.slice(0, 2).map((s) => {
9115
+ var _a3;
9116
+ return {
9117
+ id: s == null ? void 0 : s.id,
9118
+ score: s == null ? void 0 : s.score,
9119
+ contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9120
+ metadata: s == null ? void 0 : s.metadata
9121
+ };
9122
+ })
9123
+ });
8941
9124
  return { sources: resolvedSources, graphData };
8942
9125
  }
8943
9126
  /** Rewrite the user query for better retrieval performance. */
@@ -9631,6 +9814,7 @@ var import_server = require("next/server");
9631
9814
  // src/core/DatabaseStorage.ts
9632
9815
  var fs = __toESM(require("fs"));
9633
9816
  var path = __toESM(require("path"));
9817
+ var os = __toESM(require("os"));
9634
9818
  var DatabaseStorage = class {
9635
9819
  constructor(config) {
9636
9820
  // Dynamic PG Pool
@@ -9639,7 +9823,8 @@ var DatabaseStorage = class {
9639
9823
  this.mongoClient = null;
9640
9824
  this.mongoDbName = "";
9641
9825
  // Filesystem fallback configuration
9642
- this.fallbackDir = path.join(process.cwd(), ".retrivora");
9826
+ this.isServerless = Boolean(process.env.VERCEL || process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.LAMBDA_TASK_ROOT);
9827
+ this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
9643
9828
  this.historyFile = path.join(this.fallbackDir, "history.json");
9644
9829
  this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
9645
9830
  var _a2, _b, _c, _d, _e;
@@ -9769,10 +9954,27 @@ var DatabaseStorage = class {
9769
9954
  }
9770
9955
  // Helper for FS fallback writes
9771
9956
  writeLocalFile(filePath, data) {
9772
- if (!fs.existsSync(this.fallbackDir)) {
9773
- fs.mkdirSync(this.fallbackDir, { recursive: true });
9957
+ try {
9958
+ const dir = path.dirname(filePath);
9959
+ if (!fs.existsSync(dir)) {
9960
+ fs.mkdirSync(dir, { recursive: true });
9961
+ }
9962
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
9963
+ } catch (err) {
9964
+ if (err.code === "EROFS") {
9965
+ try {
9966
+ const tmpDir = path.join(os.tmpdir(), ".retrivora");
9967
+ if (!fs.existsSync(tmpDir)) {
9968
+ fs.mkdirSync(tmpDir, { recursive: true });
9969
+ }
9970
+ const tmpFilePath = path.join(tmpDir, path.basename(filePath));
9971
+ fs.writeFileSync(tmpFilePath, JSON.stringify(data, null, 2), "utf-8");
9972
+ } catch (e) {
9973
+ }
9974
+ } else {
9975
+ console.warn(`[DatabaseStorage] Failed to write local fallback file: ${err.message}`);
9976
+ }
9774
9977
  }
9775
- fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
9776
9978
  }
9777
9979
  // ─── Message History Operations ──────────────────────────────────────────
9778
9980
  async saveMessage(sessionId, message) {