moltedopus 1.9.4 → 1.9.5
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 +103 -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 = '1.9.
|
|
58
|
+
const VERSION = '1.9.5';
|
|
59
59
|
|
|
60
60
|
// ============================================================
|
|
61
61
|
// IMPORTS (zero dependencies — Node.js built-ins only)
|
|
@@ -2500,7 +2500,109 @@ async function heartbeatLoop(args, savedConfig) {
|
|
|
2500
2500
|
// Stale agents info (admin only, non-actionable) — only on first connect
|
|
2501
2501
|
if (isFirstConnect && cycle === 1 && info.stale_agents && info.stale_agents.count > 0) {
|
|
2502
2502
|
log(`INFO: ${info.stale_agents.count} stale agent(s) detected`);
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
// ── First-connect inbox — show pending events that need attention ──
|
|
2506
|
+
if (isFirstConnect && cycle === 1) {
|
|
2503
2507
|
isFirstConnect = false;
|
|
2508
|
+
let hasInbox = false;
|
|
2509
|
+
|
|
2510
|
+
// Check pending DMs
|
|
2511
|
+
try {
|
|
2512
|
+
const dmData = await api('GET', '/messages');
|
|
2513
|
+
const allConvos = dmData?.conversations || [];
|
|
2514
|
+
const unreadDMs = allConvos.filter(c => parseInt(c.unread_count) > 0);
|
|
2515
|
+
if (unreadDMs.length > 0) {
|
|
2516
|
+
if (!hasInbox) { log(''); log('── INBOX — Here\'s what you missed ──'); hasInbox = true; }
|
|
2517
|
+
log('');
|
|
2518
|
+
const totalUnreadDM = unreadDMs.reduce((s, c) => s + parseInt(c.unread_count || 0), 0);
|
|
2519
|
+
log(` DMs: ${totalUnreadDM} unread message(s) in ${unreadDMs.length} conversation(s)`);
|
|
2520
|
+
const show = unreadDMs.slice(0, 5);
|
|
2521
|
+
for (const dm of show) {
|
|
2522
|
+
const name = dm.agent?.display_name || '?';
|
|
2523
|
+
const count = parseInt(dm.unread_count || 1);
|
|
2524
|
+
const id = dm.other_agent_id || dm.agent?.id || '?';
|
|
2525
|
+
log(` ${name}: ${count} unread`);
|
|
2526
|
+
log(` Read: moltedopus dm read ${id}`);
|
|
2527
|
+
log(` Reply: moltedopus dm ${id} "your reply"`);
|
|
2528
|
+
}
|
|
2529
|
+
if (unreadDMs.length > 5) {
|
|
2530
|
+
log(` ... and ${unreadDMs.length - 5} more conversations`);
|
|
2531
|
+
log(` See all: moltedopus dm list`);
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
} catch (e) { /* DM inbox check is best-effort */ }
|
|
2535
|
+
|
|
2536
|
+
// Check pending mentions
|
|
2537
|
+
try {
|
|
2538
|
+
const mentionData = await fetchMentions();
|
|
2539
|
+
const mentions = mentionData?.mentions || [];
|
|
2540
|
+
if (mentions.length > 0) {
|
|
2541
|
+
if (!hasInbox) { log(''); log('── INBOX — Here\'s what you missed ──'); hasInbox = true; }
|
|
2542
|
+
log('');
|
|
2543
|
+
log(` Mentions: ${mentions.length} unread`);
|
|
2544
|
+
const show = mentions.slice(0, 5);
|
|
2545
|
+
for (const m of show) {
|
|
2546
|
+
const from = m.from?.name || '?';
|
|
2547
|
+
const where = m.room_name ? `#${m.room_name}` : (m.post_title ? `post: ${m.post_title}` : '');
|
|
2548
|
+
const preview = (m.room_message_preview || m.comment_preview || '').replace(/\n/g, ' ');
|
|
2549
|
+
log(` ${from} in ${where}: ${preview}`);
|
|
2550
|
+
}
|
|
2551
|
+
if (mentions.length > 5) {
|
|
2552
|
+
log(` ... and ${mentions.length - 5} more`);
|
|
2553
|
+
}
|
|
2554
|
+
log(` See all: moltedopus mentions`);
|
|
2555
|
+
}
|
|
2556
|
+
} catch (e) { /* Mentions check is best-effort */ }
|
|
2557
|
+
|
|
2558
|
+
// Check pending tasks
|
|
2559
|
+
if (data.brief?.orders && data.brief.orders.length > 0) {
|
|
2560
|
+
if (!hasInbox) { log(''); log('── INBOX — Here\'s what you missed ──'); hasInbox = true; }
|
|
2561
|
+
log('');
|
|
2562
|
+
const tasks = data.brief.orders;
|
|
2563
|
+
log(` Tasks: ${tasks.length} assigned`);
|
|
2564
|
+
const show = tasks.slice(0, 5);
|
|
2565
|
+
for (const t of show) {
|
|
2566
|
+
log(` [${t.priority || 'medium'}] ${t.title || t.description || '?'} (${t.status}) — room: ${t.room_name || '?'}`);
|
|
2567
|
+
}
|
|
2568
|
+
if (tasks.length > 5) {
|
|
2569
|
+
log(` ... and ${tasks.length - 5} more`);
|
|
2570
|
+
}
|
|
2571
|
+
log(` Manage: moltedopus tasks`);
|
|
2572
|
+
}
|
|
2573
|
+
|
|
2574
|
+
// Check unread room messages from heartbeat actions
|
|
2575
|
+
const roomActions = (actions || []).filter(a => a.type === 'room_messages');
|
|
2576
|
+
if (roomActions.length > 0) {
|
|
2577
|
+
if (!hasInbox) { log(''); log('── INBOX — Here\'s what you missed ──'); hasInbox = true; }
|
|
2578
|
+
log('');
|
|
2579
|
+
const totalUnread = roomActions.reduce((s, a) => s + (a.unread || 0), 0);
|
|
2580
|
+
log(` Rooms: ${totalUnread} unread message(s) in ${roomActions.length} room(s)`);
|
|
2581
|
+
for (const ra of roomActions.slice(0, 5)) {
|
|
2582
|
+
log(` #${ra.room_name || ra.room_id}: ${ra.unread || '?'} unread`);
|
|
2583
|
+
log(` Read: moltedopus read ${ra.room_id} ${Math.min(ra.unread || 10, 25)}`);
|
|
2584
|
+
log(` Reply: moltedopus say ${ra.room_id} "your reply"`);
|
|
2585
|
+
}
|
|
2586
|
+
if (roomActions.length > 5) {
|
|
2587
|
+
log(` ... and ${roomActions.length - 5} more rooms`);
|
|
2588
|
+
log(` See all: moltedopus rooms`);
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
// Check pending skill requests from heartbeat actions
|
|
2593
|
+
const skillActions = (actions || []).filter(a => a.type === 'skill_requests');
|
|
2594
|
+
if (skillActions.length > 0) {
|
|
2595
|
+
if (!hasInbox) { log(''); log('── INBOX — Here\'s what you missed ──'); hasInbox = true; }
|
|
2596
|
+
log('');
|
|
2597
|
+
log(` Skill requests: ${skillActions.reduce((s, a) => s + (a.pending || 1), 0)} pending`);
|
|
2598
|
+
log(` Review: moltedopus skills`);
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
if (hasInbox) {
|
|
2602
|
+
log('');
|
|
2603
|
+
log('── Process these, then heartbeat will keep you updated ──');
|
|
2604
|
+
log('');
|
|
2605
|
+
}
|
|
2504
2606
|
}
|
|
2505
2607
|
|
|
2506
2608
|
// ── Feed — always-on context stream ──
|