@azumag/opencode-rate-limit-fallback 1.0.15 → 1.0.17
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 +22 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -316,28 +316,37 @@ export const RateLimitFallback = async ({ client, directory }) => {
|
|
|
316
316
|
parts: parts,
|
|
317
317
|
model: { providerID: nextModel.providerID, modelID: nextModel.modelID },
|
|
318
318
|
};
|
|
319
|
-
|
|
320
|
-
//
|
|
321
|
-
//
|
|
322
|
-
//
|
|
323
|
-
//
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
// in
|
|
319
|
+
// CRITICAL PATH: abort → promptAsync with NO delay between them.
|
|
320
|
+
//
|
|
321
|
+
// In headless mode (opencode run), the server disposes shortly after
|
|
322
|
+
// session goes idle. Any delay (setTimeout, awaited toast, etc.) risks
|
|
323
|
+
// promptAsync arriving after the server is dead.
|
|
324
|
+
//
|
|
325
|
+
// promptAsync: HTTP POST /session/{id}/prompt_async → 204 (SDK sdk.gen.js).
|
|
326
|
+
// prompt (sync): blocks until generation completes → abort flag race in TUI,
|
|
327
|
+
// server dispose in headless. Do NOT use.
|
|
328
|
+
const t0 = Date.now();
|
|
328
329
|
try {
|
|
329
330
|
await client.session.abort({ path: { id: sessionID } });
|
|
330
|
-
logToFile(`abort succeeded for session ${sessionID}`);
|
|
331
|
+
logToFile(`abort succeeded for session ${sessionID} (${Date.now() - t0}ms)`);
|
|
331
332
|
}
|
|
332
333
|
catch (abortErr) {
|
|
333
|
-
|
|
334
|
+
// If abort fails, the session may still be in its retry loop.
|
|
335
|
+
// We still send promptAsync as best-effort: when the retry loop eventually
|
|
336
|
+
// completes (timeout or success), the queued prompt should be processed.
|
|
337
|
+
logToFile(`abort failed (${Date.now() - t0}ms): ${abortErr} — sending promptAsync as best-effort`);
|
|
334
338
|
}
|
|
339
|
+
const t1 = Date.now();
|
|
335
340
|
await client.session.promptAsync({
|
|
336
341
|
path: { id: sessionID },
|
|
337
342
|
body: promptBody,
|
|
338
343
|
});
|
|
339
|
-
logToFile(`promptAsync
|
|
340
|
-
|
|
344
|
+
logToFile(`promptAsync completed for session ${sessionID} (${Date.now() - t1}ms, total ${Date.now() - t0}ms) with model ${nextModel.providerID}/${nextModel.modelID}`);
|
|
345
|
+
// Toast is best-effort notification. The toast() function (line ~185) has
|
|
346
|
+
// built-in fallback: showToast failure → app.log. After promptAsync the
|
|
347
|
+
// server may already be disposing, so both showToast and app.log could fail.
|
|
348
|
+
// The outer .catch() ensures even total toast() failure never blocks or throws.
|
|
349
|
+
toast("Fallback Active", `Now using ${nextModel.modelID}`, "success").catch(() => { });
|
|
341
350
|
retryState.delete(stateKey);
|
|
342
351
|
// Clear fallback flag to allow next fallback if needed
|
|
343
352
|
fallbackInProgress.delete(sessionID);
|
package/package.json
CHANGED