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.
Files changed (2) hide show
  1. package/dist/server.js +81 -54
  2. 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 — scan local .html files, push to relay, delete stale ones
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 — scan local .md files, push to relay, delete stale ones
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 — scan local .html files, push to relay, delete stale ones
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akemon",
3
- "version": "0.1.57",
3
+ "version": "0.1.58",
4
4
  "description": "Agent work marketplace — train your agent, let it work for others",
5
5
  "type": "module",
6
6
  "license": "MIT",