@stevenvo780/autologic 2.0.1 → 2.2.1

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 (105) hide show
  1. package/README.md +2 -0
  2. package/dist/atoms/index.d.ts +1 -1
  3. package/dist/atoms/index.d.ts.map +1 -1
  4. package/dist/atoms/index.js +75 -3
  5. package/dist/atoms/index.js.map +1 -1
  6. package/dist/atoms/keyword-extractor.d.ts +9 -0
  7. package/dist/atoms/keyword-extractor.d.ts.map +1 -1
  8. package/dist/atoms/keyword-extractor.js +64 -2
  9. package/dist/atoms/keyword-extractor.js.map +1 -1
  10. package/dist/atoms/math-parser.d.ts +11 -0
  11. package/dist/atoms/math-parser.d.ts.map +1 -0
  12. package/dist/atoms/math-parser.js +44 -0
  13. package/dist/atoms/math-parser.js.map +1 -0
  14. package/dist/compiler-frontend.d.ts +9 -0
  15. package/dist/compiler-frontend.d.ts.map +1 -0
  16. package/dist/compiler-frontend.js +142 -0
  17. package/dist/compiler-frontend.js.map +1 -0
  18. package/dist/context/discourse-state.d.ts +10 -0
  19. package/dist/context/discourse-state.d.ts.map +1 -0
  20. package/dist/context/discourse-state.js +26 -0
  21. package/dist/context/discourse-state.js.map +1 -0
  22. package/dist/discourse/markers-es.d.ts.map +1 -1
  23. package/dist/discourse/markers-es.js +23 -0
  24. package/dist/discourse/markers-es.js.map +1 -1
  25. package/dist/discourse/pattern-detector.d.ts.map +1 -1
  26. package/dist/discourse/pattern-detector.js +2 -1
  27. package/dist/discourse/pattern-detector.js.map +1 -1
  28. package/dist/discourse/role-classifier.js +32 -3
  29. package/dist/discourse/role-classifier.js.map +1 -1
  30. package/dist/formalize.d.ts +16 -0
  31. package/dist/formalize.d.ts.map +1 -1
  32. package/dist/formalize.js +130 -0
  33. package/dist/formalize.js.map +1 -1
  34. package/dist/formula/argument-builder.d.ts.map +1 -1
  35. package/dist/formula/argument-builder.js +95 -16
  36. package/dist/formula/argument-builder.js.map +1 -1
  37. package/dist/formula/ast-compiler.d.ts +6 -0
  38. package/dist/formula/ast-compiler.d.ts.map +1 -0
  39. package/dist/formula/ast-compiler.js +105 -0
  40. package/dist/formula/ast-compiler.js.map +1 -0
  41. package/dist/formula/ast.d.ts +81 -0
  42. package/dist/formula/ast.d.ts.map +1 -0
  43. package/dist/formula/ast.js +52 -0
  44. package/dist/formula/ast.js.map +1 -0
  45. package/dist/formula/connectors.js +1 -1
  46. package/dist/formula/connectors.js.map +1 -1
  47. package/dist/formula/first-order.js +74 -7
  48. package/dist/formula/first-order.js.map +1 -1
  49. package/dist/formula/helpers.d.ts +8 -0
  50. package/dist/formula/helpers.d.ts.map +1 -0
  51. package/dist/formula/helpers.js +166 -0
  52. package/dist/formula/helpers.js.map +1 -0
  53. package/dist/formula/index.d.ts +1 -0
  54. package/dist/formula/index.d.ts.map +1 -1
  55. package/dist/formula/index.js +5 -3
  56. package/dist/formula/index.js.map +1 -1
  57. package/dist/formula/modal.d.ts.map +1 -1
  58. package/dist/formula/modal.js +56 -67
  59. package/dist/formula/modal.js.map +1 -1
  60. package/dist/formula/probabilistic.d.ts +3 -0
  61. package/dist/formula/probabilistic.d.ts.map +1 -0
  62. package/dist/formula/probabilistic.js +55 -0
  63. package/dist/formula/probabilistic.js.map +1 -0
  64. package/dist/formula/propositional.d.ts +2 -2
  65. package/dist/formula/propositional.d.ts.map +1 -1
  66. package/dist/formula/propositional.js +74 -102
  67. package/dist/formula/propositional.js.map +1 -1
  68. package/dist/formula/temporal.d.ts.map +1 -1
  69. package/dist/formula/temporal.js +87 -62
  70. package/dist/formula/temporal.js.map +1 -1
  71. package/dist/generator/validator.d.ts +20 -0
  72. package/dist/generator/validator.d.ts.map +1 -1
  73. package/dist/generator/validator.js +112 -0
  74. package/dist/generator/validator.js.map +1 -1
  75. package/dist/index.d.ts +6 -17
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +8 -17
  78. package/dist/index.js.map +1 -1
  79. package/dist/llm-parser.d.ts +31 -0
  80. package/dist/llm-parser.d.ts.map +1 -0
  81. package/dist/llm-parser.js +197 -0
  82. package/dist/llm-parser.js.map +1 -0
  83. package/dist/local-slm-web.d.ts +8 -0
  84. package/dist/local-slm-web.d.ts.map +1 -0
  85. package/dist/local-slm-web.js +87 -0
  86. package/dist/local-slm-web.js.map +1 -0
  87. package/dist/nl-linter/index.d.ts +10 -0
  88. package/dist/nl-linter/index.d.ts.map +1 -0
  89. package/dist/nl-linter/index.js +45 -0
  90. package/dist/nl-linter/index.js.map +1 -0
  91. package/dist/nl-linter/rules.d.ts +6 -0
  92. package/dist/nl-linter/rules.d.ts.map +1 -0
  93. package/dist/nl-linter/rules.js +93 -0
  94. package/dist/nl-linter/rules.js.map +1 -0
  95. package/dist/nl-linter/types.d.ts +14 -0
  96. package/dist/nl-linter/types.d.ts.map +1 -0
  97. package/dist/nl-linter/types.js +3 -0
  98. package/dist/nl-linter/types.js.map +1 -0
  99. package/dist/segmenter/clause-splitter.d.ts.map +1 -1
  100. package/dist/segmenter/clause-splitter.js +208 -10
  101. package/dist/segmenter/clause-splitter.js.map +1 -1
  102. package/dist/types.d.ts +22 -0
  103. package/dist/types.d.ts.map +1 -1
  104. package/package.json +12 -4
  105. package/readme.md +666 -1
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseTextWithLLM = parseTextWithLLM;
4
+ exports.llmResultToST = llmResultToST;
5
+ const ast_compiler_1 = require("./formula/ast-compiler");
6
+ const local_slm_web_1 = require("./local-slm-web");
7
+ /**
8
+ * Prompt maestro isomorfico y ciego al entorno.
9
+ * Instruye al LLM para actuar como un destilador proposicional situado.
10
+ */
11
+ function buildSystemPrompt(profile) {
12
+ return `You are Autologic's semantic AST parser.
13
+ Your goal is to read complex human text and translate it into Situated Propositional Logic or bounded First-Order Logic depending on the profile: '${profile}'.
14
+ DO NOT try to resolve or prove the logic. Only extract the claims and their semantic relations.
15
+ AVOID deep First-Order combinatorial explosions. Collapse contextual instances into descriptive propositional atoms like: 'CumpleInformesOrdinarios'.
16
+
17
+ You MUST return a pure JSON object conforming exactly to this interface, nothing else:
18
+ {
19
+ "axioms": [ { "name": "a1", "formulaJSON": <LogicNode> }, ... ],
20
+ "conclusions": [ { "formulaJSON": <LogicNode> } ]
21
+ }
22
+
23
+ Available LogicNode types for formulaJSON:
24
+ - AtomNode: { "type": "Atom", "id": "CAMEL_CASE_ID", "text": "human readable description" }
25
+ - ConnectiveNode: { "type": "Connective", "operator": "AND"|"OR"|"IMPLIES"|"IFF"|"NOT", "left": <node>, "right": <node> }
26
+ For NOT: { "type": "Connective", "operator": "NOT", "left": <child_node> }
27
+ - ModalNode: { "type": "Modal", "operator": "K"|"B"|"O"|"P"|"F"|"BOX"|"DIA"|"ALWAYS"|"EVENTUALLY"|"NEXT", "child": <node>, "agent": "optional" }
28
+ - QuantifierNode: { "type": "Quantifier", "operator": "FORALL"|"EXISTS", "variables": ["x"], "child": <node> }
29
+ - PredicateNode: { "type": "Predicate", "name": "P", "args": [{"type":"Object","name":"x"}] }
30
+
31
+ Rules:
32
+ - axioms = premises and rules that are assumed true
33
+ - conclusions = what should be derived from axioms
34
+ - Use the SAME Atom id across axioms/conclusions when referring to the same proposition
35
+ - Atom ids must be SCREAMING_SNAKE_CASE
36
+ - Be precise. Return ONLY the raw JSON object. No markdown, no codeblocks.`;
37
+ }
38
+ /**
39
+ * Extracts the first JSON object from a string that may contain markdown fences or trailing text.
40
+ */
41
+ function extractFirstJSON(raw) {
42
+ // Strip markdown code fences
43
+ let cleaned = raw.replace(/^```json?\s*/m, '').replace(/```\s*$/m, '').trim();
44
+ let braceCount = 0;
45
+ let jsonStart = -1;
46
+ for (let i = 0; i < cleaned.length; i++) {
47
+ if (cleaned[i] === '{') {
48
+ if (jsonStart === -1)
49
+ jsonStart = i;
50
+ braceCount++;
51
+ }
52
+ else if (cleaned[i] === '}') {
53
+ braceCount--;
54
+ if (braceCount === 0 && jsonStart !== -1) {
55
+ return cleaned.substring(jsonStart, i + 1);
56
+ }
57
+ }
58
+ }
59
+ return cleaned;
60
+ }
61
+ /**
62
+ * Parse raw LLM output to LLMParsedResult with validation.
63
+ */
64
+ function parseAndValidateLLMJSON(raw) {
65
+ const jsonStr = extractFirstJSON(raw);
66
+ try {
67
+ const parsed = JSON.parse(jsonStr);
68
+ if (!parsed.axioms || !Array.isArray(parsed.axioms))
69
+ parsed.axioms = [];
70
+ if (!parsed.conclusions || !Array.isArray(parsed.conclusions))
71
+ parsed.conclusions = [];
72
+ return parsed;
73
+ }
74
+ catch (e) {
75
+ throw new Error(`Failed to parse LLM JSON. Raw (first 300 chars): ${raw.substring(0, 300)}`);
76
+ }
77
+ }
78
+ /**
79
+ * Llama a la API del LLM (usando fetch isomorfico) para abstraer el texto a AST.
80
+ */
81
+ async function parseTextWithLLM(text, profile, config) {
82
+ const systemPrompt = buildSystemPrompt(profile);
83
+ if (config.provider === 'web-distilled') {
84
+ return await (0, local_slm_web_1.runDistilledWebInference)(text, profile, systemPrompt, config.endpoint);
85
+ }
86
+ if (config.provider === 'ollama') {
87
+ // Ollama native API (direct, no auth)
88
+ const url = config.endpoint || 'http://localhost:11434/api/chat';
89
+ const response = await fetch(url, {
90
+ method: 'POST',
91
+ headers: { 'Content-Type': 'application/json' },
92
+ body: JSON.stringify({
93
+ model: config.model || 'qwen2.5-coder:14b',
94
+ messages: [
95
+ { role: 'system', content: systemPrompt },
96
+ { role: 'user', content: `Formalize this text:\n\n${text}` }
97
+ ],
98
+ stream: false,
99
+ format: 'json',
100
+ options: {
101
+ temperature: 0.1
102
+ }
103
+ })
104
+ });
105
+ if (!response.ok) {
106
+ const errText = await response.text();
107
+ throw new Error(`Ollama API Error: ${response.status} - ${errText}`);
108
+ }
109
+ const data = await response.json();
110
+ const rawContent = data.message.content;
111
+ return parseAndValidateLLMJSON(rawContent);
112
+ }
113
+ if (config.provider === 'openwebui') {
114
+ // Open WebUI — OpenAI-compatible endpoint with Bearer auth
115
+ if (!config.endpoint)
116
+ throw new Error('openwebui provider requires an explicit endpoint URL in LLMConfig.endpoint');
117
+ const url = config.endpoint;
118
+ const response = await fetch(url, {
119
+ method: 'POST',
120
+ headers: {
121
+ 'Content-Type': 'application/json',
122
+ 'Authorization': `Bearer ${config.apiKey}`
123
+ },
124
+ body: JSON.stringify({
125
+ model: config.model || 'qwen2.5-coder:14b',
126
+ messages: [
127
+ { role: 'system', content: systemPrompt },
128
+ { role: 'user', content: `Formalize this text:\n\n${text}` }
129
+ ],
130
+ temperature: 0.1
131
+ })
132
+ });
133
+ if (!response.ok) {
134
+ const errText = await response.text();
135
+ throw new Error(`OpenWebUI API Error: ${response.status} - ${errText}`);
136
+ }
137
+ const data = await response.json();
138
+ const rawContent = data.choices?.[0]?.message?.content;
139
+ if (!rawContent)
140
+ throw new Error('OpenWebUI returned empty content');
141
+ return parseAndValidateLLMJSON(rawContent);
142
+ }
143
+ let url = config.endpoint || 'https://api.openai.com/v1/chat/completions';
144
+ let headers = {
145
+ 'Content-Type': 'application/json'
146
+ };
147
+ let body = {};
148
+ if (config.provider === 'openai') {
149
+ headers['Authorization'] = `Bearer ${config.apiKey}`;
150
+ body = {
151
+ model: config.model || 'gpt-4o',
152
+ messages: [
153
+ { role: 'system', content: systemPrompt },
154
+ { role: 'user', content: `Formalize this text:\n\n${text}` }
155
+ ],
156
+ response_format: { type: 'json_object' },
157
+ temperature: 0.1
158
+ };
159
+ }
160
+ else {
161
+ throw new Error(`Provider ${config.provider} not yet fully implemented in this isomorphic fetch stub.`);
162
+ }
163
+ const response = await fetch(url, {
164
+ method: 'POST',
165
+ headers,
166
+ body: JSON.stringify(body)
167
+ });
168
+ if (!response.ok) {
169
+ const errText = await response.text();
170
+ throw new Error(`LLM API Error: ${response.status} - ${errText}`);
171
+ }
172
+ const data = await response.json();
173
+ const rawContent = data.choices[0].message.content;
174
+ return parseAndValidateLLMJSON(rawContent);
175
+ }
176
+ /**
177
+ * Transforma la respuesta estructurada del LLM directamente a líneas de código ST seguras.
178
+ * Conclusions become 'derive' statements (derived from all axioms).
179
+ */
180
+ function llmResultToST(result) {
181
+ const lines = [];
182
+ const axiomLabels = [];
183
+ for (const ax of result.axioms) {
184
+ const label = ax.name || `a${axiomLabels.length + 1}`;
185
+ axiomLabels.push(label);
186
+ lines.push({ formula: (0, ast_compiler_1.compileAST)(ax.formulaJSON), type: 'axiom' });
187
+ }
188
+ for (const conc of result.conclusions) {
189
+ lines.push({
190
+ formula: (0, ast_compiler_1.compileAST)(conc.formulaJSON),
191
+ type: 'derive',
192
+ deriveSources: [...axiomLabels]
193
+ });
194
+ }
195
+ return lines;
196
+ }
197
+ //# sourceMappingURL=llm-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-parser.js","sourceRoot":"","sources":["../src/llm-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { LLMParsedResult } from './llm-parser';
2
+ import { LogicProfile } from './types';
3
+ /**
4
+ * Loads @huggingface/transformers asynchronously and runs local ONNX inference
5
+ * using our fine-tuned Qwen2.5-0.5B model hosted on HuggingFace or loaded locally.
6
+ */
7
+ export declare function runDistilledWebInference(text: string, profile: LogicProfile, systemPrompt: string, customModelUrl?: string): Promise<LLMParsedResult>;
8
+ //# sourceMappingURL=local-slm-web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-slm-web.d.ts","sourceRoot":"","sources":["../src/local-slm-web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA2CvC;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA2C3J"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runDistilledWebInference = runDistilledWebInference;
4
+ let pipeline = null;
5
+ const TRAINING_SYSTEM_PROMPT = `You are Autologic's semantic AST parser.
6
+ Your goal is to read complex human text (often obfuscated legal/technical jargon) and translate it into Situated Propositional Logic.
7
+ DO NOT try to resolve or prove the logic. Only extract the claims and their semantic relations.
8
+ AVOID deep First-Order combinatorial explosions. Collapse contextual instances into descriptive propositional atoms like: 'CumpleInformesOrdinarios'.
9
+
10
+ You MUST return a pure JSON object conforming exactly to this interface, nothing else:
11
+ {
12
+ "axioms": [ { "name": "a1", "formulaJSON": { "type": "Connective", "operator": "IMPLIES", "left": {...}, "right": {...} } } ],
13
+ "conclusions": [ { "formulaJSON": { "type": "Atom", "id": "X", "text": "..." } } ]
14
+ }
15
+ Available node types for formulaJSON:
16
+ - AtomNode: { "type": "Atom", "id": "CAMEL_CASE_ID", "text": "human readable" }
17
+ - ConnectiveNode: { "type": "Connective", "operator": "AND"|"OR"|"IMPLIES"|"IFF"|"NOT", "left": node, "right": node }
18
+ - ModalNode: { "type": "Modal", "operator": "K"|"B"|"O"|"P"|"BOX"|"DIA", "child": node }
19
+ - QuantifierNode: { "type": "Quantifier", "operator": "FORALL"|"EXISTS", "variables": ["x"], "child": node }
20
+
21
+ Be precise. Return ONLY the raw JSON object. No markdown, no explanation, no codeblocks.`;
22
+ /**
23
+ * Extracts the first complete JSON object from a string,
24
+ * handling trailing garbage that the model may produce after the JSON.
25
+ */
26
+ function extractFirstJSON(text) {
27
+ let braceCount = 0;
28
+ let jsonStart = -1;
29
+ for (let i = 0; i < text.length; i++) {
30
+ if (text[i] === '{') {
31
+ if (jsonStart === -1)
32
+ jsonStart = i;
33
+ braceCount++;
34
+ }
35
+ else if (text[i] === '}') {
36
+ braceCount--;
37
+ if (braceCount === 0 && jsonStart !== -1) {
38
+ return text.substring(jsonStart, i + 1);
39
+ }
40
+ }
41
+ }
42
+ return text;
43
+ }
44
+ /**
45
+ * Loads @huggingface/transformers asynchronously and runs local ONNX inference
46
+ * using our fine-tuned Qwen2.5-0.5B model hosted on HuggingFace or loaded locally.
47
+ */
48
+ async function runDistilledWebInference(text, profile, systemPrompt, customModelUrl) {
49
+ if (!pipeline) {
50
+ try {
51
+ // Dynamic import for @huggingface/transformers (ESM)
52
+ const transformers = await Function('return import("@huggingface/transformers")')();
53
+ const { pipeline: trPipeline, env } = transformers;
54
+ env.allowLocalModels = true;
55
+ if (customModelUrl) {
56
+ env.localModelPath = customModelUrl;
57
+ env.allowRemoteModels = false;
58
+ }
59
+ // HuggingFace CDN model (fp32 ONNX, ~2.4GB lazy download)
60
+ const modelName = customModelUrl ? 'model-web' : 'stevenvo780/autologic-slm-onnx';
61
+ pipeline = await trPipeline('text-generation', modelName, {
62
+ local_files_only: !!customModelUrl,
63
+ dtype: 'fp32',
64
+ });
65
+ }
66
+ catch (e) {
67
+ throw new Error(`Web inference blocked: ${e.message}`);
68
+ }
69
+ }
70
+ // Use the EXACT system prompt from training for best results
71
+ const prompt = `<|im_start|>system\n${TRAINING_SYSTEM_PROMPT}<|im_end|>\n<|im_start|>user\nFormalize this text:\n\n${text}<|im_end|>\n<|im_start|>assistant\n`;
72
+ const output = await pipeline(prompt, {
73
+ max_new_tokens: 512,
74
+ temperature: 0.1,
75
+ do_sample: false,
76
+ return_full_text: false,
77
+ });
78
+ const rawContent = output[0]?.generated_text || '';
79
+ try {
80
+ const jsonStr = extractFirstJSON(rawContent);
81
+ return JSON.parse(jsonStr);
82
+ }
83
+ catch (e) {
84
+ throw new Error(`Web inference JSON parse failed: ${rawContent.substring(0, 200)}`);
85
+ }
86
+ }
87
+ //# sourceMappingURL=local-slm-web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-slm-web.js","sourceRoot":"","sources":["../src/local-slm-web.ts"],"names":[],"mappings":";;AAgDA,4DA2CC;AAxFD,IAAI,QAAQ,GAAQ,IAAI,CAAC;AAEzB,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;yFAgB0D,CAAC;AAE1F;;;GAGG;AACH,SAAS,gBAAgB,CAAC,IAAY;IACpC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACpB,IAAI,SAAS,KAAK,CAAC,CAAC;gBAAE,SAAS,GAAG,CAAC,CAAC;YACpC,UAAU,EAAE,CAAC;QACf,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAC3B,UAAU,EAAE,CAAC;YACb,IAAI,UAAU,KAAK,CAAC,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;gBACzC,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,wBAAwB,CAAC,IAAY,EAAE,OAAqB,EAAE,YAAoB,EAAE,cAAuB;IAC/H,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,IAAI,CAAC;YACH,qDAAqD;YACrD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,4CAA4C,CAAC,EAAE,CAAC;YACpF,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC;YAEnD,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC5B,IAAI,cAAc,EAAE,CAAC;gBACnB,GAAG,CAAC,cAAc,GAAG,cAAc,CAAC;gBACpC,GAAG,CAAC,iBAAiB,GAAG,KAAK,CAAC;YAChC,CAAC;YAED,0DAA0D;YAC1D,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,gCAAgC,CAAC;YAElF,QAAQ,GAAG,MAAM,UAAU,CAAC,iBAAiB,EAAE,SAAS,EAAE;gBACxD,gBAAgB,EAAE,CAAC,CAAC,cAAc;gBAClC,KAAK,EAAE,MAAM;aACd,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,MAAM,MAAM,GAAG,uBAAuB,sBAAsB,yDAAyD,IAAI,qCAAqC,CAAC;IAE/J,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE;QACpC,cAAc,EAAE,GAAG;QACnB,WAAW,EAAE,GAAG;QAChB,SAAS,EAAE,KAAK;QAChB,gBAAgB,EAAE,KAAK;KACxB,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,cAAc,IAAI,EAAE,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAoB,CAAC;IAChD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,oCAAoC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { NLLinterDiagnostic, NLRule } from './types';
2
+ export declare const DEFAULT_RULES: NLRule[];
3
+ /**
4
+ * Escanea de forma asíncrona un texto buscando posibles violaciones de formalización sintiéndose como un Linter "ESLint".
5
+ * Totalmente compatible con ejecución en cliente.
6
+ */
7
+ export declare function lintNaturalLanguage(text: string, rules?: NLRule[]): NLLinterDiagnostic[];
8
+ export * from './types';
9
+ export * from './rules';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nl-linter/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGrD,eAAO,MAAM,aAAa,EAAE,MAAM,EAKjC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,EAAkB,GAAG,kBAAkB,EAAE,CAavG;AAED,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.DEFAULT_RULES = void 0;
18
+ exports.lintNaturalLanguage = lintNaturalLanguage;
19
+ const rules_1 = require("./rules");
20
+ exports.DEFAULT_RULES = [
21
+ rules_1.anaphoricRule,
22
+ rules_1.cognitiveDensityRule,
23
+ rules_1.fuzzyQuantifiersRule,
24
+ rules_1.logicalCompletenessRule
25
+ ];
26
+ /**
27
+ * Escanea de forma asíncrona un texto buscando posibles violaciones de formalización sintiéndose como un Linter "ESLint".
28
+ * Totalmente compatible con ejecución en cliente.
29
+ */
30
+ function lintNaturalLanguage(text, rules = exports.DEFAULT_RULES) {
31
+ if (!text || text.trim() === '')
32
+ return [];
33
+ let diagnostics = [];
34
+ for (const rule of rules) {
35
+ const result = rule.evaluate(text);
36
+ if (result && result.length) {
37
+ diagnostics = diagnostics.concat(result);
38
+ }
39
+ }
40
+ // Ordenar por aparición en el texto
41
+ return diagnostics.sort((a, b) => a.start - b.start);
42
+ }
43
+ __exportStar(require("./types"), exports);
44
+ __exportStar(require("./rules"), exports);
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nl-linter/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAcA,kDAaC;AA1BD,mCAA6G;AAEhG,QAAA,aAAa,GAAa;IACrC,qBAAa;IACb,4BAAoB;IACpB,4BAAoB;IACpB,+BAAuB;CACxB,CAAC;AAEF;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,IAAY,EAAE,QAAkB,qBAAa;IAC/E,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IAE3C,IAAI,WAAW,GAAyB,EAAE,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC5B,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC;IACJ,CAAC;IAED,oCAAoC;IACpC,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvD,CAAC;AAED,0CAAwB;AACxB,0CAAwB"}
@@ -0,0 +1,6 @@
1
+ import type { NLRule } from './types';
2
+ export declare const anaphoricRule: NLRule;
3
+ export declare const cognitiveDensityRule: NLRule;
4
+ export declare const fuzzyQuantifiersRule: NLRule;
5
+ export declare const logicalCompletenessRule: NLRule;
6
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/nl-linter/rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAsB,MAAM,SAAS,CAAC;AAG1D,eAAO,MAAM,aAAa,EAAE,MAmB3B,CAAC;AAGF,eAAO,MAAM,oBAAoB,EAAE,MAyBlC,CAAC;AAGF,eAAO,MAAM,oBAAoB,EAAE,MAmBlC,CAAC;AAGF,eAAO,MAAM,uBAAuB,EAAE,MAoBrC,CAAC"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logicalCompletenessRule = exports.fuzzyQuantifiersRule = exports.cognitiveDensityRule = exports.anaphoricRule = void 0;
4
+ // 1. Ambigüedad Anafórica
5
+ exports.anaphoricRule = {
6
+ id: 'nl-anaphoric-ambiguity',
7
+ name: 'Ambigüedad Anafórica',
8
+ severity: 'warning',
9
+ evaluate: (text) => {
10
+ const diags = [];
11
+ const regex = /\b(este|ese|aquel|el cual|los cuales|lo anterior|su)\b/gi;
12
+ let match;
13
+ while ((match = regex.exec(text)) !== null) {
14
+ diags.push({
15
+ id: 'nl-anaphoric-ambiguity',
16
+ severity: 'warning',
17
+ message: `El pronombre anafórico '${match[1]}' puede confundir al modelo o diluir la abstracción. Si es posible, usa el sujeto explícito.`,
18
+ start: match.index,
19
+ end: match.index + match[0].length
20
+ });
21
+ }
22
+ return diags;
23
+ }
24
+ };
25
+ // 2. Densidad Cognitiva (Oraciones extremadamente largas)
26
+ exports.cognitiveDensityRule = {
27
+ id: 'nl-cognitive-density',
28
+ name: 'Densidad Cognitiva Alta',
29
+ severity: 'warning',
30
+ evaluate: (text) => {
31
+ const diags = [];
32
+ const sentences = text.split(/(?<=[.!?])\s+/);
33
+ let currentOffset = 0;
34
+ for (const sentence of sentences) {
35
+ const wordCount = sentence.split(/\s+/).filter(w => w.length > 0).length;
36
+ if (wordCount > 40) {
37
+ const startIndex = text.indexOf(sentence, currentOffset);
38
+ diags.push({
39
+ id: 'nl-cognitive-density',
40
+ severity: 'warning',
41
+ message: `Oración muy larga (${wordCount} palabras). El contexto semántico formal pierde precisión en oraciones kilométricas sin puntuación. Divídela.`,
42
+ start: startIndex >= 0 ? startIndex : currentOffset,
43
+ end: startIndex >= 0 ? startIndex + sentence.length : currentOffset + sentence.length
44
+ });
45
+ }
46
+ currentOffset += sentence.length;
47
+ }
48
+ return diags;
49
+ }
50
+ };
51
+ // 3. Cuantificación difusa
52
+ exports.fuzzyQuantifiersRule = {
53
+ id: 'nl-fuzzy-quantifier',
54
+ name: 'Cuantificador Difuso',
55
+ severity: 'error',
56
+ evaluate: (text) => {
57
+ const diags = [];
58
+ const regex = /\b(frecuentemente|la mayoría de|casi nunca|a veces|probablemente|en ocasiones)\b/gi;
59
+ let match;
60
+ while ((match = regex.exec(text)) !== null) {
61
+ diags.push({
62
+ id: 'nl-fuzzy-quantifier',
63
+ severity: 'error',
64
+ message: `Término difuso '${match[1]}'. La lógica proposicional exacta requiere condicionales definidos o cuantificadores absolutos (todos, ninguno).`,
65
+ start: match.index,
66
+ end: match.index + match[0].length
67
+ });
68
+ }
69
+ return diags;
70
+ }
71
+ };
72
+ // 4. Completitud lógica (ausencia de conectores de inferencia en textos argumentativos)
73
+ exports.logicalCompletenessRule = {
74
+ id: 'nl-missing-relations',
75
+ name: 'Falta de Relaciones Estructurales',
76
+ severity: 'warning',
77
+ evaluate: (text) => {
78
+ const diags = [];
79
+ const hasConclusion = /\b(por lo tanto|en consecuencia|ergo|luego|se concluye|por ende)\b/i.test(text);
80
+ const hasImplication = /\b(si\s.*entonces|solo si|siempre que)\b/i.test(text);
81
+ if (!hasConclusion && !hasImplication && text.length > 60) {
82
+ diags.push({
83
+ id: 'nl-missing-relations',
84
+ severity: 'warning',
85
+ message: 'El texto carece de conectores lógicos evidentes (ej. "si... entonces", "por lo tanto"). ¿Deseas evaluarlo solo como premisas aisladas?',
86
+ start: 0,
87
+ end: Math.min(text.length, 60)
88
+ });
89
+ }
90
+ return diags;
91
+ }
92
+ };
93
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/nl-linter/rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface NLLinterDiagnostic {
2
+ id: string;
3
+ severity: 'warning' | 'error';
4
+ message: string;
5
+ start: number;
6
+ end: number;
7
+ }
8
+ export interface NLRule {
9
+ id: string;
10
+ name: string;
11
+ severity: 'warning' | 'error';
12
+ evaluate: (text: string) => NLLinterDiagnostic[];
13
+ }
14
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/nl-linter/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,kBAAkB,EAAE,CAAC;CAClD"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/nl-linter/types.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"clause-splitter.d.ts","sourceRoot":"","sources":["../../src/segmenter/clause-splitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,MAAM,EAAkB,QAAQ,EAAc,MAAM,UAAU,CAAC;AAW7E;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAe,GAAG,MAAM,EAAE,CAkElF"}
1
+ {"version":3,"file":"clause-splitter.d.ts","sourceRoot":"","sources":["../../src/segmenter/clause-splitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,MAAM,EAAkB,QAAQ,EAAc,MAAM,UAAU,CAAC;AAW7E;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAe,GAAG,MAAM,EAAE,CA8ElF"}