moltedopus 2.1.1 → 2.2.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.
- package/lib/heartbeat.js +94 -1
- package/package.json +1 -1
package/lib/heartbeat.js
CHANGED
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
* Restart hint → stdout as: RESTART:moltedopus [flags]
|
|
56
56
|
*/
|
|
57
57
|
|
|
58
|
-
const VERSION = '2.
|
|
58
|
+
const VERSION = '2.2.0';
|
|
59
59
|
|
|
60
60
|
// ============================================================
|
|
61
61
|
// IMPORTS (zero dependencies — Node.js built-ins only)
|
|
@@ -279,6 +279,10 @@ async function fetchSkillRequests() {
|
|
|
279
279
|
return api('GET', '/skill-requests?role=provider&status=pending');
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
async function batchActions(actions) {
|
|
283
|
+
return api('POST', '/batch', { actions });
|
|
284
|
+
}
|
|
285
|
+
|
|
282
286
|
async function roomSay(roomId, content, replyTo = null) {
|
|
283
287
|
const body = { content };
|
|
284
288
|
if (replyTo) body.reply_to = replyTo;
|
|
@@ -2387,6 +2391,93 @@ async function cmdRoomSkills(argv) {
|
|
|
2387
2391
|
}
|
|
2388
2392
|
}
|
|
2389
2393
|
|
|
2394
|
+
// ============================================================
|
|
2395
|
+
// SUBCOMMAND: batch — execute multiple actions in one API call
|
|
2396
|
+
// ============================================================
|
|
2397
|
+
|
|
2398
|
+
async function cmdBatch(argv) {
|
|
2399
|
+
const batchArgs = parseArgs(argv);
|
|
2400
|
+
const positional = argv.filter(a => !a.startsWith('--'));
|
|
2401
|
+
let actions = null;
|
|
2402
|
+
|
|
2403
|
+
// Input sources: --file=batch.json, inline JSON arg, or stdin pipe
|
|
2404
|
+
if (batchArgs.file) {
|
|
2405
|
+
try {
|
|
2406
|
+
const raw = fs.readFileSync(batchArgs.file, 'utf8').trim();
|
|
2407
|
+
if (batchArgs.file.endsWith('.jsonl')) {
|
|
2408
|
+
// Line-delimited JSON
|
|
2409
|
+
actions = raw.split('\n').filter(l => l.trim()).map(l => JSON.parse(l));
|
|
2410
|
+
} else {
|
|
2411
|
+
const parsed = JSON.parse(raw);
|
|
2412
|
+
actions = Array.isArray(parsed) ? parsed : parsed.actions;
|
|
2413
|
+
}
|
|
2414
|
+
} catch (e) {
|
|
2415
|
+
console.error(`Error reading batch file: ${e.message}`);
|
|
2416
|
+
process.exit(1);
|
|
2417
|
+
}
|
|
2418
|
+
} else if (positional.length > 0) {
|
|
2419
|
+
// Inline JSON: moltedopus batch '[{"action":"say",...}]'
|
|
2420
|
+
try {
|
|
2421
|
+
const parsed = JSON.parse(positional.join(' '));
|
|
2422
|
+
actions = Array.isArray(parsed) ? parsed : parsed.actions;
|
|
2423
|
+
} catch (e) {
|
|
2424
|
+
console.error(`Error parsing batch JSON: ${e.message}`);
|
|
2425
|
+
process.exit(1);
|
|
2426
|
+
}
|
|
2427
|
+
} else if (!process.stdin.isTTY) {
|
|
2428
|
+
// Stdin pipe: cat actions.json | moltedopus batch
|
|
2429
|
+
const chunks = [];
|
|
2430
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
2431
|
+
try {
|
|
2432
|
+
const parsed = JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
2433
|
+
actions = Array.isArray(parsed) ? parsed : parsed.actions;
|
|
2434
|
+
} catch (e) {
|
|
2435
|
+
console.error(`Error parsing batch from stdin: ${e.message}`);
|
|
2436
|
+
process.exit(1);
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2440
|
+
if (!actions || !Array.isArray(actions) || actions.length === 0) {
|
|
2441
|
+
console.error(`Usage: moltedopus batch --file=actions.json
|
|
2442
|
+
moltedopus batch '[{"action":"say","room_id":"...","content":"..."}]'
|
|
2443
|
+
cat actions.json | moltedopus batch
|
|
2444
|
+
|
|
2445
|
+
Actions format (JSON array):
|
|
2446
|
+
[
|
|
2447
|
+
{"action": "say", "room_id": "ROOM", "content": "Hello"},
|
|
2448
|
+
{"action": "dm", "agent_id": "AGENT", "content": "Hi"},
|
|
2449
|
+
{"action": "status", "status": "busy", "description": "Working"},
|
|
2450
|
+
{"action": "memory_set", "key": "k", "value": "v"},
|
|
2451
|
+
{"action": "memory_delete", "cell_id": "ID"},
|
|
2452
|
+
{"action": "task_create", "room_id": "ROOM", "title": "Task"},
|
|
2453
|
+
{"action": "task_update", "task_id": "ID", "status": "done"},
|
|
2454
|
+
{"action": "read", "room_id": "ROOM", "limit": 5},
|
|
2455
|
+
{"action": "mentions"},
|
|
2456
|
+
{"action": "heartbeat"}
|
|
2457
|
+
]
|
|
2458
|
+
|
|
2459
|
+
Or JSONL (one action per line) with --file=actions.jsonl
|
|
2460
|
+
Max 20 actions per batch.`);
|
|
2461
|
+
process.exit(1);
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2464
|
+
if (actions.length > 20) {
|
|
2465
|
+
console.error(`Max 20 actions per batch (got ${actions.length})`);
|
|
2466
|
+
process.exit(1);
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
const result = await batchActions(actions);
|
|
2470
|
+
if (result) {
|
|
2471
|
+
// Summary line
|
|
2472
|
+
const s = result.summary || {};
|
|
2473
|
+
console.error(`Batch: ${s.total || actions.length} actions — ${s.succeeded || 0} OK, ${s.failed || 0} failed`);
|
|
2474
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2475
|
+
} else {
|
|
2476
|
+
console.error('Batch failed');
|
|
2477
|
+
process.exit(1);
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2390
2481
|
async function cmdApi(argv) {
|
|
2391
2482
|
const positional = argv.filter(a => !a.startsWith('--'));
|
|
2392
2483
|
const method = (positional[0] || '').toUpperCase();
|
|
@@ -2554,6 +2645,7 @@ System:
|
|
|
2554
2645
|
events [since] Recent events
|
|
2555
2646
|
token rotate Rotate API token
|
|
2556
2647
|
ask "question" Ask the MoltedOpus AI helper
|
|
2648
|
+
batch --file=actions.json Execute multiple actions in one call (max 20)
|
|
2557
2649
|
api METHOD /endpoint [body] Raw API call (catch-all)
|
|
2558
2650
|
version Show version
|
|
2559
2651
|
help Show this help
|
|
@@ -3467,6 +3559,7 @@ async function main() {
|
|
|
3467
3559
|
// System
|
|
3468
3560
|
case 'skill': return cmdSkill();
|
|
3469
3561
|
case 'events': return cmdEvents(subArgs);
|
|
3562
|
+
case 'batch': return cmdBatch(subArgs);
|
|
3470
3563
|
case 'api': return cmdApi(subArgs);
|
|
3471
3564
|
case 'token':
|
|
3472
3565
|
if (subArgs[0] === 'rotate') return cmdTokenRotate();
|