@north-light/cli 0.3.505 → 0.3.506

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.
@@ -1,7 +1,7 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { createAssistantMessageEventStream, } from '@earendil-works/pi-ai';
3
3
  import { anthropicMessagesApi, openAICodexResponsesApi, openAIResponsesApi } from '@earendil-works/pi-ai/compat';
4
- import { ANTHROPIC_PROVIDER_ID, OPENAI_CHATGPT_PROVIDER_ID, OPENAI_CODEX_PROVIDER_ID, INVALID_REFRESH_TOKEN_BACKOFF_MS, openAIDeviceId, coolingUntilFor, formatCooldowns, formatStatusLine, getProviderLabel, isManagedProvider, isInvalidRefreshTokenError, addSubscription, enrichManagedLoginIdentity, markSubscriptionAuthenticationFailed, markSubscriptionRateLimited, markSubscriptionSuccess, retryAfterMsFromHeaders, retryAfterMsFromError, promoteSubscription, readRotationConfig, readSubscriptionPool, refreshSubscriptionCredential, removeManagedAccount, resolveProviderCandidates, upsertSubscriptionWithUniqueAccount, subscriptionNeedsSuccessWrite, } from '../../../core/subscription-state.js';
4
+ import { ANTHROPIC_PROVIDER_ID, OPENAI_CHATGPT_PROVIDER_ID, OPENAI_CODEX_PROVIDER_ID, INVALID_REFRESH_TOKEN_BACKOFF_MS, openAIDeviceId, MAX_RATE_LIMIT_COOLDOWN_MS, coolingUntilFor, formatCooldowns, formatStatusLine, getProviderLabel, isManagedProvider, isInvalidRefreshTokenError, addSubscription, enrichManagedLoginIdentity, markSubscriptionAuthenticationFailed, markSubscriptionRateLimited, markSubscriptionSuccess, retryAfterMsFromHeaders, retryAfterMsFromError, promoteSubscription, readRotationConfig, readSubscriptionPool, refreshSubscriptionCredential, removeManagedAccount, resolveProviderCandidates, upsertSubscriptionWithUniqueAccount, subscriptionNeedsSuccessWrite, } from '../../../core/subscription-state.js';
5
5
  import { classifyRateLimit, describeRateLimitScope, rateLimitHeaders } from '../../../core/rate-limit-scope.js';
6
6
  import { readMergedLaunchConfig } from '../../../core/config.js';
7
7
  import { expandModelCandidates, modelRequestFromConfig, probeRouteAvailability } from '../../../core/model-routes.js';
@@ -696,7 +696,7 @@ async function runManagedProvider(state, model, context, options, stream) {
696
696
  }
697
697
  if (result.result === 'rate_limited' || result.classification?.status !== undefined || result.classification?.hadRetryAfterHeader === true)
698
698
  sawHttpEvidence = true;
699
- const cooldownMs = result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS;
699
+ const cooldownMs = Math.min(result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS, MAX_RATE_LIMIT_COOLDOWN_MS);
700
700
  if (result.result === 'transient_exhausted')
701
701
  lastTransientFailure = result;
702
702
  if (result.result === 'rate_limited' && (result.classification?.status === 401 || result.classification?.status === 403))
@@ -754,7 +754,7 @@ async function runManagedProvider(state, model, context, options, stream) {
754
754
  }
755
755
  if (result.result === 'rate_limited' || result.classification?.status !== undefined || result.classification?.hadRetryAfterHeader === true)
756
756
  sawHttpEvidence = true;
757
- const cooldownMs = result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS;
757
+ const cooldownMs = Math.min(result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS, MAX_RATE_LIMIT_COOLDOWN_MS);
758
758
  if (result.result === 'transient_exhausted')
759
759
  lastTransientFailure = result;
760
760
  if (result.result === 'rate_limited' && (result.classification?.status === 401 || result.classification?.status === 403))
@@ -19,6 +19,7 @@ import {
19
19
  OPENAI_CODEX_PROVIDER_ID,
20
20
  INVALID_REFRESH_TOKEN_BACKOFF_MS,
21
21
  openAIDeviceId,
22
+ MAX_RATE_LIMIT_COOLDOWN_MS,
22
23
  coolingUntilFor,
23
24
  formatCooldowns,
24
25
  formatStatusLine,
@@ -913,7 +914,7 @@ async function runManagedProvider(
913
914
  const result = await streamProviderAttempt(state, providerId, candidateModel, context, attemptOptions, undefined, stream);
914
915
  if (result.result === 'success' || result.result === 'fatal') { state.transportOnlyExhaustedPasses = 0; stream.end(); return; }
915
916
  if (result.result === 'rate_limited' || result.classification?.status !== undefined || result.classification?.hadRetryAfterHeader === true) sawHttpEvidence = true;
916
- const cooldownMs = result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS;
917
+ const cooldownMs = Math.min(result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS, MAX_RATE_LIMIT_COOLDOWN_MS);
917
918
  if (result.result === 'transient_exhausted') lastTransientFailure = result;
918
919
  if (result.result === 'rate_limited' && (result.classification?.status === 401 || result.classification?.status === 403)) lastAuthRejection = result;
919
920
  if (result.rateLimit && Object.keys(result.rateLimit.headers).length) lastRateLimit = { providerId, model: candidateModel, observation: result.rateLimit };
@@ -955,7 +956,7 @@ async function runManagedProvider(
955
956
  }
956
957
  if (result.result === 'fatal') { state.transportOnlyExhaustedPasses = 0; stream.end(); return; }
957
958
  if (result.result === 'rate_limited' || result.classification?.status !== undefined || result.classification?.hadRetryAfterHeader === true) sawHttpEvidence = true;
958
- const cooldownMs = result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS;
959
+ const cooldownMs = Math.min(result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS, MAX_RATE_LIMIT_COOLDOWN_MS);
959
960
  if (result.result === 'transient_exhausted') lastTransientFailure = result;
960
961
  if (result.result === 'rate_limited' && (result.classification?.status === 401 || result.classification?.status === 403)) lastAuthRejection = result;
961
962
  if (result.rateLimit && Object.keys(result.rateLimit.headers).length) lastRateLimit = { providerId, model: candidateModel, account: freshCredential.label, observation: result.rateLimit };