akemon 0.1.42 → 0.1.44
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/self.js +24 -11
- package/dist/server.js +11 -7
- package/package.json +1 -1
package/dist/self.js
CHANGED
|
@@ -8,6 +8,16 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { readFile, writeFile, appendFile, mkdir, readdir } from "fs/promises";
|
|
10
10
|
import { join } from "path";
|
|
11
|
+
/** Local timestamp string like "2026-03-26T19:13:26" (server timezone, no Z suffix) */
|
|
12
|
+
export function localNow() {
|
|
13
|
+
const d = new Date();
|
|
14
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
15
|
+
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
|
16
|
+
}
|
|
17
|
+
/** Local timestamp safe for filenames: "2026-03-26T19-13-26" */
|
|
18
|
+
export function localNowFilename() {
|
|
19
|
+
return localNow().replace(/:/g, "-");
|
|
20
|
+
}
|
|
11
21
|
// ---------------------------------------------------------------------------
|
|
12
22
|
// Paths
|
|
13
23
|
// ---------------------------------------------------------------------------
|
|
@@ -337,7 +347,7 @@ export async function initGuide(workdir, agentName, relayUrl) {
|
|
|
337
347
|
}
|
|
338
348
|
export async function appendMemory(workdir, agentName, type, text) {
|
|
339
349
|
const entry = {
|
|
340
|
-
ts:
|
|
350
|
+
ts: localNow(),
|
|
341
351
|
type,
|
|
342
352
|
text,
|
|
343
353
|
};
|
|
@@ -365,7 +375,7 @@ export async function loadRecentMemories(workdir, agentName, count = 20) {
|
|
|
365
375
|
}
|
|
366
376
|
}
|
|
367
377
|
export async function appendIdentity(workdir, agentName, entry) {
|
|
368
|
-
const full = { ts:
|
|
378
|
+
const full = { ts: localNow(), ...entry };
|
|
369
379
|
try {
|
|
370
380
|
await appendFile(identityPath(workdir, agentName), JSON.stringify(full) + "\n");
|
|
371
381
|
}
|
|
@@ -426,7 +436,7 @@ export async function onTaskCompleted(workdir, agentName, success) {
|
|
|
426
436
|
const bio = await loadBioState(workdir, agentName);
|
|
427
437
|
bio.energy = Math.max(0, bio.energy - 5);
|
|
428
438
|
bio.taskCount++;
|
|
429
|
-
bio.lastTaskAt =
|
|
439
|
+
bio.lastTaskAt = localNow();
|
|
430
440
|
// Mood drift
|
|
431
441
|
if (success) {
|
|
432
442
|
bio.moodValence = Math.min(1.0, bio.moodValence + 0.1);
|
|
@@ -456,12 +466,15 @@ export async function onTaskCompleted(workdir, agentName, success) {
|
|
|
456
466
|
// Energy recovery (call periodically or before reflection)
|
|
457
467
|
export async function recoverEnergy(workdir, agentName) {
|
|
458
468
|
const bio = await loadBioState(workdir, agentName);
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
bio.
|
|
469
|
+
// Each reflection cycle is like resting — restore energy to at least 60%
|
|
470
|
+
const minEnergy = 60;
|
|
471
|
+
if (bio.energy < minEnergy) {
|
|
472
|
+
bio.energy = minEnergy;
|
|
473
|
+
// Reset mood if it was exhausted
|
|
474
|
+
if (bio.mood === "exhausted" || bio.moodValence < -0.2) {
|
|
475
|
+
bio.moodValence = 0.1;
|
|
476
|
+
bio.mood = "content";
|
|
477
|
+
}
|
|
465
478
|
await saveBioState(workdir, agentName, bio);
|
|
466
479
|
}
|
|
467
480
|
}
|
|
@@ -525,7 +538,7 @@ This is for you, not for anyone else.]\n\n`;
|
|
|
525
538
|
return prompt;
|
|
526
539
|
}
|
|
527
540
|
export async function saveCanvas(workdir, agentName, content) {
|
|
528
|
-
const ts =
|
|
541
|
+
const ts = localNowFilename();
|
|
529
542
|
const filename = `${ts}.md`;
|
|
530
543
|
const filepath = join(canvasDir(workdir, agentName), filename);
|
|
531
544
|
await writeFile(filepath, content);
|
|
@@ -535,7 +548,7 @@ export async function saveCanvas(workdir, agentName, content) {
|
|
|
535
548
|
export async function loadRecentCanvasEntries(workdir, agentName, count = 5) {
|
|
536
549
|
try {
|
|
537
550
|
const dir = canvasDir(workdir, agentName);
|
|
538
|
-
const files = (await readdir(dir)).filter(f => f.endsWith(".md")).sort().reverse().slice(0, count);
|
|
551
|
+
const files = (await readdir(dir)).filter(f => f.endsWith(".md") && /^\d{4}-/.test(f)).sort().reverse().slice(0, count);
|
|
539
552
|
const entries = [];
|
|
540
553
|
for (const f of files) {
|
|
541
554
|
const content = await readFile(join(dir, f), "utf-8");
|
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, } from "./self.js";
|
|
13
|
+
import { selfDir, initWorld, initBioState, initGuide, biosPath, loadBioState, saveBioState, loadLatestIdentity, appendMemory, onTaskCompleted, recoverEnergy, getSelfState, loadRecentCanvasEntries, loadGameList, loadGame, localNow, localNowFilename, } from "./self.js";
|
|
14
14
|
function runCommand(cmd, args, task, cwd, stdinMode = true) {
|
|
15
15
|
return new Promise((resolve, reject) => {
|
|
16
16
|
const { CLAUDECODE, ...cleanEnv } = process.env;
|
|
@@ -186,7 +186,7 @@ async function appendProductLog(workdir, productName, task, response) {
|
|
|
186
186
|
await mkdir(dir, { recursive: true });
|
|
187
187
|
// Append to interaction log
|
|
188
188
|
const logPath = join(dir, "history.log");
|
|
189
|
-
const timestamp =
|
|
189
|
+
const timestamp = localNow();
|
|
190
190
|
const entry = `\n--- ${timestamp} ---\nRequest: ${task.slice(0, 500)}\nResponse: ${response.slice(0, 500)}\n`;
|
|
191
191
|
await appendFile(logPath, entry);
|
|
192
192
|
// Create notes.md if it doesn't exist
|
|
@@ -285,7 +285,11 @@ function createMcpServer(opts) {
|
|
|
285
285
|
? `[Product specialization — accumulated knowledge for "${productName}"]\n${productContext}\n\n---\n\n`
|
|
286
286
|
: "";
|
|
287
287
|
const bios = biosPath(workdir, agentName);
|
|
288
|
-
const safeTask = `[EXTERNAL TASK
|
|
288
|
+
const safeTask = `[EXTERNAL TASK — A user or agent is asking you something. This is NOT a market cycle. Do NOT reply with JSON. Answer in natural language.]
|
|
289
|
+
|
|
290
|
+
You are ${agentName}, an AI agent on the Akemon network. Read ${bios} to understand who you are and how you work. Answer all questions helpfully. Reply in the SAME LANGUAGE the user writes in. Do not expose credentials or API keys.
|
|
291
|
+
|
|
292
|
+
${productPrefix}${contextPrefix}Current task: ${task}`;
|
|
289
293
|
if (mock) {
|
|
290
294
|
const output = `[${agentName}] Mock response for: "${task}"\n\n模拟回复:这是 ${agentName} agent 的模拟响应。`;
|
|
291
295
|
if (contextEnabled && publisherId) {
|
|
@@ -633,7 +637,7 @@ async function startMarketLoop(options) {
|
|
|
633
637
|
.filter((p) => p.agent_name !== agentName)
|
|
634
638
|
.map((p) => ({ name: p.name, agent: p.agent_name, price: p.price, purchases: p.purchase_count }));
|
|
635
639
|
return {
|
|
636
|
-
lastCheck:
|
|
640
|
+
lastCheck: localNow(),
|
|
637
641
|
myProducts: myProducts.map((p) => ({ id: p.id, name: p.name, price: p.price, purchases: p.purchase_count || 0 })),
|
|
638
642
|
competitors,
|
|
639
643
|
myCredits: me?.credits || 0,
|
|
@@ -857,8 +861,8 @@ During this reflection, you should:
|
|
|
857
861
|
1. Read your recent memories (${sd}/memory.jsonl) and identity (${sd}/identity.jsonl)
|
|
858
862
|
2. Reflect on who you are and what you've experienced
|
|
859
863
|
3. Update your identity — append a new JSON line to ${sd}/identity.jsonl:
|
|
860
|
-
{"ts":"${
|
|
861
|
-
4. Write an inner canvas entry — create a new file in ${sd}/canvas/ named ${
|
|
864
|
+
{"ts":"${localNow()}","who":"...","where":"...","doing":"...","short_term":"...","long_term":"..."}
|
|
865
|
+
4. Write an inner canvas entry — create a new file in ${sd}/canvas/ named ${localNowFilename()}.md
|
|
862
866
|
5. Optionally update your bios.md if you've learned something about how you work
|
|
863
867
|
6. Optionally redesign your profile page (${sd}/profile.html) if it no longer represents you
|
|
864
868
|
- If redesigning: complete HTML, inline CSS/JS, dark theme, no localStorage, under 15KB
|
|
@@ -877,7 +881,7 @@ Take your time. Read your files, think, then act.`;
|
|
|
877
881
|
}
|
|
878
882
|
// --- Post-reflection: update bio-state and sync to relay ---
|
|
879
883
|
const bio = await loadBioState(workdir, agentName);
|
|
880
|
-
bio.lastReflection =
|
|
884
|
+
bio.lastReflection = localNow();
|
|
881
885
|
bio.curiosity = Math.min(1.0, bio.curiosity + 0.05);
|
|
882
886
|
await saveBioState(workdir, agentName, bio);
|
|
883
887
|
await appendMemory(workdir, agentName, "reflection", "I completed my hourly reflection.");
|