@retrivora-ai/rag-engine 1.0.3 → 1.0.4

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.
@@ -1408,25 +1408,42 @@ Text to extract from:
1408
1408
  const response = await this.llm.chat([
1409
1409
  { role: "system", content: "You are a precise knowledge graph extraction engine. You always output valid JSON and nothing else." },
1410
1410
  { role: "user", content: prompt }
1411
- ], "", { maxTokens: 2048, temperature: 0.1 });
1411
+ ], "", { maxTokens: 4096, temperature: 0.1 });
1412
1412
  try {
1413
1413
  const jsonMatch = response.match(/\{[\s\S]*\}/);
1414
1414
  const cleanJson = jsonMatch ? jsonMatch[0] : response.trim();
1415
1415
  return JSON.parse(cleanJson);
1416
1416
  } catch (e) {
1417
- console.warn(`[EntityExtractor] Failed to parse LLM response. Length: ${response.length} chars.`);
1418
- if (response.trim().endsWith("}") === false && response.includes('"nodes"')) {
1419
- try {
1420
- const partialResponse = response.trim() + (response.includes("[") ? "]}" : "}");
1421
- const jsonMatch = partialResponse.match(/\{[\s\S]*\}/);
1422
- if (jsonMatch) return JSON.parse(jsonMatch[0]);
1423
- } catch (e2) {
1424
- }
1417
+ try {
1418
+ const repaired = this.repairTruncatedJson(response);
1419
+ if (repaired) return JSON.parse(repaired);
1420
+ } catch (e2) {
1425
1421
  }
1426
- console.warn("[EntityExtractor] Full failing response:", response.substring(0, 200) + "...");
1422
+ console.warn(`[EntityExtractor] Failed to parse LLM response. Length: ${response.length} chars.`);
1423
+ console.warn("[EntityExtractor] Snippet:", response.substring(0, 100) + "...");
1427
1424
  return { nodes: [], edges: [] };
1428
1425
  }
1429
1426
  }
1427
+ /**
1428
+ * Attempts to fix JSON that was cut off mid-generation.
1429
+ * Strategy: Find the last valid element in an array and close the structure.
1430
+ */
1431
+ repairTruncatedJson(json) {
1432
+ let text = json.trim();
1433
+ const startIdx = text.indexOf("{");
1434
+ if (startIdx === -1) return null;
1435
+ text = text.substring(startIdx);
1436
+ const lastCompleteObjectIdx = text.lastIndexOf("}");
1437
+ if (lastCompleteObjectIdx === -1) return null;
1438
+ let repaired = text.substring(0, lastCompleteObjectIdx + 1);
1439
+ const openBrackets = (repaired.match(/\{/g) || []).length;
1440
+ const closedBrackets = (repaired.match(/\}/g) || []).length;
1441
+ const openSquares = (repaired.match(/\[/g) || []).length;
1442
+ const closedSquares = (repaired.match(/\]/g) || []).length;
1443
+ for (let i = 0; i < openSquares - closedSquares; i++) repaired += "]";
1444
+ for (let i = 0; i < openBrackets - closedBrackets; i++) repaired += "}";
1445
+ return repaired;
1446
+ }
1430
1447
  };
1431
1448
 
1432
1449
  // src/rag/Reranker.ts
@@ -2871,25 +2871,42 @@ Text to extract from:
2871
2871
  const response = await this.llm.chat([
2872
2872
  { role: "system", content: "You are a precise knowledge graph extraction engine. You always output valid JSON and nothing else." },
2873
2873
  { role: "user", content: prompt }
2874
- ], "", { maxTokens: 2048, temperature: 0.1 });
2874
+ ], "", { maxTokens: 4096, temperature: 0.1 });
2875
2875
  try {
2876
2876
  const jsonMatch = response.match(/\{[\s\S]*\}/);
2877
2877
  const cleanJson = jsonMatch ? jsonMatch[0] : response.trim();
2878
2878
  return JSON.parse(cleanJson);
2879
2879
  } catch (e) {
2880
- console.warn(`[EntityExtractor] Failed to parse LLM response. Length: ${response.length} chars.`);
2881
- if (response.trim().endsWith("}") === false && response.includes('"nodes"')) {
2882
- try {
2883
- const partialResponse = response.trim() + (response.includes("[") ? "]}" : "}");
2884
- const jsonMatch = partialResponse.match(/\{[\s\S]*\}/);
2885
- if (jsonMatch) return JSON.parse(jsonMatch[0]);
2886
- } catch (e2) {
2887
- }
2880
+ try {
2881
+ const repaired = this.repairTruncatedJson(response);
2882
+ if (repaired) return JSON.parse(repaired);
2883
+ } catch (e2) {
2888
2884
  }
2889
- console.warn("[EntityExtractor] Full failing response:", response.substring(0, 200) + "...");
2885
+ console.warn(`[EntityExtractor] Failed to parse LLM response. Length: ${response.length} chars.`);
2886
+ console.warn("[EntityExtractor] Snippet:", response.substring(0, 100) + "...");
2890
2887
  return { nodes: [], edges: [] };
2891
2888
  }
2892
2889
  }
