matryoshka-rlm 0.1.0

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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +303 -0
  3. package/config.example.json +31 -0
  4. package/dist/code-fixer.d.ts +26 -0
  5. package/dist/code-fixer.d.ts.map +1 -0
  6. package/dist/code-fixer.js +209 -0
  7. package/dist/code-fixer.js.map +1 -0
  8. package/dist/config.d.ts +39 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +47 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/fuzzy-search.d.ts +14 -0
  13. package/dist/fuzzy-search.d.ts.map +1 -0
  14. package/dist/fuzzy-search.js +141 -0
  15. package/dist/fuzzy-search.js.map +1 -0
  16. package/dist/index.d.ts +8 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +178 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/llm/deepseek.d.ts +3 -0
  21. package/dist/llm/deepseek.d.ts.map +1 -0
  22. package/dist/llm/deepseek.js +32 -0
  23. package/dist/llm/deepseek.js.map +1 -0
  24. package/dist/llm/index.d.ts +26 -0
  25. package/dist/llm/index.d.ts.map +1 -0
  26. package/dist/llm/index.js +66 -0
  27. package/dist/llm/index.js.map +1 -0
  28. package/dist/llm/ollama.d.ts +3 -0
  29. package/dist/llm/ollama.d.ts.map +1 -0
  30. package/dist/llm/ollama.js +29 -0
  31. package/dist/llm/ollama.js.map +1 -0
  32. package/dist/llm/types.d.ts +23 -0
  33. package/dist/llm/types.d.ts.map +1 -0
  34. package/dist/llm/types.js +2 -0
  35. package/dist/llm/types.js.map +1 -0
  36. package/dist/mcp-server.d.ts +35 -0
  37. package/dist/mcp-server.d.ts.map +1 -0
  38. package/dist/mcp-server.js +132 -0
  39. package/dist/mcp-server.js.map +1 -0
  40. package/dist/rlm.d.ts +36 -0
  41. package/dist/rlm.d.ts.map +1 -0
  42. package/dist/rlm.js +268 -0
  43. package/dist/rlm.js.map +1 -0
  44. package/dist/sandbox.d.ts +39 -0
  45. package/dist/sandbox.d.ts.map +1 -0
  46. package/dist/sandbox.js +265 -0
  47. package/dist/sandbox.js.map +1 -0
  48. package/dist/tools.d.ts +50 -0
  49. package/dist/tools.d.ts.map +1 -0
  50. package/dist/tools.js +210 -0
  51. package/dist/tools.js.map +1 -0
  52. package/package.json +76 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 yogthos
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,303 @@
1
+ # Recursive Language Model (RLM)
2
+
3
+ Process documents 100x larger than your LLM's context window—without vector databases or chunking heuristics.
4
+
5
+ ## The Problem
6
+
7
+ LLMs have fixed context windows. Traditional solutions (RAG, chunking) lose information or miss connections across chunks. RLM takes a different approach: the model writes code to explore documents programmatically, deciding at runtime how to decompose and analyze the data.
8
+
9
+ Based on the [Recursive Language Models paper](https://arxiv.org/abs/2512.24601).
10
+
11
+ ## Installation
12
+
13
+ ### npm (recommended)
14
+
15
+ ```bash
16
+ npm install -g matryoshka-rlm
17
+ ```
18
+
19
+ ### npx (no install)
20
+
21
+ ```bash
22
+ npx matryoshka-rlm "Summarize this document" ./document.txt
23
+ ```
24
+
25
+ ### From source
26
+
27
+ ```bash
28
+ git clone https://github.com/yogthos/Matryoshka.git
29
+ cd Matryoshka
30
+ npm install
31
+ npm run build
32
+ ```
33
+
34
+ ## Configuration
35
+
36
+ Copy `config.example.json` to `config.json` and configure your LLM provider:
37
+
38
+ ```json
39
+ {
40
+ "llm": {
41
+ "provider": "ollama"
42
+ },
43
+ "providers": {
44
+ "ollama": {
45
+ "baseUrl": "http://localhost:11434",
46
+ "model": "qwen3-coder:30b",
47
+ "options": { "temperature": 0.2, "num_ctx": 8192 }
48
+ },
49
+ "deepseek": {
50
+ "baseUrl": "https://api.deepseek.com",
51
+ "apiKey": "${DEEPSEEK_API_KEY}",
52
+ "model": "deepseek-chat",
53
+ "options": { "temperature": 0.2 }
54
+ }
55
+ }
56
+ }
57
+ ```
58
+
59
+ ## Usage
60
+
61
+ ### CLI
62
+
63
+ ```bash
64
+ # Basic usage
65
+ rlm "Summarize this document" ./path/to/document.txt
66
+
67
+ # With options
68
+ rlm "Find all error codes" ./logs.txt --max-turns 15 --verbose
69
+
70
+ # See all options
71
+ rlm --help
72
+ ```
73
+
74
+ ### MCP Integration
75
+
76
+ RLM includes an MCP (Model Context Protocol) server that exposes the `analyze_document` tool. This allows Claude to analyze documents that exceed its context window.
77
+
78
+ #### MCP Tool: `analyze_document`
79
+
80
+ | Parameter | Type | Required | Description |
81
+ |-----------|------|----------|-------------|
82
+ | `query` | string | Yes | The question or task to perform on the document |
83
+ | `filePath` | string | Yes | Absolute path to the document file |
84
+ | `maxTurns` | number | No | Maximum exploration turns (default: 10) |
85
+ | `timeoutMs` | number | No | Timeout per turn in milliseconds (default: 30000) |
86
+
87
+ #### Claude Code
88
+
89
+ Add the MCP server to Claude Code:
90
+
91
+ ```bash
92
+ # Add to user config (available in all projects)
93
+ claude mcp add --transport stdio --scope user rlm -- rlm-mcp
94
+
95
+ # Or add to current project only
96
+ claude mcp add --transport stdio rlm -- rlm-mcp
97
+
98
+ # Verify it's connected
99
+ claude mcp list
100
+ ```
101
+
102
+ Then ask Claude to analyze documents:
103
+
104
+ > Use the analyze_document tool to find all sales figures in /path/to/report.txt and calculate the total
105
+
106
+ #### Claude Desktop
107
+
108
+ Add to your Claude Desktop config file:
109
+
110
+ **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
111
+ **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
112
+
113
+ Using npx (no global install needed):
114
+
115
+ ```json
116
+ {
117
+ "mcpServers": {
118
+ "rlm": {
119
+ "command": "npx",
120
+ "args": ["-y", "-p", "matryoshka-rlm", "rlm-mcp"]
121
+ }
122
+ }
123
+ }
124
+ ```
125
+
126
+ Or if installed globally:
127
+
128
+ ```json
129
+ {
130
+ "mcpServers": {
131
+ "rlm": {
132
+ "command": "rlm-mcp"
133
+ }
134
+ }
135
+ }
136
+ ```
137
+
138
+ Restart Claude Desktop after updating the config. Look for the hammer icon to confirm the server loaded.
139
+
140
+ #### Testing the MCP Server
141
+
142
+ ```bash
143
+ # Verify the server starts correctly
144
+ rlm-mcp --test
145
+ # Output: MCP server ready
146
+ # Output: Available tools: analyze_document
147
+ ```
148
+
149
+ ### Programmatic
150
+
151
+ ```typescript
152
+ import { runRLM } from "matryoshka-rlm/rlm";
153
+ import { createLLMClient } from "matryoshka-rlm";
154
+
155
+ const llmClient = createLLMClient("ollama", {
156
+ baseUrl: "http://localhost:11434",
157
+ model: "qwen3-coder:30b",
158
+ options: { temperature: 0.2 }
159
+ });
160
+
161
+ const result = await runRLM("What are the main themes?", "./book.txt", {
162
+ llmClient,
163
+ maxTurns: 10,
164
+ turnTimeoutMs: 30000,
165
+ });
166
+ ```
167
+
168
+ ## Architecture
169
+
170
+ ```mermaid
171
+ sequenceDiagram
172
+ participant User
173
+ participant RLM as RLM Engine
174
+ participant Sandbox as JavaScript Sandbox
175
+ participant LLM as LLM Provider
176
+
177
+ User->>RLM: query + document path
178
+ RLM->>Sandbox: Create sandbox with document as `context`
179
+
180
+ loop Until FINAL or maxTurns
181
+ RLM->>LLM: System prompt + history
182
+ LLM-->>RLM: JavaScript code block
183
+ RLM->>Sandbox: Execute code (with timeout)
184
+ Sandbox-->>RLM: { result, logs, error }
185
+ Note over RLM: Append output to history
186
+ end
187
+
188
+ RLM-->>User: Final answer
189
+ ```
190
+
191
+ ### Components
192
+
193
+ | Component | Purpose |
194
+ |-----------|---------|
195
+ | **RLM Engine** | Orchestrates the turn loop, builds prompts, extracts answers |
196
+ | **Sandbox** | Isolated VM executing LLM-generated JavaScript with timeout protection |
197
+ | **Tools** | `text_stats()`, `fuzzy_search()`, `llm_query()` available in sandbox |
198
+ | **Memory** | Persistent array for accumulating findings across turns |
199
+
200
+ ### How It Works
201
+
202
+ 1. Document loads into sandbox as read-only `context` variable
203
+ 2. LLM receives system prompt with available tools and writes JavaScript
204
+ 3. Code executes in sandbox, results feed back to LLM
205
+ 4. LLM iterates until it outputs `<<<FINAL>>>answer<<<END>>>`
206
+ 5. Sub-queries via `llm_query()` enable recursive decomposition
207
+
208
+ ### Sandbox Tools
209
+
210
+ The LLM has access to these tools when exploring documents:
211
+
212
+ | Tool | Description |
213
+ |------|-------------|
214
+ | `text_stats()` | Returns document metadata: length, line count, samples from start/middle/end |
215
+ | `fuzzy_search(query, limit?)` | Finds approximate matches, returns lines with scores |
216
+ | `llm_query(prompt)` | Spawns a sub-LLM call for complex analysis (limited by `maxSubCalls`) |
217
+ | `context` | The full document text (read-only string) |
218
+ | `memory` | Persistent array to accumulate findings across turns |
219
+
220
+ ### Safety
221
+
222
+ - Sandbox isolates code execution (no filesystem, network, or process access)
223
+ - Configurable timeout per turn
224
+ - `maxSubCalls` limit prevents infinite recursion
225
+ - Sub-LLM calls receive only the prompt, never parent context
226
+ - Auto-fixes common syntax errors in LLM-generated code
227
+
228
+ ## Troubleshooting
229
+
230
+ ### Model Answers Immediately Without Exploring
231
+
232
+ **Symptom**: The model provides an answer on the first turn without running any code, often with hallucinated data.
233
+
234
+ **Cause**: Smaller or less capable models may not follow the instruction to explore via code before answering.
235
+
236
+ **Solutions**:
237
+
238
+ 1. **Use a more capable model** - Models like `deepseek-chat` or larger Ollama models follow instructions better
239
+ 2. **Make your query more specific** - Instead of vague queries, be explicit:
240
+ ```bash
241
+ # Vague (may cause hallucination)
242
+ rlm "What are the sales figures?" ./report.txt
243
+
244
+ # Specific (guides exploration)
245
+ rlm "Search for SALES_DATA entries and sum the dollar amounts" ./report.txt
246
+ ```
247
+ 3. **Include data patterns in your query** - If you know how data is formatted, mention it:
248
+ ```bash
249
+ rlm "Find lines matching 'Total:' and extract the numbers" ./data.txt
250
+ ```
251
+
252
+ ### Max Turns Reached Without Answer
253
+
254
+ **Symptom**: Output shows "Max turns (N) reached without final answer"
255
+
256
+ **Cause**: The model keeps exploring but never terminates properly.
257
+
258
+ **Solutions**:
259
+
260
+ 1. Increase `--max-turns` for complex documents
261
+ 2. Check if the model is stuck in a loop (`--verbose` shows repeated patterns)
262
+ 3. Simplify the query to require less exploration
263
+
264
+ ### Sandbox Execution Errors
265
+
266
+ **Symptom**: Repeated "Error: Unexpected token" or similar JavaScript errors
267
+
268
+ **Cause**: The model is generating invalid JavaScript code.
269
+
270
+ **Solutions**:
271
+
272
+ 1. The system auto-fixes common issues (missing semicolons, TypeScript syntax)
273
+ 2. If errors persist, try a different model - some are better at generating valid code
274
+ 3. Use `--verbose` to see what code the model is generating
275
+
276
+ ## Development
277
+
278
+ ```bash
279
+ # Run tests
280
+ npm test
281
+
282
+ # Run with coverage
283
+ npm test -- --coverage
284
+
285
+ # E2E tests (requires Ollama running locally)
286
+ RUN_E2E=1 npm test -- --run tests/e2e.test.ts
287
+
288
+ # Build
289
+ npm run build
290
+
291
+ # Type check
292
+ npm run typecheck
293
+ ```
294
+
295
+ ## License
296
+
297
+ MIT
298
+
299
+ ## References
300
+
301
+ - [RLM Paper](https://arxiv.org/abs/2512.24601)
302
+ - [Original Implementation](https://github.com/alexzhang13/rlm)
303
+ - [Model Context Protocol](https://modelcontextprotocol.io/)
@@ -0,0 +1,31 @@
1
+ {
2
+ "llm": {
3
+ "provider": "ollama"
4
+ },
5
+ "providers": {
6
+ "ollama": {
7
+ "baseUrl": "http://localhost:11434",
8
+ "model": "qwen3-coder:30b",
9
+ "options": {
10
+ "temperature": 0.2,
11
+ "num_ctx": 8192
12
+ }
13
+ },
14
+ "deepseek": {
15
+ "baseUrl": "https://api.deepseek.com",
16
+ "apiKey": "${DEEPSEEK_API_KEY}",
17
+ "model": "deepseek-chat",
18
+ "options": {
19
+ "temperature": 0.2
20
+ }
21
+ }
22
+ },
23
+ "sandbox": {
24
+ "maxSubCalls": 10,
25
+ "turnTimeoutMs": 30000,
26
+ "memoryLimitMb": 128
27
+ },
28
+ "rlm": {
29
+ "maxTurns": 10
30
+ }
31
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Lightweight code fixer for common LLM-generated syntax errors
3
+ * Attempts to fix issues before sandbox execution to minimize retries
4
+ */
5
+ export interface FixResult {
6
+ code: string;
7
+ fixed: boolean;
8
+ fixes: string[];
9
+ }
10
+ /**
11
+ * Check if code has valid syntax
12
+ */
13
+ export declare function checkSyntax(code: string): {
14
+ valid: boolean;
15
+ error?: string;
16
+ };
17
+ /**
18
+ * Apply common fixes to code
19
+ */
20
+ export declare function fixCode(code: string): FixResult;
21
+ /**
22
+ * Attempt to fix code and return result
23
+ * Returns original code if fixes don't help
24
+ */
25
+ export declare function tryFixCode(code: string): FixResult;
26
+ //# sourceMappingURL=code-fixer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-fixer.d.ts","sourceRoot":"","sources":["../src/code-fixer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2FH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAS5E;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CA+G/C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CASlD"}
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Lightweight code fixer for common LLM-generated syntax errors
3
+ * Attempts to fix issues before sandbox execution to minimize retries
4
+ */
5
+ import vm from "node:vm";
6
+ /**
7
+ * Remove a block with balanced braces starting at a given position
8
+ * Returns the end index (exclusive) of the block, or -1 if not found
9
+ */
10
+ function findBalancedBraceEnd(code, startIndex) {
11
+ let depth = 0;
12
+ let inString = false;
13
+ let stringChar = "";
14
+ for (let i = startIndex; i < code.length; i++) {
15
+ const char = code[i];
16
+ const prevChar = i > 0 ? code[i - 1] : "";
17
+ // Handle string literals (skip brace counting inside strings)
18
+ if ((char === '"' || char === "'" || char === "`") && prevChar !== "\\") {
19
+ if (!inString) {
20
+ inString = true;
21
+ stringChar = char;
22
+ }
23
+ else if (char === stringChar) {
24
+ inString = false;
25
+ }
26
+ continue;
27
+ }
28
+ if (inString)
29
+ continue;
30
+ if (char === "{") {
31
+ depth++;
32
+ }
33
+ else if (char === "}") {
34
+ depth--;
35
+ if (depth === 0) {
36
+ return i + 1; // Return position after closing brace
37
+ }
38
+ }
39
+ }
40
+ return -1; // Unbalanced
41
+ }
42
+ /**
43
+ * Remove TypeScript interface/type declarations with proper brace matching
44
+ */
45
+ function removeTypeDeclarations(code) {
46
+ let result = code;
47
+ let removed = false;
48
+ // Match interface/type declarations and remove them with balanced braces
49
+ const declarationPattern = /^(interface|type)\s+\w+\s*(\{|=)/gm;
50
+ let match;
51
+ while ((match = declarationPattern.exec(result)) !== null) {
52
+ const startIndex = match.index;
53
+ const matchText = match[0];
54
+ if (matchText.endsWith("{")) {
55
+ // Interface with braces - find the balanced end
56
+ const braceStart = match.index + matchText.length - 1;
57
+ const endIndex = findBalancedBraceEnd(result, braceStart);
58
+ if (endIndex !== -1) {
59
+ // Remove the entire declaration including trailing whitespace/newline
60
+ let removeEnd = endIndex;
61
+ while (removeEnd < result.length && /[\s;]/.test(result[removeEnd])) {
62
+ removeEnd++;
63
+ }
64
+ result = result.slice(0, startIndex) + result.slice(removeEnd);
65
+ removed = true;
66
+ declarationPattern.lastIndex = startIndex; // Reset to check from same position
67
+ }
68
+ }
69
+ else {
70
+ // Type alias with = (e.g., type Foo = string;)
71
+ const semicolonIndex = result.indexOf(";", match.index);
72
+ if (semicolonIndex !== -1) {
73
+ let removeEnd = semicolonIndex + 1;
74
+ while (removeEnd < result.length && result[removeEnd] === "\n") {
75
+ removeEnd++;
76
+ }
77
+ result = result.slice(0, startIndex) + result.slice(removeEnd);
78
+ removed = true;
79
+ declarationPattern.lastIndex = startIndex;
80
+ }
81
+ }
82
+ }
83
+ return { code: result, removed };
84
+ }
85
+ /**
86
+ * Check if code has valid syntax
87
+ */
88
+ export function checkSyntax(code) {
89
+ try {
90
+ // Wrap in async IIFE like sandbox does
91
+ const wrapped = `(async () => { ${code} })()`;
92
+ new vm.Script(wrapped);
93
+ return { valid: true };
94
+ }
95
+ catch (err) {
96
+ return { valid: false, error: err.message };
97
+ }
98
+ }
99
+ /**
100
+ * Apply common fixes to code
101
+ */
102
+ export function fixCode(code) {
103
+ const fixes = [];
104
+ let fixedCode = code;
105
+ // ALWAYS remove imports/requires/exports first - they will fail at runtime in sandbox
106
+ // Do this even for syntactically valid code
107
+ // Remove import statements
108
+ const beforeImport = fixedCode;
109
+ fixedCode = fixedCode.replace(/^import\s+.*?from\s+['"].*?['"];?\s*\n?/gm, "");
110
+ if (fixedCode !== beforeImport) {
111
+ fixes.push("Removed import statements");
112
+ }
113
+ const beforeRequire = fixedCode;
114
+ fixedCode = fixedCode.replace(/^const\s+\w+\s*=\s*require\s*\(['"].*?['"]\);?\s*\n?/gm, "");
115
+ if (fixedCode !== beforeRequire) {
116
+ fixes.push("Removed require statements");
117
+ }
118
+ // Remove export statements
119
+ const beforeExport = fixedCode;
120
+ fixedCode = fixedCode.replace(/^export\s+(default\s+)?/gm, "");
121
+ if (fixedCode !== beforeExport) {
122
+ fixes.push("Removed export statements");
123
+ }
124
+ // If we made changes for runtime compatibility, check if code is now valid
125
+ if (fixes.length > 0) {
126
+ const afterRuntimeFixes = checkSyntax(fixedCode);
127
+ if (afterRuntimeFixes.valid) {
128
+ return { code: fixedCode, fixed: true, fixes };
129
+ }
130
+ }
131
+ // Check if original code (after runtime fixes) is already syntactically valid
132
+ const initial = checkSyntax(fixedCode);
133
+ if (initial.valid) {
134
+ // No further fixes needed
135
+ if (fixes.length > 0) {
136
+ return { code: fixedCode, fixed: true, fixes };
137
+ }
138
+ return { code: fixedCode, fixed: false, fixes: [] };
139
+ }
140
+ // Code has syntax errors - apply additional fixes
141
+ // Fix: Fix common template literal issues (unescaped backticks)
142
+ // This is tricky - skip for now
143
+ // Fix: Remove TypeScript type annotations that might cause issues
144
+ // Simple cases: `: string`, `: number`, `: any`, etc.
145
+ const beforeTypes = fixedCode;
146
+ fixedCode = fixedCode.replace(/:\s*(string|number|boolean|any|void|unknown|object|never)(\[\])?\s*([=,)\]}]|$)/g, "$3");
147
+ if (fixedCode !== beforeTypes) {
148
+ fixes.push("Removed TypeScript type annotations");
149
+ }
150
+ // Fix 5: Fix interface/type declarations (not valid JS) - with proper brace matching
151
+ const typeRemoval = removeTypeDeclarations(fixedCode);
152
+ if (typeRemoval.removed) {
153
+ fixedCode = typeRemoval.code;
154
+ fixes.push("Removed TypeScript interface/type declarations");
155
+ }
156
+ // Fix 6: Add missing semicolons after common patterns
157
+ // After closing braces that aren't part of control flow
158
+ fixedCode = fixedCode.replace(/\}(\s*)(const|let|var|function|class|if|for|while|switch|return|throw|console|memory|await)/g, "};\n$2");
159
+ // Fix 7: Remove trailing commas in function calls (less common issue)
160
+ fixedCode = fixedCode.replace(/,(\s*)\)/g, "$1)");
161
+ fixedCode = fixedCode.replace(/,(\s*)\]/g, "$1]");
162
+ // Check if fixes helped
163
+ const afterFixes = checkSyntax(fixedCode);
164
+ if (afterFixes.valid) {
165
+ if (fixes.length === 0)
166
+ fixes.push("Applied automatic syntax fixes");
167
+ return { code: fixedCode, fixed: true, fixes };
168
+ }
169
+ // If still invalid, try more aggressive fixes
170
+ // Fix 8: Balance brackets/braces
171
+ const openBraces = (fixedCode.match(/\{/g) || []).length;
172
+ const closeBraces = (fixedCode.match(/\}/g) || []).length;
173
+ if (openBraces > closeBraces) {
174
+ fixedCode += "\n" + "}".repeat(openBraces - closeBraces);
175
+ fixes.push(`Added ${openBraces - closeBraces} missing closing brace(s)`);
176
+ }
177
+ const openParens = (fixedCode.match(/\(/g) || []).length;
178
+ const closeParens = (fixedCode.match(/\)/g) || []).length;
179
+ if (openParens > closeParens) {
180
+ fixedCode += ")".repeat(openParens - closeParens);
181
+ fixes.push(`Added ${openParens - closeParens} missing closing paren(s)`);
182
+ }
183
+ const openBrackets = (fixedCode.match(/\[/g) || []).length;
184
+ const closeBrackets = (fixedCode.match(/\]/g) || []).length;
185
+ if (openBrackets > closeBrackets) {
186
+ fixedCode += "]".repeat(openBrackets - closeBrackets);
187
+ fixes.push(`Added ${openBrackets - closeBrackets} missing closing bracket(s)`);
188
+ }
189
+ // Final check
190
+ const finalCheck = checkSyntax(fixedCode);
191
+ return {
192
+ code: fixedCode,
193
+ fixed: finalCheck.valid && fixes.length > 0,
194
+ fixes: finalCheck.valid ? fixes : [],
195
+ };
196
+ }
197
+ /**
198
+ * Attempt to fix code and return result
199
+ * Returns original code if fixes don't help
200
+ */
201
+ export function tryFixCode(code) {
202
+ const result = fixCode(code);
203
+ // If fixes didn't make it valid, return original
204
+ if (!result.fixed && !checkSyntax(code).valid && !checkSyntax(result.code).valid) {
205
+ return { code, fixed: false, fixes: [] };
206
+ }
207
+ return result;
208
+ }
209
+ //# sourceMappingURL=code-fixer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-fixer.js","sourceRoot":"","sources":["../src/code-fixer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Configuration file types
3
+ *
4
+ * Note: These types mirror some types in llm/types.ts but serve different purposes:
5
+ * - These types represent the JSON config file structure (fields may be optional)
6
+ * - llm/types.ts types represent runtime API contracts (required fields for operation)
7
+ */
8
+ export interface LLMOptions {
9
+ temperature?: number;
10
+ num_ctx?: number;
11
+ max_tokens?: number;
12
+ }
13
+ export interface LLMConfig {
14
+ provider: string;
15
+ model?: string;
16
+ options?: LLMOptions;
17
+ }
18
+ export interface ProviderConfig {
19
+ baseUrl: string;
20
+ apiKey?: string;
21
+ model?: string;
22
+ options?: LLMOptions;
23
+ }
24
+ export interface SandboxConfig {
25
+ maxSubCalls: number;
26
+ turnTimeoutMs: number;
27
+ memoryLimitMb: number;
28
+ }
29
+ export interface RLMConfig {
30
+ maxTurns: number;
31
+ }
32
+ export interface Config {
33
+ llm: LLMConfig;
34
+ providers: Record<string, ProviderConfig>;
35
+ sandbox: SandboxConfig;
36
+ rlm: RLMConfig;
37
+ }
38
+ export declare function loadConfig(configPath?: string): Promise<Config>;
39
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AAEH,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,SAAS,CAAC;IACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,OAAO,EAAE,aAAa,CAAC;IACvB,GAAG,EAAE,SAAS,CAAC;CAChB;AA0BD,wBAAsB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBrE"}