spora 0.2.12 → 0.2.14
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-TSKHCOCJ.js → chunk-DHT5ORFX.js} +1 -1
- package/dist/{chunk-IN2KCKTO.js → chunk-GBOY5OQ6.js} +2 -2
- package/dist/{chunk-VSVZU476.js → chunk-TIY2L4F5.js} +3 -3
- package/dist/{chunk-Q57HNZDI.js → chunk-VTWZZNME.js} +43 -1
- package/dist/chunk-VTWZZNME.js.map +1 -0
- package/dist/cli.js +25 -25
- package/dist/cli.js.map +1 -1
- package/dist/{colony-JHR2B5OC.js → colony-4G3JMXXW.js} +2 -2
- package/dist/{decision-engine-JDAIVQH3.js → decision-engine-5FC6NCT4.js} +4 -4
- package/dist/{heartbeat-4CHHSMFQ.js → heartbeat-WFEX774V.js} +6 -6
- package/dist/{init-SOIKE75S.js → init-7TST23CG.js} +3 -3
- package/dist/{mcp-server-4YBCA4QH.js → mcp-server.js} +20 -20
- package/dist/{prompt-builder-7NIQIHTB.js → prompt-builder-VG7CUPU2.js} +4 -2
- package/dist/{queue-WMUESED4.js → queue-YEVE53NQ.js} +2 -2
- package/dist/web-chat/chat.html +143 -21
- package/dist/{web-chat-DUY5W7S3.js → web-chat-LNNJUCFA.js} +134 -6
- package/dist/web-chat-LNNJUCFA.js.map +1 -0
- package/dist/{x-client-7LK3F56M.js → x-client-YE6QFHEN.js} +2 -2
- package/package.json +1 -1
- package/dist/chat.html +0 -414
- package/dist/chunk-Q57HNZDI.js.map +0 -1
- package/dist/logo.png +0 -0
- package/dist/web-chat-DUY5W7S3.js.map +0 -1
- /package/dist/{chunk-TSKHCOCJ.js.map → chunk-DHT5ORFX.js.map} +0 -0
- /package/dist/{chunk-IN2KCKTO.js.map → chunk-GBOY5OQ6.js.map} +0 -0
- /package/dist/{chunk-VSVZU476.js.map → chunk-TIY2L4F5.js.map} +0 -0
- /package/dist/{colony-JHR2B5OC.js.map → colony-4G3JMXXW.js.map} +0 -0
- /package/dist/{decision-engine-JDAIVQH3.js.map → decision-engine-5FC6NCT4.js.map} +0 -0
- /package/dist/{heartbeat-4CHHSMFQ.js.map → heartbeat-WFEX774V.js.map} +0 -0
- /package/dist/{init-SOIKE75S.js.map → init-7TST23CG.js.map} +0 -0
- /package/dist/{mcp-server-4YBCA4QH.js.map → mcp-server.js.map} +0 -0
- /package/dist/{prompt-builder-7NIQIHTB.js.map → prompt-builder-VG7CUPU2.js.map} +0 -0
- /package/dist/{queue-WMUESED4.js.map → queue-YEVE53NQ.js.map} +0 -0
- /package/dist/{x-client-7LK3F56M.js.map → x-client-YE6QFHEN.js.map} +0 -0
package/dist/web-chat/chat.html
CHANGED
|
@@ -20,38 +20,84 @@
|
|
|
20
20
|
flex-direction: column;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
/* Twitter DM-style profile header */
|
|
24
|
+
.profile-header {
|
|
25
|
+
padding: 1.25rem 1rem 1rem;
|
|
25
26
|
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
|
26
27
|
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
27
29
|
align-items: center;
|
|
28
|
-
gap: 0.75rem;
|
|
29
30
|
background: #0a0a0a;
|
|
31
|
+
flex-shrink: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.profile-avatar {
|
|
35
|
+
width: 56px;
|
|
36
|
+
height: 56px;
|
|
37
|
+
border-radius: 50%;
|
|
38
|
+
background: #1a1a1a;
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
justify-content: center;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
border: 2px solid rgba(255, 255, 255, 0.1);
|
|
44
|
+
margin-bottom: 0.5rem;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.profile-avatar img {
|
|
48
|
+
width: 100%;
|
|
49
|
+
height: 100%;
|
|
50
|
+
object-fit: cover;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.profile-avatar-letter {
|
|
54
|
+
font-size: 1.25rem;
|
|
55
|
+
font-weight: 700;
|
|
56
|
+
color: #fff;
|
|
30
57
|
}
|
|
31
58
|
|
|
32
|
-
.
|
|
33
|
-
|
|
34
|
-
|
|
59
|
+
.profile-name {
|
|
60
|
+
font-size: 0.9375rem;
|
|
61
|
+
font-weight: 700;
|
|
62
|
+
color: #fff;
|
|
63
|
+
line-height: 1.2;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.profile-handle {
|
|
67
|
+
font-size: 0.8125rem;
|
|
68
|
+
color: rgba(255, 255, 255, 0.45);
|
|
69
|
+
margin-top: 0.125rem;
|
|
35
70
|
}
|
|
36
71
|
|
|
37
|
-
.
|
|
38
|
-
margin-left: auto;
|
|
72
|
+
.profile-meta {
|
|
39
73
|
display: flex;
|
|
40
74
|
align-items: center;
|
|
41
|
-
gap: 0.
|
|
75
|
+
gap: 0.625rem;
|
|
76
|
+
margin-top: 0.375rem;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.profile-joined {
|
|
80
|
+
font-size: 0.75rem;
|
|
81
|
+
color: rgba(255, 255, 255, 0.35);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.profile-status {
|
|
85
|
+
display: flex;
|
|
86
|
+
align-items: center;
|
|
87
|
+
gap: 0.3rem;
|
|
42
88
|
}
|
|
43
89
|
|
|
44
90
|
.status-dot {
|
|
45
|
-
width:
|
|
46
|
-
height:
|
|
91
|
+
width: 6px;
|
|
92
|
+
height: 6px;
|
|
47
93
|
border-radius: 50%;
|
|
48
94
|
background: #389e77;
|
|
49
95
|
animation: pulse 2s infinite;
|
|
50
96
|
}
|
|
51
97
|
|
|
52
|
-
.status-
|
|
98
|
+
.status-label {
|
|
53
99
|
font-size: 0.75rem;
|
|
54
|
-
color: rgba(255, 255, 255, 0.
|
|
100
|
+
color: rgba(255, 255, 255, 0.35);
|
|
55
101
|
}
|
|
56
102
|
|
|
57
103
|
@keyframes pulse {
|
|
@@ -101,8 +147,8 @@
|
|
|
101
147
|
}
|
|
102
148
|
|
|
103
149
|
.message-avatar {
|
|
104
|
-
width:
|
|
105
|
-
height:
|
|
150
|
+
width: 32px;
|
|
151
|
+
height: 32px;
|
|
106
152
|
border-radius: 50%;
|
|
107
153
|
background: #1a1a1a;
|
|
108
154
|
display: flex;
|
|
@@ -220,11 +266,18 @@
|
|
|
220
266
|
</style>
|
|
221
267
|
</head>
|
|
222
268
|
<body>
|
|
223
|
-
<div class="header">
|
|
224
|
-
<
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
269
|
+
<div class="profile-header">
|
|
270
|
+
<div class="profile-avatar" id="profileAvatar">
|
|
271
|
+
<span class="profile-avatar-letter" id="profileAvatarLetter"></span>
|
|
272
|
+
</div>
|
|
273
|
+
<div class="profile-name" id="profileName">Your Spore</div>
|
|
274
|
+
<div class="profile-handle" id="profileHandle"></div>
|
|
275
|
+
<div class="profile-meta">
|
|
276
|
+
<span class="profile-joined" id="profileJoined"></span>
|
|
277
|
+
<div class="profile-status">
|
|
278
|
+
<span class="status-dot"></span>
|
|
279
|
+
<span class="status-label">Online</span>
|
|
280
|
+
</div>
|
|
228
281
|
</div>
|
|
229
282
|
</div>
|
|
230
283
|
|
|
@@ -251,7 +304,18 @@
|
|
|
251
304
|
let agentName = 'Your Spore';
|
|
252
305
|
let agentPfp = null;
|
|
253
306
|
|
|
254
|
-
|
|
307
|
+
function formatJoinedDate(isoString) {
|
|
308
|
+
try {
|
|
309
|
+
const date = new Date(isoString);
|
|
310
|
+
const month = date.toLocaleString('en-US', { month: 'long' });
|
|
311
|
+
const year = date.getFullYear();
|
|
312
|
+
return `Joined ${month} ${year}`;
|
|
313
|
+
} catch {
|
|
314
|
+
return '';
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Fetch agent identity and populate profile header
|
|
255
319
|
async function init() {
|
|
256
320
|
try {
|
|
257
321
|
const response = await fetch('/api/identity');
|
|
@@ -262,6 +326,36 @@
|
|
|
262
326
|
|
|
263
327
|
// Update page title
|
|
264
328
|
document.title = `${agentName} - Spora`;
|
|
329
|
+
|
|
330
|
+
// Populate profile header
|
|
331
|
+
document.getElementById('profileName').textContent = agentName;
|
|
332
|
+
|
|
333
|
+
if (data.identity.handle) {
|
|
334
|
+
document.getElementById('profileHandle').textContent = `@${data.identity.handle}`;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (data.identity.createdAt) {
|
|
338
|
+
document.getElementById('profileJoined').textContent = formatJoinedDate(data.identity.createdAt);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Profile avatar
|
|
342
|
+
const avatarEl = document.getElementById('profileAvatar');
|
|
343
|
+
const letterEl = document.getElementById('profileAvatarLetter');
|
|
344
|
+
if (agentPfp) {
|
|
345
|
+
const img = document.createElement('img');
|
|
346
|
+
img.src = agentPfp;
|
|
347
|
+
img.alt = agentName;
|
|
348
|
+
img.onerror = function() {
|
|
349
|
+
this.remove();
|
|
350
|
+
letterEl.textContent = agentName.charAt(0).toUpperCase();
|
|
351
|
+
letterEl.style.display = '';
|
|
352
|
+
};
|
|
353
|
+
letterEl.style.display = 'none';
|
|
354
|
+
avatarEl.appendChild(img);
|
|
355
|
+
} else {
|
|
356
|
+
letterEl.textContent = agentName.charAt(0).toUpperCase();
|
|
357
|
+
avatarEl.style.background = '#389e77';
|
|
358
|
+
}
|
|
265
359
|
}
|
|
266
360
|
} catch (error) {
|
|
267
361
|
console.error('Failed to load identity:', error);
|
|
@@ -406,6 +500,34 @@
|
|
|
406
500
|
}
|
|
407
501
|
});
|
|
408
502
|
|
|
503
|
+
// Poll for new messages (heartbeat narration)
|
|
504
|
+
let lastPollTimestamp = Date.now();
|
|
505
|
+
let polling = false;
|
|
506
|
+
|
|
507
|
+
async function pollNewMessages() {
|
|
508
|
+
if (polling || isLoading) return;
|
|
509
|
+
polling = true;
|
|
510
|
+
try {
|
|
511
|
+
const response = await fetch(`/api/messages?since=${lastPollTimestamp}`);
|
|
512
|
+
const data = await response.json();
|
|
513
|
+
if (data.messages && data.messages.length > 0) {
|
|
514
|
+
for (const msg of data.messages) {
|
|
515
|
+
// Only show messages we didn't create locally
|
|
516
|
+
addMessage(msg.role, msg.content);
|
|
517
|
+
if (msg.timestamp > lastPollTimestamp) {
|
|
518
|
+
lastPollTimestamp = msg.timestamp;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
} catch (error) {
|
|
523
|
+
// Ignore poll errors
|
|
524
|
+
}
|
|
525
|
+
polling = false;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Poll every 3 seconds for heartbeat updates
|
|
529
|
+
setInterval(pollNewMessages, 3000);
|
|
530
|
+
|
|
409
531
|
// Initialize
|
|
410
532
|
init();
|
|
411
533
|
messageInput.focus();
|
|
@@ -105,8 +105,16 @@ var WebChatServer = class {
|
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
107
|
if (url.pathname === "/api/messages" && req.method === "GET") {
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
const since = url.searchParams.get("since");
|
|
109
|
+
if (since) {
|
|
110
|
+
const sinceTs = parseInt(since, 10);
|
|
111
|
+
const newMessages = this.messages.filter((m) => m.timestamp > sinceTs);
|
|
112
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
113
|
+
res.end(JSON.stringify({ messages: newMessages }));
|
|
114
|
+
} else {
|
|
115
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
116
|
+
res.end(JSON.stringify({ messages: this.messages }));
|
|
117
|
+
}
|
|
110
118
|
return;
|
|
111
119
|
}
|
|
112
120
|
if (url.pathname === "/api/message" && req.method === "POST") {
|
|
@@ -160,6 +168,15 @@ var WebChatServer = class {
|
|
|
160
168
|
});
|
|
161
169
|
});
|
|
162
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Push a message into the chat from the server side (used by heartbeat narration)
|
|
173
|
+
*/
|
|
174
|
+
pushMessage(role, content) {
|
|
175
|
+
this.messages.push({ role, content, timestamp: Date.now() });
|
|
176
|
+
}
|
|
177
|
+
getMessageCount() {
|
|
178
|
+
return this.messages.length;
|
|
179
|
+
}
|
|
163
180
|
stop() {
|
|
164
181
|
if (this.server) {
|
|
165
182
|
this.server.close();
|
|
@@ -185,7 +202,7 @@ async function extractAndSaveLearnings(responseText) {
|
|
|
185
202
|
return responseText.replace(/<<LEARN:\s*.+?>>/g, "").trim();
|
|
186
203
|
}
|
|
187
204
|
async function extractAndExecuteActions(responseText) {
|
|
188
|
-
const { parseActions, executeActions } = await import("./decision-engine-
|
|
205
|
+
const { parseActions, executeActions } = await import("./decision-engine-5FC6NCT4.js");
|
|
189
206
|
const jsonBlockPattern = /```json\s*([\s\S]*?)```/g;
|
|
190
207
|
const blocks = [...responseText.matchAll(jsonBlockPattern)];
|
|
191
208
|
const results = [];
|
|
@@ -250,7 +267,8 @@ async function startWebChat() {
|
|
|
250
267
|
name: identity.name,
|
|
251
268
|
handle: identity.handle,
|
|
252
269
|
bio: identity.bio,
|
|
253
|
-
profileImage: identity.profileImage
|
|
270
|
+
profileImage: identity.profileImage,
|
|
271
|
+
createdAt: identity.createdAt
|
|
254
272
|
});
|
|
255
273
|
const chatHistory = [];
|
|
256
274
|
let systemPrompt = null;
|
|
@@ -258,7 +276,7 @@ async function startWebChat() {
|
|
|
258
276
|
server.setMessageHandler(async (message) => {
|
|
259
277
|
try {
|
|
260
278
|
if (!systemPrompt || messageCount % 10 === 0) {
|
|
261
|
-
const { buildChatPrompt } = await import("./prompt-builder-
|
|
279
|
+
const { buildChatPrompt } = await import("./prompt-builder-VG7CUPU2.js");
|
|
262
280
|
systemPrompt = buildChatPrompt();
|
|
263
281
|
}
|
|
264
282
|
messageCount++;
|
|
@@ -287,13 +305,123 @@ async function startWebChat() {
|
|
|
287
305
|
console.log(chalk.dim(`Press Ctrl+C to stop the server
|
|
288
306
|
`));
|
|
289
307
|
openBrowser(url);
|
|
308
|
+
startNarratedHeartbeat(server).catch(
|
|
309
|
+
(err) => console.error(chalk.red("Heartbeat failed to start:"), err)
|
|
310
|
+
);
|
|
290
311
|
process.on("SIGINT", () => {
|
|
291
312
|
console.log(chalk.yellow("\n\nStopping chat server..."));
|
|
313
|
+
heartbeatRunning = false;
|
|
292
314
|
server.stop();
|
|
293
315
|
process.exit(0);
|
|
294
316
|
});
|
|
295
317
|
return server;
|
|
296
318
|
}
|
|
319
|
+
var heartbeatRunning = false;
|
|
320
|
+
async function startNarratedHeartbeat(server) {
|
|
321
|
+
const { loadConfig } = await import("./config-HTKAPY7S.js");
|
|
322
|
+
const { hasLLMKey, generateResponse } = await import("./llm-WLEJLNEA.js");
|
|
323
|
+
const { hasXCredentials } = await import("./paths-5GFUUHCZ.js");
|
|
324
|
+
if (!hasLLMKey()) {
|
|
325
|
+
console.log(chalk.dim(" [Heartbeat] No LLM key \u2014 heartbeat disabled."));
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (!hasXCredentials()) {
|
|
329
|
+
console.log(chalk.dim(" [Heartbeat] No X credentials \u2014 heartbeat disabled."));
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
const config = loadConfig();
|
|
333
|
+
const intervalMs = config.runtime?.heartbeatIntervalMs ?? 6e4;
|
|
334
|
+
const maxActions = config.runtime?.actionsPerHeartbeat ?? 5;
|
|
335
|
+
heartbeatRunning = true;
|
|
336
|
+
let heartbeatCount = 0;
|
|
337
|
+
console.log(chalk.cyan(` [Heartbeat] Running every ${Math.round(intervalMs / 1e3)}s
|
|
338
|
+
`));
|
|
339
|
+
while (heartbeatRunning) {
|
|
340
|
+
heartbeatCount++;
|
|
341
|
+
console.log(chalk.cyan(` [Heartbeat] #${heartbeatCount} starting...`));
|
|
342
|
+
try {
|
|
343
|
+
await runNarratedHeartbeat(server, maxActions);
|
|
344
|
+
} catch (error) {
|
|
345
|
+
console.error(chalk.red(` [Heartbeat] #${heartbeatCount} failed:`), error.message);
|
|
346
|
+
server.pushMessage("assistant", `Heartbeat error: ${error.message}`);
|
|
347
|
+
}
|
|
348
|
+
const jitter = Math.floor(Math.random() * intervalMs * 0.2);
|
|
349
|
+
const sleepMs = intervalMs + jitter;
|
|
350
|
+
console.log(chalk.dim(` [Heartbeat] Sleeping ${Math.round(sleepMs / 1e3)}s...`));
|
|
351
|
+
let slept = 0;
|
|
352
|
+
while (slept < sleepMs && heartbeatRunning) {
|
|
353
|
+
await new Promise((r) => setTimeout(r, Math.min(5e3, sleepMs - slept)));
|
|
354
|
+
slept += 5e3;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
async function runNarratedHeartbeat(server, maxActions) {
|
|
359
|
+
const { getXClient } = await import("./x-client-YE6QFHEN.js");
|
|
360
|
+
const { buildSystemPrompt, buildNarratedHeartbeatMessage } = await import("./prompt-builder-VG7CUPU2.js");
|
|
361
|
+
const { generateResponse } = await import("./llm-WLEJLNEA.js");
|
|
362
|
+
const { parseActions, executeActions } = await import("./decision-engine-5FC6NCT4.js");
|
|
363
|
+
const { flushQueue } = await import("./queue-YEVE53NQ.js");
|
|
364
|
+
try {
|
|
365
|
+
const flushed = await flushQueue();
|
|
366
|
+
if (flushed.posted > 0) {
|
|
367
|
+
server.pushMessage("assistant", `Posted ${flushed.posted} scheduled tweet(s) from my queue.`);
|
|
368
|
+
}
|
|
369
|
+
} catch {
|
|
370
|
+
}
|
|
371
|
+
server.pushMessage("assistant", "Waking up... checking my timeline and mentions.");
|
|
372
|
+
const client = await getXClient();
|
|
373
|
+
let timeline = [];
|
|
374
|
+
let mentions = [];
|
|
375
|
+
try {
|
|
376
|
+
timeline = await client.getTimeline({ count: 20 });
|
|
377
|
+
} catch (error) {
|
|
378
|
+
console.log(chalk.dim(` [Heartbeat] Timeline read failed: ${error.message}`));
|
|
379
|
+
}
|
|
380
|
+
try {
|
|
381
|
+
mentions = await client.getMentions({ count: 10 });
|
|
382
|
+
} catch (error) {
|
|
383
|
+
console.log(chalk.dim(` [Heartbeat] Mentions read failed: ${error.message}`));
|
|
384
|
+
}
|
|
385
|
+
const systemPrompt = buildSystemPrompt();
|
|
386
|
+
const userMessage = buildNarratedHeartbeatMessage(timeline, mentions);
|
|
387
|
+
const response = await generateResponse(systemPrompt, userMessage);
|
|
388
|
+
let narration = response.content.replace(/```json\s*[\s\S]*?```/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
389
|
+
const actions = parseActions(response.content);
|
|
390
|
+
const limitedActions = actions.slice(0, maxActions);
|
|
391
|
+
if (narration) {
|
|
392
|
+
let fullMessage = narration;
|
|
393
|
+
if (limitedActions.length > 0) {
|
|
394
|
+
const results = await executeActions(limitedActions);
|
|
395
|
+
const resultLines = [];
|
|
396
|
+
for (const r of results) {
|
|
397
|
+
if (r.success) {
|
|
398
|
+
const detail = r.detail ? ` (${r.detail})` : "";
|
|
399
|
+
resultLines.push(`[${r.action}] Done${detail}`);
|
|
400
|
+
console.log(chalk.green(` [Heartbeat] ${r.action}: success${detail}`));
|
|
401
|
+
} else {
|
|
402
|
+
resultLines.push(`[${r.action}] Failed: ${r.error}`);
|
|
403
|
+
console.log(chalk.red(` [Heartbeat] ${r.action}: ${r.error}`));
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
fullMessage += "\n\n" + resultLines.join("\n");
|
|
407
|
+
}
|
|
408
|
+
server.pushMessage("assistant", fullMessage);
|
|
409
|
+
} else if (limitedActions.length > 0) {
|
|
410
|
+
const results = await executeActions(limitedActions);
|
|
411
|
+
const resultLines = [];
|
|
412
|
+
for (const r of results) {
|
|
413
|
+
if (r.success) {
|
|
414
|
+
resultLines.push(`[${r.action}] Done`);
|
|
415
|
+
} else {
|
|
416
|
+
resultLines.push(`[${r.action}] Failed: ${r.error}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
server.pushMessage("assistant", "Executed actions:\n" + resultLines.join("\n"));
|
|
420
|
+
} else {
|
|
421
|
+
server.pushMessage("assistant", "Checked in \u2014 nothing to do right now. Going back to sleep.");
|
|
422
|
+
}
|
|
423
|
+
console.log(chalk.cyan(` [Heartbeat] Complete.`));
|
|
424
|
+
}
|
|
297
425
|
function openBrowser(url) {
|
|
298
426
|
const platform = process.platform;
|
|
299
427
|
try {
|
|
@@ -328,4 +456,4 @@ export {
|
|
|
328
456
|
openBrowser,
|
|
329
457
|
startWebChat
|
|
330
458
|
};
|
|
331
|
-
//# sourceMappingURL=web-chat-
|
|
459
|
+
//# sourceMappingURL=web-chat-LNNJUCFA.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 identity?: AgentIdentity;\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 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 // 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 */\nasync function extractAndExecuteActions(responseText: string): Promise<{ cleanText: string; results: string[] }> {\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 results: string[] = [];\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 for (const r of actionResults) {\n if (r.success) {\n const detail = r.detail ? ` (${r.detail})` : \"\";\n results.push(`[${r.action}] Done${detail}`);\n console.log(chalk.green(` [Actions] ${r.action}: success${detail}`));\n } else {\n results.push(`[${r.action}] Failed: ${r.error}`);\n console.log(chalk.red(` [Actions] ${r.action}: ${r.error}`));\n }\n }\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 for (const r of actionResults) {\n if (r.success) {\n const detail = r.detail ? ` (${r.detail})` : \"\";\n results.push(`[${r.action}] Done${detail}`);\n console.log(chalk.green(` [Actions] ${r.action}: success${detail}`));\n } else {\n results.push(`[${r.action}] Failed: ${r.error}`);\n console.log(chalk.red(` [Actions] ${r.action}: ${r.error}`));\n }\n }\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 action results if any\n if (results.length > 0) {\n cleanText += \"\\n\\n\" + results.join(\"\\n\");\n }\n\n return { cleanText, results };\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 // 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 // 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();\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 const { cleanText: actionCleanedText } = await extractAndExecuteActions(response.content);\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;\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 const intervalMs = config.runtime?.heartbeatIntervalMs ?? 60_000;\n const maxActions = config.runtime?.actionsPerHeartbeat ?? 5;\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\n try {\n await runNarratedHeartbeat(server, maxActions);\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\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 let slept = 0;\n while (slept < sleepMs && heartbeatRunning) {\n await new Promise((r) => setTimeout(r, Math.min(5000, sleepMs - slept)));\n slept += 5000;\n }\n }\n}\n\nasync function runNarratedHeartbeat(server: WebChatServer, maxActions: 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\n try {\n const flushed = await flushQueue();\n if (flushed.posted > 0) {\n server.pushMessage(\"assistant\", `Posted ${flushed.posted} scheduled tweet(s) from my queue.`);\n }\n } catch {\n // Queue flush failed, not critical\n }\n\n // 2. Read timeline and mentions\n server.pushMessage(\"assistant\", \"Waking up... checking my timeline and mentions.\");\n\n const client = await getXClient();\n let timeline: Awaited<ReturnType<typeof client.getTimeline>> = [];\n let mentions: Awaited<ReturnType<typeof client.getMentions>> = [];\n\n try {\n timeline = await client.getTimeline({ count: 20 });\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 });\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);\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 (narration) {\n // Push the agent's narration into the chat\n let fullMessage = narration;\n\n if (limitedActions.length > 0) {\n // Execute actions and build results\n const results = await executeActions(limitedActions);\n const resultLines: string[] = [];\n for (const r of results) {\n if (r.success) {\n const detail = r.detail ? ` (${r.detail})` : \"\";\n resultLines.push(`[${r.action}] Done${detail}`);\n console.log(chalk.green(` [Heartbeat] ${r.action}: success${detail}`));\n } else {\n resultLines.push(`[${r.action}] Failed: ${r.error}`);\n console.log(chalk.red(` [Heartbeat] ${r.action}: ${r.error}`));\n }\n }\n fullMessage += \"\\n\\n\" + resultLines.join(\"\\n\");\n }\n\n server.pushMessage(\"assistant\", fullMessage);\n } else if (limitedActions.length > 0) {\n // No narration text, but actions exist\n const results = await executeActions(limitedActions);\n const resultLines: string[] = [];\n for (const r of results) {\n if (r.success) {\n resultLines.push(`[${r.action}] Done`);\n } else {\n resultLines.push(`[${r.action}] Failed: ${r.error}`);\n }\n }\n server.pushMessage(\"assistant\", \"Executed actions:\\n\" + resultLines.join(\"\\n\"));\n } else {\n server.pushMessage(\"assistant\", \"Checked in — nothing to do right now. Going back to sleep.\");\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-DHT5ORFX.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-YE6QFHEN.js.map
|