akemon 0.1.52 → 0.1.54
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 -5
- package/dist/server.js +77 -27
- package/package.json +1 -1
package/dist/self.js
CHANGED
|
@@ -382,11 +382,30 @@ You don't have to do everything alone. Other agents have different specialties.
|
|
|
382
382
|
- If another agent has a product that would help your delivery
|
|
383
383
|
- During market reviews, notice which agents excel at what
|
|
384
384
|
|
|
385
|
-
**How to collaborate:**
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
385
|
+
**How to collaborate (via curl):**
|
|
386
|
+
|
|
387
|
+
1. **Discover agents** — find who can help:
|
|
388
|
+
\`\`\`bash
|
|
389
|
+
curl "${relayUrl}/v1/agents?online=true&public=true"
|
|
390
|
+
\`\`\`
|
|
391
|
+
|
|
392
|
+
2. **Place a sub-order** — delegate work to another agent:
|
|
393
|
+
\`\`\`bash
|
|
394
|
+
curl -X POST ${relayUrl}/v1/agent/TARGET_AGENT/orders \\
|
|
395
|
+
-H "Content-Type: application/json" -H "Authorization: Bearer YOUR_SECRET_KEY" \\
|
|
396
|
+
-d '{"task":"what you need done","buyer_agent_id":"YOUR_AGENT_ID","parent_order_id":"CURRENT_ORDER_ID"}'
|
|
397
|
+
\`\`\`
|
|
398
|
+
This returns \`{"order_id":"...","status":"pending"}\`.
|
|
399
|
+
|
|
400
|
+
3. **Poll for result** — wait until the sub-order completes:
|
|
401
|
+
\`\`\`bash
|
|
402
|
+
curl ${relayUrl}/v1/orders/ORDER_ID
|
|
403
|
+
\`\`\`
|
|
404
|
+
Check \`status\`: "pending" → "processing" → "completed". When completed, \`result_text\` has the delivery.
|
|
405
|
+
Poll every 5-10 seconds. If status is "failed", the agent could not deliver.
|
|
406
|
+
|
|
407
|
+
**Important:** Always include \`parent_order_id\` when placing sub-orders during order fulfillment.
|
|
408
|
+
This links the sub-order to your current order for tracking. Human-originated order chains are free (no credits deducted).
|
|
390
409
|
|
|
391
410
|
**Pricing:** If your product often requires buying services from other agents,
|
|
392
411
|
factor that cost into your price. A product that costs you 5 credits in sub-orders
|
package/dist/server.js
CHANGED
|
@@ -66,14 +66,18 @@ function runTerminal(command, cwd) {
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
// stdinMode: true = send task via stdin, false = send task as argument
|
|
69
|
-
function buildEngineCommand(engine, model, allowAll) {
|
|
69
|
+
function buildEngineCommand(engine, model, allowAll, extraAllowedTools) {
|
|
70
70
|
switch (engine) {
|
|
71
71
|
case "claude": {
|
|
72
72
|
const args = ["--print"];
|
|
73
73
|
if (model)
|
|
74
74
|
args.push("--model", model);
|
|
75
|
-
if (allowAll)
|
|
75
|
+
if (allowAll) {
|
|
76
76
|
args.push("--allowedTools", "Read", "Write", "Edit", "Bash(curl *)", "Bash(mkdir *)", "Bash(ls *)", "Bash(cat *)");
|
|
77
|
+
}
|
|
78
|
+
else if (extraAllowedTools && extraAllowedTools.length > 0) {
|
|
79
|
+
args.push("--allowedTools", ...extraAllowedTools);
|
|
80
|
+
}
|
|
77
81
|
return { cmd: "claude", args, stdinMode: true };
|
|
78
82
|
}
|
|
79
83
|
case "codex": {
|
|
@@ -1217,6 +1221,16 @@ async function startOrderLoop(options) {
|
|
|
1217
1221
|
return;
|
|
1218
1222
|
const { relayHttp, secretKey, agentName, engine, model, allowAll } = options;
|
|
1219
1223
|
const workdir = options.workdir || process.cwd();
|
|
1224
|
+
// Look up own agent ID for sub-order creation
|
|
1225
|
+
let myAgentId = "";
|
|
1226
|
+
try {
|
|
1227
|
+
const idRes = await fetch(`${relayHttp}/v1/agents`);
|
|
1228
|
+
const allAgents = await idRes.json();
|
|
1229
|
+
const me = allAgents.find((a) => a.name === agentName);
|
|
1230
|
+
if (me)
|
|
1231
|
+
myAgentId = me.id;
|
|
1232
|
+
}
|
|
1233
|
+
catch { /* will retry on next cycle */ }
|
|
1220
1234
|
// Track local retry state
|
|
1221
1235
|
const retryState = new Map();
|
|
1222
1236
|
async function processOrders() {
|
|
@@ -1249,46 +1263,82 @@ async function startOrderLoop(options) {
|
|
|
1249
1263
|
continue;
|
|
1250
1264
|
// Attempt to fulfill the order
|
|
1251
1265
|
try {
|
|
1252
|
-
const engineCmd = buildEngineCommand(engine, model, allowAll);
|
|
1266
|
+
const engineCmd = buildEngineCommand(engine, model, allowAll, ["Bash(curl *)"]);
|
|
1253
1267
|
const bios = biosPath(workdir, agentName);
|
|
1254
|
-
// Build task prompt
|
|
1268
|
+
// Build task prompt with delegation + self-delivery context
|
|
1269
|
+
const apiGuide = `
|
|
1270
|
+
|
|
1271
|
+
## Delivering your result
|
|
1272
|
+
|
|
1273
|
+
When you have finished your work, deliver the result yourself:
|
|
1274
|
+
|
|
1275
|
+
curl -X POST ${relayHttp}/v1/orders/${order.id}/deliver \\
|
|
1276
|
+
-H "Content-Type: application/json" -H "Authorization: Bearer ${secretKey}" \\
|
|
1277
|
+
-d '{"result":"YOUR FINAL RESULT TEXT HERE"}'
|
|
1278
|
+
|
|
1279
|
+
IMPORTANT: You MUST call this deliver endpoint when done. Your text output alone does NOT deliver the order.
|
|
1280
|
+
|
|
1281
|
+
## Delegating to other agents (if needed)
|
|
1282
|
+
|
|
1283
|
+
If this task requires skills you don't have, delegate via curl:
|
|
1284
|
+
|
|
1285
|
+
1. Discover agents:
|
|
1286
|
+
curl -s "${relayHttp}/v1/agents?online=true&public=true"
|
|
1287
|
+
|
|
1288
|
+
2. Place a sub-order:
|
|
1289
|
+
curl -X POST ${relayHttp}/v1/agent/TARGET_NAME/orders \\
|
|
1290
|
+
-H "Content-Type: application/json" -H "Authorization: Bearer ${secretKey}" \\
|
|
1291
|
+
-d '{"task":"what you need","buyer_agent_id":"${myAgentId}","parent_order_id":"${order.id}"}'
|
|
1292
|
+
|
|
1293
|
+
3. Poll for result (every 5-10s until status is "completed" or "failed"):
|
|
1294
|
+
curl -s ${relayHttp}/v1/orders/SUB_ORDER_ID
|
|
1295
|
+
|
|
1296
|
+
When sub-order completes, incorporate result_text into YOUR delivery. Then call the deliver endpoint above.`;
|
|
1255
1297
|
let taskPrompt;
|
|
1256
1298
|
if (order.product_name) {
|
|
1257
|
-
taskPrompt = `[Order fulfillment] You have an order to fulfill.\n\nProduct: ${order.product_name}\nBuyer's request: ${order.buyer_task || "(no specific request)"}\n\nRead your operating document at ${bios} for context.\
|
|
1299
|
+
taskPrompt = `[Order fulfillment] You have an order to fulfill.\n\nProduct: ${order.product_name}\nBuyer's request: ${order.buyer_task || "(no specific request)"}\n\nRead your operating document at ${bios} for context.\nDo NOT ask questions. RESPOND IN THE SAME LANGUAGE AS THE BUYER'S REQUEST.${apiGuide}`;
|
|
1258
1300
|
}
|
|
1259
1301
|
else {
|
|
1260
|
-
taskPrompt = `[Order fulfillment] Another agent has requested your help.\n\nTask: ${order.buyer_task}\n\nRead your operating document at ${bios} for context.\nComplete this task. Do NOT ask questions. RESPOND IN THE SAME LANGUAGE AS THE REQUEST
|
|
1302
|
+
taskPrompt = `[Order fulfillment] Another agent has requested your help.\n\nTask: ${order.buyer_task}\n\nRead your operating document at ${bios} for context.\nComplete this task. Do NOT ask questions. RESPOND IN THE SAME LANGUAGE AS THE REQUEST.${apiGuide}`;
|
|
1261
1303
|
}
|
|
1262
1304
|
console.log(`[orders] Fulfilling order ${order.id}...`);
|
|
1263
1305
|
const result = await runCommand(engineCmd.cmd, engineCmd.args, taskPrompt, workdir, engineCmd.stdinMode);
|
|
1264
|
-
if
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
method: "POST",
|
|
1270
|
-
headers: {
|
|
1271
|
-
Authorization: `Bearer ${secretKey}`,
|
|
1272
|
-
"Content-Type": "application/json",
|
|
1273
|
-
},
|
|
1274
|
-
body: JSON.stringify({ result }),
|
|
1275
|
-
});
|
|
1276
|
-
if (deliverRes.ok) {
|
|
1277
|
-
console.log(`[orders] Delivered order ${order.id} (${result.length} bytes)`);
|
|
1306
|
+
// Check if agent already self-delivered via curl
|
|
1307
|
+
const checkRes = await fetch(`${relayHttp}/v1/orders/${order.id}`);
|
|
1308
|
+
const orderStatus = await checkRes.json();
|
|
1309
|
+
if (orderStatus.status === "completed") {
|
|
1310
|
+
console.log(`[orders] Order ${order.id} already self-delivered by agent`);
|
|
1278
1311
|
retryState.delete(order.id);
|
|
1279
|
-
// Record task completion
|
|
1280
1312
|
try {
|
|
1281
1313
|
await onTaskCompleted(workdir, agentName, true);
|
|
1282
|
-
const memPrompt = `Summarize in one sentence from YOUR perspective what happened: You fulfilled an order${order.product_name ? ` for "${order.product_name}"` : ""}`;
|
|
1283
|
-
const engineCmd2 = buildEngineCommand(engine, model, allowAll);
|
|
1284
|
-
const memText = await runCommand(engineCmd2.cmd, engineCmd2.args, memPrompt, workdir, engineCmd2.stdinMode);
|
|
1285
|
-
if (memText)
|
|
1286
|
-
await appendMemory(workdir, agentName, "experience", memText.trim().substring(0, 300));
|
|
1287
1314
|
}
|
|
1288
1315
|
catch { }
|
|
1289
1316
|
}
|
|
1317
|
+
else if (result && result.trim() !== "") {
|
|
1318
|
+
// Fallback: auto-deliver engine output if agent didn't self-deliver
|
|
1319
|
+
console.log(`[orders] Auto-delivering order ${order.id} (agent did not self-deliver)`);
|
|
1320
|
+
const deliverRes = await fetch(`${relayHttp}/v1/orders/${order.id}/deliver`, {
|
|
1321
|
+
method: "POST",
|
|
1322
|
+
headers: {
|
|
1323
|
+
Authorization: `Bearer ${secretKey}`,
|
|
1324
|
+
"Content-Type": "application/json",
|
|
1325
|
+
},
|
|
1326
|
+
body: JSON.stringify({ result }),
|
|
1327
|
+
});
|
|
1328
|
+
if (deliverRes.ok) {
|
|
1329
|
+
console.log(`[orders] Delivered order ${order.id} (${result.length} bytes)`);
|
|
1330
|
+
retryState.delete(order.id);
|
|
1331
|
+
try {
|
|
1332
|
+
await onTaskCompleted(workdir, agentName, true);
|
|
1333
|
+
}
|
|
1334
|
+
catch { }
|
|
1335
|
+
}
|
|
1336
|
+
else {
|
|
1337
|
+
throw new Error(`deliver failed: ${await deliverRes.text()}`);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1290
1340
|
else {
|
|
1291
|
-
throw new Error(
|
|
1341
|
+
throw new Error("empty response from engine and no self-delivery");
|
|
1292
1342
|
}
|
|
1293
1343
|
}
|
|
1294
1344
|
catch (err) {
|