codex-multi-auth 2.3.2 → 2.4.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/.codex-plugin/plugin.json +1 -1
- package/README.md +4 -1
- package/dist/lib/accounts.d.ts +14 -0
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +59 -4
- package/dist/lib/constants.d.ts +7 -0
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +7 -0
- package/dist/lib/forecast.d.ts.map +1 -1
- package/dist/lib/forecast.js +15 -6
- package/dist/lib/local-client-tokens.d.ts.map +1 -1
- package/dist/lib/local-client-tokens.js +11 -4
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +5 -0
- package/dist/lib/preemptive-quota-scheduler.d.ts.map +1 -1
- package/dist/lib/preemptive-quota-scheduler.js +29 -3
- package/dist/lib/refresh-lease.d.ts +1 -0
- package/dist/lib/refresh-lease.d.ts.map +1 -1
- package/dist/lib/refresh-lease.js +35 -4
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
- package/dist/lib/request/fetch-helpers.js +3 -2
- package/dist/lib/request/rate-limit-decision.d.ts.map +1 -1
- package/dist/lib/request/rate-limit-decision.js +7 -2
- package/dist/lib/request/response-handler.d.ts.map +1 -1
- package/dist/lib/request/response-handler.js +63 -11
- package/dist/lib/runtime/rotation-proxy-state.d.ts +7 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-server-types.d.ts +9 -0
- package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.d.ts +10 -0
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.js +38 -1
- package/dist/lib/schemas.js +2 -2
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +6 -1
- package/package.json +1 -1
- package/scripts/codex.js +189 -8
- package/dist/index.js.map +0 -1
- package/dist/lib/account-policy.js.map +0 -1
- package/dist/lib/accounts/rate-limits.js.map +0 -1
- package/dist/lib/accounts.js.map +0 -1
- package/dist/lib/audit.js.map +0 -1
- package/dist/lib/auth/auth.js.map +0 -1
- package/dist/lib/auth/browser.js.map +0 -1
- package/dist/lib/auth/device-auth.js.map +0 -1
- package/dist/lib/auth/index.js.map +0 -1
- package/dist/lib/auth/org-override.js.map +0 -1
- package/dist/lib/auth/server.js.map +0 -1
- package/dist/lib/auth/token-utils.js.map +0 -1
- package/dist/lib/auth-rate-limit.js.map +0 -1
- package/dist/lib/budget-guard.js.map +0 -1
- package/dist/lib/capability-policy.js.map +0 -1
- package/dist/lib/circuit-breaker.js.map +0 -1
- package/dist/lib/cli.js.map +0 -1
- package/dist/lib/codex-cli/index.js.map +0 -1
- package/dist/lib/codex-cli/observability.js.map +0 -1
- package/dist/lib/codex-cli/state.js.map +0 -1
- package/dist/lib/codex-cli/sync.js.map +0 -1
- package/dist/lib/codex-cli/writer.js.map +0 -1
- package/dist/lib/codex-manager/account-manager-commands.js.map +0 -1
- package/dist/lib/codex-manager/account-pool-write.js.map +0 -1
- package/dist/lib/codex-manager/backend-category-entry.js.map +0 -1
- package/dist/lib/codex-manager/backend-category-helpers.js.map +0 -1
- package/dist/lib/codex-manager/backend-category-prompt.js.map +0 -1
- package/dist/lib/codex-manager/backend-settings-controller.js.map +0 -1
- package/dist/lib/codex-manager/backend-settings-entry.js.map +0 -1
- package/dist/lib/codex-manager/backend-settings-helpers.js.map +0 -1
- package/dist/lib/codex-manager/backend-settings-prompt.js.map +0 -1
- package/dist/lib/codex-manager/backend-settings-schema.js.map +0 -1
- package/dist/lib/codex-manager/behavior-settings-panel.js.map +0 -1
- package/dist/lib/codex-manager/commands/account.js.map +0 -1
- package/dist/lib/codex-manager/commands/best.js.map +0 -1
- package/dist/lib/codex-manager/commands/bridge.js.map +0 -1
- package/dist/lib/codex-manager/commands/budget.js.map +0 -1
- package/dist/lib/codex-manager/commands/check.js.map +0 -1
- package/dist/lib/codex-manager/commands/config-explain.js.map +0 -1
- package/dist/lib/codex-manager/commands/debug-bundle.js.map +0 -1
- package/dist/lib/codex-manager/commands/forecast.js.map +0 -1
- package/dist/lib/codex-manager/commands/init-config.js.map +0 -1
- package/dist/lib/codex-manager/commands/integrations.js.map +0 -1
- package/dist/lib/codex-manager/commands/models.js.map +0 -1
- package/dist/lib/codex-manager/commands/monitor.js.map +0 -1
- package/dist/lib/codex-manager/commands/report.js.map +0 -1
- package/dist/lib/codex-manager/commands/rotation.js.map +0 -1
- package/dist/lib/codex-manager/commands/status.js.map +0 -1
- package/dist/lib/codex-manager/commands/switch.js.map +0 -1
- package/dist/lib/codex-manager/commands/uninstall.js.map +0 -1
- package/dist/lib/codex-manager/commands/unpin.js.map +0 -1
- package/dist/lib/codex-manager/commands/usage.js.map +0 -1
- package/dist/lib/codex-manager/commands/verify.js.map +0 -1
- package/dist/lib/codex-manager/commands/why-selected.js.map +0 -1
- package/dist/lib/codex-manager/commands/workspace.js.map +0 -1
- package/dist/lib/codex-manager/dashboard-display-panel.js.map +0 -1
- package/dist/lib/codex-manager/dashboard-formatters.js.map +0 -1
- package/dist/lib/codex-manager/dashboard-settings-controller.js.map +0 -1
- package/dist/lib/codex-manager/dashboard-settings-data.js.map +0 -1
- package/dist/lib/codex-manager/dashboard-settings-entry.js.map +0 -1
- package/dist/lib/codex-manager/experimental-settings-entry.js.map +0 -1
- package/dist/lib/codex-manager/experimental-settings-prompt.js.map +0 -1
- package/dist/lib/codex-manager/experimental-settings-schema.js.map +0 -1
- package/dist/lib/codex-manager/experimental-sync-target-entry.js.map +0 -1
- package/dist/lib/codex-manager/experimental-sync-target.js.map +0 -1
- package/dist/lib/codex-manager/forecast-report-commands.d.ts +0 -54
- package/dist/lib/codex-manager/forecast-report-commands.d.ts.map +0 -1
- package/dist/lib/codex-manager/forecast-report-commands.js +0 -443
- package/dist/lib/codex-manager/forecast-report-commands.js.map +0 -1
- package/dist/lib/codex-manager/forecast-report-shared.js.map +0 -1
- package/dist/lib/codex-manager/help.js.map +0 -1
- package/dist/lib/codex-manager/manual-callback.js.map +0 -1
- package/dist/lib/codex-manager/rate-limit-markers.js.map +0 -1
- package/dist/lib/codex-manager/repair-commands.js.map +0 -1
- package/dist/lib/codex-manager/settings-hub/backend.js.map +0 -1
- package/dist/lib/codex-manager/settings-hub/dashboard.js.map +0 -1
- package/dist/lib/codex-manager/settings-hub/experimental.js.map +0 -1
- package/dist/lib/codex-manager/settings-hub/index.js.map +0 -1
- package/dist/lib/codex-manager/settings-hub/shared.js.map +0 -1
- package/dist/lib/codex-manager/settings-hub-entry.js.map +0 -1
- package/dist/lib/codex-manager/settings-hub-menu.js.map +0 -1
- package/dist/lib/codex-manager/settings-hub-prompt.js.map +0 -1
- package/dist/lib/codex-manager/settings-hub.js.map +0 -1
- package/dist/lib/codex-manager/settings-panels.js.map +0 -1
- package/dist/lib/codex-manager/settings-persist-utils.js.map +0 -1
- package/dist/lib/codex-manager/settings-preview.js.map +0 -1
- package/dist/lib/codex-manager/settings-write-queue.js.map +0 -1
- package/dist/lib/codex-manager/statusline-order.d.ts +0 -3
- package/dist/lib/codex-manager/statusline-order.d.ts.map +0 -1
- package/dist/lib/codex-manager/statusline-order.js +0 -16
- package/dist/lib/codex-manager/statusline-order.js.map +0 -1
- package/dist/lib/codex-manager/statusline-settings-panel.js.map +0 -1
- package/dist/lib/codex-manager/theme-settings-panel.js.map +0 -1
- package/dist/lib/codex-manager/unified-settings-controller.js.map +0 -1
- package/dist/lib/codex-manager/unified-settings-entry.js.map +0 -1
- package/dist/lib/codex-manager.js.map +0 -1
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/constants.js.map +0 -1
- package/dist/lib/context-overflow.js.map +0 -1
- package/dist/lib/dashboard-settings.js.map +0 -1
- package/dist/lib/entitlement-cache.js.map +0 -1
- package/dist/lib/env-parsing.js.map +0 -1
- package/dist/lib/errors.js.map +0 -1
- package/dist/lib/forecast.js.map +0 -1
- package/dist/lib/fs-retry.js.map +0 -1
- package/dist/lib/health.js.map +0 -1
- package/dist/lib/index.js.map +0 -1
- package/dist/lib/integration-generators.js.map +0 -1
- package/dist/lib/live-account-sync.js.map +0 -1
- package/dist/lib/local-bridge.js.map +0 -1
- package/dist/lib/local-client-tokens.js.map +0 -1
- package/dist/lib/logger.js.map +0 -1
- package/dist/lib/model-capability-matrix.js.map +0 -1
- package/dist/lib/named-backup-export.js.map +0 -1
- package/dist/lib/oc-chatgpt-import-adapter.js.map +0 -1
- package/dist/lib/oc-chatgpt-orchestrator.js.map +0 -1
- package/dist/lib/oc-chatgpt-target-detection.js.map +0 -1
- package/dist/lib/parallel-probe.js.map +0 -1
- package/dist/lib/policy/runtime-policy.js.map +0 -1
- package/dist/lib/preemptive-quota-scheduler.js.map +0 -1
- package/dist/lib/proactive-refresh.js.map +0 -1
- package/dist/lib/prompts/codex-host-bridge.js.map +0 -1
- package/dist/lib/prompts/codex.js.map +0 -1
- package/dist/lib/prompts/fetch-utils.js.map +0 -1
- package/dist/lib/prompts/host-codex-prompt.js.map +0 -1
- package/dist/lib/quota-cache.js.map +0 -1
- package/dist/lib/quota-probe.js.map +0 -1
- package/dist/lib/quota-readiness.js.map +0 -1
- package/dist/lib/recovery/constants.js.map +0 -1
- package/dist/lib/recovery/index.d.ts +0 -12
- package/dist/lib/recovery/index.d.ts.map +0 -1
- package/dist/lib/recovery/index.js +0 -11
- package/dist/lib/recovery/index.js.map +0 -1
- package/dist/lib/recovery/storage.js.map +0 -1
- package/dist/lib/recovery/types.js.map +0 -1
- package/dist/lib/recovery.js.map +0 -1
- package/dist/lib/refresh-guardian.js.map +0 -1
- package/dist/lib/refresh-lease.js.map +0 -1
- package/dist/lib/refresh-queue.js.map +0 -1
- package/dist/lib/request/failover-config.js.map +0 -1
- package/dist/lib/request/failure-policy.js.map +0 -1
- package/dist/lib/request/fetch-helpers.js.map +0 -1
- package/dist/lib/request/helpers/input-utils.js.map +0 -1
- package/dist/lib/request/helpers/model-map.js.map +0 -1
- package/dist/lib/request/helpers/tool-utils.js.map +0 -1
- package/dist/lib/request/index.js.map +0 -1
- package/dist/lib/request/rate-limit-backoff.js.map +0 -1
- package/dist/lib/request/request-attempt-budget.js.map +0 -1
- package/dist/lib/request/request-init.js.map +0 -1
- package/dist/lib/request/request-resilience.js.map +0 -1
- package/dist/lib/request/request-transformer.js.map +0 -1
- package/dist/lib/request/response-compaction.js.map +0 -1
- package/dist/lib/request/response-handler.js.map +0 -1
- package/dist/lib/request/response-metadata.js.map +0 -1
- package/dist/lib/request/stream-failover.js.map +0 -1
- package/dist/lib/request/wait-utils.js.map +0 -1
- package/dist/lib/rotation.js.map +0 -1
- package/dist/lib/routing-mutex.js.map +0 -1
- package/dist/lib/routing-profiles.js.map +0 -1
- package/dist/lib/runtime/account-check-helpers.js.map +0 -1
- package/dist/lib/runtime/account-check-types.js.map +0 -1
- package/dist/lib/runtime/account-check.js.map +0 -1
- package/dist/lib/runtime/account-health-check.d.ts +0 -8
- package/dist/lib/runtime/account-health-check.d.ts.map +0 -1
- package/dist/lib/runtime/account-health-check.js +0 -29
- package/dist/lib/runtime/account-health-check.js.map +0 -1
- package/dist/lib/runtime/account-manager-cache-entry.js.map +0 -1
- package/dist/lib/runtime/account-manager-cache.js.map +0 -1
- package/dist/lib/runtime/account-pool.js.map +0 -1
- package/dist/lib/runtime/account-scope.js.map +0 -1
- package/dist/lib/runtime/account-select-event.js.map +0 -1
- package/dist/lib/runtime/account-selection.js.map +0 -1
- package/dist/lib/runtime/account-state.js.map +0 -1
- package/dist/lib/runtime/account-status.js.map +0 -1
- package/dist/lib/runtime/account-storage-scope-entry.js.map +0 -1
- package/dist/lib/runtime/app-bind.js.map +0 -1
- package/dist/lib/runtime/auth-facade.js.map +0 -1
- package/dist/lib/runtime/browser-oauth-flow.js.map +0 -1
- package/dist/lib/runtime/capability-boost.js.map +0 -1
- package/dist/lib/runtime/config-toml.js.map +0 -1
- package/dist/lib/runtime/event-handler.js.map +0 -1
- package/dist/lib/runtime/flagged-verify-types.js.map +0 -1
- package/dist/lib/runtime/hydrate-emails.js.map +0 -1
- package/dist/lib/runtime/live-sync-entry.js.map +0 -1
- package/dist/lib/runtime/live-sync.js.map +0 -1
- package/dist/lib/runtime/loader-setup.js.map +0 -1
- package/dist/lib/runtime/login-menu-accounts.js.map +0 -1
- package/dist/lib/runtime/manual-oauth-flow.js.map +0 -1
- package/dist/lib/runtime/oauth-browser-flow.d.ts +0 -9
- package/dist/lib/runtime/oauth-browser-flow.d.ts.map +0 -1
- package/dist/lib/runtime/oauth-browser-flow.js +0 -33
- package/dist/lib/runtime/oauth-browser-flow.js.map +0 -1
- package/dist/lib/runtime/preemptive-quota.js.map +0 -1
- package/dist/lib/runtime/quota-headers.js.map +0 -1
- package/dist/lib/runtime/quota-probe.js.map +0 -1
- package/dist/lib/runtime/quota-settings.js.map +0 -1
- package/dist/lib/runtime/refresh-guardian-entry.js.map +0 -1
- package/dist/lib/runtime/refresh-guardian.js.map +0 -1
- package/dist/lib/runtime/request-init.js.map +0 -1
- package/dist/lib/runtime/runtime-current-account.js.map +0 -1
- package/dist/lib/runtime/runtime-observability.js.map +0 -1
- package/dist/lib/runtime/runtime-services.js.map +0 -1
- package/dist/lib/runtime/session-affinity-entry.js.map +0 -1
- package/dist/lib/runtime/session-affinity.d.ts +0 -13
- package/dist/lib/runtime/session-affinity.d.ts.map +0 -1
- package/dist/lib/runtime/session-affinity.js +0 -16
- package/dist/lib/runtime/session-affinity.js.map +0 -1
- package/dist/lib/runtime/session-recovery.js.map +0 -1
- package/dist/lib/runtime/status-marker.js.map +0 -1
- package/dist/lib/runtime/storage-scope.js.map +0 -1
- package/dist/lib/runtime/toast.js.map +0 -1
- package/dist/lib/runtime/ui-runtime-entry.js.map +0 -1
- package/dist/lib/runtime/ui-runtime.js.map +0 -1
- package/dist/lib/runtime/verify-flagged.js.map +0 -1
- package/dist/lib/runtime-constants.js.map +0 -1
- package/dist/lib/runtime-paths.js.map +0 -1
- package/dist/lib/runtime-rotation-proxy.js.map +0 -1
- package/dist/lib/schemas.js.map +0 -1
- package/dist/lib/session-affinity.js.map +0 -1
- package/dist/lib/shutdown.js.map +0 -1
- package/dist/lib/storage/account-clear-entry.js.map +0 -1
- package/dist/lib/storage/account-clear.js.map +0 -1
- package/dist/lib/storage/account-match-utils.js.map +0 -1
- package/dist/lib/storage/account-persistence.js.map +0 -1
- package/dist/lib/storage/account-port.js.map +0 -1
- package/dist/lib/storage/account-save-entry.js.map +0 -1
- package/dist/lib/storage/account-save.js.map +0 -1
- package/dist/lib/storage/account-snapshot.js.map +0 -1
- package/dist/lib/storage/backup-metadata-builder.js.map +0 -1
- package/dist/lib/storage/backup-metadata.js.map +0 -1
- package/dist/lib/storage/backup-paths.js.map +0 -1
- package/dist/lib/storage/backup-restore.js.map +0 -1
- package/dist/lib/storage/cache-artifacts.js.map +0 -1
- package/dist/lib/storage/error-hints.js.map +0 -1
- package/dist/lib/storage/file-paths.js.map +0 -1
- package/dist/lib/storage/fixture-guards.js.map +0 -1
- package/dist/lib/storage/flagged-entry.js.map +0 -1
- package/dist/lib/storage/flagged-load-entry.js.map +0 -1
- package/dist/lib/storage/flagged-save-entry.js.map +0 -1
- package/dist/lib/storage/flagged-storage-file.js.map +0 -1
- package/dist/lib/storage/flagged-storage-io.js.map +0 -1
- package/dist/lib/storage/flagged-storage.js.map +0 -1
- package/dist/lib/storage/gitignore.js.map +0 -1
- package/dist/lib/storage/hash.js.map +0 -1
- package/dist/lib/storage/health.js.map +0 -1
- package/dist/lib/storage/identity.js.map +0 -1
- package/dist/lib/storage/import-export.js.map +0 -1
- package/dist/lib/storage/metadata-section.js.map +0 -1
- package/dist/lib/storage/migrations.js.map +0 -1
- package/dist/lib/storage/named-backup-entry.js.map +0 -1
- package/dist/lib/storage/named-backups-entry.js.map +0 -1
- package/dist/lib/storage/named-backups.js.map +0 -1
- package/dist/lib/storage/path-state.js.map +0 -1
- package/dist/lib/storage/paths.js.map +0 -1
- package/dist/lib/storage/project-migration.js.map +0 -1
- package/dist/lib/storage/record-utils.js.map +0 -1
- package/dist/lib/storage/restore-assessment.js.map +0 -1
- package/dist/lib/storage/restore-backup-entry.js.map +0 -1
- package/dist/lib/storage/restore-metadata.js.map +0 -1
- package/dist/lib/storage/restore.d.ts +0 -14
- package/dist/lib/storage/restore.d.ts.map +0 -1
- package/dist/lib/storage/restore.js +0 -52
- package/dist/lib/storage/restore.js.map +0 -1
- package/dist/lib/storage/snapshot-inspectors.js.map +0 -1
- package/dist/lib/storage/storage-parser.js.map +0 -1
- package/dist/lib/storage/transactions.js.map +0 -1
- package/dist/lib/storage.js.map +0 -1
- package/dist/lib/table-formatter.js.map +0 -1
- package/dist/lib/tools/hashline-tools.js.map +0 -1
- package/dist/lib/types.js.map +0 -1
- package/dist/lib/ui/ansi.js.map +0 -1
- package/dist/lib/ui/auth-menu.js.map +0 -1
- package/dist/lib/ui/confirm.js.map +0 -1
- package/dist/lib/ui/copy.d.ts +0 -159
- package/dist/lib/ui/copy.d.ts.map +0 -1
- package/dist/lib/ui/copy.js +0 -164
- package/dist/lib/ui/copy.js.map +0 -1
- package/dist/lib/ui/display-width.js.map +0 -1
- package/dist/lib/ui/format.js.map +0 -1
- package/dist/lib/ui/runtime.js.map +0 -1
- package/dist/lib/ui/select.js.map +0 -1
- package/dist/lib/ui/theme.js.map +0 -1
- package/dist/lib/unified-settings.js.map +0 -1
- package/dist/lib/update-notice.js.map +0 -1
- package/dist/lib/usage/index.js.map +0 -1
- package/dist/lib/usage/ledger.js.map +0 -1
- package/dist/lib/usage/pricing.js.map +0 -1
- package/dist/lib/usage/redaction.js.map +0 -1
- package/dist/lib/usage/types.js.map +0 -1
- package/dist/lib/utils.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-multi-auth",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.3",
|
|
4
4
|
"description": "Install and operate codex-multi-auth for the official @openai/codex CLI with multi-account OAuth rotation, switching, health checks, and recovery tools.",
|
|
5
5
|
"interface": {
|
|
6
6
|
"composerIcon": "./assets/codex-multi-auth-icon.svg"
|
package/README.md
CHANGED
|
@@ -179,6 +179,7 @@ For remote or headless shells, prefer `codex-multi-auth login --device-auth`.
|
|
|
179
179
|
| --- | --- |
|
|
180
180
|
| `codex-multi-auth list` | Which accounts are saved and which one is active? |
|
|
181
181
|
| `codex-multi-auth switch <index>` | How do I move to a different saved account? |
|
|
182
|
+
| `codex-multi-auth-codex --account <index\|email\|id>` | How do I force one account for a single wrapper session without changing my default? |
|
|
182
183
|
| `codex-multi-auth forecast --live` | Which account looks best for the next session? |
|
|
183
184
|
|
|
184
185
|
### Repair
|
|
@@ -383,7 +384,9 @@ codex-multi-auth doctor --json
|
|
|
383
384
|
|
|
384
385
|
## Release Notes
|
|
385
386
|
|
|
386
|
-
- Current stable: [docs/releases/v2.
|
|
387
|
+
- Current stable: [docs/releases/v2.4.0.md](docs/releases/v2.4.0.md) — install via `npm i -g codex-multi-auth`
|
|
388
|
+
- Previous stable: [docs/releases/v2.3.3.md](docs/releases/v2.3.3.md)
|
|
389
|
+
- Previous stable: [docs/releases/v2.3.2.md](docs/releases/v2.3.2.md)
|
|
387
390
|
- Previous stable: [docs/releases/v2.3.1.md](docs/releases/v2.3.1.md)
|
|
388
391
|
- Previous stable: [docs/releases/v2.3.0.md](docs/releases/v2.3.0.md)
|
|
389
392
|
- Previous stable: [docs/releases/v2.2.2.md](docs/releases/v2.2.2.md)
|
package/dist/lib/accounts.d.ts
CHANGED
|
@@ -187,6 +187,20 @@ export declare class AccountManager {
|
|
|
187
187
|
shouldShowAccountToast(accountIndex: number, debounceMs?: number): boolean;
|
|
188
188
|
markToastShown(accountIndex: number): void;
|
|
189
189
|
updateFromAuth(account: ManagedAccount, auth: OAuthAuthDetails): void;
|
|
190
|
+
/**
|
|
191
|
+
* Reconcile token material from the on-disk store into a freshly-built
|
|
192
|
+
* snapshot before persisting. A long-lived proxy serializes its whole
|
|
193
|
+
* in-memory pool on every routine save (rate-limit, cooldown, refund). If a
|
|
194
|
+
* SECOND process refreshed an account and wrote a rotated (single-use)
|
|
195
|
+
* refresh token to disk in the meantime, a blind write would revert it,
|
|
196
|
+
* permanently breaking that account's next refresh (stress audit H3).
|
|
197
|
+
*
|
|
198
|
+
* For each account, if the on-disk copy of the same identity carries a
|
|
199
|
+
* strictly newer token (later expiresAt), adopt the disk's token material.
|
|
200
|
+
* Our own freshly-refreshed tokens always have the newest expiry, so this
|
|
201
|
+
* never undoes a refresh we just performed.
|
|
202
|
+
*/
|
|
203
|
+
private reconcileTokensFromDisk;
|
|
190
204
|
private buildStorageSnapshot;
|
|
191
205
|
commitRefreshedAuth(source: Pick<ManagedAccount, "index" | "accountId" | "email" | "refreshToken">, auth: OAuthAuthDetails): Promise<ManagedAccount | null>;
|
|
192
206
|
toAuthDetails(account: ManagedAccount): Auth;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../lib/accounts.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../lib/accounts.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/accounts.js
CHANGED
|
@@ -5,7 +5,7 @@ import { MODEL_FAMILIES } from "./request/helpers/model-map.js";
|
|
|
5
5
|
import { getHealthTracker, getTokenTracker, resetTrackers, selectHybridAccount, } from "./rotation.js";
|
|
6
6
|
import { withRoutingMutex, } from "./routing-mutex.js";
|
|
7
7
|
import { nowMs } from "./utils.js";
|
|
8
|
-
import { ERROR_MESSAGES, HTTP_STATUS } from "./constants.js";
|
|
8
|
+
import { ERROR_MESSAGES, HTTP_STATUS, MAX_RATE_LIMIT_DELAY_MS } from "./constants.js";
|
|
9
9
|
import { CodexAuthError } from "./errors.js";
|
|
10
10
|
import { loadCodexCliState, } from "./codex-cli/state.js";
|
|
11
11
|
import { syncAccountStorageFromCodexCli } from "./codex-cli/sync.js";
|
|
@@ -841,7 +841,9 @@ export class AccountManager {
|
|
|
841
841
|
this.markRateLimitedWithReason(account, retryAfterMs, family, "unknown", model);
|
|
842
842
|
}
|
|
843
843
|
markRateLimitedWithReason(account, retryAfterMs, family, reason, model) {
|
|
844
|
-
|
|
844
|
+
// Clamp to MAX_RATE_LIMIT_DELAY_MS so a bogus upstream retry-after value
|
|
845
|
+
// cannot wedge this account unavailable for years (see stress audit H1).
|
|
846
|
+
const retryMs = Math.min(Math.max(0, Math.floor(retryAfterMs)), MAX_RATE_LIMIT_DELAY_MS);
|
|
845
847
|
const resetAt = nowMs() + retryMs;
|
|
846
848
|
const baseKey = getQuotaKey(family);
|
|
847
849
|
if (!model || reason === "quota" || reason === "unknown") {
|
|
@@ -917,6 +919,56 @@ export class AccountManager {
|
|
|
917
919
|
account.email =
|
|
918
920
|
sanitizeEmail(extractAccountEmail(auth.access)) ?? account.email;
|
|
919
921
|
}
|
|
922
|
+
/**
|
|
923
|
+
* Reconcile token material from the on-disk store into a freshly-built
|
|
924
|
+
* snapshot before persisting. A long-lived proxy serializes its whole
|
|
925
|
+
* in-memory pool on every routine save (rate-limit, cooldown, refund). If a
|
|
926
|
+
* SECOND process refreshed an account and wrote a rotated (single-use)
|
|
927
|
+
* refresh token to disk in the meantime, a blind write would revert it,
|
|
928
|
+
* permanently breaking that account's next refresh (stress audit H3).
|
|
929
|
+
*
|
|
930
|
+
* For each account, if the on-disk copy of the same identity carries a
|
|
931
|
+
* strictly newer token (later expiresAt), adopt the disk's token material.
|
|
932
|
+
* Our own freshly-refreshed tokens always have the newest expiry, so this
|
|
933
|
+
* never undoes a refresh we just performed.
|
|
934
|
+
*/
|
|
935
|
+
reconcileTokensFromDisk(snapshot, current) {
|
|
936
|
+
if (!current || !Array.isArray(current.accounts))
|
|
937
|
+
return snapshot;
|
|
938
|
+
const diskByIdentity = new Map();
|
|
939
|
+
for (const diskAccount of current.accounts) {
|
|
940
|
+
const key = getAccountIdentityKey({
|
|
941
|
+
accountId: diskAccount.accountId,
|
|
942
|
+
email: diskAccount.email,
|
|
943
|
+
refreshToken: diskAccount.refreshToken,
|
|
944
|
+
});
|
|
945
|
+
if (key)
|
|
946
|
+
diskByIdentity.set(key, diskAccount);
|
|
947
|
+
}
|
|
948
|
+
for (const account of snapshot.accounts) {
|
|
949
|
+
const key = getAccountIdentityKey({
|
|
950
|
+
accountId: account.accountId,
|
|
951
|
+
email: account.email,
|
|
952
|
+
refreshToken: account.refreshToken,
|
|
953
|
+
});
|
|
954
|
+
if (!key)
|
|
955
|
+
continue;
|
|
956
|
+
const disk = diskByIdentity.get(key);
|
|
957
|
+
if (!disk)
|
|
958
|
+
continue;
|
|
959
|
+
const diskExpires = disk.expiresAt ?? 0;
|
|
960
|
+
const memExpires = account.expiresAt ?? 0;
|
|
961
|
+
// Disk holds a strictly-newer token than our in-memory copy: adopt it
|
|
962
|
+
// so we don't clobber another process's rotation. Equal expiries keep
|
|
963
|
+
// our copy (no-op); newer in-memory copy wins (our own refresh).
|
|
964
|
+
if (diskExpires > memExpires && disk.refreshToken) {
|
|
965
|
+
account.refreshToken = disk.refreshToken;
|
|
966
|
+
account.accessToken = disk.accessToken;
|
|
967
|
+
account.expiresAt = disk.expiresAt;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
return snapshot;
|
|
971
|
+
}
|
|
920
972
|
buildStorageSnapshot() {
|
|
921
973
|
const activeIndexByFamily = {};
|
|
922
974
|
for (const family of MODEL_FAMILIES) {
|
|
@@ -1346,8 +1398,11 @@ export class AccountManager {
|
|
|
1346
1398
|
}
|
|
1347
1399
|
async saveToDisk() {
|
|
1348
1400
|
await runWithStoragePathState(this.storagePathState, async () => {
|
|
1349
|
-
await withAccountStorageTransaction(async (
|
|
1350
|
-
|
|
1401
|
+
await withAccountStorageTransaction(async (current, persist) => {
|
|
1402
|
+
// Reconcile against the disk state loaded under the storage lock so a
|
|
1403
|
+
// routine save does not clobber a token another process just rotated
|
|
1404
|
+
// (stress audit H3).
|
|
1405
|
+
await persist(this.reconcileTokensFromDisk(this.buildStorageSnapshot(), current));
|
|
1351
1406
|
});
|
|
1352
1407
|
});
|
|
1353
1408
|
}
|
package/dist/lib/constants.d.ts
CHANGED
|
@@ -10,6 +10,12 @@ export declare const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
|
10
10
|
export declare const DUMMY_API_KEY = "chatgpt-oauth";
|
|
11
11
|
/** Provider ID for UI display - shows under "OpenAI" in auth dropdown */
|
|
12
12
|
export declare const PROVIDER_ID = "openai";
|
|
13
|
+
/**
|
|
14
|
+
* Upper bound for any rate-limit / retry-after window we will honor. A single
|
|
15
|
+
* hostile or buggy upstream value (seconds-vs-ms confusion, anti-abuse misfire)
|
|
16
|
+
* must never be able to wedge an account unavailable for longer than this.
|
|
17
|
+
*/
|
|
18
|
+
export declare const MAX_RATE_LIMIT_DELAY_MS: number;
|
|
13
19
|
/** HTTP Status Codes */
|
|
14
20
|
export declare const HTTP_STATUS: {
|
|
15
21
|
readonly BAD_REQUEST: 400;
|
|
@@ -19,6 +25,7 @@ export declare const HTTP_STATUS: {
|
|
|
19
25
|
readonly UNAUTHORIZED: 401;
|
|
20
26
|
readonly NOT_FOUND: 404;
|
|
21
27
|
readonly TOO_MANY_REQUESTS: 429;
|
|
28
|
+
readonly BAD_GATEWAY: 502;
|
|
22
29
|
readonly SERVICE_UNAVAILABLE: 503;
|
|
23
30
|
};
|
|
24
31
|
/** OpenAI-specific headers */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../lib/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uDAAuD;AACvD,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAE9C,uCAAuC;AACvC,eAAO,MAAM,cAAc,oCAAoC,CAAC;AAEhE,gEAAgE;AAChE,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,yEAAyE;AACzE,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC,wBAAwB;AACxB,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../lib/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uDAAuD;AACvD,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAE9C,uCAAuC;AACvC,eAAO,MAAM,cAAc,oCAAoC,CAAC;AAEhE,gEAAgE;AAChE,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,yEAAyE;AACzE,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAA0B,CAAC;AAE/D,wBAAwB;AACxB,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAC;AAEX,8BAA8B;AAC9B,eAAO,MAAM,cAAc;;;;;;CAMjB,CAAC;AAEX,oCAAoC;AACpC,eAAO,MAAM,oBAAoB;;;CAGvB,CAAC;AAEX,wBAAwB;AACxB,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAEX,4CAA4C;AAC5C,eAAO,MAAM,cAAc,EAAG,6BAAsC,CAAC;AAErE,qBAAqB;AACrB,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAEX,gDAAgD;AAChD,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAEX,iCAAiC;AACjC,eAAO,MAAM,WAAW;;;;;;CAQd,CAAC;AAEX,kCAAkC;AAClC,eAAO,MAAM,cAAc;IAC1B,8DAA8D;;IAE9D,sEAAsE;;IAEtE,uEAAuE;;CAE9D,CAAC"}
|
package/dist/lib/constants.js
CHANGED
|
@@ -10,6 +10,12 @@ export const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
|
10
10
|
export const DUMMY_API_KEY = "chatgpt-oauth";
|
|
11
11
|
/** Provider ID for UI display - shows under "OpenAI" in auth dropdown */
|
|
12
12
|
export const PROVIDER_ID = "openai";
|
|
13
|
+
/**
|
|
14
|
+
* Upper bound for any rate-limit / retry-after window we will honor. A single
|
|
15
|
+
* hostile or buggy upstream value (seconds-vs-ms confusion, anti-abuse misfire)
|
|
16
|
+
* must never be able to wedge an account unavailable for longer than this.
|
|
17
|
+
*/
|
|
18
|
+
export const MAX_RATE_LIMIT_DELAY_MS = 7 * 24 * 60 * 60 * 1000;
|
|
13
19
|
/** HTTP Status Codes */
|
|
14
20
|
export const HTTP_STATUS = {
|
|
15
21
|
BAD_REQUEST: 400,
|
|
@@ -19,6 +25,7 @@ export const HTTP_STATUS = {
|
|
|
19
25
|
UNAUTHORIZED: 401,
|
|
20
26
|
NOT_FOUND: 404,
|
|
21
27
|
TOO_MANY_REQUESTS: 429,
|
|
28
|
+
BAD_GATEWAY: 502,
|
|
22
29
|
SERVICE_UNAVAILABLE: 503,
|
|
23
30
|
};
|
|
24
31
|
/** OpenAI-specific headers */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../lib/forecast.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,KAAK,oBAAoB,GAAG,OAAO,GAAG,SAAS,GAAG,aAAa,CAAC;AAChE,KAAK,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,YAAY,CAAC;IAC9B,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,UAAU,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC3C,cAAc,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,sBAAsB;IACtC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,6BAA6B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,oBAAoB,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAKlB,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACtC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CACf;AAED,UAAU,0BAA0B;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,oBAAoB,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IACnC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,UAAU,EAAE,0BAA0B,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../lib/forecast.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/forecast.js
CHANGED
|
@@ -41,12 +41,19 @@ function getRiskLevel(score) {
|
|
|
41
41
|
return "medium";
|
|
42
42
|
return "low";
|
|
43
43
|
}
|
|
44
|
-
function getLiveQuotaWaitMs(snapshot, now) {
|
|
44
|
+
function getLiveQuotaWaitMs(snapshot, now, onlyExhausted) {
|
|
45
45
|
const waits = [];
|
|
46
|
-
for (const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
for (const window of [snapshot.primary, snapshot.secondary]) {
|
|
47
|
+
// Under pure usage pressure (not a 429), only an actually-exhausted window
|
|
48
|
+
// (100% used) should impose a wait. A healthy weekly secondary normally
|
|
49
|
+
// resets ~7d out; folding that in would overstate the wait by orders of
|
|
50
|
+
// magnitude and invert the account recommendation (stress audit H5). On a
|
|
51
|
+
// 429 we honor every future window, since the upstream said "slow down now"
|
|
52
|
+
// regardless of the usage gauge.
|
|
53
|
+
if (onlyExhausted && quotaLeftPercentFromUsed(window?.usedPercent) !== 0) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const resetAt = window?.resetAtMs;
|
|
50
57
|
if (typeof resetAt !== "number")
|
|
51
58
|
continue;
|
|
52
59
|
if (!Number.isFinite(resetAt))
|
|
@@ -193,7 +200,9 @@ export function evaluateForecastAccount(input) {
|
|
|
193
200
|
riskScore += 35;
|
|
194
201
|
reasons.push("live probe returned 429");
|
|
195
202
|
}
|
|
196
|
-
const liveWait = quotaPressure
|
|
203
|
+
const liveWait = quotaPressure
|
|
204
|
+
? getLiveQuotaWaitMs(quota, now, quota.status !== 429)
|
|
205
|
+
: 0;
|
|
197
206
|
waitMs = Math.max(waitMs, liveWait);
|
|
198
207
|
if (liveWait > 0 && availability === "ready") {
|
|
199
208
|
availability = "delayed";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-client-tokens.d.ts","sourceRoot":"","sources":["../../lib/local-client-tokens.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,sBAAsB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,sBAAsB,CAAC;CAC/B;AAqHD,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAahF;
|
|
1
|
+
{"version":3,"file":"local-client-tokens.d.ts","sourceRoot":"","sources":["../../lib/local-client-tokens.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,sBAAsB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,sBAAsB,CAAC;CAC/B;AAqHD,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAahF;AAsDD,wBAAsB,yBAAyB,CAC9C,KAAK,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAgB,4BAA4B,CAAC,KAAK,GAAE;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACR,GAAG,uBAAuB,CAY/B;AAED,wBAAsB,mBAAmB,CAAC,KAAK,GAAE;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACR,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAQxC;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAe1C;AAED,wBAAsB,sBAAsB,CAC3C,EAAE,EAAE,MAAM,EACV,GAAG,SAAa,GACd,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,wBAAsB,4BAA4B,CACjD,mBAAmB,EAAE,MAAM,GAAG,IAAI,EAClC,GAAG,SAAa,GACd,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAwBxC;AAED,wBAAgB,uCAAuC,IAAI,IAAI,CAE9D"}
|
|
@@ -142,10 +142,17 @@ async function writeStoreToDisk(store) {
|
|
|
142
142
|
const tempPath = tempPathFor(path);
|
|
143
143
|
let moved = false;
|
|
144
144
|
try {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
// fsync the temp file before rename so a crash/power-loss after the rename
|
|
146
|
+
// cannot leave a truncated token store (stress audit L3). Mirrors the
|
|
147
|
+
// durable-write pattern already used in runtime/app-bind.ts.
|
|
148
|
+
const handle = await fs.open(tempPath, "w", 0o600);
|
|
149
|
+
try {
|
|
150
|
+
await handle.writeFile(`${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
151
|
+
await handle.sync();
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
await handle.close();
|
|
155
|
+
}
|
|
149
156
|
for (let attempt = 0; attempt < 5; attempt += 1) {
|
|
150
157
|
try {
|
|
151
158
|
await fs.rename(tempPath, path);
|
package/dist/lib/logger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../lib/logger.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,SAAS;IACzB,GAAG,CAAC,EAAE;QACL,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE;YACf,IAAI,EAAE;gBACL,OAAO,EAAE,MAAM,CAAC;gBAChB,KAAK,EAAE,QAAQ,CAAC;gBAChB,OAAO,EAAE,MAAM,CAAC;gBAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;aAChC,CAAC;SACF,KAAK,OAAO,CAAC;KACd,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../lib/logger.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/logger.js
CHANGED
|
@@ -15,6 +15,11 @@ const TOKEN_PATTERNS = [
|
|
|
15
15
|
/[a-f0-9]{40,}/gi,
|
|
16
16
|
/sk-[A-Za-z0-9]{20,}/g,
|
|
17
17
|
/Bearer\s+\S+/gi,
|
|
18
|
+
// This app's own local bearer tokens: `cma_local_<base64url>` (see
|
|
19
|
+
// lib/local-client-tokens.ts). The structured-log key masker and the OAuth
|
|
20
|
+
// scrubber cover the normal paths, but the free-text scrubber is the last
|
|
21
|
+
// line of defense and must recognize the project's own token shape too.
|
|
22
|
+
/cma_local_[A-Za-z0-9_-]{16,}/g,
|
|
18
23
|
];
|
|
19
24
|
const EMAIL_PATTERN = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
|
|
20
25
|
const SENSITIVE_KEYS = new Set([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preemptive-quota-scheduler.d.ts","sourceRoot":"","sources":["../../lib/preemptive-quota-scheduler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"preemptive-quota-scheduler.d.ts","sourceRoot":"","sources":["../../lib/preemptive-quota-scheduler.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,oBAAoB,CAAC;IAC9B,SAAS,EAAE,oBAAoB,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACrC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,YAAY,GAAG,uBAAuB,CAAC;CAChD;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,kCAAkC,CAAC,EAAE,MAAM,CAAC;IAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AA+ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,sBAAsB,GAAG,IAAI,CAqB5H;AAED,qBAAa,wBAAwB;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6C;IACvE,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,gCAAgC,CAAS;IACjD,OAAO,CAAC,kCAAkC,CAAS;IACnD,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAK;gBAEZ,OAAO,GAAE,qBAA0B;IAQ/C,SAAS,CAAC,OAAO,GAAE,qBAA0B,GAAG,IAAI;IA2CpD,OAAO,CAAC,UAAU;IAMlB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG,IAAI;IAM3D,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI;IA8B1E,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,qBAAqB;IA0EjE,KAAK,CAAC,GAAG,SAAa,GAAG,MAAM;CAW/B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { quotaLeftPercentFromUsed } from "./quota-readiness.js";
|
|
1
2
|
const DEFAULT_REMAINING_PERCENT_THRESHOLD = 5;
|
|
2
3
|
const DEFAULT_MAX_DEFERRAL_MS = 2 * 60 * 60_000;
|
|
3
4
|
/**
|
|
@@ -162,8 +163,19 @@ export class PreemptiveQuotaScheduler {
|
|
|
162
163
|
return;
|
|
163
164
|
const waitMs = Number.isFinite(retryAfterMs) ? Math.max(0, Math.floor(retryAfterMs)) : 0;
|
|
164
165
|
const existing = this.snapshots.get(key);
|
|
165
|
-
|
|
166
|
-
|
|
166
|
+
// A 429 retry-after defines the PRIMARY rate-limit window only. Do NOT
|
|
167
|
+
// fold in a benign quota reset — neither the weekly secondary (~7d out)
|
|
168
|
+
// nor a healthy primary quota window from a prior 200 snapshot — because
|
|
169
|
+
// that would bench the account for the full deferral cap on a transient
|
|
170
|
+
// 30-60s 429 (stress audit H4). Only preserve a prior primary window that
|
|
171
|
+
// was itself a rate-limit / exhausted window (usedPercent absent or 100).
|
|
172
|
+
const existingPrimary = existing?.primary;
|
|
173
|
+
const existingPrimaryIsRateLimit = existingPrimary !== undefined &&
|
|
174
|
+
(typeof existingPrimary.usedPercent !== "number" ||
|
|
175
|
+
!Number.isFinite(existingPrimary.usedPercent) ||
|
|
176
|
+
quotaLeftPercentFromUsed(existingPrimary.usedPercent) === 0);
|
|
177
|
+
const existingPrimaryResetAtMs = existingPrimaryIsRateLimit ? (existingPrimary?.resetAtMs ?? 0) : 0;
|
|
178
|
+
const nextResetAtMs = Math.max(existingPrimaryResetAtMs, now + waitMs);
|
|
167
179
|
this.snapshots.set(key, {
|
|
168
180
|
status: 429,
|
|
169
181
|
primary: {
|
|
@@ -192,7 +204,21 @@ export class PreemptiveQuotaScheduler {
|
|
|
192
204
|
snapshot.secondary.resetAtMs > now
|
|
193
205
|
? snapshot.secondary.resetAtMs - now
|
|
194
206
|
: 0;
|
|
195
|
-
|
|
207
|
+
// For a 429 deferral, only count a window whose reset is genuinely a
|
|
208
|
+
// rate-limit / exhaustion window. A window carrying a healthy usedPercent
|
|
209
|
+
// (e.g. a weekly secondary at 30% from a prior 200 snapshot) is NOT the
|
|
210
|
+
// thing the 429 is about; folding its ~7d reset in would bench the account
|
|
211
|
+
// for the full deferral cap on a transient 429 (stress audit H4). A window
|
|
212
|
+
// with no usedPercent, or one that is exhausted, still counts.
|
|
213
|
+
const isRateLimitWindow = (window) => {
|
|
214
|
+
if (typeof window.usedPercent !== "number" || !Number.isFinite(window.usedPercent)) {
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
return quotaLeftPercentFromUsed(window.usedPercent) === 0;
|
|
218
|
+
};
|
|
219
|
+
const waitCandidates = [snapshot.primary, snapshot.secondary]
|
|
220
|
+
.filter(isRateLimitWindow)
|
|
221
|
+
.map((window) => window.resetAtMs)
|
|
196
222
|
.filter((value) => typeof value === "number" && Number.isFinite(value) && value > now)
|
|
197
223
|
.map((value) => value - now)
|
|
198
224
|
.filter((value) => value > 0);
|
|
@@ -28,6 +28,7 @@ export declare class RefreshLeaseCoordinator {
|
|
|
28
28
|
acquire(refreshToken: string): Promise<RefreshLeaseHandle>;
|
|
29
29
|
private createBypassHandle;
|
|
30
30
|
private createOwnerHandle;
|
|
31
|
+
private ownsLock;
|
|
31
32
|
private writeResult;
|
|
32
33
|
private readFreshResult;
|
|
33
34
|
private assessLockStaleness;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh-lease.d.ts","sourceRoot":"","sources":["../../lib/refresh-lease.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAMrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"refresh-lease.d.ts","sourceRoot":"","sources":["../../lib/refresh-lease.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAMrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA4B9C,KAAK,UAAU,GAAG,IAAI,CACrB,OAAO,EAAE,EACT,OAAO,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CACtF,GACA,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AAEnC,MAAM,WAAW,8BAA8B;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;IACtC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAyGD,qBAAa,uBAAuB;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;gBAEvB,OAAO,GAAE,8BAAmC;IAUxD,MAAM,CAAC,eAAe,IAAI,uBAAuB;IAgB3C,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA+FhE,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,iBAAiB;YAmCX,QAAQ;YAkBR,WAAW;YAwBX,eAAe;YAiBf,mBAAmB;YAuCnB,qBAAqB;CAsBnC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import { existsSync, promises as fs } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { parseBooleanEnv } from "./env-parsing.js";
|
|
@@ -33,6 +33,9 @@ function parseLeasePayload(raw) {
|
|
|
33
33
|
const pid = typeof raw.pid === "number" ? raw.pid : Number.NaN;
|
|
34
34
|
const acquiredAt = typeof raw.acquiredAt === "number" ? raw.acquiredAt : Number.NaN;
|
|
35
35
|
const expiresAt = typeof raw.expiresAt === "number" ? raw.expiresAt : Number.NaN;
|
|
36
|
+
// nonce is optional for backward-compat with locks written before H2; an
|
|
37
|
+
// absent nonce simply means release() falls back to a best-effort unlink.
|
|
38
|
+
const nonce = typeof raw.nonce === "string" ? raw.nonce : "";
|
|
36
39
|
if (tokenHash.length === 0 ||
|
|
37
40
|
!Number.isFinite(pid) ||
|
|
38
41
|
!Number.isFinite(acquiredAt) ||
|
|
@@ -44,6 +47,7 @@ function parseLeasePayload(raw) {
|
|
|
44
47
|
pid: Math.floor(pid),
|
|
45
48
|
acquiredAt: Math.floor(acquiredAt),
|
|
46
49
|
expiresAt: Math.floor(expiresAt),
|
|
50
|
+
nonce,
|
|
47
51
|
};
|
|
48
52
|
}
|
|
49
53
|
function parseResultPayload(raw) {
|
|
@@ -172,6 +176,7 @@ export class RefreshLeaseCoordinator {
|
|
|
172
176
|
}
|
|
173
177
|
try {
|
|
174
178
|
const handle = await this.fsOps.open(lockPath, "wx", 0o600);
|
|
179
|
+
const nonce = randomUUID();
|
|
175
180
|
try {
|
|
176
181
|
const now = Date.now();
|
|
177
182
|
const payload = {
|
|
@@ -179,13 +184,14 @@ export class RefreshLeaseCoordinator {
|
|
|
179
184
|
pid: process.pid,
|
|
180
185
|
acquiredAt: now,
|
|
181
186
|
expiresAt: now + this.leaseTtlMs,
|
|
187
|
+
nonce,
|
|
182
188
|
};
|
|
183
189
|
await handle.writeFile(`${JSON.stringify(payload)}\n`, "utf8");
|
|
184
190
|
}
|
|
185
191
|
finally {
|
|
186
192
|
await handle.close();
|
|
187
193
|
}
|
|
188
|
-
return this.createOwnerHandle(tokenHash, lockPath, resultPath);
|
|
194
|
+
return this.createOwnerHandle(tokenHash, lockPath, resultPath, nonce);
|
|
189
195
|
}
|
|
190
196
|
catch (error) {
|
|
191
197
|
const code = error.code;
|
|
@@ -228,7 +234,7 @@ export class RefreshLeaseCoordinator {
|
|
|
228
234
|
},
|
|
229
235
|
};
|
|
230
236
|
}
|
|
231
|
-
createOwnerHandle(tokenHash, lockPath, resultPath) {
|
|
237
|
+
createOwnerHandle(tokenHash, lockPath, resultPath, nonce) {
|
|
232
238
|
let released = false;
|
|
233
239
|
return {
|
|
234
240
|
role: "owner",
|
|
@@ -242,11 +248,36 @@ export class RefreshLeaseCoordinator {
|
|
|
242
248
|
}
|
|
243
249
|
}
|
|
244
250
|
finally {
|
|
245
|
-
|
|
251
|
+
// Only unlink the lock if it is still OURS. If our lease expired
|
|
252
|
+
// and another process stole the lock, the on-disk nonce no longer
|
|
253
|
+
// matches and unlinking would delete the new owner's lock mid
|
|
254
|
+
// refresh (stress audit H2). A lock written before nonces existed
|
|
255
|
+
// (empty on-disk nonce) falls back to a best-effort unlink.
|
|
256
|
+
if (await this.ownsLock(lockPath, tokenHash, nonce)) {
|
|
257
|
+
await safeUnlink(lockPath, undefined, this.fsOps);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
log.warn("Refresh lease no longer owned at release; leaving lock for current owner", { lockPath });
|
|
261
|
+
}
|
|
246
262
|
}
|
|
247
263
|
},
|
|
248
264
|
};
|
|
249
265
|
}
|
|
266
|
+
async ownsLock(lockPath, tokenHash, nonce) {
|
|
267
|
+
const raw = await readJson(lockPath, this.fsOps);
|
|
268
|
+
const parsed = raw === null ? null : parseLeasePayload(raw);
|
|
269
|
+
if (!parsed) {
|
|
270
|
+
// Unreadable/absent lock: nothing of ours to protect, allow cleanup.
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
if (parsed.tokenHash !== tokenHash)
|
|
274
|
+
return false;
|
|
275
|
+
// Backward-compat: a lock written before H2 has no nonce. Fall back to the
|
|
276
|
+
// previous (best-effort) behavior so we still clean up our own old locks.
|
|
277
|
+
if (parsed.nonce === "")
|
|
278
|
+
return true;
|
|
279
|
+
return parsed.nonce === nonce;
|
|
280
|
+
}
|
|
250
281
|
async writeResult(resultPath, tokenHash, result) {
|
|
251
282
|
const payload = {
|
|
252
283
|
tokenHash,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-helpers.d.ts","sourceRoot":"","sources":["../../../lib/request/fetch-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAIN,KAAK,wBAAwB,EAC7B,MAAM,0BAA0B,CAAC;AAMlC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"fetch-helpers.d.ts","sourceRoot":"","sources":["../../../lib/request/fetch-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAIN,KAAK,wBAAwB,EAC7B,MAAM,0BAA0B,CAAC;AAMlC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAiB3D,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EACN,wCAAwC,EACxC,oCAAoC,EACpC,4BAA4B,EAC5B,oCAAoC,EACpC,uCAAuC,EACvC,kBAAkB,EAClB,wBAAwB,EACxB,8BAA8B,GAC9B,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACX,gBAAgB,EAChB,yBAAyB,EACzB,sCAAsC,GACtC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACN,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EACX,yBAAyB,EACzB,wBAAwB,GACxB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,aAAa;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACrB;AASD,MAAM,WAAW,8BAA8B;IAC9C,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,4BAA4B,CAAC,EAAE,wBAAwB,CAAC,MAAM,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,mBAAmB;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC7C,IAAI,EAAE,WAAW,GAAG,SAAS,EAC7B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,UAAU,EACtB,SAAS,UAAO,EAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,CAAC,EAAE;IACT,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1C,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACnC,GACC,OAAO,CAAC,8BAA8B,GAAG,SAAS,CAAC,CA4FrD;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,oBAAoB,GACnC,OAAO,CAAC,mBAAmB,CAAC,CA4C9B;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACvC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,OAAO,EACpB,OAAO,CAAC,EAAE;IACZ,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B,GACC,OAAO,CAAC,QAAQ,CAAC,CAanB"}
|
|
@@ -7,14 +7,15 @@ import { getCodexInstructions, getModelFamily } from "../prompts/codex.js";
|
|
|
7
7
|
import { transformRequestBody, normalizeModel, resolveFastSessionInputTrimPlan, } from "./request-transformer.js";
|
|
8
8
|
import { attachResponseIdCapture, convertSseToJson, ensureContentType, } from "./response-handler.js";
|
|
9
9
|
import { isRecord } from "../utils.js";
|
|
10
|
-
import { HTTP_STATUS, ERROR_MESSAGES, LOG_STAGES, } from "../constants.js";
|
|
10
|
+
import { HTTP_STATUS, ERROR_MESSAGES, LOG_STAGES, MAX_RATE_LIMIT_DELAY_MS, } from "../constants.js";
|
|
11
11
|
import { CHATGPT_CODEX_UNSUPPORTED_MODEL_CODE, createEntitlementErrorResponse, extractUnsupportedCodexModelFromText, isEntitlementError, isUnsupportedCodexModelForChatGpt, } from "./error-classification.js";
|
|
12
12
|
import { logDeprecationHeaders } from "./headers.js";
|
|
13
13
|
export { shouldRefreshToken, refreshAndUpdateToken } from "./token-refresh.js";
|
|
14
14
|
export { DEFAULT_UNSUPPORTED_CODEX_FALLBACK_CHAIN, extractUnsupportedCodexModelFromText, getUnsupportedCodexModelInfo, resolveUnsupportedCodexFallbackModel, shouldFallbackToGpt52OnUnsupportedGpt53, isEntitlementError, isWorkspaceDisabledError, createEntitlementErrorResponse, } from "./error-classification.js";
|
|
15
15
|
export { extractRequestUrl, rewriteUrlForCodex, resolveProxyUrlForRequest, closeSharedProxyDispatchers, applyProxyCompatibleInit, } from "./url-rewriting.js";
|
|
16
16
|
export { createCodexHeaders } from "./headers.js";
|
|
17
|
-
|
|
17
|
+
// MAX_RATE_LIMIT_DELAY_MS is centralized in constants.ts (shared with the
|
|
18
|
+
// runtime proxy rate-limit setter so both paths clamp identically).
|
|
18
19
|
const RETRY_AFTER_DURATION_PATTERN = /\b(?:try|retry)\s+again\s+in\s+(\d+)\s*(second|minute|hour|day)s?\b/i;
|
|
19
20
|
const RETRY_AFTER_CLOCK_TIME_PATTERN = /\b(?:try|retry)\s+again\s+at\s+(\d{1,2})(?::(\d{2}))?\s*(am|pm)\b/i;
|
|
20
21
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit-decision.d.ts","sourceRoot":"","sources":["../../../lib/request/rate-limit-decision.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAe/C,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGlE;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,GAAG,OAAO,CAWjG;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAapF;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBlF;AAYD,wBAAgB,0BAA0B,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAuB3E;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBxE;AA0BD,wBAAgB,4BAA4B,CAC3C,OAAO,EAAE,OAAO,EAChB,kBAAkB,EAAE,MAAM,EAC1B,GAAG,EAAE,MAAM,GACT,MAAM,
|
|
1
|
+
{"version":3,"file":"rate-limit-decision.d.ts","sourceRoot":"","sources":["../../../lib/request/rate-limit-decision.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAe/C,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGlE;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,GAAG,OAAO,CAWjG;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAapF;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBlF;AAYD,wBAAgB,0BAA0B,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAuB3E;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBxE;AA0BD,wBAAgB,4BAA4B,CAC3C,OAAO,EAAE,OAAO,EAChB,kBAAkB,EAAE,MAAM,EAC1B,GAAG,EAAE,MAAM,GACT,MAAM,CAcR;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAE1E;AAED;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,kCAAkC,CAAC;IACzC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7C;AAED,wBAAgB,+BAA+B,CAC9C,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACtC,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7C,0BAA0B,CA0B5B"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HTTP_STATUS } from "../constants.js";
|
|
1
|
+
import { HTTP_STATUS, MAX_RATE_LIMIT_DELAY_MS } from "../constants.js";
|
|
2
2
|
import { isRecord } from "../utils.js";
|
|
3
3
|
// Phrases observed in upstream 401 response bodies when OpenAI/Microsoft has
|
|
4
4
|
// explicitly revoked an OAuth token (as opposed to a generic expired-token 401
|
|
@@ -162,7 +162,12 @@ export function getQuotaNearExhaustionWaitMs(headers, remainingThreshold, now) {
|
|
|
162
162
|
if (waitMs > 0)
|
|
163
163
|
candidates.push(waitMs);
|
|
164
164
|
}
|
|
165
|
-
|
|
165
|
+
// Clamp at source: a bogus upstream reset header must never yield an
|
|
166
|
+
// unbounded near-exhaustion wait, even for a future caller that forgets to
|
|
167
|
+
// clamp downstream (defense in depth for stress audit H1).
|
|
168
|
+
if (candidates.length === 0)
|
|
169
|
+
return 0;
|
|
170
|
+
return Math.min(Math.max(...candidates), MAX_RATE_LIMIT_DELAY_MS);
|
|
166
171
|
}
|
|
167
172
|
export function normalizeExhaustionStatus(reason) {
|
|
168
173
|
return reason === "rate-limit" ? HTTP_STATUS.TOO_MANY_REQUESTS : 503;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response-handler.d.ts","sourceRoot":"","sources":["../../../lib/request/response-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"response-handler.d.ts","sourceRoot":"","sources":["../../../lib/request/response-handler.ts"],"names":[],"mappings":"AAwwBA;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACrC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;IACT,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B,GACC,OAAO,CAAC,QAAQ,CAAC,CA2HnB;AA6DD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAQ3D;AA2BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAgCtD;AAED,wBAAgB,uBAAuB,CACtC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,GACzC,QAAQ,CAiBV"}
|