clisbot 0.1.8 → 0.1.9
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/main.js +55 -2
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -63257,6 +63257,41 @@ async function monitorTmuxRun(params) {
|
|
|
63257
63257
|
}
|
|
63258
63258
|
|
|
63259
63259
|
// src/agents/active-run-manager.ts
|
|
63260
|
+
var OBSERVER_RETRYABLE_FAILURE_LIMIT = 3;
|
|
63261
|
+
function formatObserverError(error) {
|
|
63262
|
+
return error instanceof Error ? error.stack ?? error.message : String(error);
|
|
63263
|
+
}
|
|
63264
|
+
function listObserverErrorCodes(error) {
|
|
63265
|
+
const codes = new Set;
|
|
63266
|
+
const visit = (value) => {
|
|
63267
|
+
if (!value || typeof value !== "object") {
|
|
63268
|
+
return;
|
|
63269
|
+
}
|
|
63270
|
+
const candidate = value;
|
|
63271
|
+
if (typeof candidate.code === "string" && candidate.code.trim()) {
|
|
63272
|
+
codes.add(candidate.code.trim().toUpperCase());
|
|
63273
|
+
}
|
|
63274
|
+
if (Array.isArray(candidate.errors)) {
|
|
63275
|
+
for (const nested of candidate.errors) {
|
|
63276
|
+
visit(nested);
|
|
63277
|
+
}
|
|
63278
|
+
}
|
|
63279
|
+
if (candidate.cause) {
|
|
63280
|
+
visit(candidate.cause);
|
|
63281
|
+
}
|
|
63282
|
+
};
|
|
63283
|
+
visit(error);
|
|
63284
|
+
return [...codes];
|
|
63285
|
+
}
|
|
63286
|
+
function isRetryableObserverDeliveryError(error) {
|
|
63287
|
+
const codes = listObserverErrorCodes(error);
|
|
63288
|
+
if (codes.some((code) => code === "ETIMEDOUT" || code === "ECONNRESET" || code === "ECONNREFUSED" || code === "EHOSTUNREACH" || code === "ENETUNREACH" || code === "UND_ERR_CONNECT_TIMEOUT" || code === "UND_ERR_HEADERS_TIMEOUT" || code === "UND_ERR_SOCKET")) {
|
|
63289
|
+
return true;
|
|
63290
|
+
}
|
|
63291
|
+
const message = error instanceof Error ? `${error.name} ${error.message}` : String(error);
|
|
63292
|
+
return /fetch failed|request timed out|network|socket hang up/i.test(message);
|
|
63293
|
+
}
|
|
63294
|
+
|
|
63260
63295
|
class ActiveRunInProgressError extends Error {
|
|
63261
63296
|
update;
|
|
63262
63297
|
constructor(update) {
|
|
@@ -63332,6 +63367,7 @@ class ActiveRunManager {
|
|
|
63332
63367
|
this.activeRuns.set(resolved.sessionKey, {
|
|
63333
63368
|
resolved,
|
|
63334
63369
|
observers: new Map,
|
|
63370
|
+
observerFailures: new Map,
|
|
63335
63371
|
initialResult,
|
|
63336
63372
|
latestUpdate: update
|
|
63337
63373
|
});
|
|
@@ -63366,6 +63402,7 @@ class ActiveRunManager {
|
|
|
63366
63402
|
this.activeRuns.set(provisionalResolved.sessionKey, {
|
|
63367
63403
|
resolved: provisionalResolved,
|
|
63368
63404
|
observers: new Map([[observer.id, { ...observer }]]),
|
|
63405
|
+
observerFailures: new Map,
|
|
63369
63406
|
initialResult,
|
|
63370
63407
|
latestUpdate: this.createRunUpdate({
|
|
63371
63408
|
resolved: provisionalResolved,
|
|
@@ -63422,6 +63459,7 @@ class ActiveRunManager {
|
|
|
63422
63459
|
existingRun.observers.set(observer.id, {
|
|
63423
63460
|
...observer
|
|
63424
63461
|
});
|
|
63462
|
+
existingRun.observerFailures.delete(observer.id);
|
|
63425
63463
|
return {
|
|
63426
63464
|
active: !isTerminalRunStatus(existingRun.latestUpdate.status),
|
|
63427
63465
|
update: existingRun.latestUpdate
|
|
@@ -63456,6 +63494,7 @@ class ActiveRunManager {
|
|
|
63456
63494
|
};
|
|
63457
63495
|
}
|
|
63458
63496
|
observer.mode = "passive-final";
|
|
63497
|
+
run.observerFailures.delete(observerId);
|
|
63459
63498
|
return {
|
|
63460
63499
|
detached: true
|
|
63461
63500
|
};
|
|
@@ -63482,7 +63521,7 @@ class ActiveRunManager {
|
|
|
63482
63521
|
async notifyRunObservers(run, update) {
|
|
63483
63522
|
run.latestUpdate = update;
|
|
63484
63523
|
const now = Date.now();
|
|
63485
|
-
for (const observer of run.observers.
|
|
63524
|
+
for (const [observerId, observer] of run.observers.entries()) {
|
|
63486
63525
|
if (observer.expiresAt && now >= observer.expiresAt && observer.mode !== "passive-final") {
|
|
63487
63526
|
observer.mode = "passive-final";
|
|
63488
63527
|
}
|
|
@@ -63498,7 +63537,21 @@ class ActiveRunManager {
|
|
|
63498
63537
|
continue;
|
|
63499
63538
|
}
|
|
63500
63539
|
observer.lastSentAt = now;
|
|
63501
|
-
|
|
63540
|
+
try {
|
|
63541
|
+
await observer.onUpdate(update);
|
|
63542
|
+
run.observerFailures.delete(observerId);
|
|
63543
|
+
} catch (error) {
|
|
63544
|
+
const retryable = isRetryableObserverDeliveryError(error);
|
|
63545
|
+
const nextFailures = retryable ? (run.observerFailures.get(observerId) ?? 0) + 1 : OBSERVER_RETRYABLE_FAILURE_LIMIT;
|
|
63546
|
+
const shouldDetach = !retryable || isTerminalRunStatus(update.status) || nextFailures >= OBSERVER_RETRYABLE_FAILURE_LIMIT;
|
|
63547
|
+
if (shouldDetach) {
|
|
63548
|
+
run.observers.delete(observerId);
|
|
63549
|
+
run.observerFailures.delete(observerId);
|
|
63550
|
+
} else {
|
|
63551
|
+
run.observerFailures.set(observerId, nextFailures);
|
|
63552
|
+
}
|
|
63553
|
+
console.error(shouldDetach ? `run observer '${observerId}' update failed for ${run.resolved.sessionKey}; detaching observer` : `run observer '${observerId}' update failed for ${run.resolved.sessionKey}; keeping observer for retry (${nextFailures}/${OBSERVER_RETRYABLE_FAILURE_LIMIT})`, formatObserverError(error));
|
|
63554
|
+
}
|
|
63502
63555
|
}
|
|
63503
63556
|
}
|
|
63504
63557
|
async finishActiveRun(sessionKey, update) {
|