codex-multi-auth 2.3.3 → 2.5.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.
Files changed (41) hide show
  1. package/.codex-plugin/plugin.json +9 -10
  2. package/README.md +423 -421
  3. package/config/README.md +1 -1
  4. package/config/codex-modern.json +139 -0
  5. package/dist/lib/constants.d.ts +19 -0
  6. package/dist/lib/constants.d.ts.map +1 -1
  7. package/dist/lib/constants.js +19 -0
  8. package/dist/lib/request/helpers/model-map.d.ts +2 -1
  9. package/dist/lib/request/helpers/model-map.d.ts.map +1 -1
  10. package/dist/lib/request/helpers/model-map.js +96 -0
  11. package/dist/lib/request/request-transformer.d.ts.map +1 -1
  12. package/dist/lib/request/request-transformer.js +26 -13
  13. package/dist/lib/runtime/rotation-proxy-state.d.ts +7 -0
  14. package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
  15. package/dist/lib/runtime/rotation-server-types.d.ts +9 -0
  16. package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
  17. package/dist/lib/runtime-rotation-proxy.d.ts +10 -0
  18. package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
  19. package/dist/lib/runtime-rotation-proxy.js +38 -1
  20. package/dist/lib/types.d.ts +8 -2
  21. package/dist/lib/types.d.ts.map +1 -1
  22. package/dist/lib/usage/pricing.d.ts.map +1 -1
  23. package/dist/lib/usage/pricing.js +18 -0
  24. package/node_modules/@codex-ai/plugin/dist/index.d.ts +2 -2
  25. package/node_modules/@codex-ai/plugin/dist/index.js +2 -2
  26. package/node_modules/@codex-ai/plugin/dist/tool.d.ts +42 -42
  27. package/node_modules/@codex-ai/plugin/dist/tool.js +29 -29
  28. package/node_modules/@codex-ai/plugin/package.json +9 -9
  29. package/node_modules/@codex-ai/sdk/dist/index.d.ts +4 -4
  30. package/node_modules/@codex-ai/sdk/dist/index.js +2 -2
  31. package/node_modules/@codex-ai/sdk/package.json +8 -8
  32. package/package.json +196 -196
  33. package/scripts/codex.js +189 -8
  34. package/vendor/codex-ai-plugin/dist/index.d.ts +2 -2
  35. package/vendor/codex-ai-plugin/dist/index.js +2 -2
  36. package/vendor/codex-ai-plugin/dist/tool.d.ts +42 -42
  37. package/vendor/codex-ai-plugin/dist/tool.js +29 -29
  38. package/vendor/codex-ai-plugin/package.json +9 -9
  39. package/vendor/codex-ai-sdk/dist/index.d.ts +4 -4
  40. package/vendor/codex-ai-sdk/dist/index.js +2 -2
  41. package/vendor/codex-ai-sdk/package.json +8 -8
package/config/README.md CHANGED
@@ -17,7 +17,7 @@ These files are optional model/provider templates for host/plugin configurations
17
17
 
18
18
  ## Defaults Included
19
19
 
20
- - Current documented OpenAI/Codex model families (`gpt-5.5`, `gpt-5.4`, and `gpt-5.3-codex`)
20
+ - Current documented OpenAI/Codex model families (`gpt-5.6-sol`/`terra`/`luna`, `gpt-5.5`, `gpt-5.4`, and `gpt-5.3-codex`)
21
21
  - `store: false`
22
22
  - `include: ["reasoning.encrypted_content"]`
23
23
  - Sensible fallback behavior for unsupported model entitlements
@@ -15,6 +15,145 @@
15
15
  "store": false
16
16
  },
