rentabots-sdk 1.6.4 ā 1.7.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/cli.js +248 -45
- package/dist/index.d.ts +291 -209
- package/dist/index.js +978 -712
- package/dist/queen_brain.d.ts +65 -0
- package/dist/queen_brain.js +284 -0
- package/init.js +42 -27
- package/init_templates.js +21 -20
- package/package.json +2 -2
package/cli.js
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* š¦ RENTABOTS MASTER CONTROLLER (v1.
|
|
4
|
+
* š¦ RENTABOTS MASTER CONTROLLER (v1.7.0)
|
|
5
5
|
* The all-in-one CLI for managing autonomous agents.
|
|
6
6
|
* Cross-Platform Support: Windows, Linux, Mac
|
|
7
|
+
*
|
|
8
|
+
* NEW: Interactive LLM Provider Selection (OpenClaw or Custom API)
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
11
|
const { execSync, spawn } = require('child_process');
|
|
10
12
|
const path = require('path');
|
|
11
13
|
const fs = require('fs');
|
|
14
|
+
const readline = require('readline');
|
|
12
15
|
|
|
13
16
|
const args = process.argv.slice(2);
|
|
14
17
|
const command = args[0];
|
|
15
18
|
|
|
16
|
-
// Helper
|
|
19
|
+
// --- Helper Utilities ---
|
|
20
|
+
|
|
21
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
22
|
+
const ask = (q) => new Promise((r) => rl.question(q, r));
|
|
23
|
+
|
|
17
24
|
function run(cmd, desc) {
|
|
18
25
|
console.log(`\nš ${desc}...`);
|
|
19
26
|
try {
|
|
@@ -24,56 +31,183 @@ function run(cmd, desc) {
|
|
|
24
31
|
}
|
|
25
32
|
}
|
|
26
33
|
|
|
27
|
-
//
|
|
34
|
+
// --- LLM Provider Selection ---
|
|
35
|
+
|
|
36
|
+
const LLM_PROVIDERS = [
|
|
37
|
+
{ key: 'openai', name: 'OpenAI', models: 'gpt-4o, gpt-4o-mini' },
|
|
38
|
+
{ key: 'anthropic', name: 'Anthropic', models: 'claude-sonnet-4, claude-3.5-haiku' },
|
|
39
|
+
{ key: 'google', name: 'Google', models: 'gemini-2.0-flash, gemini-2.5-pro' },
|
|
40
|
+
{ key: 'groq', name: 'Groq', models: 'llama-3.3-70b, mixtral-8x7b' },
|
|
41
|
+
{ key: 'mistral', name: 'Mistral', models: 'mistral-large, mistral-small' },
|
|
42
|
+
{ key: 'custom', name: 'Custom URL', models: 'any OpenAI-compatible endpoint' },
|
|
43
|
+
];
|
|
44
|
+
|
|
28
45
|
function checkOpenClaw() {
|
|
29
|
-
console.log("\nš¦ Checking OpenClaw Brain Connection...");
|
|
30
46
|
try {
|
|
31
|
-
// Just checking version is enough to know if it's in PATH and runnable
|
|
32
47
|
const version = execSync('openclaw --version', { stdio: 'pipe' }).toString().trim();
|
|
33
|
-
|
|
34
|
-
return true;
|
|
48
|
+
return version;
|
|
35
49
|
} catch (e) {
|
|
36
|
-
|
|
37
|
-
console.warn(` Your agent will lack autonomous reasoning capabilities.`);
|
|
38
|
-
console.warn(` Please install OpenClaw to enable full intelligence:`);
|
|
39
|
-
console.warn(` > npm install -g openclaw\n`);
|
|
40
|
-
|
|
41
|
-
// We don't exit(1) here because maybe they want to run a dumb bot,
|
|
42
|
-
// but for RentaBots standards, it's highly recommended.
|
|
43
|
-
// Uncomment next line to enforce:
|
|
44
|
-
// process.exit(1);
|
|
45
|
-
return false;
|
|
50
|
+
return null;
|
|
46
51
|
}
|
|
47
52
|
}
|
|
48
53
|
|
|
49
|
-
async function
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
async function installOpenClaw() {
|
|
55
|
+
console.log('\nš¦ Installing OpenClaw...');
|
|
56
|
+
try {
|
|
57
|
+
execSync('npm install -g openclaw', { stdio: 'inherit' });
|
|
58
|
+
const version = checkOpenClaw();
|
|
59
|
+
if (version) {
|
|
60
|
+
console.log(`ā
OpenClaw installed successfully (v${version})`);
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
} catch (e) {
|
|
64
|
+
console.error('ā OpenClaw installation failed.');
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function selectLLMProvider(nonInteractiveFlag) {
|
|
70
|
+
// Support non-interactive mode via --llm flag
|
|
71
|
+
if (nonInteractiveFlag) {
|
|
72
|
+
const key = nonInteractiveFlag.toLowerCase();
|
|
73
|
+
if (key === 'openclaw') {
|
|
74
|
+
const version = checkOpenClaw();
|
|
75
|
+
if (!version) {
|
|
76
|
+
console.error('ā OpenClaw is not installed. Run without --llm flag for interactive setup.');
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
return { provider: 'openclaw' };
|
|
80
|
+
}
|
|
81
|
+
const found = LLM_PROVIDERS.find(p => p.key === key);
|
|
82
|
+
if (found) return { provider: found.key };
|
|
83
|
+
console.error(`ā Unknown provider: ${key}. Valid: openclaw, ${LLM_PROVIDERS.map(p => p.key).join(', ')}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.log(`
|
|
88
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
89
|
+
ā š§ SELECT YOUR AGENT'S BRAIN ā
|
|
90
|
+
ā ā
|
|
91
|
+
ā 1. OpenClaw (Recommended - local AI runtime) ā
|
|
92
|
+
ā 2. Custom API (OpenAI, Anthropic, Google, etc.) ā
|
|
93
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā`);
|
|
94
|
+
|
|
95
|
+
const choice = await ask('\n Select [1/2]: ');
|
|
96
|
+
|
|
97
|
+
if (choice.trim() === '1') {
|
|
98
|
+
// --- OpenClaw Path ---
|
|
99
|
+
const version = checkOpenClaw();
|
|
100
|
+
if (version) {
|
|
101
|
+
console.log(`\nā
OpenClaw detected (v${version}). Your agent will use local AI intelligence.`);
|
|
102
|
+
return { provider: 'openclaw' };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
console.log('\nā ļø OpenClaw is not installed on this system.');
|
|
106
|
+
const install = await ask(' Install OpenClaw now? [Y/n]: ');
|
|
107
|
+
|
|
108
|
+
if (!install.trim() || install.trim().toLowerCase() === 'y') {
|
|
109
|
+
const success = await installOpenClaw();
|
|
110
|
+
if (success) return { provider: 'openclaw' };
|
|
111
|
+
console.log('\nā ļø Falling back to Custom API selection...');
|
|
112
|
+
} else {
|
|
113
|
+
console.log('\nā ļø Skipping OpenClaw. Switching to Custom API selection...\n');
|
|
114
|
+
}
|
|
115
|
+
// Fall through to custom API selection
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// --- Custom API Path ---
|
|
119
|
+
console.log('\n š” Available LLM Providers:\n');
|
|
120
|
+
LLM_PROVIDERS.forEach((p, i) => {
|
|
121
|
+
console.log(` ${i + 1}. ${p.name.padEnd(12)} (${p.models})`);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const providerChoice = await ask('\n Select provider [1-6]: ');
|
|
125
|
+
const idx = parseInt(providerChoice.trim()) - 1;
|
|
126
|
+
const selected = LLM_PROVIDERS[idx];
|
|
127
|
+
|
|
128
|
+
if (!selected) {
|
|
129
|
+
console.error('ā Invalid selection. Defaulting to OpenAI.');
|
|
130
|
+
return await collectApiKey('openai');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return await collectApiKey(selected.key);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function collectApiKey(providerKey) {
|
|
137
|
+
const result = { provider: providerKey };
|
|
138
|
+
|
|
139
|
+
const apiKey = await ask(`\n š Enter your ${providerKey.toUpperCase()} API Key: `);
|
|
140
|
+
if (!apiKey.trim()) {
|
|
141
|
+
console.error('ā API Key is required.');
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
result.apiKey = apiKey.trim();
|
|
145
|
+
|
|
146
|
+
if (providerKey === 'custom') {
|
|
147
|
+
const baseUrl = await ask(' š Enter your API Base URL (e.g. https://my-api.com/v1): ');
|
|
148
|
+
if (!baseUrl.trim()) {
|
|
149
|
+
console.error('ā Base URL is required for custom provider.');
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
result.baseUrl = baseUrl.trim();
|
|
153
|
+
|
|
154
|
+
const model = await ask(' š¤ Enter model name (e.g. gpt-4o-mini): ');
|
|
155
|
+
if (model.trim()) result.model = model.trim();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
52
160
|
|
|
161
|
+
function buildEnvContent(apiKey, llmConfig) {
|
|
162
|
+
let env = `RENTABOTS_API_KEY=${apiKey}\nRENTABOTS_SECRET_KEY=${apiKey}\nRENTABOTS_API_URL=https://rentabots.com/api\nRENTABOTS_SOCKET_URL=https://rentabots-relay-production.up.railway.app\n`;
|
|
163
|
+
env += `LLM_PROVIDER=${llmConfig.provider}\n`;
|
|
164
|
+
|
|
165
|
+
if (llmConfig.apiKey) env += `LLM_API_KEY=${llmConfig.apiKey}\n`;
|
|
166
|
+
if (llmConfig.baseUrl) env += `LLM_BASE_URL=${llmConfig.baseUrl}\n`;
|
|
167
|
+
if (llmConfig.model) env += `LLM_MODEL=${llmConfig.model}\n`;
|
|
168
|
+
|
|
169
|
+
return env;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// --- Main Commands ---
|
|
173
|
+
|
|
174
|
+
async function handleDeploy() {
|
|
175
|
+
// Parse API key
|
|
53
176
|
const keyArgIndex = args.findIndex(a => a === '--key' || a === '-k' || a === '-key');
|
|
54
177
|
const API_KEY = (keyArgIndex !== -1 && args[keyArgIndex + 1]) ? args[keyArgIndex + 1] : process.env.RENTABOTS_API_KEY;
|
|
55
178
|
|
|
56
179
|
if (!API_KEY) {
|
|
57
|
-
console.error("ā Error: API Key required for
|
|
180
|
+
console.error("ā Error: API Key required for deployment.");
|
|
58
181
|
console.log("Usage: npx rentabots-sdk deploy --key YOUR_API_KEY");
|
|
182
|
+
console.log(" npx rentabots-sdk deploy --key YOUR_API_KEY --llm openclaw");
|
|
59
183
|
process.exit(1);
|
|
60
184
|
}
|
|
61
185
|
|
|
186
|
+
// Parse --llm flag for non-interactive mode
|
|
187
|
+
const llmArgIndex = args.findIndex(a => a === '--llm');
|
|
188
|
+
const llmFlag = (llmArgIndex !== -1 && args[llmArgIndex + 1]) ? args[llmArgIndex + 1] : null;
|
|
189
|
+
|
|
190
|
+
// 0. Pre-Flight: LLM Provider Selection
|
|
191
|
+
console.log('\nš¦ RENTABOTS AGENT DEPLOYMENT WIZARD\n');
|
|
192
|
+
const llmConfig = await selectLLMProvider(llmFlag);
|
|
193
|
+
|
|
194
|
+
console.log(`\nā
Brain configured: ${llmConfig.provider.toUpperCase()}`);
|
|
195
|
+
|
|
62
196
|
const projectDir = 'my-rentabot-agent';
|
|
63
|
-
|
|
197
|
+
|
|
64
198
|
// 1. Create project if missing
|
|
65
199
|
if (!fs.existsSync(projectDir)) {
|
|
66
200
|
console.log(`\nš Project folder '${projectDir}' not found. Initializing...`);
|
|
67
201
|
fs.mkdirSync(projectDir);
|
|
68
202
|
process.chdir(projectDir);
|
|
69
|
-
|
|
70
|
-
//
|
|
203
|
+
|
|
204
|
+
// Write .env with LLM config
|
|
205
|
+
fs.writeFileSync('.env', buildEnvContent(API_KEY, llmConfig));
|
|
206
|
+
|
|
207
|
+
// Generate package.json
|
|
71
208
|
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
|
|
72
209
|
const ver = pkg.version;
|
|
73
|
-
|
|
74
|
-
fs.writeFileSync('.env', `RENTABOTS_API_KEY=${API_KEY}\nRENTABOTS_API_URL=https://rentabots.com/api\n`);
|
|
75
|
-
|
|
76
|
-
// Universal Scripts: Use 'node' or 'npx' instead of OS-specific commands
|
|
210
|
+
|
|
77
211
|
const pkgJson = {
|
|
78
212
|
name: "my-rentabot-agent",
|
|
79
213
|
version: "1.0.0",
|
|
@@ -85,28 +219,97 @@ async function handleDeploy() {
|
|
|
85
219
|
"logs": "npx pm2 logs my-rentabot-agent",
|
|
86
220
|
"status": "node -e \"console.log(require('fs').readFileSync('RENTABOT_STATUS.md', 'utf8'))\""
|
|
87
221
|
},
|
|
88
|
-
dependencies: {
|
|
89
|
-
"rentabots-sdk": `^${ver}`,
|
|
222
|
+
dependencies: {
|
|
223
|
+
"rentabots-sdk": `^${ver}`,
|
|
90
224
|
"dotenv": "^16.3.1",
|
|
91
|
-
"pm2": "^5.3.0"
|
|
225
|
+
"pm2": "^5.3.0"
|
|
92
226
|
}
|
|
93
227
|
};
|
|
94
228
|
fs.writeFileSync('package.json', JSON.stringify(pkgJson, null, 2));
|
|
95
229
|
|
|
96
|
-
// Generate Queen & Worker
|
|
97
|
-
const initScript = require('./init_templates');
|
|
230
|
+
// Generate Queen & Worker templates
|
|
231
|
+
const initScript = require('./init_templates');
|
|
98
232
|
fs.writeFileSync('agent.js', initScript.queenTemplate);
|
|
99
233
|
fs.writeFileSync('worker.js', initScript.workerTemplate);
|
|
100
|
-
|
|
234
|
+
|
|
101
235
|
run('npm install', 'Installing dependencies');
|
|
102
236
|
} else {
|
|
103
237
|
process.chdir(projectDir);
|
|
238
|
+
|
|
239
|
+
// Update .env with new LLM config if it changed
|
|
240
|
+
if (fs.existsSync('.env')) {
|
|
241
|
+
const existing = fs.readFileSync('.env', 'utf8');
|
|
242
|
+
if (!existing.includes('LLM_PROVIDER')) {
|
|
243
|
+
fs.appendFileSync('.env', `\nLLM_PROVIDER=${llmConfig.provider}\n`);
|
|
244
|
+
if (llmConfig.apiKey) fs.appendFileSync('.env', `LLM_API_KEY=${llmConfig.apiKey}\n`);
|
|
245
|
+
if (llmConfig.baseUrl) fs.appendFileSync('.env', `LLM_BASE_URL=${llmConfig.baseUrl}\n`);
|
|
246
|
+
if (llmConfig.model) fs.appendFileSync('.env', `LLM_MODEL=${llmConfig.model}\n`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
104
249
|
}
|
|
105
250
|
|
|
106
|
-
// 2. Deploy with PM2
|
|
251
|
+
// 2. Deploy with PM2
|
|
107
252
|
run('npm run deploy', 'Deploying agent to RentaBots Grid (24/7 Mode)');
|
|
108
253
|
console.log("\n⨠DEPLOYMENT SUCCESSFUL!");
|
|
109
254
|
console.log("š Run 'npx rentabots-sdk status' to see your live dashboard.");
|
|
255
|
+
rl.close();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async function handleInit() {
|
|
259
|
+
console.log('\nš¦ RENTABOTS INTERACTIVE SETUP\n');
|
|
260
|
+
|
|
261
|
+
const apiKey = await ask("š Enter Agent API Key: ");
|
|
262
|
+
if (!apiKey.startsWith('sk_agent_')) {
|
|
263
|
+
console.error("ā Invalid API Key. Must start with 'sk_agent_'");
|
|
264
|
+
process.exit(1);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// LLM Provider Selection
|
|
268
|
+
const llmConfig = await selectLLMProvider(null);
|
|
269
|
+
|
|
270
|
+
const projectDir = 'my-rentabot-agent';
|
|
271
|
+
if (!fs.existsSync(projectDir)) fs.mkdirSync(projectDir);
|
|
272
|
+
process.chdir(projectDir);
|
|
273
|
+
|
|
274
|
+
// Write .env
|
|
275
|
+
fs.writeFileSync('.env', buildEnvContent(apiKey, llmConfig));
|
|
276
|
+
|
|
277
|
+
// Generate package.json
|
|
278
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
|
|
279
|
+
const ver = pkg.version;
|
|
280
|
+
|
|
281
|
+
const pkgJson = {
|
|
282
|
+
name: "my-rentabot-agent",
|
|
283
|
+
version: "1.0.0",
|
|
284
|
+
main: "agent.js",
|
|
285
|
+
scripts: {
|
|
286
|
+
"start": "node agent.js",
|
|
287
|
+
"deploy": "npx pm2 start agent.js --name my-rentabot-agent --update-env",
|
|
288
|
+
"stop": "npx pm2 stop my-rentabot-agent",
|
|
289
|
+
"logs": "npx pm2 logs my-rentabot-agent",
|
|
290
|
+
"status": "node -e \"console.log(require('fs').readFileSync('RENTABOT_STATUS.md', 'utf8'))\""
|
|
291
|
+
},
|
|
292
|
+
dependencies: {
|
|
293
|
+
"rentabots-sdk": `^${ver}`,
|
|
294
|
+
"dotenv": "^16.3.1",
|
|
295
|
+
"pm2": "^5.3.0"
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
fs.writeFileSync('package.json', JSON.stringify(pkgJson, null, 2));
|
|
299
|
+
|
|
300
|
+
// Generate Queen & Worker templates
|
|
301
|
+
const initScript = require('./init_templates');
|
|
302
|
+
fs.writeFileSync('agent.js', initScript.queenTemplate);
|
|
303
|
+
fs.writeFileSync('worker.js', initScript.workerTemplate);
|
|
304
|
+
|
|
305
|
+
console.log("\nš¦ Installing core dependencies...");
|
|
306
|
+
try {
|
|
307
|
+
execSync('npm install', { stdio: 'inherit' });
|
|
308
|
+
} catch (e) { }
|
|
309
|
+
|
|
310
|
+
console.log(`\nā
Brain: ${llmConfig.provider.toUpperCase()}`);
|
|
311
|
+
console.log("š PROJECT READY: cd my-rentabot-agent && npm start");
|
|
312
|
+
rl.close();
|
|
110
313
|
}
|
|
111
314
|
|
|
112
315
|
async function main() {
|
|
@@ -118,18 +321,17 @@ async function main() {
|
|
|
118
321
|
|
|
119
322
|
switch (command) {
|
|
120
323
|
case 'init':
|
|
121
|
-
|
|
324
|
+
await handleInit();
|
|
122
325
|
break;
|
|
123
|
-
|
|
326
|
+
|
|
124
327
|
case 'deploy':
|
|
125
328
|
await handleDeploy();
|
|
126
329
|
break;
|
|
127
330
|
|
|
128
331
|
case 'status':
|
|
129
|
-
// Try to find status file in current or subdirectory
|
|
130
332
|
const statusPath = path.join(process.cwd(), 'my-rentabot-agent', 'RENTABOT_STATUS.md');
|
|
131
333
|
const localStatusPath = path.join(process.cwd(), 'RENTABOT_STATUS.md');
|
|
132
|
-
|
|
334
|
+
|
|
133
335
|
if (fs.existsSync(statusPath)) {
|
|
134
336
|
console.log(fs.readFileSync(statusPath, 'utf8'));
|
|
135
337
|
} else if (fs.existsSync(localStatusPath)) {
|
|
@@ -149,14 +351,15 @@ async function main() {
|
|
|
149
351
|
|
|
150
352
|
default:
|
|
151
353
|
console.log(`
|
|
152
|
-
š¦ RENTABOTS MASTER CLI v1.
|
|
354
|
+
š¦ RENTABOTS MASTER CLI v1.7.0 (Universal)
|
|
153
355
|
------------------------------
|
|
154
356
|
Usage:
|
|
155
|
-
npx rentabots-sdk init
|
|
156
|
-
npx rentabots-sdk deploy --key -
|
|
157
|
-
npx rentabots-sdk
|
|
158
|
-
npx rentabots-sdk
|
|
159
|
-
npx rentabots-sdk
|
|
357
|
+
npx rentabots-sdk init - Interactive setup wizard
|
|
358
|
+
npx rentabots-sdk deploy --key X - Deploy (interactive LLM selection)
|
|
359
|
+
npx rentabots-sdk deploy --key X --llm Y - Deploy (non-interactive, Y = openclaw|openai|anthropic|google|groq|mistral|custom)
|
|
360
|
+
npx rentabots-sdk status - Live agent dashboard
|
|
361
|
+
npx rentabots-sdk logs - Stream real-time telemetry
|
|
362
|
+
npx rentabots-sdk stop - Shutdown your agent
|
|
160
363
|
`);
|
|
161
364
|
}
|
|
162
365
|
}
|