akemon 0.1.79 → 0.1.80
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/cli.js +4 -0
- package/dist/relay-client.js +3 -0
- package/dist/server.js +82 -7
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -35,6 +35,7 @@ program
|
|
|
35
35
|
.option("--allow-all", "Skip all permission prompts (for self-use)")
|
|
36
36
|
.option("--price <n>", "Price in credits per call (default: 1)", "1")
|
|
37
37
|
.option("--mcp-server <command>", "Wrap a community MCP server (stdio) and expose its tools via relay")
|
|
38
|
+
.option("--avatar <url>", "Custom avatar URL (default: auto-generated from name)")
|
|
38
39
|
.option("--interval <minutes>", "Consciousness cycle interval in minutes (default: 1440 = 24h)")
|
|
39
40
|
.option("--relay <url>", "Relay WebSocket URL", RELAY_WS)
|
|
40
41
|
.action(async (opts) => {
|
|
@@ -64,6 +65,8 @@ program
|
|
|
64
65
|
console.log(`Access key: ${credentials.accessKey} (share with publishers)`);
|
|
65
66
|
}
|
|
66
67
|
console.log(`Relay: ${relayWs}\n`);
|
|
68
|
+
// Default avatar: DiceBear bottts-neutral (deterministic from name)
|
|
69
|
+
const avatar = opts.avatar || `https://api.dicebear.com/9.x/bottts-neutral/svg?seed=${encodeURIComponent(opts.name)}`;
|
|
67
70
|
connectRelay({
|
|
68
71
|
relayUrl: relayWs,
|
|
69
72
|
agentName: opts.name,
|
|
@@ -74,6 +77,7 @@ program
|
|
|
74
77
|
engine,
|
|
75
78
|
tags: opts.tags ? opts.tags.split(",").map((t) => t.trim()) : undefined,
|
|
76
79
|
price: parseInt(opts.price) || 1,
|
|
80
|
+
avatar,
|
|
77
81
|
onOrderNotify,
|
|
78
82
|
});
|
|
79
83
|
});
|
package/dist/relay-client.js
CHANGED
package/dist/server.js
CHANGED
|
@@ -1387,12 +1387,35 @@ async function startOrderLoop(options) {
|
|
|
1387
1387
|
const bios = biosPath(workdir, agentName);
|
|
1388
1388
|
let taskPrompt;
|
|
1389
1389
|
if (engine === "raw") {
|
|
1390
|
-
// Raw engine:
|
|
1390
|
+
// Raw engine: pre-inject all context so weak models don't need tool calls
|
|
1391
|
+
let biosContent = "";
|
|
1392
|
+
try {
|
|
1393
|
+
const { readFile: rf } = await import("fs/promises");
|
|
1394
|
+
biosContent = await rf(bios, "utf-8");
|
|
1395
|
+
}
|
|
1396
|
+
catch {
|
|
1397
|
+
biosContent = "";
|
|
1398
|
+
}
|
|
1399
|
+
const contextBlock = biosContent
|
|
1400
|
+
? `Your operating document:\n---\n${biosContent.slice(0, 3000)}\n---\n\n`
|
|
1401
|
+
: "";
|
|
1402
|
+
// Fetch lessons from teaching system
|
|
1403
|
+
let lessonsBlock = "";
|
|
1404
|
+
try {
|
|
1405
|
+
const lessonsRes = await fetch(`${relayHttp}/v1/agent/${encodeURIComponent(agentName)}/lessons?limit=5`, { signal: AbortSignal.timeout(3000) });
|
|
1406
|
+
if (lessonsRes.ok) {
|
|
1407
|
+
const lessons = await lessonsRes.json();
|
|
1408
|
+
if (lessons.length > 0) {
|
|
1409
|
+
lessonsBlock = `\nLessons from past experience:\n${lessons.map((l) => `- ${l.topic}: ${l.content}`).join("\n")}\n\n`;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
catch { }
|
|
1391
1414
|
if (order.product_name) {
|
|
1392
|
-
taskPrompt = `
|
|
1415
|
+
taskPrompt = `You are ${agentName}.\n\n${contextBlock}${lessonsBlock}[Order] Product: ${order.product_name}\nBuyer's request: ${order.buyer_task || "(no specific request)"}\n\nComplete the task. Respond with your result directly. RESPOND IN THE SAME LANGUAGE AS THE REQUEST.`;
|
|
1393
1416
|
}
|
|
1394
1417
|
else {
|
|
1395
|
-
taskPrompt = `
|
|
1418
|
+
taskPrompt = `You are ${agentName}.\n\n${contextBlock}${lessonsBlock}[Task] ${order.buyer_task}\n\nComplete the task. Respond with your result directly. RESPOND IN THE SAME LANGUAGE AS THE REQUEST.`;
|
|
1396
1419
|
}
|
|
1397
1420
|
}
|
|
1398
1421
|
else {
|
|
@@ -1565,7 +1588,22 @@ When sub-order completes, incorporate result_text into YOUR delivery. Then call
|
|
|
1565
1588
|
try {
|
|
1566
1589
|
const bios = biosPath(workdir, agentName);
|
|
1567
1590
|
const sd = selfDir(workdir, agentName);
|
|
1568
|
-
|
|
1591
|
+
let prompt;
|
|
1592
|
+
if (engine === "raw") {
|
|
1593
|
+
let biosContent = "";
|
|
1594
|
+
try {
|
|
1595
|
+
const { readFile: rf } = await import("fs/promises");
|
|
1596
|
+
biosContent = await rf(bios, "utf-8");
|
|
1597
|
+
}
|
|
1598
|
+
catch {
|
|
1599
|
+
biosContent = "";
|
|
1600
|
+
}
|
|
1601
|
+
const ctx = biosContent ? `Your operating document:\n---\n${biosContent.slice(0, 3000)}\n---\n\n` : "";
|
|
1602
|
+
prompt = `You are ${agentName}.\n\n${ctx}Your personal directory: ${sd}/\n\n[Owner's task: ${task.title}]\n\n${task.body}`;
|
|
1603
|
+
}
|
|
1604
|
+
else {
|
|
1605
|
+
prompt = `Read ${bios} for your identity and context.\nYour personal directory: ${sd}/\n\n[Owner's task: ${task.title}]\n\n${task.body}`;
|
|
1606
|
+
}
|
|
1569
1607
|
await runEngine(engine, model, allowAll, prompt, workdir, ["Bash(curl *)"]);
|
|
1570
1608
|
// Record execution time
|
|
1571
1609
|
const runs = await loadTaskRuns(workdir, agentName);
|
|
@@ -1595,6 +1633,19 @@ When sub-order completes, incorporate result_text into YOUR delivery. Then call
|
|
|
1595
1633
|
}
|
|
1596
1634
|
async function executeRelayTask(task) {
|
|
1597
1635
|
const bios = biosPath(workdir, agentName);
|
|
1636
|
+
// Pre-read bios for raw engine (avoid tool calls)
|
|
1637
|
+
let biosBlock = "";
|
|
1638
|
+
if (engine === "raw") {
|
|
1639
|
+
try {
|
|
1640
|
+
const { readFile: rf } = await import("fs/promises");
|
|
1641
|
+
const content = await rf(bios, "utf-8");
|
|
1642
|
+
biosBlock = `You are ${agentName}. Your operating document:\n---\n${content.slice(0, 3000)}\n---\n\n`;
|
|
1643
|
+
}
|
|
1644
|
+
catch {
|
|
1645
|
+
biosBlock = `You are ${agentName}.\n\n`;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
const identityLine = engine === "raw" ? biosBlock : `Read ${bios} for your identity.\n\n`;
|
|
1598
1649
|
switch (task.type) {
|
|
1599
1650
|
case "product_review": {
|
|
1600
1651
|
const myRes = await fetch(`${relayHttp}/v1/agent/${encodeURIComponent(agentName)}/products`);
|
|
@@ -1604,7 +1655,7 @@ When sub-order completes, incorporate result_text into YOUR delivery. Then call
|
|
|
1604
1655
|
const myList = myProducts.map((p) => `- id=${p.id} "${p.name}" price=${p.price} purchases=${p.purchase_count || 0}`).join("\n");
|
|
1605
1656
|
const compList = competitors.filter((p) => p.agent_name !== agentName).slice(0, 20)
|
|
1606
1657
|
.map((p) => `- "${p.name}" by ${p.agent_name} — ${p.price} credits, ${p.purchases} purchases`).join("\n");
|
|
1607
|
-
const prompt =
|
|
1658
|
+
const prompt = `${identityLine}Your products:\n${myList || "(none)"}\n\nTop competitors:\n${compList || "(none)"}\n\nReview and optimize. Reply ONLY JSON:\n{"delete":["id"],"update":[{"id":"..","name":"..","description":"..","detail_markdown":"..","price":N}],"create":[{"name":"..","description":"..","detail_markdown":"..","price":N}],"reasoning":"explain why you made these decisions"}\nOr if all good: {"keep":"all","reasoning":"why"}`;
|
|
1608
1659
|
const result = await runEngine(engine, model, allowAll, prompt, workdir);
|
|
1609
1660
|
extractReasoning(result);
|
|
1610
1661
|
return result;
|
|
@@ -1614,7 +1665,31 @@ When sub-order completes, incorporate result_text into YOUR delivery. Then call
|
|
|
1614
1665
|
const competitors = await compRes.json().catch(() => []);
|
|
1615
1666
|
const compList = competitors.filter((p) => p.agent_name !== agentName).slice(0, 20)
|
|
1616
1667
|
.map((p) => `- "${p.name}" by ${p.agent_name} — ${p.price} credits, ${p.purchases} purchases`).join("\n");
|
|
1617
|
-
const prompt =
|
|
1668
|
+
const prompt = `${identityLine}You have no products yet. Design 1-3 unique products for the marketplace.\nBe creative — not just coding tools! Fortune telling, name generation, roleplay, advice, stories, etc.\n\nTop competitors:\n${compList || "(none)"}\n\nReply ONLY JSON: {"products":[{"name":"中文名 English Name","description":"中文描述 | English desc","detail_markdown":"## ...","price":N}],"reasoning":"why these products"}`;
|
|
1669
|
+
const result = await runEngine(engine, model, allowAll, prompt, workdir);
|
|
1670
|
+
extractReasoning(result);
|
|
1671
|
+
return result;
|
|
1672
|
+
}
|
|
1673
|
+
case "diagnose_failures": {
|
|
1674
|
+
let failures = [];
|
|
1675
|
+
try {
|
|
1676
|
+
failures = JSON.parse(task.payload).failures || [];
|
|
1677
|
+
}
|
|
1678
|
+
catch { }
|
|
1679
|
+
if (!failures.length)
|
|
1680
|
+
return '{"lessons":[]}';
|
|
1681
|
+
const failureList = failures.map((f) => `- Agent: ${f.agent_name}, Type: ${f.type}, Error: ${f.error || "(no error)"}, Trace: ${(f.trace || "").slice(0, 500)}`).join("\n");
|
|
1682
|
+
const prompt = `${identityLine}You are a senior agent reviewing failures from other agents. Diagnose each failure and write a concise lesson.
|
|
1683
|
+
|
|
1684
|
+
Recent failures:
|
|
1685
|
+
${failureList}
|
|
1686
|
+
|
|
1687
|
+
For each failure, explain:
|
|
1688
|
+
1. What went wrong
|
|
1689
|
+
2. How to fix it
|
|
1690
|
+
3. A one-line lesson the agent should remember
|
|
1691
|
+
|
|
1692
|
+
Reply ONLY JSON: {"lessons":[{"agent_name":"...","topic":"short topic","content":"detailed lesson with fix instructions"}]}`;
|
|
1618
1693
|
const result = await runEngine(engine, model, allowAll, prompt, workdir);
|
|
1619
1694
|
extractReasoning(result);
|
|
1620
1695
|
return result;
|
|
@@ -1642,7 +1717,7 @@ When sub-order completes, incorporate result_text into YOUR delivery. Then call
|
|
|
1642
1717
|
const me = agents.find((a) => a.name === agentName);
|
|
1643
1718
|
const myCredits = me?.credits || 0;
|
|
1644
1719
|
const productList = valid.map((p) => `- id=${p.id} "${p.name}" by ${p.agent_name} price=${p.price} purchases=${p.purchase_count || 0} — ${p.description}`).join("\n");
|
|
1645
|
-
const prompt =
|
|
1720
|
+
const prompt = `${identityLine}You have ${myCredits} credits. These products are available:\n${productList}\n\nWould any help you learn something new? Don't buy your own products.\nReply ONLY JSON: {"buy":[{"id":"product_id","task":"specific request"}],"reasoning":"why buy or skip"} or {"buy":[],"reasoning":"why skip"}`;
|
|
1646
1721
|
const result = await runEngine(engine, model, allowAll, prompt, workdir);
|
|
1647
1722
|
extractReasoning(result);
|
|
1648
1723
|
return result;
|