2890
+ /**
2891
+ * Attempts to fix JSON that was cut off mid-generation.
2892
+ * Strategy: Find the last valid element in an array and close the structure.
2893
+ */
2894
+ repairTruncatedJson(json) {
2895
+ let text = json.trim();
2896
+ const startIdx = text.indexOf("{");
2897
+ if (startIdx === -1) return null;
2898
+ text = text.substring(startIdx);
2899
+ const lastCompleteObjectIdx = text.lastIndexOf("}");
2900
+ if (lastCompleteObjectIdx === -1) return null;
2901
+ let repaired = text.substring(0, lastCompleteObjectIdx + 1);
2902
+ const openBrackets = (repaired.match(/\{/g) || []).length;
2903
+ const closedBrackets = (repaired.match(/\}/g) || []).length;
2904
+ const openSquares = (repaired.match(/\[/g) || []).length;
2905
+ const closedSquares = (repaired.match(/\]/g) || []).length;
2906
+ for (let i = 0; i < openSquares - closedSquares; i++) repaired += "]";
2907
+ for (let i = 0; i < openBrackets - closedBrackets; i++) repaired += "}";
2908
+ return repaired;
2909
+ }
2893
2910
  };
2894
2911
 
2895
2912
  // src/rag/Reranker.ts
@@ -4,7 +4,7 @@ import {
4
4
  createIngestHandler,
5
5
  createStreamHandler,
6
6
  createUploadHandler
7
- } from "../chunk-3JR3SAWX.mjs";
7
+ } from "../chunk-6MLZHQZT.mjs";
8
8
  import "../chunk-YLTMFW4M.mjs";
9
9
  import "../chunk-X4TOT24V.mjs";
10
10
  export {
package/dist/server.js CHANGED
@@ -2953,25 +2953,42 @@ Text to extract from:
2953
2953
  const response = await this.llm.chat([
2954
2954
  { role: "system", content: "You are a precise knowledge graph extraction engine. You always output valid JSON and nothing else." },
2955
2955
  { role: "user", content: prompt }
2956
- ], "", { maxTokens: 2048, temperature: 0.1 });
2956
+ ], "", { maxTokens: 4096, temperature: 0.1 });
2957
2957
  try {
2958
2958
  const jsonMatch = response.match(/\{[\s\S]*\}/);
2959
2959
  const cleanJson = jsonMatch ? jsonMatch[0] : response.trim();
2960
2960
  return JSON.parse(cleanJson);
2961
2961
  } catch (e) {
2962
- console.warn(`[EntityExtractor] Failed to parse LLM response. Length: ${response.length} chars.`);
2963
- if (response.trim().endsWith("}") === false && response.includes('"nodes"')) {
2964
- try {
2965
- const partialResponse = response.trim() + (response.includes("[") ? "]}" : "}");
2966
- const jsonMatch = partialResponse.match(/\{[\s\S]*\}/);
2967
- if (jsonMatch) return JSON.parse(jsonMatch[0]);
2968
- } catch (e2) {
2969
- }
2962
+ try {
2963
+ const repaired = this.repairTruncatedJson(response);
2964
+ if (repaired) return JSON.parse(repaired);
2965
+ } catch (e2) {
2970
2966
  }
2971
- console.warn("[EntityExtractor] Full failing response:", response.substring(0, 200) + "...");
2967
+ console.warn(`[EntityExtractor] Failed to parse LLM response. Length: ${response.length} chars.`);
2968
+ console.warn("[EntityExtractor] Snippet:", response.substring(0, 100) + "...");
2972
2969
  return { nodes: [], edges: [] };
2973
2970
  }
2974
2971
  }
2972
+ /**
2973
+ * Attempts to fix JSON that was cut off mid-generation.
2974
+ * Strategy: Find the last valid element in an array and close the structure.
2975
+ */
2976
+ repairTruncatedJson(json) {
2977
+ let text = json.trim();
2978
+ const startIdx = text.indexOf("{");
2979
+ if (startIdx === -1) return null;
2980
+ text = text.substring(startIdx);
2981
+ const lastCompleteObjectIdx = text.lastIndexOf("}");
2982
+ if (lastCompleteObjectIdx === -1) return null;
2983
+ let repaired = text.substring(0, lastCompleteObjectIdx + 1);
2984
+ const openBrackets = (repaired.match(/\{/g) || []).length;
2985
+ const closedBrackets = (repaired.match(/\}/g) || []).length;
2986
+ const openSquares = (repaired.match(/\[/g) || []).length;
2987
+ const closedSquares = (repaired.match(/\]/g) || []).length;
2988
+ for (let i = 0; i < openSquares - closedSquares; i++) repaired += "]";
2989
+ for (let i = 0; i < openBrackets - closedBrackets; i++) repaired += "}";
2990
+ return repaired;
2991
+ }
2975
2992
  };
