@azumag/opencode-rate-limit-fallback 1.0.8 → 1.0.10

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 +146 -1
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
- import { existsSync, readFileSync } from "fs";
1
+ import { existsSync, readFileSync, appendFileSync } from "fs";
2
2
  import { join } from "path";
3
+ // Debug log at module level
4
+ console.log("[rate-limit-fallback] Module loaded, version:", process.env.npm_package_version || "unknown");
3
5
  const DEFAULT_FALLBACK_MODELS = [
4
6
  { providerID: "anthropic", modelID: "claude-sonnet-4-20250514" },
5
7
  { providerID: "google", modelID: "gemini-2.5-pro" },
@@ -71,7 +73,44 @@ function isRateLimitError(error) {
71
73
  }
72
74
  export const RateLimitFallback = async ({ client, directory }) => {
73
75
  const config = loadConfig(directory);
76
+ const logFilePath = join(process.env.HOME || "", ".opencode", "rate-limit-fallback-debug.log");
77
+ // Write to file for debugging
78
+ const logToFile = (message) => {
79
+ try {
80
+ appendFileSync(logFilePath, `[${new Date().toISOString()}] ${message}\n`);
81
+ }
82
+ catch { }
83
+ };
84
+ logToFile(`Plugin loaded, config: ${JSON.stringify(config)}`);
85
+ console.log("[rate-limit-fallback] Plugin loaded, config:", config);
86
+ // Use client.app.log for better logging in both run and TUI modes
87
+ try {
88
+ await client.app.log({
89
+ body: {
90
+ service: "rate-limit-fallback",
91
+ level: "info",
92
+ message: `Plugin loaded, config: ${JSON.stringify(config)}`,
93
+ },
94
+ });
95
+ }
96
+ catch (e) {
97
+ logToFile(`client.app.log failed: ${e}`);
98
+ console.log("[rate-limit-fallback] Plugin loaded, config:", config);
99
+ }
74
100
  if (!config.enabled) {
101
+ logToFile("Plugin disabled, returning empty object");
102
+ try {
103
+ await client.app.log({
104
+ body: {
105
+ service: "rate-limit-fallback",
106
+ level: "info",
107
+ message: "Plugin disabled, returning empty object",
108
+ },
109
+ });
110
+ }
111
+ catch {
112
+ console.log("[rate-limit-fallback] Plugin disabled, returning empty object");
113
+ }
75
114
  return {};
76
115
  }
77
116
  const rateLimitedModels = new Map();
@@ -283,29 +322,135 @@ export const RateLimitFallback = async ({ client, directory }) => {
283
322
  }
284
323
  return {
285
324
  event: async ({ event }) => {
325
+ // Log events to debug plugin execution
326
+ logToFile(`Event received: ${event.type}`);
327
+ try {
328
+ await client.app.log({
329
+ body: {
330
+ service: "rate-limit-fallback",
331
+ level: "debug",
332
+ message: `Event received: ${event.type}`,
333
+ },
334
+ });
335
+ }
336
+ catch (e) {
337
+ logToFile(`client.app.log failed for event: ${e}`);
338
+ console.log("[rate-limit-fallback] Event received:", event.type);
339
+ }
286
340
  if (event.type === "session.error") {
287
341
  const { sessionID, error } = event.properties;
342
+ logToFile(`session.error: sessionID=${sessionID}, error=${JSON.stringify(error)}`);
343
+ try {
344
+ await client.app.log({
345
+ body: {
346
+ service: "rate-limit-fallback",
347
+ level: "debug",
348
+ message: `session.error: sessionID=${sessionID}, error=${JSON.stringify(error)}`,
349
+ },
350
+ });
351
+ }
352
+ catch {
353
+ console.log("[rate-limit-fallback] session.error:", sessionID, error);
354
+ }
288
355
  if (sessionID && error && isRateLimitError(error)) {
356
+ logToFile("Rate limit error detected, attempting fallback");
357
+ try {
358
+ await client.app.log({
359
+ body: {
360
+ service: "rate-limit-fallback",
361
+ level: "info",
362
+ message: "Rate limit error detected, attempting fallback",
363
+ },
364
+ });
365
+ }
366
+ catch {
367
+ console.log("[rate-limit-fallback] Rate limit error detected, attempting fallback");
368
+ }
289
369
  await handleRateLimitFallback(sessionID, "", "");
290
370
  }
291
371
  }
292
372
  if (event.type === "message.updated") {
293
373
  const info = event.properties?.info;
374
+ logToFile(`message.updated: ${JSON.stringify(info)}`);
375
+ try {
376
+ await client.app.log({
377
+ body: {
378
+ service: "rate-limit-fallback",
379
+ level: "debug",
380
+ message: `message.updated: ${JSON.stringify(info)}`,
381
+ },
382
+ });
383
+ }
384
+ catch {
385
+ console.log("[rate-limit-fallback] message.updated:", info);
386
+ }
294
387
  if (info?.error && isRateLimitError(info.error)) {
388
+ logToFile("Rate limit error in message, attempting fallback");
389
+ try {
390
+ await client.app.log({
391
+ body: {
392
+ service: "rate-limit-fallback",
393
+ level: "info",
394
+ message: "Rate limit error in message, attempting fallback",
395
+ },
396
+ });
397
+ }
398
+ catch {
399
+ console.log("[rate-limit-fallback] Rate limit error in message, attempting fallback");
400
+ }
295
401
  await handleRateLimitFallback(info.sessionID, info.providerID || "", info.modelID || "");
296
402
  }
297
403
  }
298
404
  if (event.type === "session.status") {
299
405
  const props = event.properties;
300
406
  const status = props?.status;
407
+ logToFile(`session.status: ${JSON.stringify(status)}`);
408
+ try {
409
+ await client.app.log({
410
+ body: {
411
+ service: "rate-limit-fallback",
412
+ level: "debug",
413
+ message: `session.status: ${JSON.stringify(status)}`,
414
+ },
415
+ });
416
+ }
417
+ catch {
418
+ console.log("[rate-limit-fallback] session.status:", status);
419
+ }
301
420
  if (status?.type === "retry" && status?.message) {
302
421
  const message = status.message.toLowerCase();
303
422
  const isRateLimitRetry = message.includes("usage limit") ||
304
423
  message.includes("rate limit") ||
305
424
  message.includes("high concurrency") ||
306
425
  message.includes("reduce concurrency");
426
+ logToFile(`Is rate limit retry: ${isRateLimitRetry}, message: ${message}`);
427
+ try {
428
+ await client.app.log({
429
+ body: {
430
+ service: "rate-limit-fallback",
431
+ level: "debug",
432
+ message: `Is rate limit retry: ${isRateLimitRetry}, message: ${message}`,
433
+ },
434
+ });
435
+ }
436
+ catch {
437
+ console.log("[rate-limit-fallback] Is rate limit retry:", isRateLimitRetry, "message:", message);
438
+ }
307
439
  if (isRateLimitRetry) {
308
440
  // Try fallback on any attempt, handleRateLimitFallback will manage state
441
+ logToFile("Attempting fallback for rate limit retry");
442
+ try {
443
+ await client.app.log({
444
+ body: {
445
+ service: "rate-limit-fallback",
446
+ level: "info",
447
+ message: "Attempting fallback for rate limit retry",
448
+ },
449
+ });
450
+ }
451
+ catch {
452
+ console.log("[rate-limit-fallback] Attempting fallback for rate limit retry");
453
+ }
309
454
  await handleRateLimitFallback(props.sessionID, "", "");
310
455
  }
311
456
  }
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@azumag/opencode-rate-limit-fallback",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "OpenCode plugin that automatically switches to fallback models when rate limited",
5
5
  "type": "module",
6
+ "main": "./dist/index.js",
6
7
  "scripts": {
7
8
  "build": "tsc",
8
9
  "prepublishOnly": "npm run build"