17
17
  "models": {
18
+ "gpt-5.6-sol": {
19
+ "name": "GPT 5.6 Sol (OAuth)",
20
+ "limit": {
21
+ "context": 372000,
22
+ "output": 128000
23
+ },
24
+ "modalities": {
25
+ "input": [
26
+ "text",
27
+ "image"
28
+ ],
29
+ "output": [
30
+ "text"
31
+ ]
32
+ },
33
+ "variants": {
34
+ "low": {
35
+ "reasoningEffort": "low",
36
+ "reasoningSummary": "auto",
37
+ "textVerbosity": "medium"
38
+ },
39
+ "medium": {
40
+ "reasoningEffort": "medium",
41
+ "reasoningSummary": "auto",
42
+ "textVerbosity": "medium"
43
+ },
44
+ "high": {
45
+ "reasoningEffort": "high",
46
+ "reasoningSummary": "detailed",
47
+ "textVerbosity": "medium"
48
+ },
49
+ "xhigh": {
50
+ "reasoningEffort": "xhigh",
51
+ "reasoningSummary": "detailed",
52
+ "textVerbosity": "medium"
53
+ },
54
+ "max": {
55
+ "reasoningEffort": "max",
56
+ "reasoningSummary": "detailed",
57
+ "textVerbosity": "medium"
58
+ },
59
+ "ultra": {
60
+ "reasoningEffort": "ultra",
61
+ "reasoningSummary": "detailed",
62
+ "textVerbosity": "medium"
63
+ }
64
+ }
65
+ },
66
+ "gpt-5.6-terra": {
67
+ "name": "GPT 5.6 Terra (OAuth)",
68
+ "limit": {
69
+ "context": 372000,
70
+ "output": 128000
71
+ },
72
+ "modalities": {
73
+ "input": [
74
+ "text",
75
+ "image"
76
+ ],
77
+ "output": [
78
+ "text"
79
+ ]
80
+ },
81
+ "variants": {
82
+ "low": {
83
+ "reasoningEffort": "low",
84
+ "reasoningSummary": "auto",
85
+ "textVerbosity": "medium"
86
+ },
87
+ "medium": {
88
+ "reasoningEffort": "medium",
89
+ "reasoningSummary": "auto",
90
+ "textVerbosity": "medium"
91
+ },
92
+ "high": {
93
+ "reasoningEffort": "high",
94
+ "reasoningSummary": "detailed",
95
+ "textVerbosity": "medium"
96
+ },
97
+ "xhigh": {
98
+ "reasoningEffort": "xhigh",
99
+ "reasoningSummary": "detailed",
100
+ "textVerbosity": "medium"
101
+ },
102
+ "max": {
103
+ "reasoningEffort": "max",
104
+ "reasoningSummary": "detailed",
105
+ "textVerbosity": "medium"
106
+ },
107
+ "ultra": {
108
+ "reasoningEffort": "ultra",
109
+ "reasoningSummary": "detailed",
110
+ "textVerbosity": "medium"
111
+ }
112
+ }
113
+ },
114
+ "gpt-5.6-luna": {
115
+ "name": "GPT 5.6 Luna (OAuth)",
116
+ "limit": {
117
+ "context": 372000,
118
+ "output": 128000
119
+ },
120
+ "modalities": {
121
+ "input": [
122
+ "text",
123
+ "image"
124
+ ],
125
+ "output": [
126
+ "text"
127
+ ]
128
+ },
129
+ "variants": {
130
+ "low": {
131
+ "reasoningEffort": "low",
132
+ "reasoningSummary": "auto",
133
+ "textVerbosity": "medium"
134
+ },
135
+ "medium": {
136
+ "reasoningEffort": "medium",
137
+ "reasoningSummary": "auto",
138
+ "textVerbosity": "medium"
139
+ },
140
+ "high": {
141
+ "reasoningEffort": "high",
142
+ "reasoningSummary": "detailed",
143
+ "textVerbosity": "medium"
144
+ },
145
+ "xhigh": {
146
+ "reasoningEffort": "xhigh",
147
+ "reasoningSummary": "detailed",
148
+ "textVerbosity": "medium"
149
+ },
150
+ "max": {
151
+ "reasoningEffort": "max",
152
+ "reasoningSummary": "detailed",
153
+ "textVerbosity": "medium"
154
+ }
155
+ }
156
+ },
18
157
  "gpt-5.5": {
19
158
  "name": "GPT 5.5 (OAuth)",
20
159
  "limit": {
@@ -85,4 +85,23 @@ export declare const ACCOUNT_LIMITS: {
85
85
  /** Number of consecutive auth failures before auto-removing account */
86
86
  readonly MAX_AUTH_FAILURES_BEFORE_REMOVAL: 3;
87
87
  };
88
+ /**
89
+ * Every reasoning-effort level, weakest first.
90
+ *
91
+ * Single source of truth: the effort union and the model-id suffix pattern in
92
+ * `lib/request/request-transformer.ts` are both derived from this, so a new
93
+ * tier cannot be added to one and forgotten in the other.
94
+ *
95
+ * `max` and `ultra` arrived with GPT-5.6.
96
+ */
97
+ export declare const REASONING_EFFORTS: readonly ["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"];
98
+ /**
99
+ * `ultra` is selectable but never reaches the wire: Codex rewrites it to `max`
100
+ * before the request is sent (see `reasoning_effort_for_request` in
101
+ * codex-rs/core/src/client.rs). It denotes automatic subagent delegation on the
102
+ * client, not a distinct backend effort level.
103
+ */
104
+ export type ModelReasoningEffort = (typeof REASONING_EFFORTS)[number];
105
+ /** Effort levels the Responses API actually accepts. */
106
+ export type WireReasoningEffort = Exclude<ModelReasoningEffort, "ultra">;
88
107
  //# sourceMappingURL=constants.d.ts.map
@@ -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;;;;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"}
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;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,gFASpB,CAAC;AAEX;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,wDAAwD;AACxD,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC"}
@@ -85,3 +85,22 @@ export const ACCOUNT_LIMITS = {
85
85
  /** Number of consecutive auth failures before auto-removing account */
86
86
  MAX_AUTH_FAILURES_BEFORE_REMOVAL: 3,
87
87
  };
88
+ /**
89
+ * Every reasoning-effort level, weakest first.
90
+ *
91
+ * Single source of truth: the effort union and the model-id suffix pattern in
92
+ * `lib/request/request-transformer.ts` are both derived from this, so a new
93
+ * tier cannot be added to one and forgotten in the other.
94
+ *
95
+ * `max` and `ultra` arrived with GPT-5.6.
96
+ */
97
+ export const REASONING_EFFORTS = [
98
+ "none",
99
+ "minimal",
100
+ "low",
101
+ "medium",
102
+ "high",
103
+ "xhigh",
104
+ "max",
105
+ "ultra",
106
+ ];
@@ -6,7 +6,8 @@
6
6
  * tool-surface metadata so routing logic stays consistent across the request
7
7
  * transformer, prompt selection, and CLI diagnostics.
8
8
  */
9
- export type ModelReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
9
+ import type { ModelReasoningEffort, WireReasoningEffort } from "../../constants.js";
10
+ export type { ModelReasoningEffort, WireReasoningEffort };
10
11
  export type PromptModelFamily = "gpt-5-codex" | "codex-max" | "codex" | "gpt-5.2" | "gpt-5.1";
11
12
  /**
12
13
  * Model family type for prompt selection
@@ -1 +1 @@
1
- {"version":3,"file":"model-map.d.ts","sourceRoot":"","sources":["../../../../lib/request/helpers/model-map.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,oBAAoB,GAC7B,MAAM,GACN,SAAS,GACT,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAC1B,aAAa,GACb,WAAW,GACX,OAAO,GACP,SAAS,GACT,SAAS,CAAC;AAEb;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,iBAAiB,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,WAAW,EAMvC,CAAC;AAEX,MAAM,WAAW,iBAAiB;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,iBAAiB,CAAC;IAChC,sBAAsB,EAAE,oBAAoB,CAAC;IAC7C,yBAAyB,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC3D,YAAY,EAAE,iBAAiB,CAAC;CAChC;AA6CD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,aAAa,YAAY,CAAC;AAKvC,eAAO,MAAM,uBAAuB,kFAM1B,CAAC;AA4CX;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAqF9C,CAAC;AAEX,QAAA,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,CAAC;AAoE7C,OAAO,EAAE,SAAS,EAAE,CAAC;AA6IrB;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQtE;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAsBxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAavE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,iBAAiB,CAEjF;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAErD"}
1
+ {"version":3,"file":"model-map.d.ts","sourceRoot":"","sources":["../../../../lib/request/helpers/model-map.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EACX,oBAAoB,EACpB,mBAAmB,EACnB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,CAAC;AAE1D,MAAM,MAAM,iBAAiB,GAC1B,aAAa,GACb,WAAW,GACX,OAAO,GACP,SAAS,GACT,SAAS,CAAC;AAEb;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,iBAAiB,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,WAAW,EAMvC,CAAC;AAEX,MAAM,WAAW,iBAAiB;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,iBAAiB,CAAC;IAChC,sBAAsB,EAAE,oBAAoB,CAAC;IAC7C,yBAAyB,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC3D,YAAY,EAAE,iBAAiB,CAAC;CAChC;AA6CD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,aAAa,YAAY,CAAC;AAKvC,eAAO,MAAM,uBAAuB,kFAM1B,CAAC;AA4EX;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CA6G9C,CAAC;AAEX,QAAA,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,CAAC;AAqG7C,OAAO,EAAE,SAAS,EAAE,CAAC;AAoKrB;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQtE;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CA2BxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAavE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,iBAAiB,CAEjF;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAErD"}
@@ -65,6 +65,33 @@ export const QUOTA_PROBE_MODEL_CHAIN = [
65
65
  "gpt-5-codex",
66
66
  ];
67
67
  const LEGACY_CODEX_MODEL = "gpt-5-codex";
68
+ /**
69
+ * GPT-5.6 tiers, per the upstream Codex catalog
70
+ * (openai/codex `codex-rs/models-manager/models.json`).
71
+ *
72
+ * Sol and Terra expose `ultra`; Luna stops at `max`. No tier accepts `none` or
73
+ * `minimal`, so those aliases are deliberately never generated for them.
74
+ */
75
+ const GPT_5_6_SOL_MODEL = "gpt-5.6-sol";
76
+ const GPT_5_6_TERRA_MODEL = "gpt-5.6-terra";
77
+ const GPT_5_6_LUNA_MODEL = "gpt-5.6-luna";
78
+ /** Bare `gpt-5.6` is OpenAI's documented alias for the flagship (Sol) tier. */
79
+ const GPT_5_6_FLAGSHIP_ALIAS = "gpt-5.6";
80
+ const GPT_5_6_SOL_TERRA_EFFORTS = [
81
+ "low",
82
+ "medium",
83
+ "high",
84
+ "xhigh",
85
+ "max",
86
+ "ultra",
87
+ ];
88
+ const GPT_5_6_LUNA_EFFORTS = [
89
+ "low",
90
+ "medium",
91
+ "high",
92
+ "xhigh",
93
+ "max",
94
+ ];
68
95
  const GPT_5_5_CANONICAL_MODEL = "gpt-5.5";
69
96
  const GPT_5_5_PRO_CANONICAL_MODEL = "gpt-5.5-pro";
70
97
  const GPT_5_5_RELEASE_MODEL = "gpt-5.5-2026-04-23";
@@ -143,6 +170,30 @@ export const MODEL_PROFILES = {
143
170
  supportedReasoningEfforts: ["medium"],
144
171
  capabilities: TOOL_CAPABILITIES.compactOnly,
145
172
  },
173
+ // GPT-5.6 ships its base instructions inline in the upstream model catalog
174
+ // rather than as a `gpt_5_6_prompt.md`, so these stay on the GPT-5.2 prompt
175
+ // family alongside the other post-5.2 general models.
176
+ [GPT_5_6_SOL_MODEL]: {
177
+ normalizedModel: GPT_5_6_SOL_MODEL,
178
+ promptFamily: "gpt-5.2",
179
+ defaultReasoningEffort: "low",
180
+ supportedReasoningEfforts: GPT_5_6_SOL_TERRA_EFFORTS,
181
+ capabilities: TOOL_CAPABILITIES.full,
182
+ },
183
+ [GPT_5_6_TERRA_MODEL]: {
184
+ normalizedModel: GPT_5_6_TERRA_MODEL,
185
+ promptFamily: "gpt-5.2",
186
+ defaultReasoningEffort: "medium",
187
+ supportedReasoningEfforts: GPT_5_6_SOL_TERRA_EFFORTS,
188
+ capabilities: TOOL_CAPABILITIES.full,
189
+ },
190
+ [GPT_5_6_LUNA_MODEL]: {
191
+ normalizedModel: GPT_5_6_LUNA_MODEL,
192
+ promptFamily: "gpt-5.2",
193
+ defaultReasoningEffort: "medium",
194
+ supportedReasoningEfforts: GPT_5_6_LUNA_EFFORTS,
195
+ capabilities: TOOL_CAPABILITIES.full,
196
+ },
146
197
  [GPT_5_5_CANONICAL_MODEL]: {
147
198
  normalizedModel: GPT_5_5_CANONICAL_MODEL,
148
199
  promptFamily: "gpt-5.2",
@@ -203,6 +254,24 @@ function addReasoningAliases(alias, normalizedModel) {
203
254
  addAlias(`${alias}-${variant}`, normalizedModel);
204
255
  }
205
256
  }
257
+ /**
258
+ * Register a model plus one alias per effort it actually supports.
259
+ *
260
+ * Unlike `addReasoningAliases`, this does not assume the global variant list:
261
+ * GPT-5.6 rejects `none`/`minimal` and only Sol/Terra accept `ultra`.
262
+ */
263
+ function addEffortAliases(alias, normalizedModel, efforts) {
264
+ addAlias(alias, normalizedModel);
265
+ for (const effort of efforts) {
266
+ addAlias(`${alias}-${effort}`, normalizedModel);
267
+ }
268
+ }
269
+ function addGpt56Aliases() {
270
+ addEffortAliases(GPT_5_6_SOL_MODEL, GPT_5_6_SOL_MODEL, GPT_5_6_SOL_TERRA_EFFORTS);
271
+ addEffortAliases(GPT_5_6_TERRA_MODEL, GPT_5_6_TERRA_MODEL, GPT_5_6_SOL_TERRA_EFFORTS);
272
+ addEffortAliases(GPT_5_6_LUNA_MODEL, GPT_5_6_LUNA_MODEL, GPT_5_6_LUNA_EFFORTS);
273
+ addEffortAliases(GPT_5_6_FLAGSHIP_ALIAS, GPT_5_6_SOL_MODEL, GPT_5_6_SOL_TERRA_EFFORTS);
274
+ }
206
275
  function addGeneralAliases() {
207
276
  addReasoningAliases(GPT_5_5_CANONICAL_MODEL, GPT_5_5_CANONICAL_MODEL);
208
277
  addReasoningAliases(GPT_5_5_RELEASE_MODEL, GPT_5_5_CANONICAL_MODEL);
@@ -240,6 +309,7 @@ function addCodexAliases() {
240
309
  }
241
310
  addCodexAliases();
242
311
  addGeneralAliases();
312
+ addGpt56Aliases();
243
313
  export { MODEL_MAP };
244
314
  function stripProviderPrefix(modelId) {
245
315
  return modelId.includes("/") ? (modelId.split("/").pop() ?? modelId) : modelId;
@@ -306,6 +376,28 @@ function resolveCodexCatalogModel(modelId) {
306
376
  }
307
377
  return undefined;
308
378
  }
379
+ /**
380
+ * Resolve GPT-5.6 identifiers that are not exact aliases (for example a future
381
+ * `gpt-5.6-terra-fast`).
382
+ *
383
+ * Without this, the general GPT-5 resolver sees minor `6`, finds no catalog
384
+ * entry, and silently falls back to the stable 5.5 model — running a different
385
+ * model than the caller asked for. Unrecognised tiers resolve to Sol, matching
386
+ * OpenAI's bare `gpt-5.6` alias.
387
+ */
388
+ function resolveGpt56CatalogModel(modelId) {
389
+ const tokens = tokenizeModelId(modelId);
390
+ const gptIndex = tokens.indexOf("gpt");
391
+ const isGpt56 = gptIndex !== -1 && tokens[gptIndex + 1] === "5" && tokens[gptIndex + 2] === "6";
392
+ if (!isGpt56 || tokens.includes("codex")) {
393
+ return undefined;
394
+ }
395
+ if (tokens.includes("terra"))
396
+ return GPT_5_6_TERRA_MODEL;
397
+ if (tokens.includes("luna"))
398
+ return GPT_5_6_LUNA_MODEL;
399
+ return GPT_5_6_SOL_MODEL;
400
+ }
309
401
  function resolveGeneralGpt5CatalogModel(modelId) {
310
402
  const tokens = tokenizeModelId(modelId);
311
403
  const gptIndex = tokens.indexOf("gpt");
@@ -378,6 +470,10 @@ export function resolveNormalizedModel(model) {
378
470
  if (codexCatalogModel) {
379
471
  return codexCatalogModel;
380
472
  }
473
+ const gpt56CatalogModel = resolveGpt56CatalogModel(modelId);
474
+ if (gpt56CatalogModel) {
475
+ return gpt56CatalogModel;
476
+ }
381
477
  const generalGpt5CatalogModel = resolveGeneralGpt5CatalogModel(modelId);
382
478
  if (generalGpt5CatalogModel) {
383
479
  return generalGpt5CatalogModel;
@@ -1 +1 @@
1
- {"version":3,"file":"request-transformer.d.ts","sourceRoot":"","sources":["../../../lib/request/request-transformer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"request-transformer.d.ts","sourceRoot":"","sources":["../../../lib/request/request-transformer.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { logDebug, logWarn } from "../logger.js";
2
2
  import { TOOL_REMAP_MESSAGE } from "../prompts/codex.js";
3
3
  import { CODEX_HOST_BRIDGE } from "../prompts/codex-host-bridge.js";
4
4
  import { getHostCodexPrompt } from "../prompts/host-codex-prompt.js";
5
+ import { REASONING_EFFORTS, } from "../constants.js";
5
6
  import { getModelCapabilities, getModelProfile, resolveNormalizedModel, } from "./helpers/model-map.js";
6
7
  import { filterHostSystemPromptsWithCachedPrompt, normalizeOrphanedToolOutputs, injectMissingToolOutputs, } from "./helpers/input-utils.js";
7
8
  import { cleanupToolDefinitions } from "./helpers/tool-utils.js";
@@ -19,6 +20,18 @@ export { isHostSystemPrompt, filterHostSystemPromptsWithCachedPrompt, } from "./
19
20
  export function normalizeModel(model) {
20
21
  return resolveNormalizedModel(model);
21
22
  }
23
+ /**
24
+ * Matches a trailing reasoning-effort suffix on a model id.
25
+ *
26
+ * The alternation is derived from `REASONING_EFFORTS` so a new tier cannot be
27
+ * added to the union and silently forgotten here.
28
+ *
29
+ * `max` is split into its own alternative because it needs a lookbehind:
30
+ * `gpt-5.1-codex-max` is a model id that ends in `-max`, not Codex at `max`
31
+ * effort, and stripping it would reroute the request. The guard cannot wrap the
32
+ * whole group -- `gpt-5-codex-low` must still parse `low`.
33
+ */
34
+ const VARIANT_SUFFIX_PATTERN = new RegExp(`(?:-(${REASONING_EFFORTS.filter((effort) => effort !== "max").join("|")})|(?<!codex)-(max))$`, "i");
22
35
  /**
23
36
  * Extract configuration for a specific model
24
37
  * Merges global options with model-specific options (model-specific takes precedence)
@@ -32,21 +45,13 @@ export function getModelConfig(modelName, userConfig = { global: {}, models: {}
32
45
  const stripProviderPrefix = (name) => name.includes("/") ? (name.split("/").pop() ?? name) : name;
33
46
  const getVariantFromModelName = (name) => {
34
47
  const stripped = stripProviderPrefix(name).toLowerCase();
35
- const match = stripped.match(/-(none|minimal|low|medium|high|xhigh)$/);
48
+ const match = stripped.match(VARIANT_SUFFIX_PATTERN);
36
49
  if (!match)
37
50
  return undefined;
38
- const variant = match[1];
39
- if (variant === "none" ||
40
- variant === "minimal" ||
41
- variant === "low" ||
42
- variant === "medium" ||
43
- variant === "high" ||
44
- variant === "xhigh") {
45
- return variant;
46
- }
47
- return undefined;
51
+ const variant = match[1] ?? match[2];
52
+ return REASONING_EFFORTS.find((effort) => effort === variant);
48
53
  };
49
- const removeVariantSuffix = (name) => stripProviderPrefix(name).replace(/-(none|minimal|low|medium|high|xhigh)$/i, "");
54
+ const removeVariantSuffix = (name) => stripProviderPrefix(name).replace(VARIANT_SUFFIX_PATTERN, "");
50
55
  const findModelEntry = (candidates) => {
51
56
  for (const key of candidates) {
52
57
  const entry = modelMap[key];
@@ -324,7 +329,11 @@ export function getReasoningConfig(modelName, userConfig = {}) {
324
329
  const profile = getModelProfile(modelName);
325
330
  const defaultEffort = profile.defaultReasoningEffort;
326
331
  const requestedEffort = userConfig.reasoningEffort ?? defaultEffort;
327
- const effort = coerceReasoningEffort(profile.normalizedModel, requestedEffort, profile.supportedReasoningEfforts, defaultEffort);
332
+ const coercedEffort = coerceReasoningEffort(profile.normalizedModel, requestedEffort, profile.supportedReasoningEfforts, defaultEffort);
333
+ // `ultra` is a client-side tier: upstream Codex rewrites Ultra -> Max in
334
+ // `reasoning_effort_for_request` before the request leaves the client, so the
335
+ // API never sees it. Mirror that here rather than sending a value it rejects.
336
+ const effort = coercedEffort === "ultra" ? "max" : coercedEffort;
328
337
  const summary = sanitizeReasoningSummary(userConfig.reasoningSummary);
329
338
  return {
330
339
  effort,
@@ -338,6 +347,10 @@ const REASONING_FALLBACKS = {
338
347
  medium: ["medium", "low", "high", "minimal", "none", "xhigh"],
339
348
  high: ["high", "medium", "xhigh", "low", "minimal", "none"],
340
349
  xhigh: ["xhigh", "high", "medium", "low", "minimal", "none"],
350
+ // `max` and `ultra` only exist on GPT-5.6. Step down one rung at a time so a
351
+ // request against a pre-5.6 model lands on that model's strongest tier.
352
+ max: ["max", "xhigh", "high", "medium", "low", "minimal", "none"],
353
+ ultra: ["ultra", "max", "xhigh", "high", "medium", "low", "minimal", "none"],
341
354
  };
342
355
  function coerceReasoningEffort(modelName, effort, supportedEfforts, defaultEffort) {
343
356
  if (supportedEfforts.includes(effort)) {
@@ -29,6 +29,13 @@ export interface RotationProxyStateInit {
29
29
  quotaRemainingPercentThreshold: number;
30
30
  sessionAffinityStore: SessionAffinityStore | null;
31
31
  lastObservedAffinityGeneration: number;
32
+ /**
33
+ * Ephemeral per-invocation account pin (0-based) or null. When a number,
34
+ * the request handler treats it exactly like a manual `switch` pin — a
35
+ * deterministic, fail-hard selection — but it is never written to disk, so
36
+ * concurrent invocations with different pins never interfere (issue #623).
37
+ */
38
+ forcedAccountIndex: number | null;
32
39
  }
33
40
  /**
34
41
  * Mutable rotation-loop state shared by every request of one proxy instance.
@@ -1 +1 @@
1
- {"version":3,"file":"rotation-proxy-state.d.ts","sourceRoot":"","sources":["../../../lib/runtime/rotation-proxy-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKhD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACtC,oBAAoB,EAAE,cAAc,CAAC;IACrC,gBAAgB,EAAE,SAAS,GAAG,QAAQ,CAAC;IACvC,kBAAkB,EAAE,QAAQ,GAAG,YAAY,CAAC;IAC5C,SAAS,EAAE,OAAO,KAAK,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,2BAA2B,EAAE,MAAM,CAAC;IACpC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,yBAAyB,EAAE,MAAM,CAAC;IAClC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,8BAA8B,EAAE,MAAM,CAAC;IACvC,oBAAoB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClD,8BAA8B,EAAE,MAAM,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAmB,SAAQ,sBAAsB;IACjE,QAAQ,CAAC,oBAAoB,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAC5C,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yBAAyB,EAAE,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACjE,wBAAwB,EAAE,MAAM,CAAC;CACjC;AAID,gBAAgB;AAChB,wBAAgB,wBAAwB,CACvC,IAAI,EAAE,sBAAsB,GAC1B,kBAAkB,CAuBpB;AAED,gBAAgB;AAChB,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,kBAAkB,GACvB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAkDhC"}
1
+ {"version":3,"file":"rotation-proxy-state.d.ts","sourceRoot":"","sources":["../../../lib/runtime/rotation-proxy-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKhD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACtC,oBAAoB,EAAE,cAAc,CAAC;IACrC,gBAAgB,EAAE,SAAS,GAAG,QAAQ,CAAC;IACvC,kBAAkB,EAAE,QAAQ,GAAG,YAAY,CAAC;IAC5C,SAAS,EAAE,OAAO,KAAK,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,2BAA2B,EAAE,MAAM,CAAC;IACpC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,yBAAyB,EAAE,MAAM,CAAC;IAClC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,8BAA8B,EAAE,MAAM,CAAC;IACvC,oBAAoB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClD,8BAA8B,EAAE,MAAM,CAAC;IACvC;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAmB,SAAQ,sBAAsB;IACjE,QAAQ,CAAC,oBAAoB,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAC5C,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yBAAyB,EAAE,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACjE,wBAAwB,EAAE,MAAM,CAAC;CACjC;AAID,gBAAgB;AAChB,wBAAgB,wBAAwB,CACvC,IAAI,EAAE,sBAAsB,GAC1B,kBAAkB,CAuBpB;AAED,gBAAgB;AAChB,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,kBAAkB,GACvB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAkDhC"}
@@ -32,6 +32,15 @@ export interface RuntimeRotationProxyOptions {
32
32
  maxRequestBodyBytes?: number;
33
33
  fetchTimeoutMs?: number;
34
34
  streamStallTimeoutMs?: number;
35
+ /**
36
+ * Ephemeral, per-instance account pin (0-based) for a single invocation
37
+ * (issue #623: `codex-multi-auth-codex --account`). When set, this proxy
38
+ * routes every request to exactly this account and never rotates, without
39
+ * touching the persisted `switch` pin on disk. Falls back to
40
+ * `CODEX_MULTI_AUTH_FORCE_ACCOUNT_INDEX` in the environment when omitted so
41
+ * the value survives the launcher -> detached app-helper process boundary.
42
+ */
43
+ forcedAccountIndex?: number | null;
35
44
  }
36
45
  export interface RequestContext {
37
46
  body: Buffer;
@@ -1 +1 @@
1
- {"version":3,"file":"rotation-server-types.d.ts","sourceRoot":"","sources":["../../../lib/runtime/rotation-server-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,0BAA0B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,SAAS,EAAE,MAAM,0BAA0B,CAAC;CAC5C;AAED,MAAM,WAAW,0BAA0B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,2BAA2B;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,MAAM,gBAAgB,GACzB,YAAY,GACZ,cAAc,GACd,eAAe,GACf,cAAc,GACd,QAAQ,GACR,aAAa,GACb,YAAY,CAAC;AAChB,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,WAAW,8BAA8B;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"rotation-server-types.d.ts","sourceRoot":"","sources":["../../../lib/runtime/rotation-server-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,0BAA0B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,SAAS,EAAE,MAAM,0BAA0B,CAAC;CAC5C;AAED,MAAM,WAAW,0BAA0B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,2BAA2B;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,MAAM,gBAAgB,GACzB,YAAY,GACZ,cAAc,GACd,eAAe,GACf,cAAc,GACd,QAAQ,GACR,aAAa,GACb,YAAY,CAAC;AAChB,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,WAAW,8BAA8B;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CAClB"}
@@ -5,5 +5,15 @@ export type { PinnedUnavailableErrorBody } from "./request/rate-limit-decision.j
5
5
  export { chooseAccount } from "./runtime/rotation-account-selection.js";
6
6
  export { maybeInvalidateAffinityFromDisk, readPinnedAccountIndexFromDisk, readStorageMetaFromDisk, resetPinCacheForTesting, } from "./runtime/rotation-storage-meta.js";
7
7
  export type { StorageMeta } from "./runtime/rotation-storage-meta.js";
8
+ /**
9
+ * Coerce a forced-account pin from an option (number) or the launcher's env
10
+ * string into a normalized 0-based index, or null when absent/invalid. Invalid
11
+ * or negative values collapse to null so an out-of-range env value can never
12
+ * throw at proxy startup; chooseAccount reports the deterministic
13
+ * pinned-account failure per-request instead. Exported for unit tests.
14
+ *
15
+ * @internal
16
+ */
17
+ export declare function normalizeForcedAccountIndex(value: number | string | null | undefined): number | null;
8
18
  export declare function startRuntimeRotationProxy(options: RuntimeRotationProxyOptions): Promise<RuntimeRotationProxyServer>;
9
19
  //# sourceMappingURL=runtime-rotation-proxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-rotation-proxy.d.ts","sourceRoot":"","sources":["../../lib/runtime-rotation-proxy.ts"],"names":[],"mappings":"AAwEA,OAAO,KAAK,EAKX,2BAA2B,EAC3B,0BAA0B,EAE1B,MAAM,oCAAoC,CAAC;AAe5C,YAAY,EACX,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,GAC1B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACN,+BAA+B,EAC/B,0BAA0B,GAC1B,MAAM,kCAAkC,CAAC;AAC1C,YAAY,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EACN,+BAA+B,EAC/B,8BAA8B,EAC9B,uBAAuB,EACvB,uBAAuB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AA6etE,wBAAsB,yBAAyB,CAC9C,OAAO,EAAE,2BAA2B,GAClC,OAAO,CAAC,0BAA0B,CAAC,CA+IrC"}
1
+ {"version":3,"file":"runtime-rotation-proxy.d.ts","sourceRoot":"","sources":["../../lib/runtime-rotation-proxy.ts"],"names":[],"mappings":"AAwEA,OAAO,KAAK,EAKX,2BAA2B,EAC3B,0BAA0B,EAE1B,MAAM,oCAAoC,CAAC;AAe5C,YAAY,EACX,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,GAC1B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACN,+BAA+B,EAC/B,0BAA0B,GAC1B,MAAM,kCAAkC,CAAC;AAC1C,YAAY,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EACN,+BAA+B,EAC/B,8BAA8B,EAC9B,uBAAuB,EACvB,uBAAuB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AA6etE;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAC1C,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,MAAM,GAAG,IAAI,CAUf;AAED,wBAAsB,yBAAyB,CAC9C,OAAO,EAAE,2BAA2B,GAClC,OAAO,CAAC,0BAA0B,CAAC,CA6JrC"}
@@ -420,6 +420,25 @@ function writePoolExhausted(params) {
420
420
  },
421
421
  });
422
422
  }
423
+ /**
424
+ * Coerce a forced-account pin from an option (number) or the launcher's env
425
+ * string into a normalized 0-based index, or null when absent/invalid. Invalid
426
+ * or negative values collapse to null so an out-of-range env value can never
427
+ * throw at proxy startup; chooseAccount reports the deterministic
428
+ * pinned-account failure per-request instead. Exported for unit tests.
429
+ *
430
+ * @internal
431
+ */
432
+ export function normalizeForcedAccountIndex(value) {
433
+ if (value === null || value === undefined) {
434
+ return null;
435
+ }
436
+ const parsed = typeof value === "number" ? value : Number.parseInt(value.trim(), 10);
437
+ if (!Number.isInteger(parsed) || parsed < 0) {
438
+ return null;
439
+ }
440
+ return parsed;
441
+ }
423
442
  export async function startRuntimeRotationProxy(options) {
424
443
  const pluginConfig = loadPluginConfig();
425
444
  const activeAccountManager = options.accountManager ?? (await AccountManager.loadFromDisk());
@@ -455,6 +474,17 @@ export async function startRuntimeRotationProxy(options) {
455
474
  throw new CodexValidationError("Runtime rotation proxy requires a clientApiKey.", { field: "clientApiKey", expected: "a non-empty string" });
456
475
  }
457
476
  const now = options.now ?? Date.now;
477
+ // Ephemeral per-invocation pin (issue #623). Prefer an explicit option (used by
478
+ // tests and the in-process inline proxy); otherwise fall back to the numeric env
479
+ // the launcher publishes, which is how the value reaches a detached app-helper
480
+ // process. `??` means both `undefined` and an explicit `null` option defer to the
481
+ // env, so "no option" and "no pin" behave identically. Invalid/negative values
482
+ // are ignored (treated as "no forced pin") rather than throwing — the launcher
483
+ // already validated the selector, and an out-of-range index is surfaced
484
+ // per-request as a deterministic pinned-account failure by chooseAccount rather
485
+ // than crashing proxy startup.
486
+ const forcedAccountIndex = normalizeForcedAccountIndex(options.forcedAccountIndex ??
487
+ process.env.CODEX_MULTI_AUTH_FORCE_ACCOUNT_INDEX);
458
488
  const tokenRefreshSkewMs = getTokenRefreshSkewMs(pluginConfig);
459
489
  const networkErrorCooldownMs = getNetworkErrorCooldownMs(pluginConfig);
460
490
  const serverErrorCooldownMs = getServerErrorCooldownMs(pluginConfig);
@@ -500,6 +530,7 @@ export async function startRuntimeRotationProxy(options) {
500
530
  quotaRemainingPercentThreshold,
501
531
  sessionAffinityStore,
502
532
  lastObservedAffinityGeneration,
533
+ forcedAccountIndex,
503
534
  });
504
535
  const server = createServer((req, res) => {
505
536
  void handleRequest(state, req, res);
@@ -669,7 +700,13 @@ async function handleRequestInner(state, req, res, traceId) {
669
700
  // account. The proxy itself never bumps the generation, so its own
670
701
  // debounced disk writes do not clear affinity. See issue #474.
671
702
  const storageMeta = readStorageMetaFromDisk();
672
- const pinnedIndex = storageMeta.pinnedAccountIndex;
703
+ // The ephemeral --account pin (issue #623) takes precedence over the
704
+ // persisted `switch` pin for this invocation, without ever mutating disk
705
+ // state. Use `??` (not `||`) so a forced index of 0 is honored. When set,
706
+ // everything downstream — deterministic pick, no cursor advance, no
707
+ // stale-state recovery, the `codex_pinned_account_unavailable` failure —
708
+ // applies unchanged because it all keys off `pinnedIndex` / `isPinned`.
709
+ const pinnedIndex = state.forcedAccountIndex ?? storageMeta.pinnedAccountIndex;
673
710
  const isPinned = typeof pinnedIndex === "number";
674
711
  if (storageMeta.affinityGeneration > state.lastObservedAffinityGeneration) {
675
712
  state.sessionAffinityStore?.clearAll();
@@ -1,4 +1,5 @@
1
1
  import type { Auth, Provider, Model } from "@codex-ai/sdk";
2
+ import type { ModelReasoningEffort, WireReasoningEffort } from "./constants.js";
2
3
  export type { PluginConfigFromSchema as PluginConfig, AccountIdSourceFromSchema as AccountIdSource, TokenSuccessFromSchema as TokenSuccess, TokenFailureFromSchema as TokenFailure, TokenResultFromSchema as TokenResult, TokenFailureReasonFromSchema as TokenFailureReason, } from "./schemas.js";
3
4
  export interface UserConfig {
4
5
  global: ConfigOptions;
@@ -13,7 +14,8 @@ export interface UserConfig {
13
14
  };
14
15
  }
15
16
  export interface ConfigOptions {
16
- reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
17
+ /** `ultra` is accepted here but always resolves to `max` before the request. */
18
+ reasoningEffort?: ModelReasoningEffort;
17
19
  reasoningSummary?: "auto" | "concise" | "detailed" | "off" | "on";
18
20
  textVerbosity?: "low" | "medium" | "high";
19
21
  promptCacheRetention?: PromptCacheRetention;
@@ -21,7 +23,11 @@ export interface ConfigOptions {
21
23
  }
22
24
  export type PromptCacheRetention = "5m" | "1h" | "24h" | "7d" | (string & {});
23
25
  export interface ReasoningConfig {
24
- effort: "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
26
+ /**
27
+ * Effort as sent to the API. `ultra` is absent by construction: it is a
28
+ * client-side tier that always resolves to `max` before the request is built.
29
+ */
30
+ effort: WireReasoningEffort;
25
31
  summary: "auto" | "concise" | "detailed";
26
32
  }
27
33
  export interface ToolParametersSchema {