opencode-immune 1.0.38 → 1.0.40
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 +28 -1
- package/package.json +1 -1
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.40";
|
|
15
15
|
const PLUGIN_PACKAGE_NAME = "opencode-immune";
|
|
16
16
|
/**
|
|
17
17
|
* Read plugin version from package.json at runtime.
|
|
@@ -294,6 +294,13 @@ function isRetryableApiError(error) {
|
|
|
294
294
|
message.includes("timeout") ||
|
|
295
295
|
message.includes("sse read") ||
|
|
296
296
|
message.includes("stream error") ||
|
|
297
|
+
// Certificate/TLS provider failures must pass this primary retry gate
|
|
298
|
+
// before the managed-session fallback model branch can run.
|
|
299
|
+
message.includes("unknown certificate verification error") ||
|
|
300
|
+
message.includes("certificate has expired") ||
|
|
301
|
+
message.includes("certificate verification") ||
|
|
302
|
+
message.includes("tls") ||
|
|
303
|
+
message.includes("ssl") ||
|
|
297
304
|
message.includes("connection reset") ||
|
|
298
305
|
message.includes("socket hang up") ||
|
|
299
306
|
message.includes("aborted")) {
|
|
@@ -343,6 +350,9 @@ function isCertificateApiError(error) {
|
|
|
343
350
|
type.includes("tls") ||
|
|
344
351
|
type.includes("ssl"));
|
|
345
352
|
}
|
|
353
|
+
function isProviderRetryBanner(text) {
|
|
354
|
+
return /(?:<none>\s*)?retrying in \d+s\s*-\s*attempt #\d+/i.test(text);
|
|
355
|
+
}
|
|
346
356
|
async function setSessionFallbackModel(state, sessionID, model) {
|
|
347
357
|
const existing = state.managedUltraworkSessions.get(sessionID);
|
|
348
358
|
if (!existing)
|
|
@@ -1463,6 +1473,23 @@ function createTextCompleteHandler(state) {
|
|
|
1463
1473
|
const text = output.text ?? "";
|
|
1464
1474
|
if (!text)
|
|
1465
1475
|
return;
|
|
1476
|
+
// Some provider/SDK failures render as a retry banner instead of a
|
|
1477
|
+
// session.error event, leaving the UI waiting for long internal backoff.
|
|
1478
|
+
if (isProviderRetryBanner(text) && isManagedUltraworkSession(state, sessionID)) {
|
|
1479
|
+
const managedSession = getManagedSession(state, sessionID);
|
|
1480
|
+
const fallbackModel = managedSession?.kind === "child"
|
|
1481
|
+
? CHILD_SESSION_FALLBACK_MODEL
|
|
1482
|
+
: RATE_LIMIT_FALLBACK_MODEL;
|
|
1483
|
+
await setSessionFallbackModel(state, sessionID, fallbackModel);
|
|
1484
|
+
scheduleManagedSessionRetry(state, sessionID, {
|
|
1485
|
+
delayMs: 1_000,
|
|
1486
|
+
reason: "provider retry banner fallback",
|
|
1487
|
+
countAgainstBudget: false,
|
|
1488
|
+
abortBeforePrompt: true,
|
|
1489
|
+
});
|
|
1490
|
+
console.log(`[opencode-immune] Provider retry banner detected for session ${sessionID}. ` +
|
|
1491
|
+
`Fallback model pinned to ${fallbackModel.providerID}/${fallbackModel.modelID}.`);
|
|
1492
|
+
}
|
|
1466
1493
|
// ── ALL_CYCLES_COMPLETE: clear ultrawork marker ──
|
|
1467
1494
|
if (text.includes(ALL_CYCLES_COMPLETE_MARKER)) {
|
|
1468
1495
|
await clearUltraworkMarker(state);
|