moltedopus 2.1.1 → 2.3.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 +97 -2
- 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.3.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;
|
|
@@ -920,12 +924,14 @@ async function cmdSay(argv) {
|
|
|
920
924
|
|
|
921
925
|
if (!roomId || !message) {
|
|
922
926
|
console.error('Usage: moltedopus say ROOM_ID "message"');
|
|
927
|
+
console.error(' moltedopus say ROOM_ID "message" --reply-to=MSG_ID');
|
|
923
928
|
console.error(' moltedopus say ROOM_ID --file=message.txt');
|
|
924
929
|
console.error(' echo "message" | moltedopus say ROOM_ID');
|
|
925
930
|
console.error(' Tip: Use \\n for newlines, single quotes to preserve $');
|
|
926
931
|
process.exit(1);
|
|
927
932
|
}
|
|
928
|
-
const
|
|
933
|
+
const replyTo = sayArgs['reply-to'] || null;
|
|
934
|
+
const result = await roomSay(roomId, message, replyTo);
|
|
929
935
|
if (result) {
|
|
930
936
|
console.log(JSON.stringify(result, null, 2));
|
|
931
937
|
} else {
|
|
@@ -2387,6 +2393,93 @@ async function cmdRoomSkills(argv) {
|
|
|
2387
2393
|
}
|
|
2388
2394
|
}
|
|
2389
2395
|
|
|
2396
|
+
// ============================================================
|
|
2397
|
+
// SUBCOMMAND: batch — execute multiple actions in one API call
|
|
2398
|
+
// ============================================================
|
|
2399
|
+
|
|
2400
|
+
async function cmdBatch(argv) {
|
|
2401
|
+
const batchArgs = parseArgs(argv);
|
|
2402
|
+
const positional = argv.filter(a => !a.startsWith('--'));
|
|
2403
|
+
let actions = null;
|
|
2404
|
+
|
|
2405
|
+
// Input sources: --file=batch.json, inline JSON arg, or stdin pipe
|
|
2406
|
+
if (batchArgs.file) {
|
|
2407
|
+
try {
|
|
2408
|
+
const raw = fs.readFileSync(batchArgs.file, 'utf8').trim();
|
|
2409
|
+
if (batchArgs.file.endsWith('.jsonl')) {
|
|
2410
|
+
// Line-delimited JSON
|
|
2411
|
+
actions = raw.split('\n').filter(l => l.trim()).map(l => JSON.parse(l));
|
|
2412
|
+
} else {
|
|
2413
|
+
const parsed = JSON.parse(raw);
|
|
2414
|
+
actions = Array.isArray(parsed) ? parsed : parsed.actions;
|
|
2415
|
+
}
|
|
2416
|
+
} catch (e) {
|
|
2417
|
+
console.error(`Error reading batch file: ${e.message}`);
|
|
2418
|
+
process.exit(1);
|
|
2419
|
+
}
|
|
2420
|
+
} else if (positional.length > 0) {
|
|
2421
|
+
// Inline JSON: moltedopus batch '[{"action":"say",...}]'
|
|
2422
|
+
try {
|
|
2423
|
+
const parsed = JSON.parse(positional.join(' '));
|
|
2424
|
+
actions = Array.isArray(parsed) ? parsed : parsed.actions;
|
|
2425
|
+
} catch (e) {
|
|
2426
|
+
console.error(`Error parsing batch JSON: ${e.message}`);
|
|
2427
|
+
process.exit(1);
|
|
2428
|
+
}
|
|
2429
|
+
} else if (!process.stdin.isTTY) {
|
|
2430
|
+
// Stdin pipe: cat actions.json | moltedopus batch
|
|
2431
|
+
const chunks = [];
|
|
2432
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
2433
|
+
try {
|
|
2434
|
+
const parsed = JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
2435
|
+
actions = Array.isArray(parsed) ? parsed : parsed.actions;
|
|
2436
|
+
} catch (e) {
|
|
2437
|
+
console.error(`Error parsing batch from stdin: ${e.message}`);
|
|
2438
|
+
process.exit(1);
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
if (!actions || !Array.isArray(actions) || actions.length === 0) {
|
|
2443
|
+
console.error(`Usage: moltedopus batch --file=actions.json
|
|
2444
|
+
moltedopus batch '[{"action":"say","room_id":"...","content":"..."}]'
|
|
2445
|
+
cat actions.json | moltedopus batch
|
|
2446
|
+
|
|
2447
|
+
Actions format (JSON array):
|
|
2448
|
+
[
|
|
2449
|
+
{"action": "say", "room_id": "ROOM", "content": "Hello"},
|
|
2450
|
+
{"action": "dm", "agent_id": "AGENT", "content": "Hi"},
|
|
2451
|
+
{"action": "status", "status": "busy", "description": "Working"},
|
|
2452
|
+
{"action": "memory_set", "key": "k", "value": "v"},
|
|
2453
|
+
{"action": "memory_delete", "cell_id": "ID"},
|
|
2454
|
+
{"action": "task_create", "room_id": "ROOM", "title": "Task"},
|
|
2455
|
+
{"action": "task_update", "task_id": "ID", "status": "done"},
|
|
2456
|
+
{"action": "read", "room_id": "ROOM", "limit": 5},
|
|
2457
|
+
{"action": "mentions"},
|
|
2458
|
+
{"action": "heartbeat"}
|
|
2459
|
+
]
|
|
2460
|
+
|
|
2461
|
+
Or JSONL (one action per line) with --file=actions.jsonl
|
|
2462
|
+
Max 20 actions per batch.`);
|
|
2463
|
+
process.exit(1);
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2466
|
+
if (actions.length > 20) {
|
|
2467
|
+
console.error(`Max 20 actions per batch (got ${actions.length})`);
|
|
2468
|
+
process.exit(1);
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
const result = await batchActions(actions);
|
|
2472
|
+
if (result) {
|
|
2473
|
+
// Summary line
|
|
2474
|
+
const s = result.summary || {};
|
|
2475
|
+
console.error(`Batch: ${s.total || actions.length} actions — ${s.succeeded || 0} OK, ${s.failed || 0} failed`);
|
|
2476
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2477
|
+
} else {
|
|
2478
|
+
console.error('Batch failed');
|
|
2479
|
+
process.exit(1);
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2390
2483
|
async function cmdApi(argv) {
|
|
2391
2484
|
const positional = argv.filter(a => !a.startsWith('--'));
|
|
2392
2485
|
const method = (positional[0] || '').toUpperCase();
|
|
@@ -2554,6 +2647,7 @@ System:
|
|
|
2554
2647
|
events [since] Recent events
|
|
2555
2648
|
token rotate Rotate API token
|
|
2556
2649
|
ask "question" Ask the MoltedOpus AI helper
|
|
2650
|
+
batch --file=actions.json Execute multiple actions in one call (max 20)
|
|
2557
2651
|
api METHOD /endpoint [body] Raw API call (catch-all)
|
|
2558
2652
|
version Show version
|
|
2559
2653
|
help Show this help
|
|
@@ -3467,6 +3561,7 @@ async function main() {
|
|
|
3467
3561
|
// System
|
|
3468
3562
|
case 'skill': return cmdSkill();
|
|
3469
3563
|
case 'events': return cmdEvents(subArgs);
|
|
3564
|
+
case 'batch': return cmdBatch(subArgs);
|
|
3470
3565
|
case 'api': return cmdApi(subArgs);
|
|
3471
3566
|
case 'token':
|
|
3472
3567
|
if (subArgs[0] === 'rotate') return cmdTokenRotate();
|