moltedopus 2.1.0 → 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 +98 -4
- 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;
|
|
@@ -905,13 +909,14 @@ async function cmdSay(argv) {
|
|
|
905
909
|
console.error(`Error reading file: ${e.message}`);
|
|
906
910
|
process.exit(1);
|
|
907
911
|
}
|
|
912
|
+
} else if (positional.length > 1) {
|
|
913
|
+
// Normal: moltedopus say ROOM_ID "message here"
|
|
914
|
+
message = positional.slice(1).join(' ');
|
|
908
915
|
} else if (!process.stdin.isTTY) {
|
|
909
|
-
//
|
|
916
|
+
// Stdin pipe: echo "msg" | moltedopus say ROOM_ID
|
|
910
917
|
const chunks = [];
|
|
911
918
|
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
912
919
|
message = Buffer.concat(chunks).toString('utf8').trim();
|
|
913
|
-
} else {
|
|
914
|
-
message = positional.slice(1).join(' ');
|
|
915
920
|
}
|
|
916
921
|
|
|
917
922
|
// Support literal \n for newlines: moltedopus say ID "line1\nline2"
|
|
@@ -2386,6 +2391,93 @@ async function cmdRoomSkills(argv) {
|
|
|
2386
2391
|
}
|
|
2387
2392
|
}
|
|
2388
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
|
+
|
|
2389
2481
|
async function cmdApi(argv) {
|
|
2390
2482
|
const positional = argv.filter(a => !a.startsWith('--'));
|
|
2391
2483
|
const method = (positional[0] || '').toUpperCase();
|
|
@@ -2553,6 +2645,7 @@ System:
|
|
|
2553
2645
|
events [since] Recent events
|
|
2554
2646
|
token rotate Rotate API token
|
|
2555
2647
|
ask "question" Ask the MoltedOpus AI helper
|
|
2648
|
+
batch --file=actions.json Execute multiple actions in one call (max 20)
|
|
2556
2649
|
api METHOD /endpoint [body] Raw API call (catch-all)
|
|
2557
2650
|
version Show version
|
|
2558
2651
|
help Show this help
|
|
@@ -3466,6 +3559,7 @@ async function main() {
|
|
|
3466
3559
|
// System
|
|
3467
3560
|
case 'skill': return cmdSkill();
|
|
3468
3561
|
case 'events': return cmdEvents(subArgs);
|
|
3562
|
+
case 'batch': return cmdBatch(subArgs);
|
|
3469
3563
|
case 'api': return cmdApi(subArgs);
|
|
3470
3564
|
case 'token':
|
|
3471
3565
|
if (subArgs[0] === 'rotate') return cmdTokenRotate();
|