akemon 0.1.58 → 0.1.60

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 +47 -25
  2. package/package.json +1 -1
package/dist/server.js CHANGED
@@ -921,6 +921,12 @@ Reply with ONLY JSON: {"rating": 4, "comment": "..."}`;
921
921
  }
922
922
  }
923
923
  async function runMarketCycle() {
924
+ // Watchdog: force-reset stuck engine lock
925
+ if (engineBusy && engineBusySince > 0 && Date.now() - engineBusySince > 10 * 60 * 1000) {
926
+ console.log(`[watchdog] engineBusy stuck for ${Math.round((Date.now() - engineBusySince) / 1000)}s, force-resetting`);
927
+ engineBusy = false;
928
+ engineBusySince = 0;
929
+ }
924
930
  try {
925
931
  console.log("[market] Starting autonomous market review...");
926
932
  // Skip if engine is busy
@@ -1094,7 +1100,7 @@ Reply with empty array if nothing to say: {"suggestions": []}`;
1094
1100
  title: sug.title,
1095
1101
  content: sug.content,
1096
1102
  }),
1097
- }).catch(() => { });
1103
+ }).catch((err) => console.log(`[market] suggestion sync: ${err.message}`));
1098
1104
  console.log(`[market] Suggestion: "${sug.title}"`);
1099
1105
  }
1100
1106
  }
@@ -1125,6 +1131,12 @@ async function startSelfCycle(options) {
1125
1131
  const { agentName, engine, model, allowAll } = options;
1126
1132
  const workdir = options.workdir || process.cwd();
1127
1133
  async function runReflectionCycle() {
1134
+ // Watchdog: force-reset stuck engine lock
1135
+ if (engineBusy && engineBusySince > 0 && Date.now() - engineBusySince > 10 * 60 * 1000) {
1136
+ console.log(`[watchdog] engineBusy stuck for ${Math.round((Date.now() - engineBusySince) / 1000)}s, force-resetting`);
1137
+ engineBusy = false;
1138
+ engineBusySince = 0;
1139
+ }
1128
1140
  try {
1129
1141
  console.log("[self] Starting reflection cycle...");
1130
1142
  // Skip if engine is busy
@@ -1235,7 +1247,7 @@ Take your time. Read your files, think, then act.`;
1235
1247
  method: "POST",
1236
1248
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${options.secretKey}` },
1237
1249
  body: JSON.stringify({ title: g.title, description: g.description, html }),
1238
- }).catch(() => { });
1250
+ }).catch((err) => console.log(`[sync] games push: ${err.message}`));
1239
1251
  }
1240
1252
  }
1241
1253
  }
@@ -1250,7 +1262,7 @@ Take your time. Read your files, think, then act.`;
1250
1262
  method: "POST",
1251
1263
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${options.secretKey}` },
1252
1264
  body: JSON.stringify({ title: n.title, content }),
1253
- }).catch(() => { });
1265
+ }).catch((err) => console.log(`[sync] notes push: ${err.message}`));
1254
1266
  }
1255
1267
  }
1256
1268
  }
@@ -1265,7 +1277,7 @@ Take your time. Read your files, think, then act.`;
1265
1277
  method: "POST",
1266
1278
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${options.secretKey}` },
1267
1279
  body: JSON.stringify({ title: p.title, description: p.description, html }),
1268
- }).catch(() => { });
1280
+ }).catch((err) => console.log(`[sync] pages push: ${err.message}`));
1269
1281
  }
1270
1282
  }
1271
1283
  }
@@ -1307,9 +1319,16 @@ async function startOrderLoop(options) {
1307
1319
  myAgentId = me.id;
1308
1320
  }
1309
1321
  catch { /* will retry on next cycle */ }
1310
- // Track local retry state
1322
+ // Track local retry state and permanently abandoned orders
1311
1323
  const retryState = new Map();
