@absolutejs/ai 0.6.3 → 0.6.4

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.
@@ -344,12 +344,21 @@ var CONNECTION_ERROR_PATTERNS = [
344
344
  ];
345
345
  var isAbortError = (err) => err instanceof Error && (err.name === "AbortError" || /\babort(ed)?\b/i.test(err.message));
346
346
  var providerStatusPage = (provider) => PROVIDER_STATUS_PAGES[provider] ?? null;
347
+ var BILLING_ERROR_TYPES = new Set([
348
+ "credit_balance_exhausted",
349
+ "insufficient_quota",
350
+ "billing_hard_limit_reached",
351
+ "billing_not_active",
352
+ "insufficient_credits"
353
+ ]);
347
354
 
348
355
  class ProviderError extends Error {
349
356
  provider;
350
357
  status;
351
358
  type;
352
359
  retryable;
360
+ billingUnavailable;
361
+ notSent;
353
362
  metadata;
354
363
  statusPageUrl;
355
364
  constructor(init) {
@@ -357,8 +366,10 @@ class ProviderError extends Error {
357
366
  this.name = "ProviderError";
358
367
  this.provider = init.provider;
359
368
  this.status = init.status ?? null;
360
- this.type = init.type ?? null;
361
- this.retryable = init.retryable;
369
+ this.type = init.type ?? (typeof init.metadata?.code === "string" ? init.metadata.code : typeof init.metadata?.type === "string" ? init.metadata.type : null);
370
+ this.billingUnavailable = BILLING_ERROR_TYPES.has(this.type ?? "") || init.status === 402;
371
+ this.notSent = init.notSent === true;
372
+ this.retryable = !this.billingUnavailable && init.retryable;
362
373
  this.metadata = init.metadata;
363
374
  this.statusPageUrl = providerStatusPage(init.provider);
364
375
  }
@@ -504,6 +515,7 @@ var circuitOpen = (provider) => {
504
515
  message: `${provider} API is reported down${record.external.reason ? `: ${record.external.reason}` : ""}`,
505
516
  provider,
506
517
  retryable: true,
518
+ notSent: true,
507
519
  status: null,
508
520
  type: record.external.indicator
509
521
  });
@@ -519,11 +531,16 @@ var circuitOpen = (provider) => {
519
531
  message: `${provider} is temporarily unavailable (circuit open after ${record.consecutiveFailures} failures): ${detail}`,
520
532
  provider,
521
533
  retryable: true,
534
+ notSent: true,
522
535
  status: record.lastError?.status ?? null,
523
536
  type: record.lastError?.type ?? null
524
537
  });
525
538
  };
526
539
  var withResilience = (provider, providerName = "unknown") => {
540
+ let billingFailure = null;
541
+ let billingRetryAt = 0;
542
+ let billingProbe = false;
543
+ const billingCooldownMs = 5 * 60000;
527
544
  const attempt = async function* (params, attemptNo) {
528
545
  let yielded = false;
529
546
  try {
@@ -531,9 +548,16 @@ var withResilience = (provider, providerName = "unknown") => {
531
548
  yielded = true;
532
549
  yield chunk;
533
550
  }
551
+ billingFailure = null;
552
+ billingProbe = false;
534
553
  noteSuccess(providerName);
535
554
  } catch (err) {
536
555
  const providerError = ProviderError.from(err, providerName);
556
+ if (providerError.billingUnavailable) {
557
+ billingFailure = providerError;
558
+ billingRetryAt = Date.now() + billingCooldownMs;
559
+ }
560
+ billingProbe = false;
537
561
  const canRetry = !yielded && providerError.retryable && attemptNo < (params.maxRetries === undefined ? config.maxRetries : Math.max(0, Math.min(config.maxRetries, params.maxRetries))) && !params.signal?.aborted;
538
562
  if (canRetry) {
539
563
  await sleep(backoffDelay(attemptNo), params.signal);
@@ -548,6 +572,21 @@ var withResilience = (provider, providerName = "unknown") => {
548
572
  return {
549
573
  ...provider,
550
574
  stream: (params) => {
575
+ if (billingFailure && (Date.now() < billingRetryAt || billingProbe)) {
576
+ const failure = billingFailure;
577
+ return async function* () {
578
+ throw new ProviderError({
579
+ provider: providerName,
580
+ message: "Provider billing is unavailable",
581
+ type: failure.type,
582
+ status: failure.status,
583
+ retryable: false,
584
+ notSent: true
585
+ });
586
+ }();
587
+ }
588
+ if (billingFailure)
589
+ billingProbe = true;
551
590
  const tripped = circuitOpen(providerName);
552
591
  if (tripped) {
553
592
  return async function* () {
@@ -1989,5 +2028,5 @@ export {
1989
2028
  openai
1990
2029
  };
1991
2030
 
1992
- //# debugId=531DB284DCC12A8864756E2164756E21
2031
+ //# debugId=0CC011402536F35664756E2164756E21
1993
2032
  //# sourceMappingURL=openai.js.map