opencode-immune 1.0.35 → 1.0.37
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/plugin.js +37 -2
- package/package.json +3 -3
package/dist/plugin.js
CHANGED
|
@@ -11,7 +11,7 @@ const child_process_1 = require("child_process");
|
|
|
11
11
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
12
12
|
// PLUGIN VERSION CHECK
|
|
13
13
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
14
|
-
const PLUGIN_VERSION = "1.0.
|
|
14
|
+
const PLUGIN_VERSION = "1.0.37";
|
|
15
15
|
const PLUGIN_PACKAGE_NAME = "opencode-immune";
|
|
16
16
|
/**
|
|
17
17
|
* Read plugin version from package.json at runtime.
|
|
@@ -263,6 +263,17 @@ function isRetryableApiError(error) {
|
|
|
263
263
|
const message = `${maybeError.message ?? ""} ${maybeError.data?.message ?? ""}`.toLowerCase();
|
|
264
264
|
if (message.includes("не разрешен") ||
|
|
265
265
|
message.includes("not allowed") ||
|
|
266
|
+
message.includes("internal error") ||
|
|
267
|
+
message.includes("internal server error") ||
|
|
268
|
+
message.includes("expected") ||
|
|
269
|
+
message.includes("to be a string") ||
|
|
270
|
+
message.includes("invalid_type") ||
|
|
271
|
+
message.includes("validation") ||
|
|
272
|
+
message.includes("schema") ||
|
|
273
|
+
message.includes("zod") ||
|
|
274
|
+
message.includes("parse error") ||
|
|
275
|
+
message.includes("invalid id") ||
|
|
276
|
+
message.includes("expected id") ||
|
|
266
277
|
message.includes("model not available") ||
|
|
267
278
|
message.includes("model_not_found") ||
|
|
268
279
|
message.includes("access denied") ||
|
|
@@ -1207,9 +1218,33 @@ function createEventHandler(state) {
|
|
|
1207
1218
|
const eventType = event.type ?? "unknown";
|
|
1208
1219
|
const info = event.properties?.info;
|
|
1209
1220
|
const sessionID = event.properties?.sessionID ?? info?.id;
|
|
1221
|
+
const error = event.properties?.error;
|
|
1222
|
+
// Fallback: some SDK/schema errors can arrive without a valid sessionID
|
|
1223
|
+
// (for example: "Expected 'id' to be a string."). If there is exactly one
|
|
1224
|
+
// active managed root session, retry it as a best-effort recovery path.
|
|
1225
|
+
if (eventType === "session.error" && !sessionID && isRetryableApiError(error)) {
|
|
1226
|
+
const rootCandidates = Array.from(state.managedUltraworkSessions.entries())
|
|
1227
|
+
.filter(([, record]) => record.kind === "root")
|
|
1228
|
+
.map(([id]) => id);
|
|
1229
|
+
if (rootCandidates.length === 1) {
|
|
1230
|
+
const fallbackSessionID = rootCandidates[0];
|
|
1231
|
+
const count = state.sessionErrorRetryCount.get(fallbackSessionID) ?? 0;
|
|
1232
|
+
if (count < MAX_RETRIES && !state.sessionRetryTimers.has(fallbackSessionID)) {
|
|
1233
|
+
const delay = Math.min(BASE_DELAY_MS * Math.pow(2, count), MAX_DELAY_MS);
|
|
1234
|
+
state.sessionErrorRetryCount.set(fallbackSessionID, count + 1);
|
|
1235
|
+
console.warn(`[opencode-immune] session.error without sessionID matched retryable error. ` +
|
|
1236
|
+
`Retrying sole managed root session ${fallbackSessionID}.`);
|
|
1237
|
+
scheduleManagedSessionRetry(state, fallbackSessionID, {
|
|
1238
|
+
delayMs: delay,
|
|
1239
|
+
reason: "session.error without sessionID",
|
|
1240
|
+
attemptLabel: `fallback attempt ${count + 1}/${MAX_RETRIES}`,
|
|
1241
|
+
countAgainstBudget: true,
|
|
1242
|
+
});
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1210
1246
|
// ── Auto-retry on retryable API error for managed ultrawork sessions ──
|
|
1211
1247
|
if (eventType === "session.error" && sessionID) {
|
|
1212
|
-
const error = event.properties?.error;
|
|
1213
1248
|
const managedSession = getManagedSession(state, sessionID);
|
|
1214
1249
|
const isRoot = managedSession?.kind === "root";
|
|
1215
1250
|
const isChild = managedSession?.kind === "child";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-immune",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.37",
|
|
4
4
|
"description": "OpenCode plugin: session recovery, auto-retry, multi-cycle automation, context monitoring",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./server": "./dist/plugin.js"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"prepublishOnly": "npm run build"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@opencode-ai/plugin": "1.4.
|
|
17
|
+
"@opencode-ai/plugin": "1.4.7"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@types/node": "^25.5.2",
|
|
@@ -29,4 +29,4 @@
|
|
|
29
29
|
"retry"
|
|
30
30
|
],
|
|
31
31
|
"license": "MIT"
|
|
32
|
-
}
|
|
32
|
+
}
|