@retrivora-ai/rag-engine 1.0.2 → 1.0.3

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.
@@ -1391,26 +1391,39 @@ var EntityExtractor = class {
1391
1391
  async extract(text) {
1392
1392
  const prompt = `
1393
1393
  Extract entities and relationships from the following text.
1394
- Format the output as JSON with two keys: "nodes" (array of {id, label, properties}) and "edges" (array of {source, target, type, properties}).
1395
- Use the same ID for the same entity.
1394
+ Format the output as a JSON object with exactly two keys: "nodes" and "edges".
1396
1395
 
1397
- IMPORTANT: Ensure all property values are valid JSON types (strings, numbers, booleans, or null).
1398
- DO NOT include mathematical expressions like "4.5/5" as numbers; use strings instead.
1396
+ Nodes: {id, label, properties}
1397
+ Edges: {source, target, type, properties}
1399
1398
 
1400
- Text:
1401
- "${text}"
1399
+ IMPORTANT:
1400
+ - Ensure all property values are simple JSON types (string, number, boolean).
1401
+ - Do not use mathematical expressions or complex nested objects in properties.
1402
+ - If no entities are found, return empty arrays.
1403
+ - RESPOND ONLY WITH THE JSON OBJECT.
1402
1404
 
1403
- Output JSON:
1405
+ Text to extract from:
1406
+ "${text}"
1404
1407
  `;
1405
1408
  const response = await this.llm.chat([
1406
- { role: "system", content: "You are an expert at knowledge graph extraction. Respond only with valid JSON." },
1409
+ { role: "system", content: "You are a precise knowledge graph extraction engine. You always output valid JSON and nothing else." },
1407
1410
  { role: "user", content: prompt }
1408
- ], "");
1411
+ ], "", { maxTokens: 2048, temperature: 0.1 });
1409
1412
  try {
1410
- const cleanJson = response.replace(/```json\n?|\n?```/g, "").trim();
1413
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
1414
+ const cleanJson = jsonMatch ? jsonMatch[0] : response.trim();
1411
1415
  return JSON.parse(cleanJson);
1412
1416
  } catch (e) {
1413
- console.warn("[EntityExtractor] Failed to parse LLM response as JSON:", response);
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
+ }
1425
+ }
1426
+ console.warn("[EntityExtractor] Full failing response:", response.substring(0, 200) + "...");
1414
1427
  return { nodes: [], edges: [] };
1415
1428
  }
1416
1429
  }
@@ -2854,26 +2854,39 @@ var EntityExtractor = class {
2854
2854
  async extract(text) {
2855
2855
  const prompt = `
2856
2856
  Extract entities and relationships from the following text.
2857
- Format the output as JSON with two keys: "nodes" (array of {id, label, properties}) and "edges" (array of {source, target, type, properties}).
2858
- Use the same ID for the same entity.
2857
+ Format the output as a JSON object with exactly two keys: "nodes" and "edges".
2859
2858
 
2860
- IMPORTANT: Ensure all property values are valid JSON types (strings, numbers, booleans, or null).
2861
- DO NOT include mathematical expressions like "4.5/5" as numbers; use strings instead.
2859
+ Nodes: {id, label, properties}
2860
+ Edges: {source, target, type, properties}
2862
2861
 
2863
- Text:
2864
- "${text}"
2862
+ IMPORTANT:
2863
+ - Ensure all property values are simple JSON types (string, number, boolean).
2864
+ - Do not use mathematical expressions or complex nested objects in properties.
2865
+ - If no entities are found, return empty arrays.
2866
+ - RESPOND ONLY WITH THE JSON OBJECT.
2865
2867
 
2866
- Output JSON:
2868
+ Text to extract from:
2869
+ "${text}"
2867
2870
  `;
2868
2871
  const response = await this.llm.chat([
2869
- { role: "system", content: "You are an expert at knowledge graph extraction. Respond only with valid JSON." },
2872
+ { role: "system", content: "You are a precise knowledge graph extraction engine. You always output valid JSON and nothing else." },
2870
2873
  { role: "user", content: prompt }
2871
- ], "");
2874
+ ], "", { maxTokens: 2048, temperature: 0.1 });
2872
2875
  try {
2873
- const cleanJson = response.replace(/```json\n?|\n?```/g, "").trim();
2876
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
2877
+ const cleanJson = jsonMatch ? jsonMatch[0] : response.trim();
2874
2878
  return JSON.parse(cleanJson);
2875
2879
  } catch (e) {
2876
- console.warn("[EntityExtractor] Failed to parse LLM response as JSON:", response);
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
+ }
2888
+ }
2889
+ console.warn("[EntityExtractor] Full failing response:", response.substring(0, 200) + "...");
2877
2890
  return { nodes: [], edges: [] };
2878
2891
  }
2879
2892
  }
@@ -4,7 +4,7 @@ import {
4
4
  createIngestHandler,
5
5
  createStreamHandler,
6
6
  createUploadHandler
7
- } from "../chunk-OJNAKSQ2.mjs";
7
+ } from "../chunk-3JR3SAWX.mjs";
8
8
  import "../chunk-YLTMFW4M.mjs";
