@azumag/opencode-rate-limit-fallback 1.66.0 → 1.68.0

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 CHANGED
@@ -158,6 +158,11 @@ export const RateLimitFallback = async ({ client, directory, worktree }) => {
158
158
  if (!config.enabled) {
159
159
  return {};
160
160
  }
161
+ // Disable fallback in headless mode — headless sessions should use their configured model only
162
+ if (isHeadless) {
163
+ logger.info("Headless mode detected — model fallback disabled");
164
+ return {};
165
+ }
161
166
  // Initialize error pattern registry
162
167
  const errorPatternRegistry = new ErrorPatternRegistry(logger);
163
168
  if (config.errorPatterns?.custom) {
@@ -43,13 +43,9 @@ export declare class FallbackHandler {
43
43
  modelID: string;
44
44
  } | null;
45
45
  /**
46
- * Abort current session with error handling
47
- */
48
- private abortSession;
49
- /**
50
- * Queue prompt asynchronously (non-blocking), then abort retry loop.
51
- * promptAsync FIRST queues pending work so that server doesn't dispose on idle.
52
- * abort SECOND cancels the retry loop; the server sees the queued prompt and processes it.
46
+ * Queue prompt asynchronously (non-blocking) to schedule fallback.
47
+ * The server's retry loop finishes naturally; it then picks up the queued prompt.
48
+ * We do NOT call abort — its AbortController signal persists and kills the new stream.
53
49
  */
54
50
  retryWithModel(targetSessionID: string, model: FallbackModel, parts: MessagePart[], hierarchy: SessionHierarchy | null): Promise<void>;
55
51
  /**
@@ -92,21 +92,9 @@ export class FallbackHandler {
92
92
  return tracked ? { providerID: tracked.providerID, modelID: tracked.modelID } : null;
93
93
  }
94
94
  /**
95
- * Abort current session with error handling
96
- */
97
- async abortSession(sessionID) {
98
- try {
99
- await this.client.session.abort({ path: { id: sessionID } });
100
- }
101
- catch (abortError) {
102
- // Silently ignore abort errors and continue with fallback
103
- this.logger.debug(`Failed to abort session ${sessionID}`, { error: abortError });
104
- }
105
- }
106
- /**
107
- * Queue prompt asynchronously (non-blocking), then abort retry loop.
108
- * promptAsync FIRST queues pending work so that server doesn't dispose on idle.
109
- * abort SECOND cancels the retry loop; the server sees the queued prompt and processes it.
95
+ * Queue prompt asynchronously (non-blocking) to schedule fallback.
96
+ * The server's retry loop finishes naturally; it then picks up the queued prompt.
97
+ * We do NOT call abort — its AbortController signal persists and kills the new stream.
110
98
  */
111
99
  async retryWithModel(targetSessionID, model, parts, hierarchy) {
112
100
  // Record model usage for dynamic prioritization
@@ -152,11 +140,13 @@ export class FallbackHandler {
152
140
  model: { providerID: model.providerID, modelID: model.modelID },
153
141
  },
154
142
  });
155
- // 2. abort: cancel the retry loop; server sees queued prompt and processes it
156
- await this.abortSession(targetSessionID);
143
+ // Do NOT call abort after promptAsync.
144
+ // The AbortController signal persists and kills the newly queued stream too,
145
+ // causing "interrupted" in TUI mode and server disposal in headless mode.
146
+ // Let the server's retry loop finish naturally; it will pick up the queued prompt.
157
147
  await safeShowToast(this.client, {
158
148
  body: {
159
- title: "Fallback Successful",
149
+ title: "Fallback Queued",
160
150
  message: `Now using ${model.modelID}`,
161
151
  variant: "success",
162
152
  duration: 3000,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azumag/opencode-rate-limit-fallback",
3
- "version": "1.66.0",
3
+ "version": "1.68.0",
4
4
  "description": "OpenCode plugin that automatically switches to fallback models when rate limited",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",