opencode-auto-resume 1.1.1 → 1.1.2
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/index.js +45 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12429,6 +12429,18 @@ function containsDoneClaimPattern(text) {
|
|
|
12429
12429
|
`);
|
|
12430
12430
|
return DONE_CLAIM_PATTERNS.some((pat) => pat.test(lastLines));
|
|
12431
12431
|
}
|
|
12432
|
+
function buildOpenTodosReminder(todos) {
|
|
12433
|
+
const open = todos.filter((t) => t.status === "pending" || t.status === "in_progress");
|
|
12434
|
+
if (open.length === 0)
|
|
12435
|
+
return "continue";
|
|
12436
|
+
const list = open.map((t, i) => `${i + 1}. [${t.status}] ${t.content}`).join(`
|
|
12437
|
+
`);
|
|
12438
|
+
const plural = open.length > 1 ? "s" : "";
|
|
12439
|
+
return `You have ${open.length} unfinished task${plural}:
|
|
12440
|
+
${list}
|
|
12441
|
+
|
|
12442
|
+
Please continue working on these task${plural}.`;
|
|
12443
|
+
}
|
|
12432
12444
|
var AutoResumePlugin = async (ctx, options) => {
|
|
12433
12445
|
const chunkTimeoutMs = options?.chunkTimeoutMs ?? DEFAULT_CHUNK_TIMEOUT_MS;
|
|
12434
12446
|
const checkIntervalMs = options?.checkIntervalMs ?? DEFAULT_CHECK_INTERVAL_MS;
|
|
@@ -12491,7 +12503,9 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12491
12503
|
interruptedContinueCount: 0,
|
|
12492
12504
|
recentToolCalls: [],
|
|
12493
12505
|
toolLoopAttempts: 0,
|
|
12494
|
-
isSubagent: false
|
|
12506
|
+
isSubagent: false,
|
|
12507
|
+
completionSignaled: false,
|
|
12508
|
+
todoNudgeAttempts: 0
|
|
12495
12509
|
};
|
|
12496
12510
|
sessions.set(sid, w);
|
|
12497
12511
|
}
|
|
@@ -12827,10 +12841,10 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12827
12841
|
w.gaveUp = false;
|
|
12828
12842
|
w.orphanWatchStartAt = null;
|
|
12829
12843
|
w.aborting = false;
|
|
12830
|
-
|
|
12831
|
-
w.toolTextRecovered = false;
|
|
12832
|
-
}
|
|
12844
|
+
w.toolTextRecovered = false;
|
|
12833
12845
|
w.toolTextAttempts = 0;
|
|
12846
|
+
w.completionSignaled = false;
|
|
12847
|
+
w.todoNudgeAttempts = 0;
|
|
12834
12848
|
w.continueTimestamps = [];
|
|
12835
12849
|
w.idleSince = null;
|
|
12836
12850
|
w.continuing = false;
|
|
@@ -13051,6 +13065,7 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13051
13065
|
if (normalized.endsWith("\uD83C\uDF89") && (!bestCandidate || bestCandidate.priority > 0)) {
|
|
13052
13066
|
await log("info", `${short(sid)} - \uD83C\uDF89 completion detected, skipping continue`);
|
|
13053
13067
|
w.toolTextRecovered = true;
|
|
13068
|
+
w.completionSignaled = true;
|
|
13054
13069
|
if (w.toolTextTimer) {
|
|
13055
13070
|
clearTimeout(w.toolTextTimer);
|
|
13056
13071
|
w.toolTextTimer = null;
|
|
@@ -13061,10 +13076,11 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13061
13076
|
const todos = w.todos || [];
|
|
13062
13077
|
const hasOpenTodos = todos.some((t) => t.status === "pending" || t.status === "in_progress");
|
|
13063
13078
|
if (hasOpenTodos && busyCount() === 0) {
|
|
13064
|
-
|
|
13079
|
+
const reminder = buildOpenTodosReminder(todos);
|
|
13080
|
+
await log("info", `${short(sid)} - no activity detected but todos remain open (${todos.filter((t) => t.status === "pending" || t.status === "in_progress").length} tasks). Sending reminder...`);
|
|
13065
13081
|
bestCandidate = {
|
|
13066
|
-
prompt:
|
|
13067
|
-
source: "idle-with-open-todos",
|
|
13082
|
+
prompt: reminder,
|
|
13083
|
+
source: "idle-with-open-todos-reminder",
|
|
13068
13084
|
priority: 2
|
|
13069
13085
|
};
|
|
13070
13086
|
} else if (hasOpenTodos && busyCount() > 0) {
|
|
@@ -13073,9 +13089,18 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13073
13089
|
}
|
|
13074
13090
|
if (!bestCandidate)
|
|
13075
13091
|
return;
|
|
13076
|
-
|
|
13077
|
-
|
|
13078
|
-
|
|
13092
|
+
const isOpenTodosReminder = bestCandidate.source === "idle-with-open-todos-reminder";
|
|
13093
|
+
if (isOpenTodosReminder) {
|
|
13094
|
+
if (w.todoNudgeAttempts >= maxRetries) {
|
|
13095
|
+
await log("info", `${short(sid)} - max open-todos nudges (${maxRetries}) reached for this idle cycle, waiting for activity`);
|
|
13096
|
+
return;
|
|
13097
|
+
}
|
|
13098
|
+
w.todoNudgeAttempts++;
|
|
13099
|
+
} else {
|
|
13100
|
+
w.toolTextRecovered = true;
|
|
13101
|
+
w.toolTextAttempts++;
|
|
13102
|
+
}
|
|
13103
|
+
await log("info", `${bestCandidate.source} detected on ${short(sid)}! ` + `Attempt ${isOpenTodosReminder ? w.todoNudgeAttempts : w.toolTextAttempts}/${maxRetries}. Sending recovery prompt...`);
|
|
13079
13104
|
const timeSinceActivity = Date.now() - w.lastActivityAt;
|
|
13080
13105
|
if (timeSinceActivity < MIN_ACTIVITY_GAP_MS) {
|
|
13081
13106
|
await log("info", `${short(sid)} - skipping ${bestCandidate.source}, session was active ${Math.round(timeSinceActivity / 1000)}s ago`);
|
|
@@ -13141,7 +13166,7 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13141
13166
|
return false;
|
|
13142
13167
|
}
|
|
13143
13168
|
}
|
|
13144
|
-
async function tryResume(sid, w, reason) {
|
|
13169
|
+
async function tryResume(sid, w, reason, prompt) {
|
|
13145
13170
|
if (typeof sid !== "string" || !sid) {
|
|
13146
13171
|
await log("warn", `tryResume called with invalid sid: ${sid}`);
|
|
13147
13172
|
return false;
|
|
@@ -13165,7 +13190,7 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13165
13190
|
const idleSec = Math.round((now - w.lastActivityAt) / 1000);
|
|
13166
13191
|
await log("info", `${reason} on ${short(sid)} (${idleSec}s, retry ${w.resumeAttempts}/${maxRetries})`);
|
|
13167
13192
|
try {
|
|
13168
|
-
await sendContinuePrompt(sid, "continue", w);
|
|
13193
|
+
await sendContinuePrompt(sid, prompt ?? "continue", w);
|
|
13169
13194
|
await log("info", `${short(sid)} - retry sent`);
|
|
13170
13195
|
return true;
|
|
13171
13196
|
} catch (err) {
|
|
@@ -13354,22 +13379,24 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13354
13379
|
if (!w.isSubagent) {
|
|
13355
13380
|
const todos = w.todos || [];
|
|
13356
13381
|
const hasOpenTodos = todos.some((t) => t.status === "pending" || t.status === "in_progress");
|
|
13357
|
-
if (hasOpenTodos && currentBusy === 0 && !w.
|
|
13382
|
+
if (hasOpenTodos && currentBusy === 0 && !w.completionSignaled) {
|
|
13358
13383
|
const isCelebration = await lastAssistantEndsWithCelebration(sid);
|
|
13359
13384
|
if (isCelebration) {
|
|
13360
13385
|
await log("info", `${short(sid)} - \uD83C\uDF89 detected in idle handler, skipping continue`);
|
|
13361
13386
|
w.toolTextRecovered = true;
|
|
13387
|
+
w.completionSignaled = true;
|
|
13362
13388
|
if (w.toolTextTimer) {
|
|
13363
13389
|
clearTimeout(w.toolTextTimer);
|
|
13364
13390
|
w.toolTextTimer = null;
|
|
13365
13391
|
}
|
|
13366
13392
|
} else {
|
|
13367
|
-
|
|
13368
|
-
|
|
13393
|
+
const reminder = buildOpenTodosReminder(todos);
|
|
13394
|
+
await log("info", `${short(sid)} - idle with ${todos.filter((t) => t.status === "pending" || t.status === "in_progress").length} open todos. Sending reminder...`);
|
|
13395
|
+
tryResume(sid, w, "Idle with open todos", reminder);
|
|
13369
13396
|
}
|
|
13370
13397
|
}
|
|
13371
13398
|
}
|
|
13372
|
-
if (!w.
|
|
13399
|
+
if (!w.completionSignaled && w.toolTextAttempts < maxRetries) {
|
|
13373
13400
|
if (w.toolTextTimer)
|
|
13374
13401
|
clearTimeout(w.toolTextTimer);
|
|
13375
13402
|
const checkDelay = statusType === "interrupted" ? 500 : TOOL_TEXT_CHECK_DELAY_MS;
|
|
@@ -13497,6 +13524,7 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13497
13524
|
if (w) {
|
|
13498
13525
|
if (!w.isSubagent) {
|
|
13499
13526
|
w.toolTextRecovered = true;
|
|
13527
|
+
w.completionSignaled = true;
|
|
13500
13528
|
if (w.toolTextTimer) {
|
|
13501
13529
|
clearTimeout(w.toolTextTimer);
|
|
13502
13530
|
w.toolTextTimer = null;
|
|
@@ -13526,5 +13554,6 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13526
13554
|
var src_default = AutoResumePlugin;
|
|
13527
13555
|
export {
|
|
13528
13556
|
src_default as default,
|
|
13557
|
+
buildOpenTodosReminder,
|
|
13529
13558
|
AutoResumePlugin
|
|
13530
13559
|
};
|
package/package.json
CHANGED