2976
2993
 
2977
2994
  // src/rag/Reranker.ts
package/dist/server.mjs CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  createIngestHandler,
35
35
  createUploadHandler,
36
36
  getRagConfig
37
- } from "./chunk-3JR3SAWX.mjs";
37
+ } from "./chunk-6MLZHQZT.mjs";
38
38
  import "./chunk-YLTMFW4M.mjs";
39
39
  import {
40
40
  PineconeProvider
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retrivora-ai/rag-engine",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Retrivora AI is a plug-and-play AI engine for RAG chat experiences — generic vector DB + LLM provider, embeddable or standalone.",
5
5
  "author": "Abhinav Alkuchi",
6
6
  "license": "MIT",
@@ -35,7 +35,7 @@ Text to extract from:
35
35
  const response = await this.llm.chat([
36
36
  { role: 'system', content: 'You are a precise knowledge graph extraction engine. You always output valid JSON and nothing else.' },
37
37
  { role: 'user', content: prompt }
38
- ], '', { maxTokens: 2048, temperature: 0.1 });
38
+ ], '', { maxTokens: 4096, temperature: 0.1 });
39
39
 
40
40
  try {
41
41
  // 1. Try to find the JSON block using a regex
@@ -44,20 +44,47 @@ Text to extract from:
44
44
 
45
45
  return JSON.parse(cleanJson);
46
46
  } catch {
47
+ // 2. If parsing fails, try to repair truncated JSON
48
+ try {
49
+ const repaired = this.repairTruncatedJson(response);
50
+ if (repaired) return JSON.parse(repaired);
51
+ } catch { /* ignore repair failure */ }
52
+
47
53
  console.warn(`[EntityExtractor] Failed to parse LLM response. Length: ${response.length} chars.`);
48
-
49
- // Attempt very basic "fix" if it looks like it was truncated
50
- if (response.trim().endsWith('}') === false && response.includes('"nodes"')) {
51
- try {
52
- // This is a last-resort attempt to see if we can get anything out of a truncated response
53
- const partialResponse = response.trim() + (response.includes('[') ? ']}' : '}');
54
- const jsonMatch = partialResponse.match(/\{[\s\S]*\}/);
55
- if (jsonMatch) return JSON.parse(jsonMatch[0]);
56
- } catch { /* ignore */ }
57
- }
58
-
59
- console.warn('[EntityExtractor] Full failing response:', response.substring(0, 200) + '...');
54
+ console.warn('[EntityExtractor] Snippet:', response.substring(0, 100) + '...');
60
55
  return { nodes: [], edges: [] };
61
56
  }
62
57
  }
58
+
59
+ /**
60
+ * Attempts to fix JSON that was cut off mid-generation.
61
+ * Strategy: Find the last valid element in an array and close the structure.
62
+ */
63
+ private repairTruncatedJson(json: string): string | null {
64
+ let text = json.trim();
65
+
66
+ // Find the first { and work from there
67
+ const startIdx = text.indexOf('{');
68
+ if (startIdx === -1) return null;
69
+ text = text.substring(startIdx);
70
+
71
+ // If it's truncated in an array like "nodes": [ ... , { ...
72
+ // We try to find the last complete object before the truncation
73
+ const lastCompleteObjectIdx = text.lastIndexOf('}');
74
+ if (lastCompleteObjectIdx === -1) return null;
75
+
76
+ // Truncate at the last complete object
77
+ let repaired = text.substring(0, lastCompleteObjectIdx + 1);
78
+
79
+ // Close any open structures (arrays or the main object)
80
+ const openBrackets = (repaired.match(/\{/g) || []).length;
81
+ const closedBrackets = (repaired.match(/\}/g) || []).length;
82
+ const openSquares = (repaired.match(/\[/g) || []).length;
83
+ const closedSquares = (repaired.match(/\]/g) || []).length;
84
+
85
+ for (let i = 0; i < openSquares - closedSquares; i++) repaired += ']';
86
+ for (let i = 0; i < openBrackets - closedBrackets; i++) repaired += '}';
87
+
88
+ return repaired;
89
+ }
63
90
  }