cascade-ai 0.2.0 → 0.2.1

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.cjs CHANGED
@@ -164,7 +164,7 @@ var require_keytar2 = __commonJS({
164
164
  });
165
165
 
166
166
  // src/constants.ts
167
- var CASCADE_VERSION = "0.1.2";
167
+ var CASCADE_VERSION = "0.2.0";
168
168
  var CASCADE_CONFIG_DIR = ".cascade";
169
169
  var CASCADE_MD_FILE = "CASCADE.md";
170
170
  var CASCADE_IGNORE_FILE = ".cascadeignore";
@@ -1284,6 +1284,15 @@ var ModelSelector = class {
1284
1284
  markProviderUnavailable(provider) {
1285
1285
  this.availableProviders.delete(provider);
1286
1286
  }
1287
+ /**
1288
+ * Re-add a provider to the available set after it has recovered (e.g. after
1289
+ * a failover timeout expires or a successful call confirms recovery). Only
1290
+ * re-enables providers that were originally configured — callers should
1291
+ * guard against enabling providers that were never configured.
1292
+ */
1293
+ markProviderAvailable(provider) {
1294
+ this.availableProviders.add(provider);
1295
+ }
1287
1296
  resolveDynamicModel(overrideModelId) {
1288
1297
  let providerStr = null;
1289
1298
  let actualId = overrideModelId;
@@ -1353,10 +1362,23 @@ var FailoverManager = class {
1353
1362
  if (!failure) return true;
1354
1363
  if (Date.now() - failure.failedAt >= failure.retryAfterMs) {
1355
1364
  this.failures.delete(provider);
1365
+ this.selector.markProviderAvailable(provider);
1356
1366
  return true;
1357
1367
  }
1358
1368
  return false;
1359
1369
  }
1370
+ /**
1371
+ * Call after a successful generation to immediately re-enable a provider
1372
+ * that had previously been marked unavailable. This allows fast recovery
1373
+ * when a transient rate-limit clears before the backoff window expires,
1374
+ * preventing unnecessary routing to more expensive fallback models.
1375
+ */
1376
+ recordSuccess(provider) {
1377
+ if (this.failures.has(provider)) {
1378
+ this.failures.delete(provider);
1379
+ this.selector.markProviderAvailable(provider);
1380
+ }
1381
+ }
1360
1382
  getFallbackModel(currentModel, tier) {
1361
1383
  return this.selector.getNextFallback(currentModel.id, tier);
1362
1384
  }
@@ -1373,6 +1395,7 @@ var FailoverManager = class {
1373
1395
  }
1374
1396
  clearFailure(provider) {
1375
1397
  this.failures.delete(provider);
1398
+ this.selector.markProviderAvailable(provider);
1376
1399
  }
1377
1400
  };
1378
1401
 
@@ -1585,6 +1608,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
1585
1608
  throw new Error(`Provider ${model.provider}:${model.id} returned an invalid generation result.`);
1586
1609
  }
1587
1610
  this.recordStats(tier, model, result.usage);
1611
+ this.failover.recordSuccess(model.provider);
1588
1612
  return result;
1589
1613
  } catch (err) {
1590
1614
  const errMsg = err instanceof Error ? err.message : String(err);