9
9
  import "../chunk-X4TOT24V.mjs";
10
10
  export {
package/dist/server.js CHANGED
@@ -2936,26 +2936,39 @@ var EntityExtractor = class {
2936
2936
  async extract(text) {
2937
2937
  const prompt = `
2938
2938
  Extract entities and relationships from the following text.
2939
- Format the output as JSON with two keys: "nodes" (array of {id, label, properties}) and "edges" (array of {source, target, type, properties}).
2940
- Use the same ID for the same entity.
2939
+ Format the output as a JSON object with exactly two keys: "nodes" and "edges".
2941
2940
 
2942
- IMPORTANT: Ensure all property values are valid JSON types (strings, numbers, booleans, or null).
2943
- DO NOT include mathematical expressions like "4.5/5" as numbers; use strings instead.
2941
+ Nodes: {id, label, properties}
2942
+ Edges: {source, target, type, properties}
2944
2943
 
2945
- Text:
2946
- "${text}"
2944
+ IMPORTANT:
2945
+ - Ensure all property values are simple JSON types (string, number, boolean).
2946
+ - Do not use mathematical expressions or complex nested objects in properties.
2947
+ - If no entities are found, return empty arrays.
2948
+ - RESPOND ONLY WITH THE JSON OBJECT.
2947
2949
 
2948
- Output JSON:
2950
+ Text to extract from:
2951
+ "${text}"
2949
2952
  `;
2950
2953
  const response = await this.llm.chat([
2951
- { role: "system", content: "You are an expert at knowledge graph extraction. Respond only with valid JSON." },
2954
+ { role: "system", content: "You are a precise knowledge graph extraction engine. You always output valid JSON and nothing else." },
2952
2955
  { role: "user", content: prompt }
2953
- ], "");
2956
+ ], "", { maxTokens: 2048, temperature: 0.1 });
2954
2957
  try {
2955
- const cleanJson = response.replace(/```json\n?|\n?```/g, "").trim();
2958
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
2959
+ const cleanJson = jsonMatch ? jsonMatch[0] : response.trim();
2956
2960
  return JSON.parse(cleanJson);
2957
2961
  } catch (e) {
2958
- console.warn("[EntityExtractor] Failed to parse LLM response as JSON:", response);
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
+ }
2970
+ }
2971
+ console.warn("[EntityExtractor] Full failing response:", response.substring(0, 200) + "...");
2959
2972
  return { nodes: [], edges: [] };
2960
2973
  }
2961
2974
  }
package/dist/server.mjs CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  createIngestHandler,
35
35
  createUploadHandler,
36
36
  getRagConfig
37
- } from "./chunk-OJNAKSQ2.mjs";
37
+ } from "./chunk-3JR3SAWX.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.2",
3
+ "version": "1.0.3",
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",
@@ -17,29 +17,46 @@ export class EntityExtractor {
17
17
  async extract(text: string): Promise<{ nodes: GraphNode[]; edges: Edge[] }> {
18
18
  const prompt = `
19
19
  Extract entities and relationships from the following text.
20
- Format the output as JSON with two keys: "nodes" (array of {id, label, properties}) and "edges" (array of {source, target, type, properties}).
21
- Use the same ID for the same entity.
20
+ Format the output as a JSON object with exactly two keys: "nodes" and "edges".
22
21
 
23
- IMPORTANT: Ensure all property values are valid JSON types (strings, numbers, booleans, or null).
24
- DO NOT include mathematical expressions like "4.5/5" as numbers; use strings instead.
22
+ Nodes: {id, label, properties}
23
+ Edges: {source, target, type, properties}
25
24
 
26
- Text:
27
- "${text}"
25
+ IMPORTANT:
26
+ - Ensure all property values are simple JSON types (string, number, boolean).
27
+ - Do not use mathematical expressions or complex nested objects in properties.
28
+ - If no entities are found, return empty arrays.
29
+ - RESPOND ONLY WITH THE JSON OBJECT.
28
30
 
29
- Output JSON:
31
+ Text to extract from:
32
+ "${text}"
30
33
  `;
31
34
 
32
35
  const response = await this.llm.chat([
33
- { role: 'system', content: 'You are an expert at knowledge graph extraction. Respond only with valid JSON.' },
36
+ { role: 'system', content: 'You are a precise knowledge graph extraction engine. You always output valid JSON and nothing else.' },
34
37
  { role: 'user', content: prompt }
35
- ], '');
38
+ ], '', { maxTokens: 2048, temperature: 0.1 });
36
39
 
37
40
  try {
38
- // Clean up LLM response (sometimes it adds markdown blocks)
39
- const cleanJson = response.replace(/```json\n?|\n?```/g, '').trim();
41
+ // 1. Try to find the JSON block using a regex
42
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
43
+ const cleanJson = jsonMatch ? jsonMatch[0] : response.trim();
44
+
40
45
  return JSON.parse(cleanJson);
41
46
  } catch {
42
- console.warn('[EntityExtractor] Failed to parse LLM response as JSON:', response);
47
+ 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) + '...');
43
60
  return { nodes: [], edges: [] };
44
61
  }
45
62
  }