spora 0.2.28 → 0.2.30
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/dist/{chunk-NJHDY4ON.js → chunk-4D73N6VY.js} +2 -2
- package/dist/{chunk-ZNLJN7YO.js → chunk-7FN5GDSB.js} +3 -3
- package/dist/{chunk-JKGCF23V.js → chunk-NHNOCAP3.js} +8 -8
- package/dist/chunk-NHNOCAP3.js.map +1 -0
- package/dist/{chunk-M23MGGHE.js → chunk-OGFMGURJ.js} +2 -2
- package/dist/cli.js +24 -24
- package/dist/{client-N7JMM5U7.js → client-3VP7YBBE.js} +2 -3
- package/dist/client-3VP7YBBE.js.map +1 -0
- package/dist/{colony-NE2MZ7RP.js → colony-YDOTBQFD.js} +2 -2
- package/dist/{decision-engine-RVQRDHEI.js → decision-engine-IIA5J2QG.js} +4 -4
- package/dist/{heartbeat-4Q344LIV.js → heartbeat-Q6GLGCGN.js} +5 -5
- package/dist/{init-Z72CJZUC.js → init-ULHKJ6XQ.js} +3 -3
- package/dist/mcp-server.js +19 -19
- package/dist/{prompt-builder-4SWKDPNG.js → prompt-builder-3AJUQUVZ.js} +2 -2
- package/dist/{queue-T3OYWUII.js → queue-LHRG6JOP.js} +2 -2
- package/dist/web-chat/chat.html +73 -20
- package/dist/{web-chat-7SSETYWK.js → web-chat-6ZRJE73E.js} +18 -11
- package/dist/web-chat-6ZRJE73E.js.map +1 -0
- package/dist/{x-client-5FBD32B2.js → x-client-QNLSLY2R.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-JKGCF23V.js.map +0 -1
- package/dist/client-N7JMM5U7.js.map +0 -1
- package/dist/web-chat-7SSETYWK.js.map +0 -1
- /package/dist/{chunk-NJHDY4ON.js.map → chunk-4D73N6VY.js.map} +0 -0
- /package/dist/{chunk-ZNLJN7YO.js.map → chunk-7FN5GDSB.js.map} +0 -0
- /package/dist/{chunk-M23MGGHE.js.map → chunk-OGFMGURJ.js.map} +0 -0
- /package/dist/{colony-NE2MZ7RP.js.map → colony-YDOTBQFD.js.map} +0 -0
- /package/dist/{decision-engine-RVQRDHEI.js.map → decision-engine-IIA5J2QG.js.map} +0 -0
- /package/dist/{heartbeat-4Q344LIV.js.map → heartbeat-Q6GLGCGN.js.map} +0 -0
- /package/dist/{init-Z72CJZUC.js.map → init-ULHKJ6XQ.js.map} +0 -0
- /package/dist/{prompt-builder-4SWKDPNG.js.map → prompt-builder-3AJUQUVZ.js.map} +0 -0
- /package/dist/{queue-T3OYWUII.js.map → queue-LHRG6JOP.js.map} +0 -0
- /package/dist/{x-client-5FBD32B2.js.map → x-client-QNLSLY2R.js.map} +0 -0
package/dist/mcp-server.js
CHANGED
|
@@ -388,7 +388,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
388
388
|
},
|
|
389
389
|
async ({ content }) => {
|
|
390
390
|
try {
|
|
391
|
-
const { getXClient } = await import("./x-client-
|
|
391
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
392
392
|
const client = await getXClient();
|
|
393
393
|
const result = await client.postTweet(content);
|
|
394
394
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
@@ -406,7 +406,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
406
406
|
},
|
|
407
407
|
async ({ tweetId, content }) => {
|
|
408
408
|
try {
|
|
409
|
-
const { getXClient } = await import("./x-client-
|
|
409
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
410
410
|
const client = await getXClient();
|
|
411
411
|
const result = await client.replyToTweet(tweetId, content);
|
|
412
412
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
@@ -421,7 +421,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
421
421
|
{ tweetId: z.string().describe("The ID of the tweet to like") },
|
|
422
422
|
async ({ tweetId }) => {
|
|
423
423
|
try {
|
|
424
|
-
const { getXClient } = await import("./x-client-
|
|
424
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
425
425
|
const client = await getXClient();
|
|
426
426
|
const result = await client.likeTweet(tweetId);
|
|
427
427
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
@@ -436,7 +436,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
436
436
|
{ tweetId: z.string().describe("The ID of the tweet to retweet") },
|
|
437
437
|
async ({ tweetId }) => {
|
|
438
438
|
try {
|
|
439
|
-
const { getXClient } = await import("./x-client-
|
|
439
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
440
440
|
const client = await getXClient();
|
|
441
441
|
const result = await client.retweet(tweetId);
|
|
442
442
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
@@ -451,7 +451,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
451
451
|
{ userId: z.string().describe("The user ID to follow") },
|
|
452
452
|
async ({ userId }) => {
|
|
453
453
|
try {
|
|
454
|
-
const { getXClient } = await import("./x-client-
|
|
454
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
455
455
|
const client = await getXClient();
|
|
456
456
|
const result = await client.followUser(userId);
|
|
457
457
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
@@ -466,7 +466,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
466
466
|
{ userId: z.string().describe("The user ID to unfollow") },
|
|
467
467
|
async ({ userId }) => {
|
|
468
468
|
try {
|
|
469
|
-
const { getXClient } = await import("./x-client-
|
|
469
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
470
470
|
const client = await getXClient();
|
|
471
471
|
const result = await client.unfollowUser(userId);
|
|
472
472
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
@@ -481,7 +481,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
481
481
|
{ count: z.number().optional().describe("Number of tweets to fetch (default 20)") },
|
|
482
482
|
async ({ count }) => {
|
|
483
483
|
try {
|
|
484
|
-
const { getXClient } = await import("./x-client-
|
|
484
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
485
485
|
const client = await getXClient();
|
|
486
486
|
const result = await client.getTimeline({ count: count ?? 20 });
|
|
487
487
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
@@ -496,7 +496,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
496
496
|
{ count: z.number().optional().describe("Number of mentions to fetch (default 20)") },
|
|
497
497
|
async ({ count }) => {
|
|
498
498
|
try {
|
|
499
|
-
const { getXClient } = await import("./x-client-
|
|
499
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
500
500
|
const client = await getXClient();
|
|
501
501
|
const result = await client.getMentions({ count: count ?? 20 });
|
|
502
502
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
@@ -514,7 +514,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
514
514
|
},
|
|
515
515
|
async ({ query, count }) => {
|
|
516
516
|
try {
|
|
517
|
-
const { getXClient } = await import("./x-client-
|
|
517
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
518
518
|
const client = await getXClient();
|
|
519
519
|
const result = await client.searchTweets(query, { count: count ?? 20 });
|
|
520
520
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
@@ -529,7 +529,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
529
529
|
{ handle: z.string().describe("X handle (without @)") },
|
|
530
530
|
async ({ handle }) => {
|
|
531
531
|
try {
|
|
532
|
-
const { getXClient } = await import("./x-client-
|
|
532
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
533
533
|
const client = await getXClient();
|
|
534
534
|
const result = await client.getProfile(handle);
|
|
535
535
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
@@ -547,7 +547,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
547
547
|
},
|
|
548
548
|
async ({ content, scheduledFor }) => {
|
|
549
549
|
try {
|
|
550
|
-
const { addToQueue } = await import("./queue-
|
|
550
|
+
const { addToQueue } = await import("./queue-LHRG6JOP.js");
|
|
551
551
|
const entry = addToQueue(content, scheduledFor);
|
|
552
552
|
return {
|
|
553
553
|
content: [
|
|
@@ -565,7 +565,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
565
565
|
{},
|
|
566
566
|
async () => {
|
|
567
567
|
try {
|
|
568
|
-
const { flushQueue } = await import("./queue-
|
|
568
|
+
const { flushQueue } = await import("./queue-LHRG6JOP.js");
|
|
569
569
|
const results = await flushQueue();
|
|
570
570
|
return {
|
|
571
571
|
content: [
|
|
@@ -586,7 +586,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
586
586
|
{ message: z.string().optional().describe("Optional message to post to the Colony community") },
|
|
587
587
|
async ({ message }) => {
|
|
588
588
|
try {
|
|
589
|
-
const { colonyCheckin } = await import("./colony-
|
|
589
|
+
const { colonyCheckin } = await import("./colony-YDOTBQFD.js");
|
|
590
590
|
const result = await colonyCheckin(message);
|
|
591
591
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
592
592
|
} catch (error) {
|
|
@@ -600,7 +600,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
600
600
|
{},
|
|
601
601
|
async () => {
|
|
602
602
|
try {
|
|
603
|
-
const { getColonyMemory } = await import("./colony-
|
|
603
|
+
const { getColonyMemory } = await import("./colony-YDOTBQFD.js");
|
|
604
604
|
const memory = getColonyMemory();
|
|
605
605
|
return { content: [{ type: "text", text: JSON.stringify(memory, null, 2) }] };
|
|
606
606
|
} catch (error) {
|
|
@@ -614,7 +614,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
614
614
|
{},
|
|
615
615
|
async () => {
|
|
616
616
|
try {
|
|
617
|
-
const { getActivePlans } = await import("./colony-
|
|
617
|
+
const { getActivePlans } = await import("./colony-YDOTBQFD.js");
|
|
618
618
|
const plans = getActivePlans();
|
|
619
619
|
return {
|
|
620
620
|
content: [
|
|
@@ -637,7 +637,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
637
637
|
},
|
|
638
638
|
async ({ description }) => {
|
|
639
639
|
try {
|
|
640
|
-
const { proposePlan } = await import("./colony-
|
|
640
|
+
const { proposePlan } = await import("./colony-YDOTBQFD.js");
|
|
641
641
|
const result = await proposePlan(description);
|
|
642
642
|
if (result.success) {
|
|
643
643
|
return {
|
|
@@ -660,7 +660,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
660
660
|
},
|
|
661
661
|
async ({ planId }) => {
|
|
662
662
|
try {
|
|
663
|
-
const { joinPlan } = await import("./colony-
|
|
663
|
+
const { joinPlan } = await import("./colony-YDOTBQFD.js");
|
|
664
664
|
const result = await joinPlan(planId);
|
|
665
665
|
if (result.success) {
|
|
666
666
|
return { content: [{ type: "text", text: "Joined the plan! Go execute it." }] };
|
|
@@ -679,7 +679,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
679
679
|
},
|
|
680
680
|
async ({ status }) => {
|
|
681
681
|
try {
|
|
682
|
-
const { postStatus } = await import("./colony-
|
|
682
|
+
const { postStatus } = await import("./colony-YDOTBQFD.js");
|
|
683
683
|
const result = await postStatus(status);
|
|
684
684
|
if (result.success) {
|
|
685
685
|
return { content: [{ type: "text", text: "Status posted to the Colony." }] };
|
|
@@ -696,7 +696,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
|
|
|
696
696
|
{},
|
|
697
697
|
async () => {
|
|
698
698
|
try {
|
|
699
|
-
const { getTodaysActivity } = await import("./colony-
|
|
699
|
+
const { getTodaysActivity } = await import("./colony-YDOTBQFD.js");
|
|
700
700
|
const activity = getTodaysActivity();
|
|
701
701
|
return {
|
|
702
702
|
content: [
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
buildHeartbeatUserMessage,
|
|
4
4
|
buildNarratedHeartbeatMessage,
|
|
5
5
|
buildSystemPrompt
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-NHNOCAP3.js";
|
|
7
7
|
import "./chunk-C3INKEY6.js";
|
|
8
8
|
import "./chunk-RCJQI7FR.js";
|
|
9
9
|
import "./chunk-AIEXQCQS.js";
|
|
@@ -16,4 +16,4 @@ export {
|
|
|
16
16
|
buildNarratedHeartbeatMessage,
|
|
17
17
|
buildSystemPrompt
|
|
18
18
|
};
|
|
19
|
-
//# sourceMappingURL=prompt-builder-
|
|
19
|
+
//# sourceMappingURL=prompt-builder-3AJUQUVZ.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
addToQueue,
|
|
3
3
|
flushQueue,
|
|
4
4
|
showQueue
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OGFMGURJ.js";
|
|
6
6
|
import "./chunk-RCJQI7FR.js";
|
|
7
7
|
import "./chunk-KELPENM3.js";
|
|
8
8
|
import "./chunk-53YLFYJF.js";
|
|
@@ -11,4 +11,4 @@ export {
|
|
|
11
11
|
flushQueue,
|
|
12
12
|
showQueue
|
|
13
13
|
};
|
|
14
|
-
//# sourceMappingURL=queue-
|
|
14
|
+
//# sourceMappingURL=queue-LHRG6JOP.js.map
|
package/dist/web-chat/chat.html
CHANGED
|
@@ -486,12 +486,11 @@
|
|
|
486
486
|
background: #389e77;
|
|
487
487
|
}
|
|
488
488
|
|
|
489
|
-
/* Sleep indicator */
|
|
489
|
+
/* Sleep indicator — styled like a chat message */
|
|
490
490
|
.sleep-indicator {
|
|
491
491
|
display: none;
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
padding: 12px 0 4px;
|
|
492
|
+
gap: 0.625rem;
|
|
493
|
+
padding: 0 1.25rem;
|
|
495
494
|
animation: fadeIn 0.4s ease-in;
|
|
496
495
|
}
|
|
497
496
|
|
|
@@ -499,43 +498,78 @@
|
|
|
499
498
|
display: flex;
|
|
500
499
|
}
|
|
501
500
|
|
|
501
|
+
.sleep-avatar {
|
|
502
|
+
width: 32px;
|
|
503
|
+
height: 32px;
|
|
504
|
+
border-radius: 50%;
|
|
505
|
+
background: #1a1a1a;
|
|
506
|
+
display: flex;
|
|
507
|
+
align-items: center;
|
|
508
|
+
justify-content: center;
|
|
509
|
+
flex-shrink: 0;
|
|
510
|
+
overflow: hidden;
|
|
511
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.sleep-avatar img {
|
|
515
|
+
width: 100%;
|
|
516
|
+
height: 100%;
|
|
517
|
+
object-fit: cover;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.sleep-bubble {
|
|
521
|
+
display: flex;
|
|
522
|
+
align-items: center;
|
|
523
|
+
gap: 8px;
|
|
524
|
+
background: #141414;
|
|
525
|
+
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
526
|
+
border-radius: 0.75rem;
|
|
527
|
+
border-bottom-left-radius: 0.25rem;
|
|
528
|
+
padding: 0.5rem 0.75rem;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
.sleep-text {
|
|
532
|
+
font-size: 0.8125rem;
|
|
533
|
+
color: rgba(255, 255, 255, 0.4);
|
|
534
|
+
white-space: nowrap;
|
|
535
|
+
}
|
|
536
|
+
|
|
502
537
|
.sleep-zzz {
|
|
503
538
|
display: flex;
|
|
504
539
|
align-items: baseline;
|
|
505
|
-
gap:
|
|
506
|
-
font-size: 1rem;
|
|
507
|
-
font-weight: 700;
|
|
508
|
-
color: rgba(255, 255, 255, 0.25);
|
|
509
|
-
margin-bottom: 4px;
|
|
540
|
+
gap: 1px;
|
|
510
541
|
}
|
|
511
542
|
|
|
512
543
|
.sleep-zzz span {
|
|
513
544
|
display: inline-block;
|
|
545
|
+
font-weight: 700;
|
|
546
|
+
color: rgba(255, 255, 255, 0.25);
|
|
514
547
|
animation: zzzFloat 2s ease-in-out infinite;
|
|
515
548
|
}
|
|
516
549
|
|
|
517
550
|
.sleep-zzz span:nth-child(1) {
|
|
518
|
-
font-size: 0.
|
|
551
|
+
font-size: 0.5rem;
|
|
519
552
|
animation-delay: 0s;
|
|
520
553
|
}
|
|
521
554
|
.sleep-zzz span:nth-child(2) {
|
|
522
|
-
font-size: 0.
|
|
555
|
+
font-size: 0.65rem;
|
|
523
556
|
animation-delay: 0.3s;
|
|
524
557
|
}
|
|
525
558
|
.sleep-zzz span:nth-child(3) {
|
|
526
|
-
font-size:
|
|
559
|
+
font-size: 0.8rem;
|
|
527
560
|
animation-delay: 0.6s;
|
|
528
561
|
}
|
|
529
562
|
|
|
530
563
|
@keyframes zzzFloat {
|
|
531
564
|
0%, 100% { opacity: 0.3; transform: translateY(0); }
|
|
532
|
-
50% { opacity: 1; transform: translateY(-
|
|
565
|
+
50% { opacity: 1; transform: translateY(-3px); }
|
|
533
566
|
}
|
|
534
567
|
|
|
535
568
|
.sleep-countdown {
|
|
536
569
|
font-size: 0.6875rem;
|
|
537
570
|
color: rgba(255, 255, 255, 0.2);
|
|
538
571
|
font-variant-numeric: tabular-nums;
|
|
572
|
+
margin-left: 2px;
|
|
539
573
|
}
|
|
540
574
|
</style>
|
|
541
575
|
</head>
|
|
@@ -576,10 +610,14 @@
|
|
|
576
610
|
</div>
|
|
577
611
|
|
|
578
612
|
<div class="sleep-indicator" id="sleepIndicator">
|
|
579
|
-
<div class="sleep-
|
|
580
|
-
|
|
613
|
+
<div class="sleep-avatar" id="sleepAvatar"></div>
|
|
614
|
+
<div class="sleep-bubble">
|
|
615
|
+
<span class="sleep-text">Sleeping</span>
|
|
616
|
+
<div class="sleep-zzz">
|
|
617
|
+
<span>z</span><span>z</span><span>z</span>
|
|
618
|
+
</div>
|
|
619
|
+
<span class="sleep-countdown" id="sleepCountdown"></span>
|
|
581
620
|
</div>
|
|
582
|
-
<div class="sleep-countdown" id="sleepCountdown">Sleeping...</div>
|
|
583
621
|
</div>
|
|
584
622
|
|
|
585
623
|
<div class="input-container">
|
|
@@ -1009,18 +1047,33 @@
|
|
|
1009
1047
|
let sleepTimer = null;
|
|
1010
1048
|
|
|
1011
1049
|
function formatCountdown(ms) {
|
|
1012
|
-
if (ms <= 0) return '
|
|
1050
|
+
if (ms <= 0) return '';
|
|
1013
1051
|
const totalSec = Math.ceil(ms / 1000);
|
|
1014
1052
|
const h = Math.floor(totalSec / 3600);
|
|
1015
1053
|
const m = Math.floor((totalSec % 3600) / 60);
|
|
1016
1054
|
const s = totalSec % 60;
|
|
1017
|
-
if (h > 0) return
|
|
1018
|
-
if (m > 0) return
|
|
1019
|
-
return
|
|
1055
|
+
if (h > 0) return `${h}h ${m}m`;
|
|
1056
|
+
if (m > 0) return `${m}m ${s}s`;
|
|
1057
|
+
return `${s}s`;
|
|
1020
1058
|
}
|
|
1021
1059
|
|
|
1022
1060
|
function startSleepCountdown(wakeAt) {
|
|
1023
1061
|
stopSleepCountdown();
|
|
1062
|
+
|
|
1063
|
+
// Populate sleep avatar to match agent PFP
|
|
1064
|
+
const sleepAvatarEl = document.getElementById('sleepAvatar');
|
|
1065
|
+
if (sleepAvatarEl && !sleepAvatarEl.hasChildNodes()) {
|
|
1066
|
+
if (agentPfp) {
|
|
1067
|
+
sleepAvatarEl.innerHTML = `<img src="${agentPfp}" alt="${agentName}" />`;
|
|
1068
|
+
} else {
|
|
1069
|
+
sleepAvatarEl.textContent = agentName.charAt(0).toUpperCase();
|
|
1070
|
+
sleepAvatarEl.style.background = '#389e77';
|
|
1071
|
+
sleepAvatarEl.style.color = '#fff';
|
|
1072
|
+
sleepAvatarEl.style.fontSize = '0.75rem';
|
|
1073
|
+
sleepAvatarEl.style.fontWeight = '700';
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1024
1077
|
sleepIndicator.classList.add('visible');
|
|
1025
1078
|
statusDot.style.background = '#71767b';
|
|
1026
1079
|
statusDot.style.animation = 'none';
|
|
@@ -256,7 +256,7 @@ async function extractAndSaveLearnings(responseText) {
|
|
|
256
256
|
return responseText.replace(/<<LEARN:\s*.+?>>/g, "").trim();
|
|
257
257
|
}
|
|
258
258
|
async function extractAndExecuteActions(responseText) {
|
|
259
|
-
const { parseActions, executeActions } = await import("./decision-engine-
|
|
259
|
+
const { parseActions, executeActions } = await import("./decision-engine-IIA5J2QG.js");
|
|
260
260
|
const jsonBlockPattern = /```json\s*([\s\S]*?)```/g;
|
|
261
261
|
const blocks = [...responseText.matchAll(jsonBlockPattern)];
|
|
262
262
|
const visibleResults = [];
|
|
@@ -336,7 +336,7 @@ async function startWebChat() {
|
|
|
336
336
|
try {
|
|
337
337
|
const { hasXCredentials } = await import("./paths-5GFUUHCZ.js");
|
|
338
338
|
if (hasXCredentials()) {
|
|
339
|
-
const { getXClient } = await import("./x-client-
|
|
339
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
340
340
|
const client = await getXClient();
|
|
341
341
|
if ("getAuthenticatedHandle" in client) {
|
|
342
342
|
realHandle = await client.getAuthenticatedHandle();
|
|
@@ -358,8 +358,9 @@ async function startWebChat() {
|
|
|
358
358
|
let messageCount = 0;
|
|
359
359
|
server.setMessageHandler(async (message) => {
|
|
360
360
|
try {
|
|
361
|
+
server.setAwake();
|
|
361
362
|
if (!systemPrompt || messageCount % 10 === 0) {
|
|
362
|
-
const { buildChatPrompt } = await import("./prompt-builder-
|
|
363
|
+
const { buildChatPrompt } = await import("./prompt-builder-3AJUQUVZ.js");
|
|
363
364
|
systemPrompt = buildChatPrompt(realHandle);
|
|
364
365
|
}
|
|
365
366
|
messageCount++;
|
|
@@ -472,7 +473,7 @@ async function startNarratedHeartbeat(server) {
|
|
|
472
473
|
await new Promise((r) => setTimeout(r, Math.min(1e4, sleepMs - slept)));
|
|
473
474
|
slept += 1e4;
|
|
474
475
|
try {
|
|
475
|
-
const { flushQueue } = await import("./queue-
|
|
476
|
+
const { flushQueue } = await import("./queue-LHRG6JOP.js");
|
|
476
477
|
const flushed = await flushQueue();
|
|
477
478
|
if (flushed.posted > 0) {
|
|
478
479
|
console.log(chalk.green(` [Queue] Posted ${flushed.posted} scheduled tweet(s)`));
|
|
@@ -484,11 +485,11 @@ async function startNarratedHeartbeat(server) {
|
|
|
484
485
|
}
|
|
485
486
|
}
|
|
486
487
|
async function runNarratedHeartbeat(server, maxActions, intervalMs) {
|
|
487
|
-
const { getXClient } = await import("./x-client-
|
|
488
|
-
const { buildSystemPrompt, buildNarratedHeartbeatMessage } = await import("./prompt-builder-
|
|
488
|
+
const { getXClient } = await import("./x-client-QNLSLY2R.js");
|
|
489
|
+
const { buildSystemPrompt, buildNarratedHeartbeatMessage } = await import("./prompt-builder-3AJUQUVZ.js");
|
|
489
490
|
const { generateResponse } = await import("./llm-WLEJLNEA.js");
|
|
490
|
-
const { parseActions, executeActions } = await import("./decision-engine-
|
|
491
|
-
const { flushQueue } = await import("./queue-
|
|
491
|
+
const { parseActions, executeActions } = await import("./decision-engine-IIA5J2QG.js");
|
|
492
|
+
const { flushQueue } = await import("./queue-LHRG6JOP.js");
|
|
492
493
|
try {
|
|
493
494
|
const flushed = await flushQueue();
|
|
494
495
|
if (flushed.posted > 0) {
|
|
@@ -539,8 +540,14 @@ async function runNarratedHeartbeat(server, maxActions, intervalMs) {
|
|
|
539
540
|
if (r.action === "schedule") {
|
|
540
541
|
console.log(chalk.dim(` [Heartbeat] ${r.action}: ${r.success ? "queued" : r.error}${detail}`));
|
|
541
542
|
} else if (r.success) {
|
|
542
|
-
|
|
543
|
-
|
|
543
|
+
if ((r.action === "post" || r.action === "reply") && r.content) {
|
|
544
|
+
const tweetData = JSON.stringify({ action: r.action, tweetId: r.detail ?? null, content: r.content });
|
|
545
|
+
visibleResults.push(`<<TWEET:${tweetData}>>`);
|
|
546
|
+
console.log(chalk.green(` [Heartbeat] ${r.action}: success (tweet preview)`));
|
|
547
|
+
} else {
|
|
548
|
+
visibleResults.push(`[${r.action}] Done${detail}`);
|
|
549
|
+
console.log(chalk.green(` [Heartbeat] ${r.action}: success${detail}`));
|
|
550
|
+
}
|
|
544
551
|
} else {
|
|
545
552
|
visibleResults.push(`[${r.action}] Failed: ${r.error}`);
|
|
546
553
|
console.log(chalk.red(` [Heartbeat] ${r.action}: ${r.error}`));
|
|
@@ -592,4 +599,4 @@ export {
|
|
|
592
599
|
openBrowser,
|
|
593
600
|
startWebChat
|
|
594
601
|
};
|
|
595
|
-
//# sourceMappingURL=web-chat-
|
|
602
|
+
//# sourceMappingURL=web-chat-6ZRJE73E.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/web-chat/server.ts","../src/web-chat/index.ts"],"sourcesContent":["/**\n * Local web chat server\n * Serves a simple chat interface for interacting with your Spore\n */\n\nimport http from \"node:http\";\nimport { URL } from \"node:url\";\nimport { readFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\ninterface ChatMessage {\n role: \"user\" | \"assistant\";\n content: string;\n timestamp: number;\n}\n\ninterface AgentIdentity {\n name: string;\n handle: string;\n bio?: string;\n profileImage?: string;\n createdAt?: string;\n}\n\nexport class WebChatServer {\n private server: http.Server | null = null;\n private port: number;\n private messages: ChatMessage[] = [];\n private onUserMessage?: (message: string) => Promise<string>;\n private onHeartbeatChange?: (intervalMs: number) => void;\n private identity?: AgentIdentity;\n private sleepState: { sleeping: boolean; wakeAt: number | null; intervalMs: number } = {\n sleeping: false,\n wakeAt: null,\n intervalMs: 60_000,\n };\n\n constructor(port = 3737) {\n this.port = port;\n }\n\n setIdentity(identity: AgentIdentity) {\n this.identity = identity;\n }\n\n setMessageHandler(handler: (message: string) => Promise<string>) {\n this.onUserMessage = handler;\n }\n\n setHeartbeatChangeHandler(handler: (intervalMs: number) => void) {\n this.onHeartbeatChange = handler;\n }\n\n setSleeping(wakeAt: number) {\n this.sleepState.sleeping = true;\n this.sleepState.wakeAt = wakeAt;\n }\n\n setAwake() {\n this.sleepState.sleeping = false;\n this.sleepState.wakeAt = null;\n }\n\n setHeartbeatInterval(intervalMs: number) {\n this.sleepState.intervalMs = intervalMs;\n }\n\n getHeartbeatInterval(): number {\n return this.sleepState.intervalMs;\n }\n\n async start(): Promise<string> {\n return new Promise((resolve, reject) => {\n this.server = http.createServer(async (req, res) => {\n const url = new URL(req.url || \"/\", `http://${req.headers.host}`);\n\n // CORS headers\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\");\n res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type\");\n\n if (req.method === \"OPTIONS\") {\n res.writeHead(200);\n res.end();\n return;\n }\n\n // Serve HTML\n if (url.pathname === \"/\" || url.pathname === \"/index.html\") {\n try {\n // Try multiple paths since __dirname changes based on build output\n const possiblePaths = [\n join(__dirname, \"web-chat\", \"chat.html\"),\n join(__dirname, \"chat.html\"),\n join(__dirname, \"..\", \"web-chat\", \"chat.html\"),\n join(__dirname, \"..\", \"src\", \"web-chat\", \"chat.html\"),\n ];\n\n let html: string | null = null;\n for (const p of possiblePaths) {\n try {\n html = readFileSync(p, \"utf-8\");\n break;\n } catch {\n continue;\n }\n }\n\n if (html) {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(html);\n } else {\n console.error(\"Could not find chat.html in any of:\", possiblePaths);\n res.writeHead(500);\n res.end(\"Error: Could not find chat.html\");\n }\n } catch (error) {\n res.writeHead(500);\n res.end(\"Error loading chat interface\");\n }\n return;\n }\n\n // Serve logo\n if (url.pathname === \"/logo.png\") {\n try {\n const logoPaths = [\n join(__dirname, \"web-chat\", \"logo.png\"),\n join(__dirname, \"logo.png\"),\n join(__dirname, \"..\", \"web-chat\", \"logo.png\"),\n join(__dirname, \"..\", \"src\", \"web-chat\", \"logo.png\"),\n ];\n let logoData: Buffer | null = null;\n for (const p of logoPaths) {\n try {\n logoData = readFileSync(p) as unknown as Buffer;\n break;\n } catch {\n continue;\n }\n }\n if (logoData) {\n res.writeHead(200, { \"Content-Type\": \"image/png\", \"Cache-Control\": \"public, max-age=86400\" });\n res.end(logoData);\n } else {\n res.writeHead(404);\n res.end(\"Logo not found\");\n }\n } catch {\n res.writeHead(404);\n res.end(\"Logo not found\");\n }\n return;\n }\n\n // API: Get agent identity\n if (url.pathname === \"/api/identity\" && req.method === \"GET\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ identity: this.identity || null }));\n return;\n }\n\n // API: Get messages (optionally since a timestamp)\n if (url.pathname === \"/api/messages\" && req.method === \"GET\") {\n const since = url.searchParams.get(\"since\");\n if (since) {\n const sinceTs = parseInt(since, 10);\n const newMessages = this.messages.filter((m) => m.timestamp > sinceTs);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ messages: newMessages }));\n } else {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ messages: this.messages }));\n }\n return;\n }\n\n // API: Send message\n if (url.pathname === \"/api/message\" && req.method === \"POST\") {\n let body = \"\";\n req.on(\"data\", (chunk) => {\n body += chunk.toString();\n });\n\n req.on(\"end\", async () => {\n try {\n const { message } = JSON.parse(body);\n\n // Add user message\n this.messages.push({\n role: \"user\",\n content: message,\n timestamp: Date.now(),\n });\n\n // Get response\n if (this.onUserMessage) {\n const response = await this.onUserMessage(message);\n this.messages.push({\n role: \"assistant\",\n content: response,\n timestamp: Date.now(),\n });\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ success: true, response }));\n } else {\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"No message handler configured\" }));\n }\n } catch (error) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Invalid request\" }));\n }\n });\n return;\n }\n\n // API: Get sleep state\n if (url.pathname === \"/api/sleep-state\" && req.method === \"GET\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(this.sleepState));\n return;\n }\n\n // API: Update heartbeat interval\n if (url.pathname === \"/api/config/heartbeat\" && req.method === \"POST\") {\n let body = \"\";\n req.on(\"data\", (chunk) => { body += chunk.toString(); });\n req.on(\"end\", () => {\n try {\n const { intervalMs } = JSON.parse(body);\n if (typeof intervalMs === \"number\" && intervalMs >= 60_000) {\n this.sleepState.intervalMs = intervalMs;\n if (this.onHeartbeatChange) {\n this.onHeartbeatChange(intervalMs);\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ success: true, intervalMs }));\n } else {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Invalid interval\" }));\n }\n } catch {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Invalid request\" }));\n }\n });\n return;\n }\n\n // 404\n res.writeHead(404);\n res.end(\"Not found\");\n });\n\n this.server.listen(this.port, () => {\n const url = `http://localhost:${this.port}`;\n resolve(url);\n });\n\n this.server.on(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code === \"EADDRINUSE\") {\n // Port in use, try next port\n this.port++;\n this.server?.close();\n this.start().then(resolve).catch(reject);\n } else {\n reject(error);\n }\n });\n });\n }\n\n /**\n * Push a message into the chat from the server side (used by heartbeat narration)\n */\n pushMessage(role: \"user\" | \"assistant\", content: string) {\n this.messages.push({ role, content, timestamp: Date.now() });\n }\n\n getMessageCount(): number {\n return this.messages.length;\n }\n\n stop() {\n if (this.server) {\n this.server.close();\n this.server = null;\n }\n }\n}\n","/**\n * Web chat integration\n */\n\nimport { WebChatServer } from \"./server.js\";\nimport { loadIdentity } from \"../identity/index.js\";\nimport { execSync } from \"node:child_process\";\nimport chalk from \"chalk\";\n\n/**\n * Extract <<LEARN: ...>> tags from response, save them, and return cleaned text\n */\nasync function extractAndSaveLearnings(responseText: string): Promise<string> {\n const learnPattern = /<<LEARN:\\s*(.+?)>>/g;\n const matches = [...responseText.matchAll(learnPattern)];\n\n if (matches.length > 0) {\n const { addLearning } = await import(\"../memory/index.js\");\n for (const match of matches) {\n const learning = match[1].trim();\n addLearning(learning, \"web-chat\", [\"chat\", \"creator-interaction\"]);\n console.log(chalk.dim(` [Memory] Saved learning: ${learning}`));\n }\n }\n\n // Strip the learn tags from the response the user sees\n return responseText.replace(/<<LEARN:\\s*.+?>>/g, \"\").trim();\n}\n\n/**\n * Extract JSON action blocks from the LLM response, execute them, and return cleaned text + results.\n * Search results are returned separately so the caller can feed them back to the LLM.\n */\nasync function extractAndExecuteActions(responseText: string): Promise<{\n cleanText: string;\n results: string[];\n searchResults: string | null;\n}> {\n const { parseActions, executeActions } = await import(\"../runtime/decision-engine.js\");\n\n // Try to find JSON code blocks in the response\n const jsonBlockPattern = /```json\\s*([\\s\\S]*?)```/g;\n const blocks = [...responseText.matchAll(jsonBlockPattern)];\n const visibleResults: string[] = [];\n let searchResults: string | null = null;\n\n const processResults = (actionResults: Awaited<ReturnType<typeof executeActions>>) => {\n for (const r of actionResults) {\n if (r.action === \"search\") {\n // Search results are internal — don't show in chat\n if (r.success && r.detail && r.detail !== \"No results found\") {\n searchResults = r.detail;\n console.log(chalk.green(` [Actions] search: found results (internal)`));\n } else {\n console.log(chalk.dim(` [Actions] search: ${r.detail ?? r.error ?? \"no results\"}`));\n }\n } else if (r.success) {\n // For post/reply/schedule with content, emit a tweet preview tag\n if ((r.action === \"post\" || r.action === \"reply\" || r.action === \"schedule\") && r.content) {\n const tweetData = JSON.stringify({ action: r.action, tweetId: r.detail ?? null, content: r.content });\n visibleResults.push(`<<TWEET:${tweetData}>>`);\n console.log(chalk.green(` [Actions] ${r.action}: success (tweet preview)`));\n } else {\n const detail = r.detail ? ` (${r.detail})` : \"\";\n visibleResults.push(`[${r.action}] Done${detail}`);\n console.log(chalk.green(` [Actions] ${r.action}: success${detail}`));\n }\n } else {\n visibleResults.push(`[${r.action}] Failed: ${r.error}`);\n console.log(chalk.red(` [Actions] ${r.action}: ${r.error}`));\n }\n }\n };\n\n if (blocks.length > 0) {\n for (const block of blocks) {\n const actions = parseActions(block[1]);\n if (actions.length > 0) {\n console.log(chalk.cyan(` [Actions] Executing ${actions.length} action(s)...`));\n const actionResults = await executeActions(actions);\n processResults(actionResults);\n }\n }\n } else {\n // Also try raw JSON (no code block wrapper)\n const actions = parseActions(responseText);\n if (actions.length > 0 && actions[0].action) {\n console.log(chalk.cyan(` [Actions] Executing ${actions.length} action(s)...`));\n const actionResults = await executeActions(actions);\n processResults(actionResults);\n }\n }\n\n // Strip JSON code blocks from the user-visible text\n let cleanText = responseText.replace(/```json\\s*[\\s\\S]*?```/g, \"\").trim();\n // Clean up extra whitespace from removal\n cleanText = cleanText.replace(/\\n{3,}/g, \"\\n\\n\").trim();\n\n // Append visible action results (search excluded)\n if (visibleResults.length > 0) {\n cleanText += \"\\n\\n\" + visibleResults.join(\"\\n\");\n }\n\n return { cleanText, results: visibleResults, searchResults };\n}\n\n/**\n * Log a chat exchange as an interaction in memory\n */\nasync function logChatInteraction(userMessage: string, agentResponse: string): Promise<void> {\n const { logInteraction } = await import(\"../memory/index.js\");\n logInteraction({\n id: `chat-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n timestamp: new Date().toISOString(),\n type: \"reply\",\n content: agentResponse.slice(0, 200),\n targetHandle: \"creator\",\n creditsUsed: 0,\n success: true,\n });\n}\n\nexport async function startWebChat() {\n const identity = loadIdentity();\n\n const server = new WebChatServer();\n\n // Pass identity to server so the chat UI can display it\n server.setIdentity({\n name: identity.name,\n handle: identity.handle,\n bio: identity.bio,\n profileImage: identity.profileImage,\n createdAt: identity.createdAt,\n });\n\n // Resolve real Twitter handle on startup\n let realHandle: string | undefined;\n try {\n const { hasXCredentials } = await import(\"../utils/paths.js\");\n if (hasXCredentials()) {\n const { getXClient } = await import(\"../x-client/index.js\");\n const client = await getXClient();\n if (\"getAuthenticatedHandle\" in client) {\n realHandle = await (client as any).getAuthenticatedHandle();\n console.log(chalk.dim(` [Auth] Real Twitter handle: @${realHandle}`));\n // Update the server identity to show the real handle\n server.setIdentity({\n name: identity.name,\n handle: realHandle,\n bio: identity.bio,\n profileImage: identity.profileImage,\n createdAt: identity.createdAt,\n });\n }\n }\n } catch (err) {\n console.log(chalk.dim(` [Auth] Could not resolve real handle: ${(err as Error).message}`));\n }\n\n // Set up message handler - connected to actual LLM with memory\n const chatHistory: Array<{ role: \"user\" | \"assistant\"; content: string }> = [];\n let systemPrompt: string | null = null;\n let messageCount = 0;\n\n server.setMessageHandler(async (message: string) => {\n try {\n // Manual message = instant wake — clear sleep indicator\n server.setAwake();\n\n // Build system prompt on first message, rebuild every 10 messages to refresh memory\n if (!systemPrompt || messageCount % 10 === 0) {\n const { buildChatPrompt } = await import(\"../runtime/prompt-builder.js\");\n systemPrompt = buildChatPrompt(realHandle);\n }\n messageCount++;\n\n // Check for LLM key\n const { hasLLMKey, chat: chatLLM } = await import(\"../runtime/llm.js\");\n if (!hasLLMKey()) {\n return \"I can't respond right now - no API key configured. Run `spora set-llm-key` to set one up.\";\n }\n\n // Add user message to history\n chatHistory.push({ role: \"user\", content: message });\n\n // Call LLM with full conversation history\n const response = await chatLLM(systemPrompt, chatHistory);\n\n // Extract and execute any actions (posts, likes, etc.) from the response\n let { cleanText: actionCleanedText, searchResults } = await extractAndExecuteActions(response.content);\n\n // Two-pass: if search returned results, feed them back to the LLM so it can act on them\n if (searchResults) {\n console.log(chalk.cyan(\" [Chat] Search returned results — doing follow-up LLM call...\"));\n\n // Add the first response (narration) to history as context\n const firstNarration = actionCleanedText.replace(/```json\\s*[\\s\\S]*?```/g, \"\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\n if (firstNarration) {\n chatHistory.push({ role: \"assistant\", content: firstNarration });\n }\n\n // Inject search results as a system-style user message the LLM can act on\n chatHistory.push({\n role: \"user\",\n content: `[Internal: here are the search results you requested. Pick one or more to act on (reply, like, etc.) and do it now. Do NOT show these results to me — just act on them and tell me what you did.]\\n\\n${searchResults}`,\n });\n\n // Second LLM call — it now has search results and can reply/like\n const followUp = await chatLLM(systemPrompt, chatHistory);\n const followUpResult = await extractAndExecuteActions(followUp.content);\n actionCleanedText = followUpResult.cleanText;\n\n // Remove the internal search-results message from visible history\n chatHistory.pop();\n if (firstNarration) {\n chatHistory.pop();\n }\n }\n\n // Extract learnings from response and clean the text\n const cleanResponse = await extractAndSaveLearnings(actionCleanedText);\n\n // Add cleaned assistant response to history\n chatHistory.push({ role: \"assistant\", content: cleanResponse });\n\n // Log interaction to memory (async, don't block response)\n logChatInteraction(message, cleanResponse).catch((err) =>\n console.error(chalk.dim(\" [Memory] Failed to log interaction:\"), err)\n );\n\n return cleanResponse;\n } catch (error) {\n console.error(\"Chat error:\", error);\n return `Sorry, I ran into an issue: ${(error as Error).message}`;\n }\n });\n\n const url = await server.start();\n\n console.log(chalk.green(`\\n✓ Chat interface started at ${chalk.bold(url)}\\n`));\n console.log(chalk.dim(`Press Ctrl+C to stop the server\\n`));\n\n // Open browser\n openBrowser(url);\n\n // Start background heartbeat (narrates into chat)\n startNarratedHeartbeat(server).catch((err) =>\n console.error(chalk.red(\"Heartbeat failed to start:\"), err)\n );\n\n // Keep process alive\n process.on(\"SIGINT\", () => {\n console.log(chalk.yellow(\"\\n\\nStopping chat server...\"));\n heartbeatRunning = false;\n server.stop();\n process.exit(0);\n });\n\n // Return the server instance for external control\n return server;\n}\n\n/**\n * Background heartbeat that narrates into the chat UI\n */\nlet heartbeatRunning = false;\nlet lastTimelineSinceId: string | undefined;\nlet lastMentionsSinceId: string | undefined;\n\nasync function startNarratedHeartbeat(server: WebChatServer) {\n const { loadConfig } = await import(\"../utils/config.js\");\n const { hasLLMKey, generateResponse } = await import(\"../runtime/llm.js\");\n const { hasXCredentials } = await import(\"../utils/paths.js\");\n\n if (!hasLLMKey()) {\n console.log(chalk.dim(\" [Heartbeat] No LLM key — heartbeat disabled.\"));\n return;\n }\n\n if (!hasXCredentials()) {\n console.log(chalk.dim(\" [Heartbeat] No X credentials — heartbeat disabled.\"));\n return;\n }\n\n const config = loadConfig();\n let intervalMs = config.runtime?.heartbeatIntervalMs ?? 60_000;\n const maxActions = config.runtime?.actionsPerHeartbeat ?? 10;\n\n // Set initial heartbeat interval on server and listen for UI changes\n server.setHeartbeatInterval(intervalMs);\n server.setHeartbeatChangeHandler((newIntervalMs: number) => {\n intervalMs = newIntervalMs;\n console.log(chalk.cyan(` [Heartbeat] Interval changed to ${Math.round(newIntervalMs / 1000)}s`));\n // Persist to config (async, fire-and-forget)\n import(\"../utils/config.js\").then(({ loadConfig: reloadConfig, saveConfig }) => {\n const cfg = reloadConfig();\n if (!cfg.runtime) cfg.runtime = {};\n cfg.runtime.heartbeatIntervalMs = newIntervalMs;\n saveConfig(cfg);\n }).catch(() => {\n // Config save failed, not critical — will use new interval in memory\n });\n });\n\n heartbeatRunning = true;\n let heartbeatCount = 0;\n\n console.log(chalk.cyan(` [Heartbeat] Running every ${Math.round(intervalMs / 1000)}s\\n`));\n\n while (heartbeatRunning) {\n heartbeatCount++;\n console.log(chalk.cyan(` [Heartbeat] #${heartbeatCount} starting...`));\n server.setAwake();\n\n try {\n await runNarratedHeartbeat(server, maxActions, intervalMs);\n } catch (error) {\n console.error(chalk.red(` [Heartbeat] #${heartbeatCount} failed:`), (error as Error).message);\n server.pushMessage(\"assistant\", `Heartbeat error: ${(error as Error).message}`);\n }\n\n // Sleep with jitter — flush queue during sleep so scheduled posts go out on time\n const jitter = Math.floor(Math.random() * intervalMs * 0.2);\n const sleepMs = intervalMs + jitter;\n console.log(chalk.dim(` [Heartbeat] Sleeping ${Math.round(sleepMs / 1000)}s...`));\n\n // Tell the server we're sleeping so the UI can show the indicator\n server.setSleeping(Date.now() + sleepMs);\n\n let slept = 0;\n while (slept < sleepMs && heartbeatRunning) {\n await new Promise((r) => setTimeout(r, Math.min(10000, sleepMs - slept)));\n slept += 10000;\n\n // Flush queue during sleep so scheduled posts go out at their intended times\n try {\n const { flushQueue } = await import(\"../scheduler/queue.js\");\n const flushed = await flushQueue();\n if (flushed.posted > 0) {\n console.log(chalk.green(` [Queue] Posted ${flushed.posted} scheduled tweet(s)`));\n }\n } catch {\n // Queue flush failed during sleep, not critical\n }\n }\n\n server.setAwake();\n }\n}\n\nasync function runNarratedHeartbeat(server: WebChatServer, maxActions: number, intervalMs: number) {\n const { getXClient } = await import(\"../x-client/index.js\");\n const { buildSystemPrompt, buildNarratedHeartbeatMessage } = await import(\"../runtime/prompt-builder.js\");\n const { generateResponse } = await import(\"../runtime/llm.js\");\n const { parseActions, executeActions } = await import(\"../runtime/decision-engine.js\");\n const { flushQueue } = await import(\"../scheduler/queue.js\");\n\n // 1. Flush queued posts (silent — user doesn't see this)\n try {\n const flushed = await flushQueue();\n if (flushed.posted > 0) {\n console.log(chalk.green(` [Queue] Flushed ${flushed.posted} scheduled tweet(s)`));\n }\n } catch {\n // Queue flush failed, not critical\n }\n\n // 2. Read timeline and mentions (only new since last check)\n\n const client = await getXClient();\n let timeline: Awaited<ReturnType<typeof client.getTimeline>> = [];\n let mentions: Awaited<ReturnType<typeof client.getMentions>> = [];\n\n // Get the bot's own handle to filter own tweets from timeline\n let ownHandle: string | undefined;\n if (\"getAuthenticatedHandle\" in client) {\n try {\n ownHandle = await (client as any).getAuthenticatedHandle();\n } catch {}\n }\n\n try {\n timeline = await client.getTimeline({ count: 20, sinceId: lastTimelineSinceId });\n if (timeline.length > 0) {\n lastTimelineSinceId = timeline[0].id;\n // Filter out own tweets (can't like your own)\n if (ownHandle) {\n timeline = timeline.filter(t => t.authorHandle.toLowerCase() !== ownHandle!.toLowerCase());\n }\n }\n } catch (error) {\n console.log(chalk.dim(` [Heartbeat] Timeline read failed: ${(error as Error).message}`));\n }\n\n try {\n mentions = await client.getMentions({ count: 10, sinceId: lastMentionsSinceId });\n if (mentions.length > 0) {\n lastMentionsSinceId = mentions[0].id;\n }\n } catch (error) {\n console.log(chalk.dim(` [Heartbeat] Mentions read failed: ${(error as Error).message}`));\n }\n\n // 3. Build prompts and ask LLM\n const systemPrompt = buildSystemPrompt();\n const userMessage = buildNarratedHeartbeatMessage(timeline, mentions, intervalMs);\n\n const response = await generateResponse(systemPrompt, userMessage);\n\n // 4. Extract narration text (everything outside JSON blocks)\n let narration = response.content.replace(/```json\\s*[\\s\\S]*?```/g, \"\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\n\n // 5. Parse and execute actions\n const actions = parseActions(response.content);\n const limitedActions = actions.slice(0, maxActions);\n\n if (limitedActions.length > 0) {\n // Execute actions\n const results = await executeActions(limitedActions);\n\n // Build visible results — use tweet preview tags for post/reply\n const visibleResults: string[] = [];\n for (const r of results) {\n const detail = r.detail ? ` (${r.detail})` : \"\";\n if (r.action === \"schedule\") {\n // Log to terminal only, don't show in chat\n console.log(chalk.dim(` [Heartbeat] ${r.action}: ${r.success ? \"queued\" : r.error}${detail}`));\n } else if (r.success) {\n // Emit tweet preview card for post/reply with content\n if ((r.action === \"post\" || r.action === \"reply\") && r.content) {\n const tweetData = JSON.stringify({ action: r.action, tweetId: r.detail ?? null, content: r.content });\n visibleResults.push(`<<TWEET:${tweetData}>>`);\n console.log(chalk.green(` [Heartbeat] ${r.action}: success (tweet preview)`));\n } else {\n visibleResults.push(`[${r.action}] Done${detail}`);\n console.log(chalk.green(` [Heartbeat] ${r.action}: success${detail}`));\n }\n } else {\n visibleResults.push(`[${r.action}] Failed: ${r.error}`);\n console.log(chalk.red(` [Heartbeat] ${r.action}: ${r.error}`));\n }\n }\n\n // Combine narration with visible action results\n let fullMessage = narration || \"\";\n if (visibleResults.length > 0) {\n fullMessage += (fullMessage ? \"\\n\\n\" : \"\") + visibleResults.join(\"\\n\");\n }\n if (fullMessage) {\n server.pushMessage(\"assistant\", fullMessage);\n }\n } else if (narration) {\n server.pushMessage(\"assistant\", narration);\n }\n\n console.log(chalk.cyan(` [Heartbeat] Complete.`));\n}\n\n/**\n * Open URL in a separate browser window (app-like)\n */\nfunction openBrowser(url: string) {\n const platform = process.platform;\n\n try {\n if (platform === \"darwin\") {\n // Open as a standalone Chrome app window (smaller, separate from existing tabs)\n try {\n execSync(`open -na \"Google Chrome\" --args --app=\"${url}\" --window-size=420,620`, { stdio: \"ignore\" });\n } catch {\n // Fallback: try Chromium-based browsers, then default\n try {\n execSync(`open -na \"Brave Browser\" --args --app=\"${url}\" --window-size=420,620`, { stdio: \"ignore\" });\n } catch {\n execSync(`open \"${url}\"`, { stdio: \"ignore\" });\n }\n }\n } else if (platform === \"win32\") {\n try {\n execSync(`start chrome --app=\"${url}\" --window-size=420,620`, { stdio: \"ignore\" });\n } catch {\n execSync(`start \"\" \"${url}\"`, { stdio: \"ignore\" });\n }\n } else {\n // Linux\n try {\n execSync(`google-chrome --app=\"${url}\" --window-size=420,620`, { stdio: \"ignore\" });\n } catch {\n execSync(`xdg-open \"${url}\"`, { stdio: \"ignore\" });\n }\n }\n } catch (error) {\n // Browser couldn't be opened, that's okay\n console.log(chalk.dim(`(Couldn't open browser automatically - please visit ${url} manually)`));\n }\n}\n\nexport { openBrowser };\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getXClient,
|
|
3
3
|
resetXClient
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4D73N6VY.js";
|
|
5
5
|
import "./chunk-RCJQI7FR.js";
|
|
6
6
|
import "./chunk-KELPENM3.js";
|
|
7
7
|
import "./chunk-53YLFYJF.js";
|
|
@@ -9,4 +9,4 @@ export {
|
|
|
9
9
|
getXClient,
|
|
10
10
|
resetXClient
|
|
11
11
|
};
|
|
12
|
-
//# sourceMappingURL=x-client-
|
|
12
|
+
//# sourceMappingURL=x-client-QNLSLY2R.js.map
|