@azumag/opencode-rate-limit-fallback 1.0.13 → 1.0.15

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.
Files changed (2) hide show
  1. package/dist/index.js +14 -22
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -316,7 +316,15 @@ export const RateLimitFallback = async ({ client, directory }) => {
316
316
  parts: parts,
317
317
  model: { providerID: nextModel.providerID, modelID: nextModel.modelID },
318
318
  };
319
- // Abort to cancel the retry loop
319
+ toast("Retrying", `Using ${nextModel.providerID}/${nextModel.modelID}`, "info").catch(() => { });
320
+ // Abort to cancel the retry loop, then promptAsync immediately.
321
+ // CRITICAL: no delay between abort and promptAsync.
322
+ // - In headless (opencode run), server disposes ~8ms after session idle.
323
+ // Any delay (even 50ms) means promptAsync arrives after server is dead.
324
+ // - promptAsync returns immediately (just queues), so it fires before
325
+ // the server can shut down.
326
+ // - Do NOT use prompt (sync) here — it causes abort flag race condition
327
+ // in TUI mode (prompt immediately interrupted).
320
328
  try {
321
329
  await client.session.abort({ path: { id: sessionID } });
322
330
  logToFile(`abort succeeded for session ${sessionID}`);
@@ -324,27 +332,11 @@ export const RateLimitFallback = async ({ client, directory }) => {
324
332
  catch (abortErr) {
325
333
  logToFile(`abort failed (non-critical): ${abortErr}`);
326
334
  }
327
- // await toast AFTER abort — provides natural delay (~50ms) for abort flag to clear
328
- // before prompting. Without this delay, the new prompt gets immediately aborted.
329
- await toast("Retrying", `Using ${nextModel.providerID}/${nextModel.modelID}`, "info");
330
- // Try prompt (sync) first — reliably triggers generation in TUI mode.
331
- // If it fails (e.g. run mode where server shuts down after abort),
332
- // fall back to promptAsync which fires before server can exit.
333
- try {
334
- await client.session.prompt({
335
- path: { id: sessionID },
336
- body: promptBody,
337
- });
338
- logToFile(`prompt completed successfully for session ${sessionID} with model ${nextModel.providerID}/${nextModel.modelID}`);
339
- }
340
- catch (promptErr) {
341
- logToFile(`prompt failed (${promptErr}), falling back to promptAsync`);
342
- await client.session.promptAsync({
343
- path: { id: sessionID },
344
- body: promptBody,
345
- });
346
- logToFile(`promptAsync sent successfully for session ${sessionID} with model ${nextModel.providerID}/${nextModel.modelID}`);
347
- }
335
+ await client.session.promptAsync({
336
+ path: { id: sessionID },
337
+ body: promptBody,
338
+ });
339
+ logToFile(`promptAsync sent successfully for session ${sessionID} with model ${nextModel.providerID}/${nextModel.modelID}`);
348
340
  toast("Fallback Successful", `Now using ${nextModel.modelID}`, "success").catch(() => { });
349
341
  retryState.delete(stateKey);
350
342
  // Clear fallback flag to allow next fallback if needed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azumag/opencode-rate-limit-fallback",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "OpenCode plugin that automatically switches to fallback models when rate limited",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",