codex-multi-auth 2.9.2 → 2.11.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 +2 -1
- package/config/README.md +3 -1
- package/config/codex-legacy.json +300 -0
- package/config/codex-modern.json +96 -0
- package/config/schema/config.schema.json +23 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -2
- package/dist/lib/accounts.d.ts +25 -1
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +26 -6
- package/dist/lib/capability-policy.d.ts.map +1 -1
- package/dist/lib/capability-policy.js +16 -1
- package/dist/lib/codex-manager/backend-settings-helpers.d.ts.map +1 -1
- package/dist/lib/codex-manager/backend-settings-helpers.js +10 -1
- package/dist/lib/codex-manager/backend-settings-schema.d.ts +18 -0
- package/dist/lib/codex-manager/backend-settings-schema.d.ts.map +1 -1
- package/dist/lib/codex-manager/backend-settings-schema.js +19 -0
- package/dist/lib/codex-manager/experimental-settings-prompt.d.ts +1 -0
- package/dist/lib/codex-manager/experimental-settings-prompt.d.ts.map +1 -1
- package/dist/lib/codex-manager/experimental-settings-prompt.js +12 -0
- package/dist/lib/codex-manager/experimental-settings-schema.d.ts +2 -0
- package/dist/lib/codex-manager/experimental-settings-schema.d.ts.map +1 -1
- package/dist/lib/codex-manager/experimental-settings-schema.js +2 -0
- package/dist/lib/config.d.ts +29 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +91 -1
- package/dist/lib/context-budget/model-context-windows.d.ts +25 -0
- package/dist/lib/context-budget/model-context-windows.d.ts.map +1 -0
- package/dist/lib/context-budget/model-context-windows.js +130 -0
- package/dist/lib/context-budget-guard.d.ts +100 -0
- package/dist/lib/context-budget-guard.d.ts.map +1 -0
- package/dist/lib/context-budget-guard.js +183 -0
- package/dist/lib/context-budget-response.d.ts +25 -0
- package/dist/lib/context-budget-response.d.ts.map +1 -0
- package/dist/lib/context-budget-response.js +57 -0
- package/dist/lib/context-overflow.d.ts.map +1 -1
- package/dist/lib/context-overflow.js +5 -60
- package/dist/lib/model-capability-matrix.d.ts.map +1 -1
- package/dist/lib/model-capability-matrix.js +9 -1
- package/dist/lib/request/error-classification.d.ts.map +1 -1
- package/dist/lib/request/error-classification.js +43 -2
- package/dist/lib/request/helpers/model-map.d.ts.map +1 -1
- package/dist/lib/request/helpers/model-map.js +181 -0
- package/dist/lib/request/rate-limit-decision.d.ts +4 -5
- package/dist/lib/request/rate-limit-decision.d.ts.map +1 -1
- package/dist/lib/request/rate-limit-decision.js +33 -4
- package/dist/lib/request/response-metadata.d.ts.map +1 -1
- package/dist/lib/request/response-metadata.js +1 -0
- package/dist/lib/request/stream-failover-runtime.d.ts +3 -1
- package/dist/lib/request/stream-failover-runtime.d.ts.map +1 -1
- package/dist/lib/request/stream-failover-runtime.js +7 -2
- package/dist/lib/runtime/context-budget-settings.d.ts +13 -0
- package/dist/lib/runtime/context-budget-settings.d.ts.map +1 -0
- package/dist/lib/runtime/context-budget-settings.js +8 -0
- package/dist/lib/runtime/loader-setup.d.ts +1 -0
- package/dist/lib/runtime/loader-setup.d.ts.map +1 -1
- package/dist/lib/runtime/loader-setup.js +1 -0
- package/dist/lib/runtime/rotation-account-selection.d.ts +23 -0
- package/dist/lib/runtime/rotation-account-selection.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-account-selection.js +15 -6
- package/dist/lib/runtime/rotation-proxy-state.d.ts +2 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-server-types.d.ts +11 -0
- package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.js +251 -43
- package/dist/lib/schemas.d.ts +4 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +10 -0
- package/dist/lib/synthetic-response.d.ts +31 -0
- package/dist/lib/synthetic-response.d.ts.map +1 -0
- package/dist/lib/synthetic-response.js +79 -0
- package/dist/lib/ui/ui-copy.d.ts +2 -1
- package/dist/lib/ui/ui-copy.d.ts.map +1 -1
- package/dist/lib/ui/ui-copy.js +2 -1
- package/dist/lib/usage/pricing.d.ts +1 -1
- package/dist/lib/usage/pricing.d.ts.map +1 -1
- package/dist/lib/usage/pricing.js +33 -0
- package/package.json +1 -1
- package/scripts/codex.js +153 -2
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared builder for locally-answered Responses API replies.
|
|
3
|
+
*
|
|
4
|
+
* Both the reactive context-overflow handler (`lib/context-overflow.ts`) and
|
|
5
|
+
* the proactive context budget guard (`lib/context-budget-response.ts`) need
|
|
6
|
+
* to hand the caller a plugin-authored notice instead of forwarding to
|
|
7
|
+
* upstream, in the exact SSE dialect the Codex CLI / Responses client
|
|
8
|
+
* expects. Extracted here so both answer with one audited SSE shape rather
|
|
9
|
+
* than two independently-maintained copies of it.
|
|
10
|
+
*/
|
|
11
|
+
function randomSuffix() {
|
|
12
|
+
return Math.random().toString(36).slice(2, 8);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Build a synthetic OpenAI Responses API SSE stream carrying a single
|
|
16
|
+
* assistant text message, then a terminal `response.completed`.
|
|
17
|
+
*
|
|
18
|
+
* Emits `response.*` events — the dialect the Codex CLI client and this
|
|
19
|
+
* package's own `convertSseToJson` parser speak, not the Anthropic Messages
|
|
20
|
+
* API dialect. Returns 200 OK so the host session never locks on a 4xx for a
|
|
21
|
+
* notice the plugin itself generated.
|
|
22
|
+
*/
|
|
23
|
+
export function createSyntheticSseResponse(options) {
|
|
24
|
+
const { model, message, idPrefix, errorType } = options;
|
|
25
|
+
const messageId = `msg_${idPrefix}_${Date.now()}_${randomSuffix()}`;
|
|
26
|
+
const responseId = `resp_${idPrefix}_${Date.now()}_${randomSuffix()}`;
|
|
27
|
+
const events = [];
|
|
28
|
+
const push = (type, payload) => {
|
|
29
|
+
events.push(`event: ${type}\ndata: ${JSON.stringify({ type, ...payload })}\n\n`);
|
|
30
|
+
};
|
|
31
|
+
const baseResponse = {
|
|
32
|
+
id: responseId,
|
|
33
|
+
object: "response",
|
|
34
|
+
model,
|
|
35
|
+
};
|
|
36
|
+
push("response.created", { response: { ...baseResponse, status: "in_progress" } });
|
|
37
|
+
push("response.output_item.added", {
|
|
38
|
+
output_index: 0,
|
|
39
|
+
item: {
|
|
40
|
+
id: messageId,
|
|
41
|
+
type: "message",
|
|
42
|
+
role: "assistant",
|
|
43
|
+
content: [],
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
push("response.output_text.delta", {
|
|
47
|
+
output_index: 0,
|
|
48
|
+
content_index: 0,
|
|
49
|
+
delta: message,
|
|
50
|
+
});
|
|
51
|
+
push("response.output_text.done", {
|
|
52
|
+
output_index: 0,
|
|
53
|
+
content_index: 0,
|
|
54
|
+
text: message,
|
|
55
|
+
});
|
|
56
|
+
push("response.completed", {
|
|
57
|
+
response: {
|
|
58
|
+
...baseResponse,
|
|
59
|
+
status: "completed",
|
|
60
|
+
output: [
|
|
61
|
+
{
|
|
62
|
+
id: messageId,
|
|
63
|
+
type: "message",
|
|
64
|
+
role: "assistant",
|
|
65
|
+
content: [{ type: "output_text", text: message }],
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
usage: { input_tokens: 0, output_tokens: 0, total_tokens: 0 },
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
return new Response(events.join(""), {
|
|
72
|
+
status: 200,
|
|
73
|
+
headers: {
|
|
74
|
+
"Content-Type": "text/event-stream",
|
|
75
|
+
"X-Codex-Plugin-Synthetic": "true",
|
|
76
|
+
"X-Codex-Plugin-Error-Type": errorType,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
}
|
package/dist/lib/ui/ui-copy.d.ts
CHANGED
|
@@ -91,7 +91,7 @@ export declare const UI_COPY: {
|
|
|
91
91
|
readonly experimental: "Experimental";
|
|
92
92
|
readonly experimentalTitle: "Experimental";
|
|
93
93
|
readonly experimentalSubtitle: "Preview sync and backup actions before they become stable";
|
|
94
|
-
readonly experimentalHelpMenu: "Enter Select | 1 Sync | 2 Backup | 3 Guard | [ - Down | ] + Up | S Save | Q Back";
|
|
94
|
+
readonly experimentalHelpMenu: "Enter Select | 1 Sync | 2 Backup | 3 Guard | 4 Budget | [ - Down | ] + Up | S Save | Q Back";
|
|
95
95
|
readonly experimentalHelpPreview: "Enter Select | A Apply | Q Back";
|
|
96
96
|
readonly experimentalHelpStatus: "Enter Select | Q Back";
|
|
97
97
|
readonly experimentalSync: "Sync Accounts to oc-chatgpt-multi-auth";
|
|
@@ -102,6 +102,7 @@ export declare const UI_COPY: {
|
|
|
102
102
|
readonly experimentalRefreshInterval: "Refresh Guard Interval";
|
|
103
103
|
readonly experimentalDecreaseInterval: "Decrease Refresh Interval";
|
|
104
104
|
readonly experimentalIncreaseInterval: "Increase Refresh Interval";
|
|
105
|
+
readonly experimentalContextBudgetGuard: "Enable Context Budget Guard";
|
|
105
106
|
readonly backend: "Backend Controls";
|
|
106
107
|
readonly back: "Back";
|
|
107
108
|
readonly previewHeading: "Live Preview";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-copy.d.ts","sourceRoot":"","sources":["../../../lib/ui/ui-copy.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gDAqDP,MAAM,gBACF,MAAM,WACX,MAAM;kDAGiB,MAAM,WAAW,MAAM;kDAEvB,MAAM,gBAAgB,MAAM;iDAE7B,MAAM,gBAAgB,MAAM;;;;;;;;;;;;;;;;;;;;uCAyBtC,MAAM
|
|
1
|
+
{"version":3,"file":"ui-copy.d.ts","sourceRoot":"","sources":["../../../lib/ui/ui-copy.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gDAqDP,MAAM,gBACF,MAAM,WACX,MAAM;kDAGiB,MAAM,WAAW,MAAM;kDAEvB,MAAM,gBAAgB,MAAM;iDAE7B,MAAM,gBAAgB,MAAM;;;;;;;;;;;;;;;;;;;;uCAyBtC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6CAgFA,MAAM;;;;CAM1B,CAAC;AAEX;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAIpE"}
|
package/dist/lib/ui/ui-copy.js
CHANGED
|
@@ -92,7 +92,7 @@ export const UI_COPY = {
|
|
|
92
92
|
experimental: "Experimental",
|
|
93
93
|
experimentalTitle: "Experimental",
|
|
94
94
|
experimentalSubtitle: "Preview sync and backup actions before they become stable",
|
|
95
|
-
experimentalHelpMenu: "Enter Select | 1 Sync | 2 Backup | 3 Guard | [ - Down | ] + Up | S Save | Q Back",
|
|
95
|
+
experimentalHelpMenu: "Enter Select | 1 Sync | 2 Backup | 3 Guard | 4 Budget | [ - Down | ] + Up | S Save | Q Back",
|
|
96
96
|
experimentalHelpPreview: "Enter Select | A Apply | Q Back",
|
|
97
97
|
experimentalHelpStatus: "Enter Select | Q Back",
|
|
98
98
|
experimentalSync: "Sync Accounts to oc-chatgpt-multi-auth",
|
|
@@ -103,6 +103,7 @@ export const UI_COPY = {
|
|
|
103
103
|
experimentalRefreshInterval: "Refresh Guard Interval",
|
|
104
104
|
experimentalDecreaseInterval: "Decrease Refresh Interval",
|
|
105
105
|
experimentalIncreaseInterval: "Increase Refresh Interval",
|
|
106
|
+
experimentalContextBudgetGuard: "Enable Context Budget Guard",
|
|
106
107
|
backend: "Backend Controls",
|
|
107
108
|
back: "Back",
|
|
108
109
|
previewHeading: "Live Preview",
|
|
@@ -19,7 +19,7 @@ export interface UsageModelPricing {
|
|
|
19
19
|
* `test/usage-pricing-coverage.test.ts` fails if a NEW routable model appears
|
|
20
20
|
* in neither list.
|
|
21
21
|
*/
|
|
22
|
-
export declare const UNPRICED_ROUTABLE_MODELS: readonly ["gpt-5.1", "gpt-5.2-pro", "gpt-5.4-mini", "gpt-5.4-nano", "gpt-5.4-pro", "gpt-5.5-pro", "gpt-5-mini", "gpt-5-nano"];
|
|
22
|
+
export declare const UNPRICED_ROUTABLE_MODELS: readonly ["gpt-6-astra-aeon", "gpt-daybreak-blue-latest", "gpt-daybreak-red-latest", "gpt-5.1", "gpt-5.2-pro", "gpt-5.4-mini", "gpt-5.4-nano", "gpt-5.4-pro", "gpt-5.5-pro", "gpt-5-mini", "gpt-5-nano"];
|
|
23
23
|
export declare function getUsageModelPricing(model: string | null | undefined): UsageModelPricing | null;
|
|
24
24
|
export declare function estimateUsageCostUsd(model: string | null | undefined, tokens: UsageTokenCounts): number | null;
|
|
25
25
|
export declare function listUsageModelPricing(): Record<string, UsageModelPricing>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../../lib/usage/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,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;CAChC;
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../../lib/usage/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,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;CAChC;AAwED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,0MAkB3B,CAAC;AAOX,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,iBAAiB,GAAG,IAAI,CAiB1B;AAED,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,MAAM,EAAE,gBAAgB,GACtB,MAAM,GAAG,IAAI,CAqBf;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAEzE"}
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
const MODEL_PRICING = {
|
|
2
|
+
// GPT-6 Astra, published at the 2026-09-03 launch: $10 / 1M input,
|
|
3
|
+
// $50 / 1M output on the standard service tier. Fast mode is 2x standard
|
|
4
|
+
// ($20 / $100); this table has no service-tier dimension, so it prices the
|
|
5
|
+
// standard tier and a Fast-mode session is under-counted by half. No cached
|
|
6
|
+
// input rate was published, so `cachedInputUsdPerMillion` is deliberately
|
|
7
|
+
// absent: `estimateUsageCostUsd` then bills cached tokens at the full input
|
|
8
|
+
// rate, which over-states cost. That is the safe direction for a
|
|
9
|
+
// `maxCostUsd` budget — it trips early, never late.
|
|
10
|
+
"gpt-6-astra": {
|
|
11
|
+
inputUsdPerMillion: 10,
|
|
12
|
+
outputUsdPerMillion: 50,
|
|
13
|
+
reasoningUsdPerMillion: 50,
|
|
14
|
+
},
|
|
2
15
|
"gpt-5-codex": {
|
|
3
16
|
inputUsdPerMillion: 1.25,
|
|
4
17
|
outputUsdPerMillion: 10,
|
|
@@ -69,6 +82,15 @@ const MODEL_PRICING = {
|
|
|
69
82
|
* in neither list.
|
|
70
83
|
*/
|
|
71
84
|
export const UNPRICED_ROUTABLE_MODELS = [
|
|
85
|
+
// OpenAI published a rate for the Astra flagship at launch but not for the
|
|
86
|
+
// long-horizon `aeon` variant, and the Daybreak cyber models are sold under
|
|
87
|
+
// a separate controlled-access agreement with no public per-token rate.
|
|
88
|
+
// Pricing `aeon` off the flagship would be a guess on the model whose whole
|
|
89
|
+
// purpose is running for days, which is exactly where a wrong rate does the
|
|
90
|
+
// most damage.
|
|
91
|
+
"gpt-6-astra-aeon",
|
|
92
|
+
"gpt-daybreak-blue-latest",
|
|
93
|
+
"gpt-daybreak-red-latest",
|
|
72
94
|
"gpt-5.1",
|
|
73
95
|
"gpt-5.2-pro",
|
|
74
96
|
"gpt-5.4-mini",
|
|
@@ -87,6 +109,17 @@ export function getUsageModelPricing(model) {
|
|
|
87
109
|
if (!normalized) {
|
|
88
110
|
return null;
|
|
89
111
|
}
|
|
112
|
+
// `Object.hasOwn`, not a bare index. The model string arrives raw from the
|
|
113
|
+
// client (`createUsageLedgerRow` only trims it), so `constructor`,
|
|
114
|
+
// `toString` and friends reach this lookup and a bare index hands back the
|
|
115
|
+
// matching `Object.prototype` member. That object is truthy, so it is
|
|
116
|
+
// returned as a rate, and every field on it is undefined: the cost comes out
|
|
117
|
+
// `NaN` instead of `null`. A NaN cost is worse than an unknown one, because
|
|
118
|
+
// `NaN >= limit` is false, so it silently makes a `maxCostUsd` budget
|
|
119
|
+
// unenforceable rather than failing closed the way an unpriced model does.
|
|
120
|
+
if (!Object.hasOwn(MODEL_PRICING, normalized)) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
90
123
|
return MODEL_PRICING[normalized] ?? null;
|
|
91
124
|
}
|
|
92
125
|
export function estimateUsageCostUsd(model, tokens) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-multi-auth",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.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",
|
package/scripts/codex.js
CHANGED
|
@@ -574,7 +574,27 @@ async function applyForcedAccountSelection(rawArgs, env = process.env) {
|
|
|
574
574
|
}
|
|
575
575
|
|
|
576
576
|
function resolveModelFamilyForStatus(model) {
|
|
577
|
-
|
|
577
|
+
// `resolveStatusModel` hands over the raw `--model` / `-m` value or the
|
|
578
|
+
// config value verbatim, so a provider-qualified id arrives intact. Every
|
|
579
|
+
// branch below is a `startsWith`, so `openai/gpt-6` used to match none of
|
|
580
|
+
// them and return null, dropping status routing back to `activeIndex`
|
|
581
|
+
// instead of the family index. Strip the prefix once, for all of them.
|
|
582
|
+
const normalized =
|
|
583
|
+
typeof model === "string"
|
|
584
|
+
? stripProviderPrefix(model.trim()).toLowerCase()
|
|
585
|
+
: "";
|
|
586
|
+
// GPT-6 Astra and the Daybreak cyber models share the gpt-5.2 prompt family
|
|
587
|
+
// with the GPT-5.6 general tiers (see lib/request/helpers/model-map.ts
|
|
588
|
+
// MODEL_PROFILES). Daybreak has to be checked explicitly: its slug matches
|
|
589
|
+
// none of the branches below, so it used to fall through to `null` and get
|
|
590
|
+
// bucketed against no family at all.
|
|
591
|
+
if (
|
|
592
|
+
(normalized.startsWith("gpt-6") || normalized.startsWith("astra")) &&
|
|
593
|
+
!normalized.includes("codex")
|
|
594
|
+
) {
|
|
595
|
+
return "gpt-5.2";
|
|
596
|
+
}
|
|
597
|
+
if (normalized.includes("daybreak")) return "gpt-5.2";
|
|
578
598
|
// GPT-5.6 general tiers share the gpt-5.2 prompt family (see
|
|
579
599
|
// lib/request/helpers/model-map.ts MODEL_PROFILES). Check before the generic
|
|
580
600
|
// gpt-5 catch-all, which would otherwise mis-bucket them as codex.
|
|
@@ -1259,7 +1279,18 @@ const DIRECT_UNSUPPORTED_MODEL_PATTERN =
|
|
|
1259
1279
|
/['"]([^'"]+)['"]\s+model is not supported when using codex with a chatgpt account/i;
|
|
1260
1280
|
const CURRENT_CODEX_MODEL = "gpt-5.3-codex";
|
|
1261
1281
|
const LEGACY_CODEX_MODEL = "gpt-5-codex";
|
|
1282
|
+
// Mirrors the GPT-6 rows of lib/request/error-classification.ts
|
|
1283
|
+
// `DEFAULT_UNSUPPORTED_CODEX_FALLBACK_CHAIN`. This table is walked differently
|
|
1284
|
+
// from lib's: `resolveUnsupportedModelRetryTarget` keys on the model named in
|
|
1285
|
+
// the error output and falls back to the original requested model, with
|
|
1286
|
+
// `attemptedModels` accumulating, so a row's later entries ARE reachable here.
|
|
1287
|
+
// The two tables are not identical today (`gpt-5.3-codex` has a row in lib and
|
|
1288
|
+
// not here), which predates GPT-6 and is left alone; the GPT-6 rows are pinned
|
|
1289
|
+
// in parity by test/codex-model-resolution.test.ts.
|
|
1262
1290
|
const WRAPPER_UNSUPPORTED_MODEL_FALLBACK_CHAIN = {
|
|
1291
|
+
"gpt-6-astra": ["gpt-5.6-sol", "gpt-5.5"],
|
|
1292
|
+
"gpt-6-astra-aeon": ["gpt-6-astra", "gpt-5.6-sol"],
|
|
1293
|
+
"gpt-5.6-sol": ["gpt-5.5"],
|
|
1263
1294
|
"gpt-5": ["gpt-5.5"],
|
|
1264
1295
|
"gpt-5-pro": ["gpt-5.5-pro"],
|
|
1265
1296
|
"gpt-5-chat-latest": ["gpt-5.5"],
|
|
@@ -1901,6 +1932,10 @@ function hasCliAuthCredentialsStoreOverride(args) {
|
|
|
1901
1932
|
// This wrapper runs before the TypeScript build, so it cannot import that source.
|
|
1902
1933
|
const SUPPORTED_REASONING_EFFORTS_BY_MODEL = {
|
|
1903
1934
|
[CURRENT_CODEX_MODEL]: ["low", "medium", "high", "xhigh"],
|
|
1935
|
+
"gpt-6-astra": ["low", "medium", "high", "xhigh", "max", "ultra"],
|
|
1936
|
+
"gpt-6-astra-aeon": ["low", "medium", "high", "xhigh", "max", "ultra"],
|
|
1937
|
+
"gpt-daybreak-blue-latest": ["low", "medium", "high", "xhigh", "max", "ultra"],
|
|
1938
|
+
"gpt-daybreak-red-latest": ["low", "medium", "high", "xhigh", "max", "ultra"],
|
|
1904
1939
|
"gpt-5.6-sol": ["low", "medium", "high", "xhigh", "max", "ultra"],
|
|
1905
1940
|
"gpt-5.6-terra": ["low", "medium", "high", "xhigh", "max", "ultra"],
|
|
1906
1941
|
"gpt-5.6-luna": ["low", "medium", "high", "xhigh", "max"],
|
|
@@ -1960,6 +1995,18 @@ const GPT_5_6_LUNA_MODEL = "gpt-5.6-luna";
|
|
|
1960
1995
|
const GPT_5_6_FLAGSHIP_ALIAS = "gpt-5.6";
|
|
1961
1996
|
const GPT_5_6_SOL_TERRA_EFFORTS = ["low", "medium", "high", "xhigh", "max", "ultra"];
|
|
1962
1997
|
const GPT_5_6_LUNA_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
|
|
1998
|
+
// GPT-6 Astra (2026-09-03). No Sol/Terra/Luna split this generation: the
|
|
1999
|
+
// flagship plus `aeon`, a long-horizon variant. Same frontier effort ladder as
|
|
2000
|
+
// 5.6 (no `none`/`minimal`, `ultra` at the top). Bare `gpt-6` -> flagship.
|
|
2001
|
+
const GPT_6_ASTRA_MODEL = "gpt-6-astra";
|
|
2002
|
+
const GPT_6_ASTRA_AEON_MODEL = "gpt-6-astra-aeon";
|
|
2003
|
+
const GPT_6_FLAGSHIP_ALIAS = "gpt-6";
|
|
2004
|
+
const GPT_6_ASTRA_EFFORTS = ["low", "medium", "high", "xhigh", "max", "ultra"];
|
|
2005
|
+
// Daybreak cyber models from the upstream Codex catalog. `red` is the
|
|
2006
|
+
// cyber-permissive variant, `blue` the defensive one.
|
|
2007
|
+
const DAYBREAK_BLUE_MODEL = "gpt-daybreak-blue-latest";
|
|
2008
|
+
const DAYBREAK_RED_MODEL = "gpt-daybreak-red-latest";
|
|
2009
|
+
const DAYBREAK_EFFORTS = ["low", "medium", "high", "xhigh", "max", "ultra"];
|
|
1963
2010
|
const GENERAL_GPT5_VERSION_CATALOG = {
|
|
1964
2011
|
1: {
|
|
1965
2012
|
base: "gpt-5.1",
|
|
@@ -2163,6 +2210,47 @@ function seedRequestedModelAliases() {
|
|
|
2163
2210
|
GPT_5_6_SOL_MODEL,
|
|
2164
2211
|
GPT_5_6_SOL_TERRA_EFFORTS,
|
|
2165
2212
|
);
|
|
2213
|
+
addRequestedModelEffortAliases(
|
|
2214
|
+
GPT_6_ASTRA_MODEL,
|
|
2215
|
+
GPT_6_ASTRA_MODEL,
|
|
2216
|
+
GPT_6_ASTRA_EFFORTS,
|
|
2217
|
+
);
|
|
2218
|
+
addRequestedModelEffortAliases(
|
|
2219
|
+
GPT_6_ASTRA_AEON_MODEL,
|
|
2220
|
+
GPT_6_ASTRA_AEON_MODEL,
|
|
2221
|
+
GPT_6_ASTRA_EFFORTS,
|
|
2222
|
+
);
|
|
2223
|
+
addRequestedModelEffortAliases(
|
|
2224
|
+
GPT_6_FLAGSHIP_ALIAS,
|
|
2225
|
+
GPT_6_ASTRA_MODEL,
|
|
2226
|
+
GPT_6_ASTRA_EFFORTS,
|
|
2227
|
+
);
|
|
2228
|
+
addRequestedModelEffortAliases("astra", GPT_6_ASTRA_MODEL, GPT_6_ASTRA_EFFORTS);
|
|
2229
|
+
addRequestedModelEffortAliases(
|
|
2230
|
+
"astra-aeon",
|
|
2231
|
+
GPT_6_ASTRA_AEON_MODEL,
|
|
2232
|
+
GPT_6_ASTRA_EFFORTS,
|
|
2233
|
+
);
|
|
2234
|
+
addRequestedModelEffortAliases(
|
|
2235
|
+
DAYBREAK_BLUE_MODEL,
|
|
2236
|
+
DAYBREAK_BLUE_MODEL,
|
|
2237
|
+
DAYBREAK_EFFORTS,
|
|
2238
|
+
);
|
|
2239
|
+
addRequestedModelEffortAliases(
|
|
2240
|
+
DAYBREAK_RED_MODEL,
|
|
2241
|
+
DAYBREAK_RED_MODEL,
|
|
2242
|
+
DAYBREAK_EFFORTS,
|
|
2243
|
+
);
|
|
2244
|
+
addRequestedModelEffortAliases(
|
|
2245
|
+
"daybreak-blue",
|
|
2246
|
+
DAYBREAK_BLUE_MODEL,
|
|
2247
|
+
DAYBREAK_EFFORTS,
|
|
2248
|
+
);
|
|
2249
|
+
addRequestedModelEffortAliases(
|
|
2250
|
+
"daybreak-red",
|
|
2251
|
+
DAYBREAK_RED_MODEL,
|
|
2252
|
+
DAYBREAK_EFFORTS,
|
|
2253
|
+
);
|
|
2166
2254
|
addRequestedModelReasoningAliases(CURRENT_CODEX_MODEL, CURRENT_CODEX_MODEL);
|
|
2167
2255
|
addRequestedModelReasoningAliases("gpt-5.3-codex-spark", CURRENT_CODEX_MODEL);
|
|
2168
2256
|
addRequestedModelReasoningAliases(LEGACY_CODEX_MODEL, CURRENT_CODEX_MODEL);
|
|
@@ -2218,6 +2306,13 @@ function resolveStableGeneralGpt5Variant(variant) {
|
|
|
2218
2306
|
return fallback;
|
|
2219
2307
|
}
|
|
2220
2308
|
|
|
2309
|
+
// The final clause is a catch-all on the `codex` substring, matching
|
|
2310
|
+
// `resolveCodexCatalogModel` in lib/request/helpers/model-map.ts. It used to be
|
|
2311
|
+
// an exact `normalized === "codex"` check, so any codex id the explicit list
|
|
2312
|
+
// above did not name (`gpt-6-codex`, `gpt-5.7-codex`, …) resolved to nothing in
|
|
2313
|
+
// the wrapper while lib resolved it to the current codex model — a silent drift
|
|
2314
|
+
// between the two, which is exactly what test/codex-model-resolution.test.ts
|
|
2315
|
+
// exists to prevent.
|
|
2221
2316
|
function resolveCodexRequestedModel(normalized) {
|
|
2222
2317
|
if (
|
|
2223
2318
|
normalized.includes("gpt-5.1-codex-max") ||
|
|
@@ -2246,7 +2341,7 @@ function resolveCodexRequestedModel(normalized) {
|
|
|
2246
2341
|
normalized.includes("gpt 5.1 codex") ||
|
|
2247
2342
|
normalized.includes("gpt-5-codex") ||
|
|
2248
2343
|
normalized.includes("gpt 5 codex") ||
|
|
2249
|
-
normalized
|
|
2344
|
+
normalized.includes("codex")
|
|
2250
2345
|
) {
|
|
2251
2346
|
return CURRENT_CODEX_MODEL;
|
|
2252
2347
|
}
|
|
@@ -2258,6 +2353,51 @@ function resolveCodexRequestedModel(normalized) {
|
|
|
2258
2353
|
// future `gpt-5.6-terra-fast`). Without this the general GPT-5 resolver sees
|
|
2259
2354
|
// minor `6`, finds no catalog entry, and silently falls back to 5.5. Unknown
|
|
2260
2355
|
// tiers resolve to Sol, matching OpenAI's bare `gpt-5.6` alias.
|
|
2356
|
+
// Resolve GPT-6 identifiers that are not exact aliases (a dated snapshot, the
|
|
2357
|
+
// `gpt-6-astra-pro` plan tier, or a tier OpenAI adds later). Without this the
|
|
2358
|
+
// general GPT-5 resolver never matches (it needs a `gpt 5` token pair) and the
|
|
2359
|
+
// id falls through to 5.5 — running GPT-5.5 for a caller who asked for the
|
|
2360
|
+
// frontier model. `aeon` keeps its own id because it is a behaviourally
|
|
2361
|
+
// different model, not a rename. Mirrors lib/request/helpers/model-map.ts.
|
|
2362
|
+
function resolveGpt6RequestedModel(stripped) {
|
|
2363
|
+
const tokens = tokenizeRequestedModel(stripped);
|
|
2364
|
+
const gptIndex = tokens.indexOf("gpt");
|
|
2365
|
+
// `gpt6` with no separator tokenizes as one token, so the `gpt` + `6` pair
|
|
2366
|
+
// never forms; mirror lib and claim it here.
|
|
2367
|
+
const versionToken = gptIndex === -1 ? undefined : tokens[gptIndex + 1];
|
|
2368
|
+
// `gpt6` with no separator tokenizes as one token, so the `gpt` + `6` pair
|
|
2369
|
+
// never forms; mirror lib and claim it here.
|
|
2370
|
+
const isGpt6 = versionToken === "6" || tokens.includes("gpt6");
|
|
2371
|
+
// A bare `astra` token counts too: picker labels and OpenAI's own material
|
|
2372
|
+
// say "Astra" with no `gpt-6` prefix, so `Astra Pro` arrives with no version
|
|
2373
|
+
// tokens and would otherwise miss every branch and land on 5.5. Anchored so
|
|
2374
|
+
// an id naming a different GPT major version, `gpt-4-astra-x`, is not
|
|
2375
|
+
// claimed for the frontier model.
|
|
2376
|
+
const namesOtherGptVersion =
|
|
2377
|
+
versionToken !== undefined &&
|
|
2378
|
+
/^\d+$/.test(versionToken) &&
|
|
2379
|
+
versionToken !== "6";
|
|
2380
|
+
const isAstra = tokens.includes("astra") && !namesOtherGptVersion;
|
|
2381
|
+
if ((!isGpt6 && !isAstra) || tokens.includes("codex")) {
|
|
2382
|
+
return "";
|
|
2383
|
+
}
|
|
2384
|
+
if (tokens.includes("aeon")) return GPT_6_ASTRA_AEON_MODEL;
|
|
2385
|
+
return GPT_6_ASTRA_MODEL;
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2388
|
+
// Daybreak slugs carry neither a `codex` nor a `gpt 5` token, so every other
|
|
2389
|
+
// resolver declines them and they would reach the 5.5 default. An unrecognised
|
|
2390
|
+
// Daybreak id resolves to `blue`, the more restricted of the two, so a typo
|
|
2391
|
+
// cannot silently upgrade a caller into the cyber-permissive model.
|
|
2392
|
+
function resolveDaybreakRequestedModel(stripped) {
|
|
2393
|
+
const tokens = tokenizeRequestedModel(stripped);
|
|
2394
|
+
if (!tokens.includes("daybreak")) {
|
|
2395
|
+
return "";
|
|
2396
|
+
}
|
|
2397
|
+
if (tokens.includes("red")) return DAYBREAK_RED_MODEL;
|
|
2398
|
+
return DAYBREAK_BLUE_MODEL;
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2261
2401
|
function resolveGpt56RequestedModel(stripped) {
|
|
2262
2402
|
const tokens = tokenizeRequestedModel(stripped);
|
|
2263
2403
|
const gptIndex = tokens.indexOf("gpt");
|
|
@@ -2316,11 +2456,21 @@ function normalizeRequestedModel(model) {
|
|
|
2316
2456
|
return exactMatch;
|
|
2317
2457
|
}
|
|
2318
2458
|
|
|
2459
|
+
const daybreakModel = resolveDaybreakRequestedModel(stripped);
|
|
2460
|
+
if (daybreakModel) {
|
|
2461
|
+
return daybreakModel;
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2319
2464
|
const codexModel = resolveCodexRequestedModel(normalized);
|
|
2320
2465
|
if (codexModel) {
|
|
2321
2466
|
return codexModel;
|
|
2322
2467
|
}
|
|
2323
2468
|
|
|
2469
|
+
const gpt6Model = resolveGpt6RequestedModel(stripped);
|
|
2470
|
+
if (gpt6Model) {
|
|
2471
|
+
return gpt6Model;
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2324
2474
|
const gpt56Model = resolveGpt56RequestedModel(stripped);
|
|
2325
2475
|
if (gpt56Model) {
|
|
2326
2476
|
return gpt56Model;
|
|
@@ -6240,6 +6390,7 @@ export {
|
|
|
6240
6390
|
coerceReasoningEffortForModel,
|
|
6241
6391
|
resolveModelFamilyForStatus,
|
|
6242
6392
|
canonicalizeRequestedModelName,
|
|
6393
|
+
WRAPPER_UNSUPPORTED_MODEL_FALLBACK_CHAIN,
|
|
6243
6394
|
};
|
|
6244
6395
|
|
|
6245
6396
|
// Run the wrapper only when actually launched (as the `codex-multi-auth-codex`
|