recursive-llm-ts 5.0.2 → 5.1.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.
- package/README.md +2 -12
- package/dist/bridge-factory.d.ts +5 -4
- package/dist/bridge-factory.js +8 -70
- package/dist/bridge-interface.d.ts +1 -2
- package/dist/config.js +0 -6
- package/dist/coordinator.js +1 -1
- package/dist/go-bridge.d.ts +2 -2
- package/dist/go-bridge.js +1 -1
- package/dist/rlm.d.ts +1 -1
- package/dist/rlm.js +3 -3
- package/package.json +16 -1
- package/scripts/build-go-binary.js +18 -5
- package/dist/bunpy-bridge.d.ts +0 -7
- package/dist/bunpy-bridge.js +0 -37
- package/dist/rlm-bridge.d.ts +0 -8
- package/dist/rlm-bridge.js +0 -179
package/README.md
CHANGED
|
@@ -44,11 +44,8 @@ npm install recursive-llm-ts
|
|
|
44
44
|
|
|
45
45
|
### Prerequisites
|
|
46
46
|
|
|
47
|
-
- **Node.js 16+**
|
|
47
|
+
- **Node.js 16+**
|
|
48
48
|
- **Go 1.25+** (for building from source during install)
|
|
49
|
-
|
|
50
|
-
> **Note**: The package includes pre-built binaries for common platforms. Go is only needed if building from source.
|
|
51
|
-
|
|
52
49
|
### Go Binary (Automatic)
|
|
53
50
|
|
|
54
51
|
The `postinstall` script automatically builds the Go binary during installation. If Go is not available, the script will warn but not fail.
|
|
@@ -72,13 +69,11 @@ export RLM_GO_BINARY=/custom/path/to/rlm-go
|
|
|
72
69
|
|
|
73
70
|
## Usage
|
|
74
71
|
|
|
75
|
-
###
|
|
76
|
-
|
|
72
|
+
### Quick Start
|
|
77
73
|
```typescript
|
|
78
74
|
import { RLM } from 'recursive-llm-ts';
|
|
79
75
|
|
|
80
76
|
// Initialize RLM with a model
|
|
81
|
-
// Automatically detects Node.js or Bun and uses appropriate bridge
|
|
82
77
|
const rlm = new RLM('gpt-4o-mini', {
|
|
83
78
|
max_iterations: 15,
|
|
84
79
|
api_key: process.env.OPENAI_API_KEY
|
|
@@ -420,9 +415,6 @@ const rlmGo = new RLM('gpt-4o-mini', {
|
|
|
420
415
|
api_key: process.env.OPENAI_API_KEY
|
|
421
416
|
}, 'go');
|
|
422
417
|
|
|
423
|
-
// Legacy: Use Python bridges (bunpy for Bun, pythonia for Node)
|
|
424
|
-
// Note: Requires separate Python dependencies
|
|
425
|
-
const rlmPython = new RLM('gpt-4o-mini', {}, 'bunpy');
|
|
426
418
|
```
|
|
427
419
|
|
|
428
420
|
|
|
@@ -781,7 +773,6 @@ interface RLMConfig {
|
|
|
781
773
|
// Execution limits
|
|
782
774
|
max_depth?: number; // Maximum recursion depth (default: 5)
|
|
783
775
|
max_iterations?: number; // Maximum REPL iterations per call (default: 30)
|
|
784
|
-
pythonia_timeout?: number; // Python bridge timeout in ms (default: 100000ms = 100s)
|
|
785
776
|
go_binary_path?: string; // Override path for Go binary (optional)
|
|
786
777
|
|
|
787
778
|
// Meta-agent configuration
|
|
@@ -1005,7 +996,6 @@ For large documents or queue-based processing that may take longer than the defa
|
|
|
1005
996
|
```typescript
|
|
1006
997
|
const rlm = new RLM('gpt-4o-mini', {
|
|
1007
998
|
max_iterations: 50, // Allow more iterations for complex processing
|
|
1008
|
-
pythonia_timeout: 600000, // 10 minutes timeout for Python bridge
|
|
1009
999
|
timeout: 300 // 5 minutes timeout for LLM API calls
|
|
1010
1000
|
});
|
|
1011
1001
|
|
package/dist/bridge-factory.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type BridgeType = 'go'
|
|
1
|
+
import { Bridge } from './bridge-interface';
|
|
2
|
+
export type BridgeType = 'go';
|
|
3
3
|
/**
|
|
4
|
-
* Create
|
|
4
|
+
* Create the Go bridge for RLM communication.
|
|
5
|
+
* Throws if the Go binary is not available.
|
|
5
6
|
*/
|
|
6
|
-
export declare function createBridge(bridgeType?: BridgeType): Promise<
|
|
7
|
+
export declare function createBridge(bridgeType?: BridgeType): Promise<Bridge>;
|
package/dist/bridge-factory.js
CHANGED
|
@@ -57,78 +57,16 @@ function isGoBinaryAvailable() {
|
|
|
57
57
|
return fs.existsSync(resolveDefaultGoBinary());
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
61
|
-
|
|
62
|
-
function detectRuntime() {
|
|
63
|
-
// Check for Bun
|
|
64
|
-
if (typeof globalThis.Bun !== 'undefined') {
|
|
65
|
-
return 'bun';
|
|
66
|
-
}
|
|
67
|
-
// Check for Node.js
|
|
68
|
-
if (typeof process !== 'undefined' && process.versions && process.versions.node) {
|
|
69
|
-
return 'node';
|
|
70
|
-
}
|
|
71
|
-
return 'unknown';
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Create appropriate Python bridge based on runtime or explicit choice
|
|
60
|
+
* Create the Go bridge for RLM communication.
|
|
61
|
+
* Throws if the Go binary is not available.
|
|
75
62
|
*/
|
|
76
63
|
function createBridge() {
|
|
77
|
-
return __awaiter(this, arguments, void 0, function* (bridgeType = '
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
selectedBridge = 'go';
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
const runtime = detectRuntime();
|
|
85
|
-
if (runtime === 'bun') {
|
|
86
|
-
selectedBridge = 'bunpy';
|
|
87
|
-
}
|
|
88
|
-
else if (runtime === 'node') {
|
|
89
|
-
selectedBridge = 'pythonia';
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
throw new Error('Unable to detect runtime. Please explicitly specify bridge type.\n' +
|
|
93
|
-
'Supported runtimes: Go binary, Node.js (pythonia), or Bun (bunpy)');
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
selectedBridge = bridgeType;
|
|
99
|
-
}
|
|
100
|
-
if (selectedBridge === 'go') {
|
|
101
|
-
const { GoBridge } = yield Promise.resolve().then(() => __importStar(require('./go-bridge')));
|
|
102
|
-
return new GoBridge();
|
|
103
|
-
}
|
|
104
|
-
if (selectedBridge === 'bunpy') {
|
|
105
|
-
try {
|
|
106
|
-
const { BunpyBridge } = yield Promise.resolve().then(() => __importStar(require('./bunpy-bridge')));
|
|
107
|
-
return new BunpyBridge();
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
const errorMsg = (error === null || error === void 0 ? void 0 : error.code) === 'MODULE_NOT_FOUND'
|
|
111
|
-
? 'bunpy bridge not available (Python dependencies removed in v3.0)'
|
|
112
|
-
: error.message;
|
|
113
|
-
if (bridgeType === 'auto') {
|
|
114
|
-
console.warn(`[recursive-llm-ts] ${errorMsg}, falling back to pythonia`);
|
|
115
|
-
selectedBridge = 'pythonia';
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
throw new Error(`${errorMsg}. Use 'go' bridge instead (default in v3.0).`);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
if (selectedBridge === 'pythonia') {
|
|
123
|
-
try {
|
|
124
|
-
const { PythoniaBridge } = yield Promise.resolve().then(() => __importStar(require('./rlm-bridge')));
|
|
125
|
-
return new PythoniaBridge();
|
|
126
|
-
}
|
|
127
|
-
catch (error) {
|
|
128
|
-
throw new Error('pythonia bridge not available (Python dependencies removed in v3.0). ' +
|
|
129
|
-
'Use the Go bridge instead (default) or install bunpy/pythonia separately.');
|
|
130
|
-
}
|
|
64
|
+
return __awaiter(this, arguments, void 0, function* (bridgeType = 'go') {
|
|
65
|
+
if (!isGoBinaryAvailable()) {
|
|
66
|
+
throw new Error('Go RLM binary not found. Build it with: node scripts/build-go-binary.js\n' +
|
|
67
|
+
'Ensure Go 1.25+ is installed: https://go.dev/dl/');
|
|
131
68
|
}
|
|
132
|
-
|
|
69
|
+
const { GoBridge } = yield Promise.resolve().then(() => __importStar(require('./go-bridge')));
|
|
70
|
+
return new GoBridge();
|
|
133
71
|
});
|
|
134
72
|
}
|
|
@@ -205,7 +205,6 @@ export interface RLMConfig {
|
|
|
205
205
|
api_key?: string;
|
|
206
206
|
max_depth?: number;
|
|
207
207
|
max_iterations?: number;
|
|
208
|
-
pythonia_timeout?: number;
|
|
209
208
|
go_binary_path?: string;
|
|
210
209
|
meta_agent?: MetaAgentConfig;
|
|
211
210
|
observability?: ObservabilityConfig;
|
|
@@ -264,7 +263,7 @@ export interface FileStorageConfig {
|
|
|
264
263
|
/** File extensions to include (e.g. ['.ts', '.md', '.txt']) */
|
|
265
264
|
extensions?: string[];
|
|
266
265
|
}
|
|
267
|
-
export interface
|
|
266
|
+
export interface Bridge {
|
|
268
267
|
completion(model: string, query: string, context: string, rlmConfig: RLMConfig): Promise<RLMResult>;
|
|
269
268
|
cleanup(): Promise<void>;
|
|
270
269
|
}
|
package/dist/config.js
CHANGED
|
@@ -15,7 +15,6 @@ const KNOWN_CONFIG_KEYS = new Set([
|
|
|
15
15
|
'api_key',
|
|
16
16
|
'max_depth',
|
|
17
17
|
'max_iterations',
|
|
18
|
-
'pythonia_timeout',
|
|
19
18
|
'go_binary_path',
|
|
20
19
|
'meta_agent',
|
|
21
20
|
'observability',
|
|
@@ -58,11 +57,6 @@ function validateConfig(config) {
|
|
|
58
57
|
issues.push({ level: 'error', field: 'max_iterations', message: 'max_iterations must be a positive integer' });
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
|
-
if (config.pythonia_timeout !== undefined) {
|
|
62
|
-
if (typeof config.pythonia_timeout !== 'number' || config.pythonia_timeout < 0) {
|
|
63
|
-
issues.push({ level: 'error', field: 'pythonia_timeout', message: 'pythonia_timeout must be a non-negative number (milliseconds)' });
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
60
|
// Validate API base URL
|
|
67
61
|
if (config.api_base !== undefined && typeof config.api_base === 'string') {
|
|
68
62
|
try {
|
package/dist/coordinator.js
CHANGED
|
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.RLMAgentCoordinator = void 0;
|
|
13
13
|
const rlm_1 = require("./rlm");
|
|
14
14
|
class RLMAgentCoordinator {
|
|
15
|
-
constructor(model, rlmConfig = {}, bridgeType = '
|
|
15
|
+
constructor(model, rlmConfig = {}, bridgeType = 'go', coordinatorConfig = {}) {
|
|
16
16
|
var _a, _b, _c;
|
|
17
17
|
this.rlm = new rlm_1.RLM(model, rlmConfig, bridgeType);
|
|
18
18
|
this.config = {
|
package/dist/go-bridge.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare class GoBridge implements
|
|
1
|
+
import { Bridge, RLMConfig, RLMResult } from './bridge-interface';
|
|
2
|
+
export declare class GoBridge implements Bridge {
|
|
3
3
|
completion(model: string, query: string, context: string, rlmConfig?: RLMConfig): Promise<RLMResult>;
|
|
4
4
|
cleanup(): Promise<void>;
|
|
5
5
|
}
|
package/dist/go-bridge.js
CHANGED
|
@@ -82,7 +82,7 @@ function assertBinaryExists(binaryPath) {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
function sanitizeConfig(config) {
|
|
85
|
-
const {
|
|
85
|
+
const { go_binary_path, structured } = config, sanitized = __rest(config, ["go_binary_path", "structured"]);
|
|
86
86
|
return { config: sanitized, structured };
|
|
87
87
|
}
|
|
88
88
|
class GoBridge {
|
package/dist/rlm.d.ts
CHANGED
|
@@ -111,7 +111,7 @@ export declare class RLM {
|
|
|
111
111
|
*
|
|
112
112
|
* @param model - The LLM model identifier (e.g., 'gpt-4o-mini', 'claude-sonnet-4-20250514')
|
|
113
113
|
* @param rlmConfig - Configuration options for the RLM engine
|
|
114
|
-
* @param bridgeType - Bridge selection: '
|
|
114
|
+
* @param bridgeType - Bridge selection: 'go' (default)
|
|
115
115
|
*
|
|
116
116
|
* @example
|
|
117
117
|
* ```typescript
|
package/dist/rlm.js
CHANGED
|
@@ -119,7 +119,7 @@ exports.RLMResultFormatter = RLMResultFormatter;
|
|
|
119
119
|
class RLMBuilder {
|
|
120
120
|
constructor(model) {
|
|
121
121
|
this.config = {};
|
|
122
|
-
this.bridgeType = '
|
|
122
|
+
this.bridgeType = 'go';
|
|
123
123
|
this.model = model;
|
|
124
124
|
}
|
|
125
125
|
/** Set the API key */
|
|
@@ -208,7 +208,7 @@ class RLM {
|
|
|
208
208
|
*
|
|
209
209
|
* @param model - The LLM model identifier (e.g., 'gpt-4o-mini', 'claude-sonnet-4-20250514')
|
|
210
210
|
* @param rlmConfig - Configuration options for the RLM engine
|
|
211
|
-
* @param bridgeType - Bridge selection: '
|
|
211
|
+
* @param bridgeType - Bridge selection: 'go' (default)
|
|
212
212
|
*
|
|
213
213
|
* @example
|
|
214
214
|
* ```typescript
|
|
@@ -220,7 +220,7 @@ class RLM {
|
|
|
220
220
|
* });
|
|
221
221
|
* ```
|
|
222
222
|
*/
|
|
223
|
-
constructor(model, rlmConfig = {}, bridgeType = '
|
|
223
|
+
constructor(model, rlmConfig = {}, bridgeType = 'go') {
|
|
224
224
|
this.bridge = null;
|
|
225
225
|
this.lastTraceEvents = [];
|
|
226
226
|
this.model = model;
|
package/package.json
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "recursive-llm-ts",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.1",
|
|
4
4
|
"description": "TypeScript bridge for recursive-llm: Recursive Language Models for unbounded context processing with structured outputs",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"require": "./dist/index.js",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
7
14
|
"files": [
|
|
8
15
|
"dist",
|
|
9
16
|
"go/cmd",
|
|
@@ -66,5 +73,13 @@
|
|
|
66
73
|
"ts-node": "^10.9.2",
|
|
67
74
|
"typescript": "^5.3.3",
|
|
68
75
|
"vitest": "^4.0.18"
|
|
76
|
+
},
|
|
77
|
+
"peerDependencies": {
|
|
78
|
+
"@aws-sdk/client-s3": "^3.0.0"
|
|
79
|
+
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"@aws-sdk/client-s3": {
|
|
82
|
+
"optional": true
|
|
83
|
+
}
|
|
69
84
|
}
|
|
70
85
|
}
|
|
@@ -19,21 +19,34 @@ function goAvailable() {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
if (!fs.existsSync(goRoot)) {
|
|
22
|
-
|
|
22
|
+
// No Go source — this is fine for pre-built binary installs
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (fs.existsSync(binaryPath)) {
|
|
27
|
+
console.log('[recursive-llm-ts] ✓ Go binary already exists at ' + binaryPath);
|
|
23
28
|
process.exit(0);
|
|
24
29
|
}
|
|
25
30
|
|
|
26
31
|
if (!goAvailable()) {
|
|
27
|
-
console.warn('
|
|
28
|
-
console.warn('
|
|
32
|
+
console.warn('');
|
|
33
|
+
console.warn('╔══════════════════════════════════════════════════════════════════╗');
|
|
34
|
+
console.warn('║ recursive-llm-ts: Go binary could not be built ║');
|
|
35
|
+
console.warn('║ ║');
|
|
36
|
+
console.warn('║ Go 1.25+ is required to compile the backend binary. ║');
|
|
37
|
+
console.warn('║ Without it, all RLM operations will fail at runtime. ║');
|
|
38
|
+
console.warn('║ ║');
|
|
39
|
+
console.warn('║ Install Go: https://go.dev/dl/ ║');
|
|
40
|
+
console.warn('║ Then run: node scripts/build-go-binary.js ║');
|
|
41
|
+
console.warn('╚══════════════════════════════════════════════════════════════════╝');
|
|
42
|
+
console.warn('');
|
|
29
43
|
process.exit(0);
|
|
30
44
|
}
|
|
31
45
|
|
|
32
46
|
try {
|
|
33
47
|
fs.mkdirSync(binDir, { recursive: true });
|
|
34
|
-
// Build with optimization: -s removes symbol table, -w removes DWARF debug info
|
|
35
48
|
execFileSync('go', ['build', '-ldflags=-s -w', '-o', binaryPath, './cmd/rlm'], { stdio: 'inherit', cwd: goRoot });
|
|
36
|
-
console.log(
|
|
49
|
+
console.log('[recursive-llm-ts] ✓ Go binary built at ' + binaryPath);
|
|
37
50
|
} catch (error) {
|
|
38
51
|
console.warn('[recursive-llm-ts] Warning: Failed to build Go binary');
|
|
39
52
|
console.warn(error.message || error);
|
package/dist/bunpy-bridge.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { PythonBridge, RLMConfig, RLMResult } from './bridge-interface';
|
|
2
|
-
export declare class BunpyBridge implements PythonBridge {
|
|
3
|
-
constructor();
|
|
4
|
-
initialize(_model: string, _config: RLMConfig): Promise<void>;
|
|
5
|
-
completion(_query: string, _context: string): Promise<RLMResult>;
|
|
6
|
-
cleanup(): Promise<void>;
|
|
7
|
-
}
|
package/dist/bunpy-bridge.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Stub file for bunpy bridge (removed in v3.0)
|
|
3
|
-
// Python dependencies are no longer included by default
|
|
4
|
-
// To use bunpy bridge, install: npm install bunpy
|
|
5
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.BunpyBridge = void 0;
|
|
16
|
-
class BunpyBridge {
|
|
17
|
-
constructor() {
|
|
18
|
-
throw new Error('bunpy bridge is not available (Python dependencies removed in v3.0). ' +
|
|
19
|
-
'Please use the Go bridge (default) or install bunpy separately: npm install bunpy');
|
|
20
|
-
}
|
|
21
|
-
initialize(_model, _config) {
|
|
22
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
-
throw new Error('bunpy bridge not available');
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
completion(_query, _context) {
|
|
27
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
-
throw new Error('bunpy bridge not available');
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
cleanup() {
|
|
32
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
-
// No-op
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
exports.BunpyBridge = BunpyBridge;
|
package/dist/rlm-bridge.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { PythonBridge, RLMConfig, RLMResult } from './bridge-interface';
|
|
2
|
-
export declare class PythoniaBridge implements PythonBridge {
|
|
3
|
-
private rlmModule;
|
|
4
|
-
private python;
|
|
5
|
-
private ensureRLMModule;
|
|
6
|
-
completion(model: string, query: string, context: string, rlmConfig?: RLMConfig): Promise<RLMResult>;
|
|
7
|
-
cleanup(): Promise<void>;
|
|
8
|
-
}
|
package/dist/rlm-bridge.js
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
45
|
-
var t = {};
|
|
46
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
47
|
-
t[p] = s[p];
|
|
48
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
49
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
50
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
51
|
-
t[p[i]] = s[p[i]];
|
|
52
|
-
}
|
|
53
|
-
return t;
|
|
54
|
-
};
|
|
55
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
56
|
-
exports.PythoniaBridge = void 0;
|
|
57
|
-
const path = __importStar(require("path"));
|
|
58
|
-
const fs = __importStar(require("fs"));
|
|
59
|
-
class PythoniaBridge {
|
|
60
|
-
constructor() {
|
|
61
|
-
this.rlmModule = null;
|
|
62
|
-
this.python = null;
|
|
63
|
-
}
|
|
64
|
-
ensureRLMModule() {
|
|
65
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
-
var _a;
|
|
67
|
-
if (this.rlmModule)
|
|
68
|
-
return;
|
|
69
|
-
// Lazy load pythonia to avoid errors in Bun environments
|
|
70
|
-
if (!this.python) {
|
|
71
|
-
try {
|
|
72
|
-
// @ts-ignore - Optional dependency, may not be installed
|
|
73
|
-
const pythonia = yield Promise.resolve().then(() => __importStar(require('pythonia')));
|
|
74
|
-
this.python = pythonia.python;
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
throw new Error('pythonia is not available (Python dependencies removed in v3.0). ' +
|
|
78
|
-
'Please use the Go bridge (default) or install pythonia separately: npm install pythonia\n' +
|
|
79
|
-
'Note: pythonia only works with Node.js runtime, not Bun');
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
const pythonPackagePath = path.join(__dirname, '..', 'recursive-llm');
|
|
83
|
-
// Import sys module to add path
|
|
84
|
-
const sys = yield this.python('sys');
|
|
85
|
-
const pythonExecutable = String((yield sys.executable) || 'python');
|
|
86
|
-
const pythonCmd = pythonExecutable.includes(' ') ? `"${pythonExecutable}"` : pythonExecutable;
|
|
87
|
-
const pipCmd = `${pythonCmd} -m pip install -e "${pythonPackagePath}"`;
|
|
88
|
-
const pythonDepsPath = path.join(pythonPackagePath, '.pydeps');
|
|
89
|
-
const pyprojectPath = path.join(pythonPackagePath, 'pyproject.toml');
|
|
90
|
-
const dependencySpecifiers = (() => {
|
|
91
|
-
try {
|
|
92
|
-
const pyproject = fs.readFileSync(pyprojectPath, 'utf8');
|
|
93
|
-
const depsBlock = pyproject.match(/dependencies\s*=\s*\[[\s\S]*?\]/);
|
|
94
|
-
if (!depsBlock)
|
|
95
|
-
return [];
|
|
96
|
-
return Array.from(depsBlock[0].matchAll(/"([^"]+)"/g), (match) => match[1]);
|
|
97
|
-
}
|
|
98
|
-
catch (_a) {
|
|
99
|
-
return [];
|
|
100
|
-
}
|
|
101
|
-
})();
|
|
102
|
-
const depsInstallCmd = dependencySpecifiers.length > 0
|
|
103
|
-
? `${pythonCmd} -m pip install --upgrade --target "${pythonDepsPath}" ${dependencySpecifiers.map((dep) => `"${dep}"`).join(' ')}`
|
|
104
|
-
: '';
|
|
105
|
-
const installCmd = depsInstallCmd || pipCmd;
|
|
106
|
-
const pathList = yield sys.path;
|
|
107
|
-
fs.mkdirSync(pythonDepsPath, { recursive: true });
|
|
108
|
-
yield pathList.insert(0, pythonDepsPath);
|
|
109
|
-
yield pathList.insert(0, path.join(pythonPackagePath, 'src'));
|
|
110
|
-
// Try to import rlm, install deps if import fails
|
|
111
|
-
try {
|
|
112
|
-
this.rlmModule = yield this.python('rlm');
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
// If import fails, try installing dependencies
|
|
116
|
-
if ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('No module named')) {
|
|
117
|
-
console.log('[recursive-llm-ts] Installing Python dependencies locally (first time only)...');
|
|
118
|
-
try {
|
|
119
|
-
const { execSync } = yield Promise.resolve().then(() => __importStar(require('child_process')));
|
|
120
|
-
execSync(installCmd, { stdio: 'inherit' });
|
|
121
|
-
console.log('[recursive-llm-ts] ✓ Python dependencies installed');
|
|
122
|
-
// Try import again
|
|
123
|
-
this.rlmModule = yield this.python('rlm');
|
|
124
|
-
}
|
|
125
|
-
catch (installError) {
|
|
126
|
-
throw new Error('Failed to import rlm module after installing dependencies.\n' +
|
|
127
|
-
`Manual installation: ${installCmd}\n` +
|
|
128
|
-
`Error: ${installError.message || installError}`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
throw new Error('Failed to import rlm module.\n' +
|
|
133
|
-
`Run: ${installCmd}\n` +
|
|
134
|
-
`Original error: ${error.message || error}`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
completion(model_1, query_1, context_1) {
|
|
140
|
-
return __awaiter(this, arguments, void 0, function* (model, query, context, rlmConfig = {}) {
|
|
141
|
-
yield this.ensureRLMModule();
|
|
142
|
-
try {
|
|
143
|
-
// Extract pythonia timeout (default: 100000ms)
|
|
144
|
-
const pythoniaTimeout = rlmConfig.pythonia_timeout || 100000;
|
|
145
|
-
// Remove pythonia_timeout from config passed to Python
|
|
146
|
-
const { pythonia_timeout } = rlmConfig, pythonConfig = __rest(rlmConfig, ["pythonia_timeout"]);
|
|
147
|
-
// Create RLM instance with config, passing timeout to pythonia
|
|
148
|
-
const RLMClass = yield this.rlmModule.RLM;
|
|
149
|
-
const rlmInstance = yield RLMClass(model, Object.assign(Object.assign({}, pythonConfig), { $timeout: pythoniaTimeout }));
|
|
150
|
-
// Call completion method with timeout
|
|
151
|
-
const result = yield rlmInstance.completion(query, context, { $timeout: pythoniaTimeout });
|
|
152
|
-
const stats = yield rlmInstance.stats;
|
|
153
|
-
// Convert Python stats dict to JS object
|
|
154
|
-
const statsObj = {
|
|
155
|
-
llm_calls: yield stats.llm_calls,
|
|
156
|
-
iterations: yield stats.iterations,
|
|
157
|
-
depth: yield stats.depth
|
|
158
|
-
};
|
|
159
|
-
return {
|
|
160
|
-
result: String(result),
|
|
161
|
-
stats: statsObj
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
throw new Error(`RLM completion failed: ${error.message || error}`);
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
cleanup() {
|
|
170
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
171
|
-
if (this.python && this.rlmModule) {
|
|
172
|
-
this.python.exit();
|
|
173
|
-
this.rlmModule = null;
|
|
174
|
-
this.python = null;
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
exports.PythoniaBridge = PythoniaBridge;
|