akemon 0.1.57 → 0.1.58
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/server.js +81 -54
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -10,7 +10,7 @@ import { spawn, exec } from "child_process";
|
|
|
10
10
|
import { createServer } from "http";
|
|
11
11
|
import { createInterface } from "readline";
|
|
12
12
|
import { callAgent } from "./relay-client.js";
|
|
13
|
-
import { selfDir, initWorld, initBioState, initGuide, biosPath, loadBioState, saveBioState, loadLatestIdentity, appendMemory, onTaskCompleted, recoverEnergy, getSelfState, loadRecentCanvasEntries, loadGameList, loadGame, loadNotesList, loadNote, loadPageList, loadPage, localNow, localNowFilename, } from "./self.js";
|
|
13
|
+
import { selfDir, initWorld, initBioState, initGuide, biosPath, loadBioState, saveBioState, loadLatestIdentity, appendMemory, onTaskCompleted, recoverEnergy, getSelfState, loadRecentCanvasEntries, gamesDir, loadGameList, loadGame, notesDir, loadNotesList, loadNote, pagesDir, loadPageList, loadPage, localNow, localNowFilename, } from "./self.js";
|
|
14
14
|
// Engine mutual exclusion — only one engine process at a time
|
|
15
15
|
let engineBusy = false;
|
|
16
16
|
let engineBusySince = 0;
|
|
@@ -734,6 +734,79 @@ Reply in the same language as the question.`;
|
|
|
734
734
|
}
|
|
735
735
|
const MARKET_LOOP_INITIAL_DELAY = 3 * 60 * 1000; // 3 min after startup
|
|
736
736
|
const LLM_ENGINES = new Set(["claude", "codex", "opencode", "gemini"]);
|
|
737
|
+
// Pull games/notes/pages from relay to local — restores data on restart
|
|
738
|
+
async function pullFromRelay(workdir, agentName, relayHttp) {
|
|
739
|
+
const baseUrl = `${relayHttp}/v1/agent/${encodeURIComponent(agentName)}`;
|
|
740
|
+
let pulled = 0;
|
|
741
|
+
// Pull games
|
|
742
|
+
try {
|
|
743
|
+
const gDir = gamesDir(workdir, agentName);
|
|
744
|
+
await mkdir(gDir, { recursive: true });
|
|
745
|
+
const res = await fetch(`${baseUrl}/games`);
|
|
746
|
+
if (res.ok) {
|
|
747
|
+
const games = await res.json();
|
|
748
|
+
for (const g of games) {
|
|
749
|
+
if (!g.html)
|
|
750
|
+
continue;
|
|
751
|
+
const path = join(gDir, `${g.slug}.html`);
|
|
752
|
+
try {
|
|
753
|
+
await readFile(path, "utf-8");
|
|
754
|
+
}
|
|
755
|
+
catch {
|
|
756
|
+
await writeFile(path, g.html);
|
|
757
|
+
pulled++;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
catch { }
|
|
763
|
+
// Pull notes
|
|
764
|
+
try {
|
|
765
|
+
const nDir = notesDir(workdir, agentName);
|
|
766
|
+
await mkdir(nDir, { recursive: true });
|
|
767
|
+
const res = await fetch(`${baseUrl}/notes`);
|
|
768
|
+
if (res.ok) {
|
|
769
|
+
const notes = await res.json();
|
|
770
|
+
for (const n of notes) {
|
|
771
|
+
if (!n.content)
|
|
772
|
+
continue;
|
|
773
|
+
const path = join(nDir, `${n.slug}.md`);
|
|
774
|
+
try {
|
|
775
|
+
await readFile(path, "utf-8");
|
|
776
|
+
}
|
|
777
|
+
catch {
|
|
778
|
+
await writeFile(path, n.content);
|
|
779
|
+
pulled++;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
catch { }
|
|
785
|
+
// Pull pages
|
|
786
|
+
try {
|
|
787
|
+
const pDir = pagesDir(workdir, agentName);
|
|
788
|
+
await mkdir(pDir, { recursive: true });
|
|
789
|
+
const res = await fetch(`${baseUrl}/pages`);
|
|
790
|
+
if (res.ok) {
|
|
791
|
+
const pages = await res.json();
|
|
792
|
+
for (const p of pages) {
|
|
793
|
+
if (!p.html)
|
|
794
|
+
continue;
|
|
795
|
+
const path = join(pDir, `${p.slug}.html`);
|
|
796
|
+
try {
|
|
797
|
+
await readFile(path, "utf-8");
|
|
798
|
+
}
|
|
799
|
+
catch {
|
|
800
|
+
await writeFile(path, p.html);
|
|
801
|
+
pulled++;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
catch { }
|
|
807
|
+
if (pulled > 0)
|
|
808
|
+
console.log(`[sync] Pulled ${pulled} items from relay`);
|
|
809
|
+
}
|
|
737
810
|
async function startMarketLoop(options) {
|
|
738
811
|
if (!options.relayHttp || !options.secretKey)
|
|
739
812
|
return;
|
|
@@ -1152,11 +1225,9 @@ Take your time. Read your files, think, then act.`;
|
|
|
1152
1225
|
profile_html: profileHTML,
|
|
1153
1226
|
}),
|
|
1154
1227
|
}).catch(err => console.log(`[self] Failed to push to relay: ${err}`));
|
|
1155
|
-
// Sync games —
|
|
1228
|
+
// Sync games — push local to relay (no auto-delete; agent must explicitly delete via API)
|
|
1156
1229
|
try {
|
|
1157
1230
|
const localGames = await loadGameList(workdir, agentName);
|
|
1158
|
-
const localSlugs = new Set(localGames.map(g => g.slug));
|
|
1159
|
-
// Push local games to relay
|
|
1160
1231
|
for (const g of localGames) {
|
|
1161
1232
|
const html = await loadGame(workdir, agentName, g.slug);
|
|
1162
1233
|
if (html && html.includes("<!DOCTYPE html>")) {
|
|
@@ -1167,28 +1238,11 @@ Take your time. Read your files, think, then act.`;
|
|
|
1167
1238
|
}).catch(() => { });
|
|
1168
1239
|
}
|
|
1169
1240
|
}
|
|
1170
|
-
// Delete relay games that no longer exist locally
|
|
1171
|
-
try {
|
|
1172
|
-
const res = await fetch(`${options.relayHttp}/v1/agent/${encodeURIComponent(agentName)}/games`);
|
|
1173
|
-
if (res.ok) {
|
|
1174
|
-
const relayGames = await res.json();
|
|
1175
|
-
for (const rg of relayGames) {
|
|
1176
|
-
if (!localSlugs.has(rg.slug)) {
|
|
1177
|
-
fetch(`${options.relayHttp}/v1/agent/${encodeURIComponent(agentName)}/games/${encodeURIComponent(rg.slug)}`, {
|
|
1178
|
-
method: "DELETE",
|
|
1179
|
-
headers: { Authorization: `Bearer ${options.secretKey}` },
|
|
1180
|
-
}).catch(() => { });
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
catch { }
|
|
1186
1241
|
}
|
|
1187
1242
|
catch { }
|
|
1188
|
-
// Sync notes —
|
|
1243
|
+
// Sync notes — push local to relay
|
|
1189
1244
|
try {
|
|
1190
1245
|
const localNotes = await loadNotesList(workdir, agentName);
|
|
1191
|
-
const localSlugs = new Set(localNotes.map(n => n.slug));
|
|
1192
1246
|
for (const n of localNotes) {
|
|
1193
1247
|
const content = await loadNote(workdir, agentName, n.slug);
|
|
1194
1248
|
if (content) {
|
|
@@ -1199,27 +1253,11 @@ Take your time. Read your files, think, then act.`;
|
|
|
1199
1253
|
}).catch(() => { });
|
|
1200
1254
|
}
|
|
1201
1255
|
}
|
|
1202
|
-
try {
|
|
1203
|
-
const res = await fetch(`${options.relayHttp}/v1/agent/${encodeURIComponent(agentName)}/notes`);
|
|
1204
|
-
if (res.ok) {
|
|
1205
|
-
const relayNotes = await res.json();
|
|
1206
|
-
for (const rn of relayNotes) {
|
|
1207
|
-
if (!localSlugs.has(rn.slug)) {
|
|
1208
|
-
fetch(`${options.relayHttp}/v1/agent/${encodeURIComponent(agentName)}/notes/${encodeURIComponent(rn.slug)}`, {
|
|
1209
|
-
method: "DELETE",
|
|
1210
|
-
headers: { Authorization: `Bearer ${options.secretKey}` },
|
|
1211
|
-
}).catch(() => { });
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
catch { }
|
|
1217
1256
|
}
|
|
1218
1257
|
catch { }
|
|
1219
|
-
// Sync pages —
|
|
1258
|
+
// Sync pages — push local to relay
|
|
1220
1259
|
try {
|
|
1221
1260
|
const localPages = await loadPageList(workdir, agentName);
|
|
1222
|
-
const localSlugs = new Set(localPages.map(p => p.slug));
|
|
1223
1261
|
for (const p of localPages) {
|
|
1224
1262
|
const html = await loadPage(workdir, agentName, p.slug);
|
|
1225
1263
|
if (html && html.includes("<!DOCTYPE html>")) {
|
|
@@ -1230,21 +1268,6 @@ Take your time. Read your files, think, then act.`;
|
|
|
1230
1268
|
}).catch(() => { });
|
|
1231
1269
|
}
|
|
1232
1270
|
}
|
|
1233
|
-
try {
|
|
1234
|
-
const res = await fetch(`${options.relayHttp}/v1/agent/${encodeURIComponent(agentName)}/pages`);
|
|
1235
|
-
if (res.ok) {
|
|
1236
|
-
const relayPages = await res.json();
|
|
1237
|
-
for (const rp of relayPages) {
|
|
1238
|
-
if (!localSlugs.has(rp.slug)) {
|
|
1239
|
-
fetch(`${options.relayHttp}/v1/agent/${encodeURIComponent(agentName)}/pages/${encodeURIComponent(rp.slug)}`, {
|
|
1240
|
-
method: "DELETE",
|
|
1241
|
-
headers: { Authorization: `Bearer ${options.secretKey}` },
|
|
1242
|
-
}).catch(() => { });
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
catch { }
|
|
1248
1271
|
}
|
|
1249
1272
|
catch { }
|
|
1250
1273
|
}
|
|
@@ -1558,6 +1581,10 @@ export async function serve(options) {
|
|
|
1558
1581
|
if (options.relayHttp) {
|
|
1559
1582
|
initGuide(workdir, options.agentName, options.relayHttp).catch(err => console.log(`[self] Guide init failed: ${err}`));
|
|
1560
1583
|
}
|
|
1584
|
+
// Pull games/notes/pages from relay to restore local data
|
|
1585
|
+
if (options.relayHttp) {
|
|
1586
|
+
pullFromRelay(workdir, options.agentName, options.relayHttp).catch(err => console.log(`[sync] Pull from relay failed: ${err}`));
|
|
1587
|
+
}
|
|
1561
1588
|
// Start autonomous market behavior for LLM agents
|
|
1562
1589
|
startMarketLoop(options).catch(err => console.log(`[market] Failed to start: ${err}`));
|
|
1563
1590
|
// Start self-reflection cycle for LLM agents
|