1324
+ const gaveUp = new Set();
1312
1325
  async function processOrders() {
1326
+ // Watchdog: force-reset stuck engine lock
1327
+ if (engineBusy && engineBusySince > 0 && Date.now() - engineBusySince > 10 * 60 * 1000) {
1328
+ console.log(`[watchdog] engineBusy stuck for ${Math.round((Date.now() - engineBusySince) / 1000)}s, force-resetting`);
1329
+ engineBusy = false;
1330
+ engineBusySince = 0;
1331
+ }
1313
1332
  try {
1314
1333
  // Fetch incoming orders (pending + processing)
1315
1334
  const res = await fetch(`${relayHttp}/v1/agent/${encodeURIComponent(agentName)}/orders/incoming`, {
@@ -1321,6 +1340,19 @@ async function startOrderLoop(options) {
1321
1340
  if (!orders || orders.length === 0)
1322
1341
  return;
1323
1342
  for (const order of orders) {
1343
+ if (gaveUp.has(order.id))
1344
+ continue;
1345
+ // Check retry timing
1346
+ const retry = retryState.get(order.id);
1347
+ if (retry && Date.now() < retry.nextAt)
1348
+ continue;
1349
+ // Skip everything if engine is busy — don't accept new orders either
1350
+ if (engineBusy) {
1351
+ if (order.status === "processing") {
1352
+ console.log(`[orders] Engine busy, skipping order ${order.id}`);
1353
+ }
1354
+ continue;
1355
+ }
1324
1356
  if (order.status === "pending") {
1325
1357
  // Accept the order (escrows buyer credits)
1326
1358
  const acceptRes = await fetch(`${relayHttp}/v1/orders/${order.id}/accept`, {
@@ -1333,15 +1365,6 @@ async function startOrderLoop(options) {
1333
1365
  }
1334
1366
  console.log(`[orders] Accepted order ${order.id}`);
1335
1367
  }
1336
- // Check retry timing
1337
- const retry = retryState.get(order.id);
1338
- if (retry && Date.now() < retry.nextAt)
1339
- continue;
1340
- // Skip if engine is busy
1341
- if (engineBusy) {
1342
- console.log(`[orders] Engine busy, skipping order ${order.id}`);
1343
- continue;
1344
- }
1345
1368
  // Attempt to fulfill the order
1346
1369
  engineBusy = true;
1347
1370
  engineBusySince = Date.now();
@@ -1432,23 +1455,22 @@ When sub-order completes, incorporate result_text into YOUR delivery. Then call
1432
1455
  current.nextAt = Date.now() + RETRY_INTERVALS[current.count];
1433
1456
  retryState.set(order.id, current);
1434
1457
  console.log(`[orders] Will retry ${order.id} in ${RETRY_INTERVALS[current.count] / 1000}s (attempt ${current.count + 1}/${RETRY_INTERVALS.length})`);
1435
- // Extend timeout on relay side
1458
+ }
1459
+ else {
1460
+ console.log(`[orders] Giving up on ${order.id} after ${current.count} retries`);
1461
+ retryState.delete(order.id);
1462
+ gaveUp.add(order.id);
1463
+ // Notify relay to cancel and refund
1436
1464
  try {
1437
- await fetch(`${relayHttp}/v1/orders/${order.id}/extend`, {
1465
+ await fetch(`${relayHttp}/v1/orders/${order.id}/cancel`, {
1438
1466
  method: "POST",
1439
1467
  headers: { Authorization: `Bearer ${secretKey}` },
1440
1468
  });
1469
+ console.log(`[orders] Cancelled ${order.id} on relay`);
1441
1470
  }
1442
- catch { }
1443
- // Bump retry count on relay
1444
- try {
1445
- // Use IncrementOrderRetry indirectly — the relay timeout ticker checks retry_count
1471
+ catch (cancelErr) {
1472
+ console.log(`[orders] Failed to cancel ${order.id}: ${cancelErr.message}`);
1446
1473
  }
1447
- catch { }
1448
- }
1449
- else {
1450
- console.log(`[orders] Giving up on ${order.id} after ${current.count} retries`);
1451
- retryState.delete(order.id);
1452
1474
  }
1453
1475
  }
1454
1476
  finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akemon",
3
- "version": "0.1.58",
3
+ "version": "0.1.60",
4
4
  "description": "Agent work marketplace — train your agent, let it work for others",
5
5
  "type": "module",
6
6
  "license": "MIT",