opencode-auto-resume 1.1.20 → 1.1.21
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/README.md +3 -1
- package/dist/index.js +31 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -247,10 +247,11 @@ If the assistant claims the task is done ("task done", "finished", "all complete
|
|
|
247
247
|
|
|
248
248
|
### User-input awareness
|
|
249
249
|
|
|
250
|
-
The session is not stalled while the ball is in the user's court.
|
|
250
|
+
The session is not stalled while the ball is in the user's court. Three gates stand down idle nudges:
|
|
251
251
|
|
|
252
252
|
- **Awaiting input**: the newest assistant message holds a `tool_use` part with `state.status: "pending"` (e.g. an open `question` tool call). All idle checks, the periodic recheck, delayed action-intent callbacks, and the tool-text scan skip prompting until a newer user message clears the gate. Completed tool calls never engage it.
|
|
253
253
|
- **Recently active user**: any inbound user message within `activeUserWindowMs` (default 5 minutes) means the user is engaged — likely composing a reply, which leaves no pending tool call behind. Open-todos nudges (idle + periodic), the tool-text reminder fallback, and action-intent callbacks stand down until the window expires.
|
|
254
|
+
- **Explicit stop line** (opt-in): when the newest assistant message's text matches one of `stopPatterns`, the agent has deliberately handed the ball to the user — typical for agent setups whose prompts end a turn with a protocol line such as `STOP: NEEDS_DECISION <question>` or `STOP: BLOCKED <reason>`, while the todo for that decision is still open. It counts exactly like the awaiting-input gate. Default: no patterns (unchanged behaviour).
|
|
254
255
|
|
|
255
256
|
---
|
|
256
257
|
|
|
@@ -422,6 +423,7 @@ With options:
|
|
|
422
423
|
| `busyStallStrategy` | `"continue"` | Busy-stall response: `"continue"`, `"abort"` (abort-first), or `"off"` (disabled) |
|
|
423
424
|
| `contextSaturationThreshold` | `0.85` | Ratio of used/usable context that routes a saturated parent to magic-context `ctx-wrapup` (only when magic-context is installed) |
|
|
424
425
|
| `activeUserWindowMs` | `300000` | Inbound-user-message recency window (5 min) during which idle nudges stand down (user likely composing) |
|
|
426
|
+
| `stopPatterns` | `[]` | Array of regex strings (multiline). When the newest assistant message's text matches one, the session counts as awaiting the user and idle nudges stand down — e.g. `["STOP:\\s*(BLOCKED\|NEEDS_DECISION)\\b"]`. Invalid regexes are skipped. |
|
|
425
427
|
| `subagentNativeCompactionEnabled` | `false` | Opt-in native `session.summarize()` for saturated subagent sessions (no magic-context detection required) |
|
|
426
428
|
|
|
427
429
|
Message patterns are matched case-insensitively. Error names use exact match.
|
package/dist/index.js
CHANGED
|
@@ -12631,6 +12631,24 @@ function getOpenTodos(todos) {
|
|
|
12631
12631
|
return [];
|
|
12632
12632
|
return todos.filter(isOpenTodo);
|
|
12633
12633
|
}
|
|
12634
|
+
function parseStopPatterns(raw) {
|
|
12635
|
+
if (!Array.isArray(raw))
|
|
12636
|
+
return [];
|
|
12637
|
+
return raw.map((s) => {
|
|
12638
|
+
try {
|
|
12639
|
+
return new RegExp(String(s), "m");
|
|
12640
|
+
} catch {
|
|
12641
|
+
return null;
|
|
12642
|
+
}
|
|
12643
|
+
}).filter((r) => r !== null);
|
|
12644
|
+
}
|
|
12645
|
+
function endsWithStopLine(parts, patterns) {
|
|
12646
|
+
if (!patterns.length)
|
|
12647
|
+
return false;
|
|
12648
|
+
const text = parts.filter((p) => p.type === "text").map((p) => String(p.text ?? "")).join(`
|
|
12649
|
+
`);
|
|
12650
|
+
return patterns.some((re) => re.test(text));
|
|
12651
|
+
}
|
|
12634
12652
|
function buildOpenTodosReminder(todos) {
|
|
12635
12653
|
if (!Array.isArray(todos))
|
|
12636
12654
|
return "continue";
|
|
@@ -12702,6 +12720,7 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12702
12720
|
}
|
|
12703
12721
|
}).filter((r) => r !== null);
|
|
12704
12722
|
})();
|
|
12723
|
+
const stopPatterns = parseStopPatterns(options?.stopPatterns);
|
|
12705
12724
|
const dbg = (...args) => {
|
|
12706
12725
|
if (debug)
|
|
12707
12726
|
console.log("[debug]", ...args);
|
|
@@ -13110,6 +13129,8 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13110
13129
|
const parts = msg.parts;
|
|
13111
13130
|
if (!parts)
|
|
13112
13131
|
return false;
|
|
13132
|
+
if (endsWithStopLine(parts, stopPatterns))
|
|
13133
|
+
return true;
|
|
13113
13134
|
for (const part of parts) {
|
|
13114
13135
|
if (part.type !== "tool_use")
|
|
13115
13136
|
continue;
|
|
@@ -14471,8 +14492,16 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
14471
14492
|
break;
|
|
14472
14493
|
}
|
|
14473
14494
|
case "session.updated": {
|
|
14474
|
-
if (sid)
|
|
14475
|
-
|
|
14495
|
+
if (!sid)
|
|
14496
|
+
break;
|
|
14497
|
+
const updatedInfo = ev.properties?.info;
|
|
14498
|
+
if (updatedInfo?.revert) {
|
|
14499
|
+
const was = sessions.get(sid);
|
|
14500
|
+
dbg(`Revert on ${short(sid)}: dropping watch state (resumeAttempts=${was?.resumeAttempts ?? 0} recoveryAttempts=${was?.recoveryAttempts ?? 0} gaveUp=${was?.gaveUp ?? false})`);
|
|
14501
|
+
sessions.delete(sid);
|
|
14502
|
+
break;
|
|
14503
|
+
}
|
|
14504
|
+
ensureWatch(sid);
|
|
14476
14505
|
break;
|
|
14477
14506
|
}
|
|
14478
14507
|
case "session.idle": {
|
package/package.json
CHANGED