codex-multi-auth 2.15.0 → 2.17.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 +22 -1
- package/config/README.md +2 -2
- package/config/codex-legacy.json +109 -184
- package/config/codex-modern.json +44 -114
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/lib/account-policy.d.ts +4 -0
- package/dist/lib/account-policy.d.ts.map +1 -1
- package/dist/lib/account-policy.js +8 -0
- package/dist/lib/accounts/rate-limits.d.ts.map +1 -1
- package/dist/lib/accounts/rate-limits.js +2 -0
- package/dist/lib/accounts.d.ts +21 -3
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +229 -17
- package/dist/lib/api-route-store.d.ts +24 -0
- package/dist/lib/api-route-store.d.ts.map +1 -0
- package/dist/lib/api-route-store.js +145 -0
- package/dist/lib/auth/account-access.d.ts +115 -0
- package/dist/lib/auth/account-access.d.ts.map +1 -0
- package/dist/lib/auth/account-access.js +214 -0
- package/dist/lib/auth/token-utils.d.ts +54 -1
- package/dist/lib/auth/token-utils.d.ts.map +1 -1
- package/dist/lib/auth/token-utils.js +92 -7
- package/dist/lib/cli.d.ts +1 -1
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js +4 -0
- package/dist/lib/codex-cli/state.d.ts +7 -0
- package/dist/lib/codex-cli/state.d.ts.map +1 -1
- package/dist/lib/codex-cli/state.js +18 -0
- package/dist/lib/codex-cli/writer.d.ts.map +1 -1
- package/dist/lib/codex-cli/writer.js +60 -8
- package/dist/lib/codex-manager/account-manager-commands.d.ts.map +1 -1
- package/dist/lib/codex-manager/account-manager-commands.js +1 -0
- package/dist/lib/codex-manager/account-pool-write.d.ts +3 -1
- package/dist/lib/codex-manager/account-pool-write.d.ts.map +1 -1
- package/dist/lib/codex-manager/account-pool-write.js +4 -0
- package/dist/lib/codex-manager/api-login-menu.d.ts +14 -0
- package/dist/lib/codex-manager/api-login-menu.d.ts.map +1 -0
- package/dist/lib/codex-manager/api-login-menu.js +224 -0
- package/dist/lib/codex-manager/commands/account.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/account.js +27 -0
- package/dist/lib/codex-manager/commands/best.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/best.js +6 -2
- package/dist/lib/codex-manager/commands/check.d.ts +7 -1
- package/dist/lib/codex-manager/commands/check.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/check.js +24 -3
- package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/forecast.js +5 -1
- package/dist/lib/codex-manager/commands/report.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/report.js +5 -1
- package/dist/lib/codex-manager/commands/resets.d.ts +2 -0
- package/dist/lib/codex-manager/commands/resets.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/resets.js +67 -0
- package/dist/lib/codex-manager/commands/rotation.d.ts +2 -2
- package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/rotation.js +63 -12
- package/dist/lib/codex-manager/commands/status.d.ts +12 -1
- package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/status.js +166 -22
- package/dist/lib/codex-manager/commands/uninstall.js +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.js +3 -2
- package/dist/lib/codex-manager/health-check.d.ts +3 -0
- package/dist/lib/codex-manager/health-check.d.ts.map +1 -1
- package/dist/lib/codex-manager/health-check.js +56 -6
- package/dist/lib/codex-manager/help.d.ts.map +1 -1
- package/dist/lib/codex-manager/help.js +4 -2
- package/dist/lib/codex-manager/login-flow.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-flow.js +69 -7
- package/dist/lib/codex-manager/login-menu-data.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-menu-data.js +14 -5
- package/dist/lib/codex-manager/login-oauth.d.ts +3 -0
- package/dist/lib/codex-manager/login-oauth.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-oauth.js +6 -1
- package/dist/lib/codex-manager/login-workspace-choice.d.ts +11 -0
- package/dist/lib/codex-manager/login-workspace-choice.d.ts.map +1 -0
- package/dist/lib/codex-manager/login-workspace-choice.js +37 -0
- package/dist/lib/codex-manager/persist-selected-account.d.ts.map +1 -1
- package/dist/lib/codex-manager/persist-selected-account.js +2 -1
- package/dist/lib/codex-manager/repair-commands.d.ts +13 -0
- package/dist/lib/codex-manager/repair-commands.d.ts.map +1 -1
- package/dist/lib/codex-manager/repair-commands.js +143 -8
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +25 -6
- package/dist/lib/concurrency.d.ts +3 -0
- package/dist/lib/concurrency.d.ts.map +1 -0
- package/dist/lib/concurrency.js +31 -0
- package/dist/lib/context-budget/model-context-windows.d.ts +1 -1
- package/dist/lib/context-budget/model-context-windows.d.ts.map +1 -1
- package/dist/lib/context-budget/model-context-windows.js +9 -10
- package/dist/lib/model-route-policy.d.ts +52 -0
- package/dist/lib/model-route-policy.d.ts.map +1 -0
- package/dist/lib/model-route-policy.js +159 -0
- package/dist/lib/policy/runtime-policy.d.ts +1 -0
- package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
- package/dist/lib/policy/runtime-policy.js +3 -0
- package/dist/lib/preemptive-quota-scheduler.d.ts +2 -0
- package/dist/lib/preemptive-quota-scheduler.d.ts.map +1 -1
- package/dist/lib/preemptive-quota-scheduler.js +4 -0
- package/dist/lib/prompts/codex.d.ts.map +1 -1
- package/dist/lib/prompts/codex.js +3 -1
- package/dist/lib/quota-probe.d.ts +5 -0
- package/dist/lib/quota-probe.d.ts.map +1 -1
- package/dist/lib/quota-probe.js +26 -2
- package/dist/lib/request/client-cancellation.d.ts +5 -0
- package/dist/lib/request/client-cancellation.d.ts.map +1 -0
- package/dist/lib/request/client-cancellation.js +7 -0
- package/dist/lib/request/error-classification.d.ts.map +1 -1
- package/dist/lib/request/error-classification.js +39 -25
- package/dist/lib/request/fetch-helpers.js +1 -1
- package/dist/lib/request/helpers/model-map.d.ts +12 -2
- package/dist/lib/request/helpers/model-map.d.ts.map +1 -1
- package/dist/lib/request/helpers/model-map.js +174 -147
- package/dist/lib/request/response-outcome.d.ts +25 -0
- package/dist/lib/request/response-outcome.d.ts.map +1 -0
- package/dist/lib/request/response-outcome.js +49 -0
- package/dist/lib/request/stream-failover-runtime.d.ts +2 -1
- package/dist/lib/request/stream-failover-runtime.d.ts.map +1 -1
- package/dist/lib/request/stream-failover-runtime.js +29 -10
- package/dist/lib/runtime/account-check.d.ts.map +1 -1
- package/dist/lib/runtime/account-check.js +2 -8
- package/dist/lib/runtime/account-model-catalog.d.ts +64 -0
- package/dist/lib/runtime/account-model-catalog.d.ts.map +1 -0
- package/dist/lib/runtime/account-model-catalog.js +154 -0
- package/dist/lib/runtime/account-pool.d.ts +3 -1
- package/dist/lib/runtime/account-pool.d.ts.map +1 -1
- package/dist/lib/runtime/account-pool.js +4 -0
- package/dist/lib/runtime/account-reset-credits.d.ts +42 -0
- package/dist/lib/runtime/account-reset-credits.d.ts.map +1 -0
- package/dist/lib/runtime/account-reset-credits.js +82 -0
- package/dist/lib/runtime/api-model-capabilities.d.ts +30 -0
- package/dist/lib/runtime/api-model-capabilities.d.ts.map +1 -0
- package/dist/lib/runtime/api-model-capabilities.js +434 -0
- package/dist/lib/runtime/api-model-runtime.d.ts +42 -0
- package/dist/lib/runtime/api-model-runtime.d.ts.map +1 -0
- package/dist/lib/runtime/api-model-runtime.js +358 -0
- package/dist/lib/runtime/app-bind.d.ts +19 -1
- package/dist/lib/runtime/app-bind.d.ts.map +1 -1
- package/dist/lib/runtime/app-bind.js +79 -9
- package/dist/lib/runtime/automatic-account-checks.d.ts +31 -0
- package/dist/lib/runtime/automatic-account-checks.d.ts.map +1 -0
- package/dist/lib/runtime/automatic-account-checks.js +113 -0
- package/dist/lib/runtime/automatic-subscription-checks.d.ts +7 -0
- package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +1 -0
- package/dist/lib/runtime/automatic-subscription-checks.js +57 -0
- package/dist/lib/runtime/catalog-capabilities.d.ts +8 -0
- package/dist/lib/runtime/catalog-capabilities.d.ts.map +1 -0
- package/dist/lib/runtime/catalog-capabilities.js +61 -0
- package/dist/lib/runtime/inference-activity.d.ts +15 -0
- package/dist/lib/runtime/inference-activity.d.ts.map +1 -0
- package/dist/lib/runtime/inference-activity.js +95 -0
- package/dist/lib/runtime/model-discovery-status.d.ts +100 -0
- package/dist/lib/runtime/model-discovery-status.d.ts.map +1 -0
- package/dist/lib/runtime/model-discovery-status.js +387 -0
- package/dist/lib/runtime/native-account-storage.d.ts +11 -0
- package/dist/lib/runtime/native-account-storage.d.ts.map +1 -0
- package/dist/lib/runtime/native-account-storage.js +50 -0
- package/dist/lib/runtime/native-account-sync.d.ts +19 -0
- package/dist/lib/runtime/native-account-sync.d.ts.map +1 -0
- package/dist/lib/runtime/native-account-sync.js +62 -0
- package/dist/lib/runtime/native-binding-lock.d.ts +3 -0
- package/dist/lib/runtime/native-binding-lock.d.ts.map +1 -0
- package/dist/lib/runtime/native-binding-lock.js +5 -0
- package/dist/lib/runtime/native-client-auth.d.ts +3 -0
- package/dist/lib/runtime/native-client-auth.d.ts.map +1 -0
- package/dist/lib/runtime/native-client-auth.js +42 -0
- package/dist/lib/runtime/native-provider-config.d.ts +4 -0
- package/dist/lib/runtime/native-provider-config.d.ts.map +1 -0
- package/dist/lib/runtime/native-provider-config.js +52 -0
- package/dist/lib/runtime/native-rate-limits.d.ts +18 -0
- package/dist/lib/runtime/native-rate-limits.d.ts.map +1 -0
- package/dist/lib/runtime/native-rate-limits.js +135 -0
- package/dist/lib/runtime/reset-credit-routing.d.ts +41 -0
- package/dist/lib/runtime/reset-credit-routing.d.ts.map +1 -0
- package/dist/lib/runtime/reset-credit-routing.js +66 -0
- package/dist/lib/runtime/reset-credits.d.ts +101 -0
- package/dist/lib/runtime/reset-credits.d.ts.map +1 -0
- package/dist/lib/runtime/reset-credits.js +162 -0
- package/dist/lib/runtime/response-output-history.d.ts +17 -0
- package/dist/lib/runtime/response-output-history.d.ts.map +1 -0
- package/dist/lib/runtime/response-output-history.js +85 -0
- package/dist/lib/runtime/responses-websocket.d.ts +31 -0
- package/dist/lib/runtime/responses-websocket.d.ts.map +1 -0
- package/dist/lib/runtime/responses-websocket.js +636 -0
- package/dist/lib/runtime/resume-picker.d.ts +41 -0
- package/dist/lib/runtime/resume-picker.d.ts.map +1 -0
- package/dist/lib/runtime/resume-picker.js +169 -0
- package/dist/lib/runtime/rotation-account-selection.d.ts +6 -0
- package/dist/lib/runtime/rotation-account-selection.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-account-selection.js +63 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts +33 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-server-types.d.ts +18 -0
- package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-capability-failures.d.ts +14 -0
- package/dist/lib/runtime/runtime-capability-failures.d.ts.map +1 -0
- package/dist/lib/runtime/runtime-capability-failures.js +76 -0
- package/dist/lib/runtime/runtime-observability.d.ts +7 -0
- package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-observability.js +42 -2
- package/dist/lib/runtime/subscription-first-use.d.ts +10 -0
- package/dist/lib/runtime/subscription-first-use.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-first-use.js +64 -0
- package/dist/lib/runtime/subscription-quota-event.d.ts +6 -0
- package/dist/lib/runtime/subscription-quota-event.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-quota-event.js +31 -0
- package/dist/lib/runtime/subscription-quota-order.d.ts +17 -0
- package/dist/lib/runtime/subscription-quota-order.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-quota-order.js +31 -0
- package/dist/lib/runtime/workspace-model-scopes.d.ts +15 -0
- package/dist/lib/runtime/workspace-model-scopes.d.ts.map +1 -0
- package/dist/lib/runtime/workspace-model-scopes.js +34 -0
- package/dist/lib/runtime-constants.d.ts +3 -0
- package/dist/lib/runtime-constants.d.ts.map +1 -1
- package/dist/lib/runtime-constants.js +5 -0
- package/dist/lib/runtime-paths.d.ts.map +1 -1
- package/dist/lib/runtime-paths.js +4 -1
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.js +855 -46
- package/dist/lib/schemas.d.ts +20 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +3 -0
- package/dist/lib/storage/credential-sidecars.d.ts +13 -0
- package/dist/lib/storage/credential-sidecars.d.ts.map +1 -0
- package/dist/lib/storage/credential-sidecars.js +52 -0
- package/dist/lib/storage/file-lock.d.ts +9 -0
- package/dist/lib/storage/file-lock.d.ts.map +1 -0
- package/dist/lib/storage/file-lock.js +186 -0
- package/dist/lib/storage/flagged-storage.d.ts.map +1 -1
- package/dist/lib/storage/flagged-storage.js +12 -0
- package/dist/lib/storage/path-state.d.ts +2 -0
- package/dist/lib/storage/path-state.d.ts.map +1 -1
- package/dist/lib/storage/path-state.js +9 -0
- package/dist/lib/storage/paths.js +4 -4
- package/dist/lib/storage/pending-auth.d.ts +17 -0
- package/dist/lib/storage/pending-auth.d.ts.map +1 -0
- package/dist/lib/storage/pending-auth.js +153 -0
- package/dist/lib/storage/public-types.d.ts +13 -0
- package/dist/lib/storage/public-types.d.ts.map +1 -1
- package/dist/lib/storage/snapshot-merge.d.ts +16 -0
- package/dist/lib/storage/snapshot-merge.d.ts.map +1 -0
- package/dist/lib/storage/snapshot-merge.js +206 -0
- package/dist/lib/storage/transactions.d.ts.map +1 -1
- package/dist/lib/storage/transactions.js +5 -4
- package/dist/lib/storage.d.ts +6 -0
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +77 -7
- package/dist/lib/ui/auth-menu-builder.d.ts +2 -0
- package/dist/lib/ui/auth-menu-builder.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu-builder.js +1 -0
- package/dist/lib/ui/auth-menu.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu.js +1 -0
- package/dist/lib/ui/check-progress.d.ts +8 -0
- package/dist/lib/ui/check-progress.d.ts.map +1 -0
- package/dist/lib/ui/check-progress.js +30 -0
- package/dist/lib/ui/format.d.ts +3 -1
- package/dist/lib/ui/format.d.ts.map +1 -1
- package/dist/lib/ui/format.js +8 -0
- package/dist/lib/ui/ui-copy.d.ts +2 -2
- package/dist/lib/ui/ui-copy.js +2 -2
- package/dist/lib/usage/pricing.d.ts +19 -2
- package/dist/lib/usage/pricing.d.ts.map +1 -1
- package/dist/lib/usage/pricing.js +101 -40
- package/dist/lib/usage/usage-extraction.d.ts +3 -1
- package/dist/lib/usage/usage-extraction.d.ts.map +1 -1
- package/dist/lib/usage/usage-extraction.js +46 -9
- package/package.json +7 -4
- package/scripts/codex-app-router.js +7 -0
- package/scripts/codex-bin-resolver.js +40 -8
- package/scripts/codex-routing.js +1 -0
- package/scripts/codex.js +209 -126
package/dist/lib/ui/ui-copy.js
CHANGED
|
@@ -144,8 +144,8 @@ export const UI_COPY = {
|
|
|
144
144
|
fallback: {
|
|
145
145
|
addAnotherTip: "Tip: Use private mode or sign out before adding another account.",
|
|
146
146
|
addAnotherQuestion: (count) => `Add another account? (${count} added) (y/n): `,
|
|
147
|
-
selectModePrompt: "(a) add, (c) check, (b) best, fi(x), (s) settings, (d) deep, (g) problem, (f) fresh, (q) back [a/c/b/x/s/d/g/f/q]: ",
|
|
148
|
-
invalidModePrompt: "Use one of: a, c, b, x, s, d, g, f, q.",
|
|
147
|
+
selectModePrompt: "(api) API models, (a) add, (c) check, (b) best, fi(x), (s) settings, (d) deep, (g) problem, (f) fresh, (q) back [api/a/c/b/x/s/d/g/f/q]: ",
|
|
148
|
+
invalidModePrompt: "Use one of: api, a, c, b, x, s, d, g, f, q.",
|
|
149
149
|
},
|
|
150
150
|
};
|
|
151
151
|
/**
|
|
@@ -12,14 +12,31 @@ export interface UsageModelPricing {
|
|
|
12
12
|
* row under-counts it by half and lets a `maxCostUsd` cap overrun.
|
|
13
13
|
*
|
|
14
14
|
* A tier absent from this map is deliberately NOT approximated from the
|
|
15
|
-
* standard rate. Only
|
|
15
|
+
* standard rate. Only the GPT-6 Fast rates are published; inventing one for
|
|
16
16
|
* the rest would move a budget's trip point on a guess, which is the failure
|
|
17
17
|
* this file exists to avoid. `estimateUsageCostUsd` reports an unlisted tier
|
|
18
18
|
* as unknown cost instead, so a budget fails closed the same way it does for
|
|
19
19
|
* an unpriced model.
|
|
20
20
|
*/
|
|
21
21
|
serviceTiers?: Partial<Record<UsageServiceTier, UsageModelPricing>>;
|
|
22
|
+
/**
|
|
23
|
+
* Rates once a response's input exceeds `SHORT_CONTEXT_MAX_INPUT_TOKENS`.
|
|
24
|
+
*
|
|
25
|
+
* OpenAI bills a GPT-6 request whose context crosses 272K at a separate,
|
|
26
|
+
* higher rate. A row that declares this block (every tier inside it too) is
|
|
27
|
+
* priced from it past the threshold. A row that declares it but whose
|
|
28
|
+
* resolved service tier does not reports unknown cost there instead of the
|
|
29
|
+
* cheaper short-context figure, for the same fail-closed reason as an
|
|
30
|
+
* unlisted tier. Rows with no long-context data at all are unchanged.
|
|
31
|
+
*/
|
|
32
|
+
longContext?: UsageModelPricing;
|
|
22
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Largest input still billed at the short-context rate. OpenAI's GPT-6 model
|
|
36
|
+
* pages say "Prompts with more than 272K input tokens are priced at 2x input
|
|
37
|
+
* and cache rates", so exactly 272,000 is short and 272,001 is long.
|
|
38
|
+
*/
|
|
39
|
+
export declare const SHORT_CONTEXT_MAX_INPUT_TOKENS = 272000;
|
|
23
40
|
/**
|
|
24
41
|
* Models the router can normalize to that have no published rate here yet.
|
|
25
42
|
*
|
|
@@ -34,7 +51,7 @@ export interface UsageModelPricing {
|
|
|
34
51
|
* `test/usage-pricing-coverage.test.ts` fails if a NEW routable model appears
|
|
35
52
|
* in neither list.
|
|
36
53
|
*/
|
|
37
|
-
export declare const UNPRICED_ROUTABLE_MODELS: readonly ["gpt-6-astra-aeon", "gpt-daybreak-blue-latest", "gpt-daybreak-red-latest", "gpt-5.
|
|
54
|
+
export declare const UNPRICED_ROUTABLE_MODELS: readonly ["gpt-6-astra-aeon", "gpt-daybreak-blue-latest", "gpt-daybreak-red-latest", "gpt-5.5-pro"];
|
|
38
55
|
export declare function getUsageModelPricing(model: string | null | undefined): UsageModelPricing | null;
|
|
39
56
|
export declare function estimateUsageCostUsd(model: string | null | undefined, tokens: UsageTokenCounts): number | null;
|
|
40
57
|
export declare function listUsageModelPricing(): Record<string, UsageModelPricing>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../../lib/usage/pricing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../../lib/usage/pricing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,WAAW,iBAAiB;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACpE;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,SAAU,CAAC;AA8HtD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,qGAW3B,CAAC;AAOX,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,iBAAiB,GAAG,IAAI,CA0B1B;AAmCD,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,MAAM,EAAE,gBAAgB,GACtB,MAAM,GAAG,IAAI,CAsCf;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAEzE"}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { RETIRED_MODEL_REPLACEMENTS } from "../request/helpers/model-map.js";
|
|
2
|
+
/**
|
|
3
|
+
* Largest input still billed at the short-context rate. OpenAI's GPT-6 model
|
|
4
|
+
* pages say "Prompts with more than 272K input tokens are priced at 2x input
|
|
5
|
+
* and cache rates", so exactly 272,000 is short and 272,001 is long.
|
|
6
|
+
*/
|
|
7
|
+
export const SHORT_CONTEXT_MAX_INPUT_TOKENS = 272_000;
|
|
1
8
|
const MODEL_PRICING = {
|
|
2
9
|
// GPT-6 Astra, published at the 2026-09-03 launch: $10 / 1M input,
|
|
3
10
|
// $50 / 1M output on the standard service tier, and $20 / $100 on Fast,
|
|
@@ -16,48 +23,85 @@ const MODEL_PRICING = {
|
|
|
16
23
|
outputUsdPerMillion: 50,
|
|
17
24
|
cachedInputUsdPerMillion: 1,
|
|
18
25
|
reasoningUsdPerMillion: 50,
|
|
26
|
+
// Long-context rows from the same page (read 2026-09-23).
|
|
27
|
+
longContext: {
|
|
28
|
+
inputUsdPerMillion: 20,
|
|
29
|
+
outputUsdPerMillion: 75,
|
|
30
|
+
cachedInputUsdPerMillion: 2,
|
|
31
|
+
reasoningUsdPerMillion: 75,
|
|
32
|
+
},
|
|
19
33
|
serviceTiers: {
|
|
20
34
|
// Published at launch alongside the standard rate: Fast mode is up to
|
|
21
|
-
// 2.5x the speed at 2x the price, $20 / $100 per 1M.
|
|
22
|
-
//
|
|
23
|
-
// which is why it is the only one listed anywhere in this file.
|
|
35
|
+
// 2.5x the speed at 2x the price, $20 / $100 per 1M. Only the GPT-6
|
|
36
|
+
// rows list a Fast tier, because only GPT-6 has a published Fast rate.
|
|
24
37
|
priority: {
|
|
25
38
|
inputUsdPerMillion: 20,
|
|
26
39
|
outputUsdPerMillion: 100,
|
|
27
40
|
cachedInputUsdPerMillion: 2,
|
|
28
41
|
reasoningUsdPerMillion: 100,
|
|
42
|
+
longContext: {
|
|
43
|
+
inputUsdPerMillion: 40,
|
|
44
|
+
outputUsdPerMillion: 150,
|
|
45
|
+
cachedInputUsdPerMillion: 4,
|
|
46
|
+
reasoningUsdPerMillion: 150,
|
|
47
|
+
},
|
|
29
48
|
},
|
|
30
49
|
},
|
|
31
50
|
},
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
"gpt-5.1-codex": {
|
|
39
|
-
inputUsdPerMillion: 1.25,
|
|
40
|
-
outputUsdPerMillion: 10,
|
|
41
|
-
cachedInputUsdPerMillion: 0.125,
|
|
42
|
-
reasoningUsdPerMillion: 10,
|
|
43
|
-
},
|
|
44
|
-
"gpt-5.2": {
|
|
45
|
-
inputUsdPerMillion: 1.25,
|
|
46
|
-
outputUsdPerMillion: 10,
|
|
47
|
-
cachedInputUsdPerMillion: 0.125,
|
|
48
|
-
reasoningUsdPerMillion: 10,
|
|
49
|
-
},
|
|
50
|
-
"gpt-5.3-codex": {
|
|
51
|
-
inputUsdPerMillion: 1.25,
|
|
51
|
+
// GPT-6 Sol and Luna, from the OpenAI API pricing page (read 2026-09-23;
|
|
52
|
+
// short- and long-context rows). Both publish a Fast tier at exactly 2x,
|
|
53
|
+
// like Astra.
|
|
54
|
+
"gpt-6-sol": {
|
|
55
|
+
inputUsdPerMillion: 2,
|
|
52
56
|
outputUsdPerMillion: 10,
|
|
53
|
-
cachedInputUsdPerMillion: 0.
|
|
57
|
+
cachedInputUsdPerMillion: 0.2,
|
|
54
58
|
reasoningUsdPerMillion: 10,
|
|
59
|
+
longContext: {
|
|
60
|
+
inputUsdPerMillion: 4,
|
|
61
|
+
outputUsdPerMillion: 15,
|
|
62
|
+
cachedInputUsdPerMillion: 0.4,
|
|
63
|
+
reasoningUsdPerMillion: 15,
|
|
64
|
+
},
|
|
65
|
+
serviceTiers: {
|
|
66
|
+
priority: {
|
|
67
|
+
inputUsdPerMillion: 4,
|
|
68
|
+
outputUsdPerMillion: 20,
|
|
69
|
+
cachedInputUsdPerMillion: 0.4,
|
|
70
|
+
reasoningUsdPerMillion: 20,
|
|
71
|
+
longContext: {
|
|
72
|
+
inputUsdPerMillion: 8,
|
|
73
|
+
outputUsdPerMillion: 30,
|
|
74
|
+
cachedInputUsdPerMillion: 0.8,
|
|
75
|
+
reasoningUsdPerMillion: 30,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
55
79
|
},
|
|
56
|
-
"gpt-
|
|
57
|
-
inputUsdPerMillion:
|
|
58
|
-
outputUsdPerMillion:
|
|
59
|
-
cachedInputUsdPerMillion: 0.
|
|
60
|
-
reasoningUsdPerMillion:
|
|
80
|
+
"gpt-6-luna": {
|
|
81
|
+
inputUsdPerMillion: 0.1,
|
|
82
|
+
outputUsdPerMillion: 0.5,
|
|
83
|
+
cachedInputUsdPerMillion: 0.01,
|
|
84
|
+
reasoningUsdPerMillion: 0.5,
|
|
85
|
+
longContext: {
|
|
86
|
+
inputUsdPerMillion: 0.2,
|
|
87
|
+
outputUsdPerMillion: 0.75,
|
|
88
|
+
cachedInputUsdPerMillion: 0.02,
|
|
89
|
+
reasoningUsdPerMillion: 0.75,
|
|
90
|
+
},
|
|
91
|
+
serviceTiers: {
|
|
92
|
+
priority: {
|
|
93
|
+
inputUsdPerMillion: 0.2,
|
|
94
|
+
outputUsdPerMillion: 1,
|
|
95
|
+
cachedInputUsdPerMillion: 0.02,
|
|
96
|
+
reasoningUsdPerMillion: 1,
|
|
97
|
+
longContext: {
|
|
98
|
+
inputUsdPerMillion: 0.4,
|
|
99
|
+
outputUsdPerMillion: 1.5,
|
|
100
|
+
cachedInputUsdPerMillion: 0.04,
|
|
101
|
+
reasoningUsdPerMillion: 1.5,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
61
105
|
},
|
|
62
106
|
"gpt-5.5": {
|
|
63
107
|
inputUsdPerMillion: 2,
|
|
@@ -108,21 +152,14 @@ export const UNPRICED_ROUTABLE_MODELS = [
|
|
|
108
152
|
"gpt-6-astra-aeon",
|
|
109
153
|
"gpt-daybreak-blue-latest",
|
|
110
154
|
"gpt-daybreak-red-latest",
|
|
111
|
-
"gpt-5.1",
|
|
112
|
-
"gpt-5.2-pro",
|
|
113
|
-
"gpt-5.4-mini",
|
|
114
|
-
"gpt-5.4-nano",
|
|
115
|
-
"gpt-5.4-pro",
|
|
116
155
|
"gpt-5.5-pro",
|
|
117
|
-
"gpt-5-mini",
|
|
118
|
-
"gpt-5-nano",
|
|
119
156
|
];
|
|
120
157
|
function normalizeModelName(model) {
|
|
121
158
|
const trimmed = model?.trim().toLowerCase();
|
|
122
159
|
return trimmed && trimmed.length > 0 ? trimmed : null;
|
|
123
160
|
}
|
|
124
161
|
export function getUsageModelPricing(model) {
|
|
125
|
-
const normalized = normalizeModelName(model);
|
|
162
|
+
const normalized = normalizeModelName(model?.replace(/^(api|zdr)\//, ""));
|
|
126
163
|
if (!normalized) {
|
|
127
164
|
return null;
|
|
128
165
|
}
|
|
@@ -134,10 +171,19 @@ export function getUsageModelPricing(model) {
|
|
|
134
171
|
// `NaN` instead of `null`. A NaN cost is worse than an unknown one, because
|
|
135
172
|
// `NaN >= limit` is false, so it silently makes a `maxCostUsd` budget
|
|
136
173
|
// unenforceable rather than failing closed the way an unpriced model does.
|
|
137
|
-
|
|
174
|
+
//
|
|
175
|
+
// A retired id is priced as the model it now runs on. The proxy records the
|
|
176
|
+
// raw client model string, so a new `gpt-5-codex` row is really a
|
|
177
|
+
// `gpt-5.6-sol` request; pricing it at the retired model's old rate would
|
|
178
|
+
// under-count a `maxCostUsd` budget. Rows already on disk are unaffected:
|
|
179
|
+
// the ledger stores `costUsd` when a row is written and never re-prices it.
|
|
180
|
+
const effective = !/^(api|zdr)\//.test(model ?? "") && Object.hasOwn(RETIRED_MODEL_REPLACEMENTS, normalized)
|
|
181
|
+
? RETIRED_MODEL_REPLACEMENTS[normalized]
|
|
182
|
+
: normalized;
|
|
183
|
+
if (!effective || !Object.hasOwn(MODEL_PRICING, effective)) {
|
|
138
184
|
return null;
|
|
139
185
|
}
|
|
140
|
-
return MODEL_PRICING[
|
|
186
|
+
return MODEL_PRICING[effective] ?? null;
|
|
141
187
|
}
|
|
142
188
|
/**
|
|
143
189
|
* Pick the rate that applies to a response's service tier.
|
|
@@ -152,6 +198,17 @@ function resolveServiceTierPricing(pricing, serviceTier) {
|
|
|
152
198
|
}
|
|
153
199
|
return pricing.serviceTiers?.[serviceTier] ?? null;
|
|
154
200
|
}
|
|
201
|
+
function resolveContextLengthPricing(basePricing, tierPricing, inputTokens) {
|
|
202
|
+
if (inputTokens <= SHORT_CONTEXT_MAX_INPUT_TOKENS) {
|
|
203
|
+
return tierPricing;
|
|
204
|
+
}
|
|
205
|
+
if (tierPricing.longContext) {
|
|
206
|
+
return tierPricing.longContext;
|
|
207
|
+
}
|
|
208
|
+
// The model has long-context rates but not for this tier: unknown, never
|
|
209
|
+
// the cheaper short-context rate.
|
|
210
|
+
return basePricing.longContext ? null : tierPricing;
|
|
211
|
+
}
|
|
155
212
|
export function estimateUsageCostUsd(model, tokens) {
|
|
156
213
|
const basePricing = getUsageModelPricing(model);
|
|
157
214
|
if (!basePricing) {
|
|
@@ -161,7 +218,11 @@ export function estimateUsageCostUsd(model, tokens) {
|
|
|
161
218
|
// table has no rate for must report unknown cost, not a standard-tier
|
|
162
219
|
// figure: under-counting is what lets a `maxCostUsd` cap overrun, and
|
|
163
220
|
// `evaluateBudgetGuard` already knows how to fail closed on `null`.
|
|
164
|
-
const
|
|
221
|
+
const tierPricing = resolveServiceTierPricing(basePricing, tokens.serviceTier);
|
|
222
|
+
if (!tierPricing) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
const pricing = resolveContextLengthPricing(basePricing, tierPricing, tokens.inputTokens);
|
|
165
226
|
if (!pricing) {
|
|
166
227
|
return null;
|
|
167
228
|
}
|
|
@@ -30,7 +30,7 @@ export interface UsageStreamScanner {
|
|
|
30
30
|
/**
|
|
31
31
|
* Observe a forwarded response body and recover its token counts.
|
|
32
32
|
*
|
|
33
|
-
* SSE bodies are scanned
|
|
33
|
+
* SSE bodies are scanned frame by frame so only the current bounded event is
|
|
34
34
|
* retained; a full response can be gigabytes of deltas and must never be
|
|
35
35
|
* buffered. Non-SSE JSON bodies have no incremental structure to exploit, so
|
|
36
36
|
* they are accumulated up to `MAX_BUFFERED_BYTES` and parsed at the end —
|
|
@@ -39,5 +39,7 @@ export interface UsageStreamScanner {
|
|
|
39
39
|
*/
|
|
40
40
|
export declare function createUsageStreamScanner(options: {
|
|
41
41
|
contentType?: string | null;
|
|
42
|
+
/** Observe parsed upstream events without reparsing the stream. */
|
|
43
|
+
onEvent?: (event: unknown) => void;
|
|
42
44
|
}): UsageStreamScanner;
|
|
43
45
|
//# sourceMappingURL=usage-extraction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-extraction.d.ts","sourceRoot":"","sources":["../../../lib/usage/usage-extraction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA+BrE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACtC,KAAK,EAAE,OAAO,GACZ,gBAAgB,GAAG,IAAI,CA+BzB;AAoCD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CAa/E;AAED,MAAM,WAAW,kBAAkB;IAClC,8CAA8C;IAC9C,IAAI,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,2EAA2E;IAC3E,MAAM,EAAE,MAAM,gBAAgB,GAAG,IAAI,CAAC;CACtC;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IACjD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"usage-extraction.d.ts","sourceRoot":"","sources":["../../../lib/usage/usage-extraction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA+BrE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACtC,KAAK,EAAE,OAAO,GACZ,gBAAgB,GAAG,IAAI,CA+BzB;AAoCD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CAa/E;AAED,MAAM,WAAW,kBAAkB;IAClC,8CAA8C;IAC9C,IAAI,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,2EAA2E;IAC3E,MAAM,EAAE,MAAM,gBAAgB,GAAG,IAAI,CAAC;CACtC;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IACjD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mEAAmE;IACnE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACnC,GAAG,kBAAkB,CAmGrB"}
|
|
@@ -124,7 +124,7 @@ export function extractResponsesUsage(payload) {
|
|
|
124
124
|
/**
|
|
125
125
|
* Observe a forwarded response body and recover its token counts.
|
|
126
126
|
*
|
|
127
|
-
* SSE bodies are scanned
|
|
127
|
+
* SSE bodies are scanned frame by frame so only the current bounded event is
|
|
128
128
|
* retained; a full response can be gigabytes of deltas and must never be
|
|
129
129
|
* buffered. Non-SSE JSON bodies have no incremental structure to exploit, so
|
|
130
130
|
* they are accumulated up to `MAX_BUFFERED_BYTES` and parsed at the end —
|
|
@@ -138,11 +138,20 @@ export function createUsageStreamScanner(options) {
|
|
|
138
138
|
let bufferedBytes = 0;
|
|
139
139
|
let overflowed = false;
|
|
140
140
|
let latest = null;
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
let eventData = [];
|
|
142
|
+
let eventSize = 0;
|
|
143
|
+
let droppingEvent = false;
|
|
144
|
+
let droppingLine = false;
|
|
145
|
+
const consumeEvent = () => {
|
|
146
|
+
if (droppingEvent) {
|
|
147
|
+
droppingEvent = false;
|
|
148
|
+
eventData = [];
|
|
149
|
+
eventSize = 0;
|
|
144
150
|
return;
|
|
145
|
-
|
|
151
|
+
}
|
|
152
|
+
const payload = eventData.join("\n");
|
|
153
|
+
eventData = [];
|
|
154
|
+
eventSize = 0;
|
|
146
155
|
if (payload.length === 0 || payload === "[DONE]")
|
|
147
156
|
return;
|
|
148
157
|
let parsed;
|
|
@@ -152,6 +161,7 @@ export function createUsageStreamScanner(options) {
|
|
|
152
161
|
catch {
|
|
153
162
|
return;
|
|
154
163
|
}
|
|
164
|
+
options.onEvent?.(parsed);
|
|
155
165
|
// Prefer terminal events, which carry the authoritative totals, but fall
|
|
156
166
|
// back to any event that reports usage so a stream that ends on a
|
|
157
167
|
// non-standard terminal type still records something.
|
|
@@ -162,6 +172,24 @@ export function createUsageStreamScanner(options) {
|
|
|
162
172
|
latest = counts;
|
|
163
173
|
}
|
|
164
174
|
};
|
|
175
|
+
const consumeLine = (raw) => {
|
|
176
|
+
const line = raw.endsWith("\r") ? raw.slice(0, -1) : raw;
|
|
177
|
+
if (line.length === 0) {
|
|
178
|
+
consumeEvent();
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (droppingEvent || !line.startsWith("data:"))
|
|
182
|
+
return;
|
|
183
|
+
const value = line.slice(5).replace(/^ /, "");
|
|
184
|
+
eventSize += value.length + 1;
|
|
185
|
+
if (eventSize > MAX_BUFFERED_BYTES) {
|
|
186
|
+
droppingEvent = true;
|
|
187
|
+
eventData = [];
|
|
188
|
+
eventSize = 0;
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
eventData.push(value);
|
|
192
|
+
};
|
|
165
193
|
return {
|
|
166
194
|
push: (chunk) => {
|
|
167
195
|
try {
|
|
@@ -178,14 +206,20 @@ export function createUsageStreamScanner(options) {
|
|
|
178
206
|
}
|
|
179
207
|
let newlineAt = pending.indexOf("\n");
|
|
180
208
|
while (newlineAt !== -1) {
|
|
181
|
-
|
|
209
|
+
if (droppingLine)
|
|
210
|
+
droppingLine = false;
|
|
211
|
+
else
|
|
212
|
+
consumeLine(pending.slice(0, newlineAt));
|
|
182
213
|
pending = pending.slice(newlineAt + 1);
|
|
183
214
|
newlineAt = pending.indexOf("\n");
|
|
184
215
|
}
|
|
185
216
|
// A single unterminated line this long is not SSE any more; stop
|
|
186
217
|
// retaining it rather than growing the buffer for the whole body.
|
|
187
|
-
if (pending.length > MAX_BUFFERED_BYTES) {
|
|
188
|
-
|
|
218
|
+
if (pending.length > MAX_BUFFERED_BYTES || droppingLine) {
|
|
219
|
+
droppingEvent = true;
|
|
220
|
+
droppingLine = true;
|
|
221
|
+
eventData = [];
|
|
222
|
+
eventSize = 0;
|
|
189
223
|
pending = "";
|
|
190
224
|
}
|
|
191
225
|
}
|
|
@@ -202,13 +236,16 @@ export function createUsageStreamScanner(options) {
|
|
|
202
236
|
if (pending.length > 0)
|
|
203
237
|
consumeLine(pending);
|
|
204
238
|
pending = "";
|
|
239
|
+
consumeEvent();
|
|
205
240
|
return latest;
|
|
206
241
|
}
|
|
207
242
|
if (pending.trim().length === 0)
|
|
208
243
|
return latest;
|
|
209
244
|
const parsed = JSON.parse(pending);
|
|
210
245
|
pending = "";
|
|
211
|
-
|
|
246
|
+
options.onEvent?.(parsed);
|
|
247
|
+
latest = extractResponsesUsage(parsed) ?? latest;
|
|
248
|
+
return latest;
|
|
212
249
|
}
|
|
213
250
|
catch {
|
|
214
251
|
return latest;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-multi-auth",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.0",
|
|
4
4
|
"description": "Codex CLI multi-account OAuth manager with account switching, health checks, runtime rotation, diagnostics, and recovery tools for @openai/codex",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -157,6 +157,7 @@
|
|
|
157
157
|
},
|
|
158
158
|
"devDependencies": {
|
|
159
159
|
"@types/node": "^20.19.42",
|
|
160
|
+
"@types/ws": "8.18.1",
|
|
160
161
|
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
161
162
|
"@typescript-eslint/parser": "^8.56.0",
|
|
162
163
|
"@vitest/coverage-v8": "^4.1.8",
|
|
@@ -174,12 +175,13 @@
|
|
|
174
175
|
"dependencies": {
|
|
175
176
|
"@codex-ai/plugin": "file:vendor/codex-ai-plugin",
|
|
176
177
|
"@codex-ai/sdk": "file:vendor/codex-ai-sdk",
|
|
177
|
-
"hono": "4.
|
|
178
|
+
"hono": "4.13.9",
|
|
178
179
|
"undici": "6.28.0",
|
|
180
|
+
"ws": "8.21.3",
|
|
179
181
|
"zod": "4.4.3"
|
|
180
182
|
},
|
|
181
183
|
"overrides": {
|
|
182
|
-
"hono": "4.
|
|
184
|
+
"hono": "4.13.9",
|
|
183
185
|
"flatted": "3.4.2",
|
|
184
186
|
"minimatch": "10.2.4",
|
|
185
187
|
"picomatch": "4.0.4",
|
|
@@ -192,6 +194,7 @@
|
|
|
192
194
|
"minimatch": "9.0.9"
|
|
193
195
|
},
|
|
194
196
|
"brace-expansion": "5.0.9",
|
|
195
|
-
"postcss": "8.5.25"
|
|
197
|
+
"postcss": "8.5.25",
|
|
198
|
+
"nanoid": "3.3.18"
|
|
196
199
|
}
|
|
197
200
|
}
|
|
@@ -177,11 +177,16 @@ function createStatusPayload({
|
|
|
177
177
|
baseUrl: proxyServer?.baseUrl ?? stateRecord?.baseUrl ?? null,
|
|
178
178
|
totalRequests: proxyStatus.totalRequests ?? 0,
|
|
179
179
|
upstreamRequests: proxyStatus.upstreamRequests ?? 0,
|
|
180
|
+
websocketConnections: proxyStatus.websocketConnections ?? 0,
|
|
181
|
+
websocketUpstreamRequests: proxyStatus.websocketUpstreamRequests ?? 0,
|
|
182
|
+
streamQuotaUpdates: proxyStatus.streamQuotaUpdates ?? 0,
|
|
183
|
+
lastStreamQuotaUpdateAt: proxyStatus.lastStreamQuotaUpdateAt ?? null,
|
|
180
184
|
retries: proxyStatus.retries ?? 0,
|
|
181
185
|
rotations: proxyStatus.rotations ?? 0,
|
|
182
186
|
lastAccountIndex,
|
|
183
187
|
lastAccountLabel,
|
|
184
188
|
lastAccountId: proxyStatus.lastAccountId ?? null,
|
|
189
|
+
lastRequestedWorkspaceId: proxyStatus.lastRequestedWorkspaceId ?? null,
|
|
185
190
|
lastAccountUpdatedAt: proxyStatus.lastAccountUpdatedAt ?? null,
|
|
186
191
|
lastError: error ? (error instanceof Error ? error.message : String(error)) : proxyStatus.lastError ?? null,
|
|
187
192
|
};
|
|
@@ -323,6 +328,8 @@ async function main() {
|
|
|
323
328
|
try {
|
|
324
329
|
const proxyModule = await import("../dist/lib/runtime-rotation-proxy.js");
|
|
325
330
|
proxyServer = await proxyModule.startRuntimeRotationProxy({
|
|
331
|
+
nativeOpenai: stateRecord?.nativeOpenai === true,
|
|
332
|
+
catalogAccount: stateRecord?.catalogAccount,
|
|
326
333
|
host,
|
|
327
334
|
port,
|
|
328
335
|
clientApiKey,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import { existsSync, realpathSync } from "node:fs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
-
import { basename,
|
|
4
|
+
import { basename, dirname, extname, isAbsolute, join, posix, relative, win32 } from "node:path";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
@@ -55,6 +55,29 @@ function defaultResolvePackageBin(moduleUrl) {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// spawn() without a shell cannot run these on Windows: `.cmd`/`.bat` are
|
|
59
|
+
// EINVAL, `.ps1` is not an executable image, and an extensionless file
|
|
60
|
+
// (npm's `#!/bin/sh` shim) is ENOENT even when it is a real PE image. Going through cmd.exe instead would put every
|
|
61
|
+
// forwarded argument through cmd's quoting rules.
|
|
62
|
+
export function isWindowsShimPath(candidatePath) {
|
|
63
|
+
const extension = win32.extname(candidatePath).toLowerCase();
|
|
64
|
+
return extension === "" || extension === ".cmd" || extension === ".bat" || extension === ".ps1";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// npm's Windows shims sit in the prefix dir and run
|
|
68
|
+
// `<prefix>\node_modules\@openai\codex\bin\codex.js`.
|
|
69
|
+
export function resolveWindowsShimPackageEntry(shimPath, existsSyncImpl = existsSync) {
|
|
70
|
+
const entry = win32.join(
|
|
71
|
+
win32.dirname(shimPath),
|
|
72
|
+
"node_modules",
|
|
73
|
+
"@openai",
|
|
74
|
+
"codex",
|
|
75
|
+
"bin",
|
|
76
|
+
"codex.js",
|
|
77
|
+
);
|
|
78
|
+
return existsSyncImpl(entry) ? entry : null;
|
|
79
|
+
}
|
|
80
|
+
|
|
58
81
|
function resolveWindowsCmdPath(env) {
|
|
59
82
|
const comSpec = (env.ComSpec ?? env.COMSPEC ?? "").trim();
|
|
60
83
|
if (comSpec.length > 0) return comSpec;
|
|
@@ -67,12 +90,12 @@ function resolveWindowsCmdPath(env) {
|
|
|
67
90
|
return "cmd.exe";
|
|
68
91
|
}
|
|
69
92
|
|
|
70
|
-
export function splitPathEntries(pathValue) {
|
|
93
|
+
export function splitPathEntries(pathValue, platform = process.platform) {
|
|
71
94
|
if (typeof pathValue !== "string" || pathValue.trim().length === 0) {
|
|
72
95
|
return [];
|
|
73
96
|
}
|
|
74
97
|
return pathValue
|
|
75
|
-
.split(
|
|
98
|
+
.split(platform === "win32" ? ";" : ":")
|
|
76
99
|
.map((entry) => entry.trim())
|
|
77
100
|
.filter((entry) => entry.length > 0);
|
|
78
101
|
}
|
|
@@ -85,7 +108,12 @@ function resolveCandidateExecutableNames(platform) {
|
|
|
85
108
|
if (platform !== "win32") {
|
|
86
109
|
return [resolvePathExecutableName(platform)];
|
|
87
110
|
}
|
|
88
|
-
|
|
111
|
+
// npm on Windows puts `codex.cmd` plus an extensionless `#!/bin/sh` shim in
|
|
112
|
+
// the prefix dir and the package under `<prefix>\node_modules`. Neither shim
|
|
113
|
+
// can be spawned without a shell (`.cmd` is EINVAL, the sh script ENOENT),
|
|
114
|
+
// so launch the package entry the shims point at before falling back to an
|
|
115
|
+
// extensionless `codex`.
|
|
116
|
+
return ["codex.exe", win32.join("node_modules", "@openai", "codex", "bin", "codex.js"), "codex"];
|
|
89
117
|
}
|
|
90
118
|
|
|
91
119
|
function resolveCodexExecutableFromPath(
|
|
@@ -97,7 +125,7 @@ function resolveCodexExecutableFromPath(
|
|
|
97
125
|
) {
|
|
98
126
|
for (const entry of pathEntries) {
|
|
99
127
|
for (const executableName of resolveCandidateExecutableNames(platform)) {
|
|
100
|
-
const candidate = join(entry, executableName);
|
|
128
|
+
const candidate = (platform === "win32" ? win32 : posix).join(entry, executableName);
|
|
101
129
|
if (!existsSyncImpl(candidate)) {
|
|
102
130
|
continue;
|
|
103
131
|
}
|
|
@@ -134,7 +162,7 @@ function resolveCodexExecutableFromSystemPath(
|
|
|
134
162
|
selfScriptPath,
|
|
135
163
|
realpathSyncImpl,
|
|
136
164
|
) {
|
|
137
|
-
const pathEntries = splitPathEntries(env.PATH ?? env.Path ?? "");
|
|
165
|
+
const pathEntries = splitPathEntries(env.PATH ?? env.Path ?? "", platform);
|
|
138
166
|
const fromEnvPath = resolveCodexExecutableFromPath(
|
|
139
167
|
pathEntries,
|
|
140
168
|
platform,
|
|
@@ -207,8 +235,12 @@ export function resolveRealCodexBin(options = {}) {
|
|
|
207
235
|
|
|
208
236
|
const override = (env.CODEX_MULTI_AUTH_REAL_CODEX_BIN ?? "").trim();
|
|
209
237
|
if (override.length > 0) {
|
|
210
|
-
if (existsSyncImpl(override)) return
|
|
211
|
-
|
|
238
|
+
if (!existsSyncImpl(override)) return null;
|
|
239
|
+
if (platform === "win32" && isWindowsShimPath(override)) {
|
|
240
|
+
const entry = resolveWindowsShimPackageEntry(override, existsSyncImpl);
|
|
241
|
+
return entry ? createResolvedCodexBin(entry) : null;
|
|
242
|
+
}
|
|
243
|
+
return createResolvedCodexBin(override);
|
|
212
244
|
}
|
|
213
245
|
|
|
214
246
|
const resolved = resolvePackageBin(moduleUrl);
|