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.
Files changed (272) hide show
  1. package/.codex-plugin/plugin.json +1 -1
  2. package/README.md +22 -1
  3. package/config/README.md +2 -2
  4. package/config/codex-legacy.json +109 -184
  5. package/config/codex-modern.json +44 -114
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +10 -4
  8. package/dist/lib/account-policy.d.ts +4 -0
  9. package/dist/lib/account-policy.d.ts.map +1 -1
  10. package/dist/lib/account-policy.js +8 -0
  11. package/dist/lib/accounts/rate-limits.d.ts.map +1 -1
  12. package/dist/lib/accounts/rate-limits.js +2 -0
  13. package/dist/lib/accounts.d.ts +21 -3
  14. package/dist/lib/accounts.d.ts.map +1 -1
  15. package/dist/lib/accounts.js +229 -17
  16. package/dist/lib/api-route-store.d.ts +24 -0
  17. package/dist/lib/api-route-store.d.ts.map +1 -0
  18. package/dist/lib/api-route-store.js +145 -0
  19. package/dist/lib/auth/account-access.d.ts +115 -0
  20. package/dist/lib/auth/account-access.d.ts.map +1 -0
  21. package/dist/lib/auth/account-access.js +214 -0
  22. package/dist/lib/auth/token-utils.d.ts +54 -1
  23. package/dist/lib/auth/token-utils.d.ts.map +1 -1
  24. package/dist/lib/auth/token-utils.js +92 -7
  25. package/dist/lib/cli.d.ts +1 -1
  26. package/dist/lib/cli.d.ts.map +1 -1
  27. package/dist/lib/cli.js +4 -0
  28. package/dist/lib/codex-cli/state.d.ts +7 -0
  29. package/dist/lib/codex-cli/state.d.ts.map +1 -1
  30. package/dist/lib/codex-cli/state.js +18 -0
  31. package/dist/lib/codex-cli/writer.d.ts.map +1 -1
  32. package/dist/lib/codex-cli/writer.js +60 -8
  33. package/dist/lib/codex-manager/account-manager-commands.d.ts.map +1 -1
  34. package/dist/lib/codex-manager/account-manager-commands.js +1 -0
  35. package/dist/lib/codex-manager/account-pool-write.d.ts +3 -1
  36. package/dist/lib/codex-manager/account-pool-write.d.ts.map +1 -1
  37. package/dist/lib/codex-manager/account-pool-write.js +4 -0
  38. package/dist/lib/codex-manager/api-login-menu.d.ts +14 -0
  39. package/dist/lib/codex-manager/api-login-menu.d.ts.map +1 -0
  40. package/dist/lib/codex-manager/api-login-menu.js +224 -0
  41. package/dist/lib/codex-manager/commands/account.d.ts.map +1 -1
  42. package/dist/lib/codex-manager/commands/account.js +27 -0
  43. package/dist/lib/codex-manager/commands/best.d.ts.map +1 -1
  44. package/dist/lib/codex-manager/commands/best.js +6 -2
  45. package/dist/lib/codex-manager/commands/check.d.ts +7 -1
  46. package/dist/lib/codex-manager/commands/check.d.ts.map +1 -1
  47. package/dist/lib/codex-manager/commands/check.js +24 -3
  48. package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
  49. package/dist/lib/codex-manager/commands/forecast.js +5 -1
  50. package/dist/lib/codex-manager/commands/report.d.ts.map +1 -1
  51. package/dist/lib/codex-manager/commands/report.js +5 -1
  52. package/dist/lib/codex-manager/commands/resets.d.ts +2 -0
  53. package/dist/lib/codex-manager/commands/resets.d.ts.map +1 -0
  54. package/dist/lib/codex-manager/commands/resets.js +67 -0
  55. package/dist/lib/codex-manager/commands/rotation.d.ts +2 -2
  56. package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -1
  57. package/dist/lib/codex-manager/commands/rotation.js +63 -12
  58. package/dist/lib/codex-manager/commands/status.d.ts +12 -1
  59. package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
  60. package/dist/lib/codex-manager/commands/status.js +166 -22
  61. package/dist/lib/codex-manager/commands/uninstall.js +1 -1
  62. package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +1 -1
  63. package/dist/lib/codex-manager/formatters/quota-formatters.js +3 -2
  64. package/dist/lib/codex-manager/health-check.d.ts +3 -0
  65. package/dist/lib/codex-manager/health-check.d.ts.map +1 -1
  66. package/dist/lib/codex-manager/health-check.js +56 -6
  67. package/dist/lib/codex-manager/help.d.ts.map +1 -1
  68. package/dist/lib/codex-manager/help.js +4 -2
  69. package/dist/lib/codex-manager/login-flow.d.ts.map +1 -1
  70. package/dist/lib/codex-manager/login-flow.js +69 -7
  71. package/dist/lib/codex-manager/login-menu-data.d.ts.map +1 -1
  72. package/dist/lib/codex-manager/login-menu-data.js +14 -5
  73. package/dist/lib/codex-manager/login-oauth.d.ts +3 -0
  74. package/dist/lib/codex-manager/login-oauth.d.ts.map +1 -1
  75. package/dist/lib/codex-manager/login-oauth.js +6 -1
  76. package/dist/lib/codex-manager/login-workspace-choice.d.ts +11 -0
  77. package/dist/lib/codex-manager/login-workspace-choice.d.ts.map +1 -0
  78. package/dist/lib/codex-manager/login-workspace-choice.js +37 -0
  79. package/dist/lib/codex-manager/persist-selected-account.d.ts.map +1 -1
  80. package/dist/lib/codex-manager/persist-selected-account.js +2 -1
  81. package/dist/lib/codex-manager/repair-commands.d.ts +13 -0
  82. package/dist/lib/codex-manager/repair-commands.d.ts.map +1 -1
  83. package/dist/lib/codex-manager/repair-commands.js +143 -8
  84. package/dist/lib/codex-manager.d.ts.map +1 -1
  85. package/dist/lib/codex-manager.js +25 -6
  86. package/dist/lib/concurrency.d.ts +3 -0
  87. package/dist/lib/concurrency.d.ts.map +1 -0
  88. package/dist/lib/concurrency.js +31 -0
  89. package/dist/lib/context-budget/model-context-windows.d.ts +1 -1
  90. package/dist/lib/context-budget/model-context-windows.d.ts.map +1 -1
  91. package/dist/lib/context-budget/model-context-windows.js +9 -10
  92. package/dist/lib/model-route-policy.d.ts +52 -0
  93. package/dist/lib/model-route-policy.d.ts.map +1 -0
  94. package/dist/lib/model-route-policy.js +159 -0
  95. package/dist/lib/policy/runtime-policy.d.ts +1 -0
  96. package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
  97. package/dist/lib/policy/runtime-policy.js +3 -0
  98. package/dist/lib/preemptive-quota-scheduler.d.ts +2 -0
  99. package/dist/lib/preemptive-quota-scheduler.d.ts.map +1 -1
  100. package/dist/lib/preemptive-quota-scheduler.js +4 -0
  101. package/dist/lib/prompts/codex.d.ts.map +1 -1
  102. package/dist/lib/prompts/codex.js +3 -1
  103. package/dist/lib/quota-probe.d.ts +5 -0
  104. package/dist/lib/quota-probe.d.ts.map +1 -1
  105. package/dist/lib/quota-probe.js +26 -2
  106. package/dist/lib/request/client-cancellation.d.ts +5 -0
  107. package/dist/lib/request/client-cancellation.d.ts.map +1 -0
  108. package/dist/lib/request/client-cancellation.js +7 -0
  109. package/dist/lib/request/error-classification.d.ts.map +1 -1
  110. package/dist/lib/request/error-classification.js +39 -25
  111. package/dist/lib/request/fetch-helpers.js +1 -1
  112. package/dist/lib/request/helpers/model-map.d.ts +12 -2
  113. package/dist/lib/request/helpers/model-map.d.ts.map +1 -1
  114. package/dist/lib/request/helpers/model-map.js +174 -147
  115. package/dist/lib/request/response-outcome.d.ts +25 -0
  116. package/dist/lib/request/response-outcome.d.ts.map +1 -0
  117. package/dist/lib/request/response-outcome.js +49 -0
  118. package/dist/lib/request/stream-failover-runtime.d.ts +2 -1
  119. package/dist/lib/request/stream-failover-runtime.d.ts.map +1 -1
  120. package/dist/lib/request/stream-failover-runtime.js +29 -10
  121. package/dist/lib/runtime/account-check.d.ts.map +1 -1
  122. package/dist/lib/runtime/account-check.js +2 -8
  123. package/dist/lib/runtime/account-model-catalog.d.ts +64 -0
  124. package/dist/lib/runtime/account-model-catalog.d.ts.map +1 -0
  125. package/dist/lib/runtime/account-model-catalog.js +154 -0
  126. package/dist/lib/runtime/account-pool.d.ts +3 -1
  127. package/dist/lib/runtime/account-pool.d.ts.map +1 -1
  128. package/dist/lib/runtime/account-pool.js +4 -0
  129. package/dist/lib/runtime/account-reset-credits.d.ts +42 -0
  130. package/dist/lib/runtime/account-reset-credits.d.ts.map +1 -0
  131. package/dist/lib/runtime/account-reset-credits.js +82 -0
  132. package/dist/lib/runtime/api-model-capabilities.d.ts +30 -0
  133. package/dist/lib/runtime/api-model-capabilities.d.ts.map +1 -0
  134. package/dist/lib/runtime/api-model-capabilities.js +434 -0
  135. package/dist/lib/runtime/api-model-runtime.d.ts +42 -0
  136. package/dist/lib/runtime/api-model-runtime.d.ts.map +1 -0
  137. package/dist/lib/runtime/api-model-runtime.js +358 -0
  138. package/dist/lib/runtime/app-bind.d.ts +19 -1
  139. package/dist/lib/runtime/app-bind.d.ts.map +1 -1
  140. package/dist/lib/runtime/app-bind.js +79 -9
  141. package/dist/lib/runtime/automatic-account-checks.d.ts +31 -0
  142. package/dist/lib/runtime/automatic-account-checks.d.ts.map +1 -0
  143. package/dist/lib/runtime/automatic-account-checks.js +113 -0
  144. package/dist/lib/runtime/automatic-subscription-checks.d.ts +7 -0
  145. package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +1 -0
  146. package/dist/lib/runtime/automatic-subscription-checks.js +57 -0
  147. package/dist/lib/runtime/catalog-capabilities.d.ts +8 -0
  148. package/dist/lib/runtime/catalog-capabilities.d.ts.map +1 -0
  149. package/dist/lib/runtime/catalog-capabilities.js +61 -0
  150. package/dist/lib/runtime/inference-activity.d.ts +15 -0
  151. package/dist/lib/runtime/inference-activity.d.ts.map +1 -0
  152. package/dist/lib/runtime/inference-activity.js +95 -0
  153. package/dist/lib/runtime/model-discovery-status.d.ts +100 -0
  154. package/dist/lib/runtime/model-discovery-status.d.ts.map +1 -0
  155. package/dist/lib/runtime/model-discovery-status.js +387 -0
  156. package/dist/lib/runtime/native-account-storage.d.ts +11 -0
  157. package/dist/lib/runtime/native-account-storage.d.ts.map +1 -0
  158. package/dist/lib/runtime/native-account-storage.js +50 -0
  159. package/dist/lib/runtime/native-account-sync.d.ts +19 -0
  160. package/dist/lib/runtime/native-account-sync.d.ts.map +1 -0
  161. package/dist/lib/runtime/native-account-sync.js +62 -0
  162. package/dist/lib/runtime/native-binding-lock.d.ts +3 -0
  163. package/dist/lib/runtime/native-binding-lock.d.ts.map +1 -0
  164. package/dist/lib/runtime/native-binding-lock.js +5 -0
  165. package/dist/lib/runtime/native-client-auth.d.ts +3 -0
  166. package/dist/lib/runtime/native-client-auth.d.ts.map +1 -0
  167. package/dist/lib/runtime/native-client-auth.js +42 -0
  168. package/dist/lib/runtime/native-provider-config.d.ts +4 -0
  169. package/dist/lib/runtime/native-provider-config.d.ts.map +1 -0
  170. package/dist/lib/runtime/native-provider-config.js +52 -0
  171. package/dist/lib/runtime/native-rate-limits.d.ts +18 -0
  172. package/dist/lib/runtime/native-rate-limits.d.ts.map +1 -0
  173. package/dist/lib/runtime/native-rate-limits.js +135 -0
  174. package/dist/lib/runtime/reset-credit-routing.d.ts +41 -0
  175. package/dist/lib/runtime/reset-credit-routing.d.ts.map +1 -0
  176. package/dist/lib/runtime/reset-credit-routing.js +66 -0
  177. package/dist/lib/runtime/reset-credits.d.ts +101 -0
  178. package/dist/lib/runtime/reset-credits.d.ts.map +1 -0
  179. package/dist/lib/runtime/reset-credits.js +162 -0
  180. package/dist/lib/runtime/response-output-history.d.ts +17 -0
  181. package/dist/lib/runtime/response-output-history.d.ts.map +1 -0
  182. package/dist/lib/runtime/response-output-history.js +85 -0
  183. package/dist/lib/runtime/responses-websocket.d.ts +31 -0
  184. package/dist/lib/runtime/responses-websocket.d.ts.map +1 -0
  185. package/dist/lib/runtime/responses-websocket.js +636 -0
  186. package/dist/lib/runtime/resume-picker.d.ts +41 -0
  187. package/dist/lib/runtime/resume-picker.d.ts.map +1 -0
  188. package/dist/lib/runtime/resume-picker.js +169 -0
  189. package/dist/lib/runtime/rotation-account-selection.d.ts +6 -0
  190. package/dist/lib/runtime/rotation-account-selection.d.ts.map +1 -1
  191. package/dist/lib/runtime/rotation-account-selection.js +63 -0
  192. package/dist/lib/runtime/rotation-proxy-state.d.ts +33 -0
  193. package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
  194. package/dist/lib/runtime/rotation-server-types.d.ts +18 -0
  195. package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
  196. package/dist/lib/runtime/runtime-capability-failures.d.ts +14 -0
  197. package/dist/lib/runtime/runtime-capability-failures.d.ts.map +1 -0
  198. package/dist/lib/runtime/runtime-capability-failures.js +76 -0
  199. package/dist/lib/runtime/runtime-observability.d.ts +7 -0
  200. package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
  201. package/dist/lib/runtime/runtime-observability.js +42 -2
  202. package/dist/lib/runtime/subscription-first-use.d.ts +10 -0
  203. package/dist/lib/runtime/subscription-first-use.d.ts.map +1 -0
  204. package/dist/lib/runtime/subscription-first-use.js +64 -0
  205. package/dist/lib/runtime/subscription-quota-event.d.ts +6 -0
  206. package/dist/lib/runtime/subscription-quota-event.d.ts.map +1 -0
  207. package/dist/lib/runtime/subscription-quota-event.js +31 -0
  208. package/dist/lib/runtime/subscription-quota-order.d.ts +17 -0
  209. package/dist/lib/runtime/subscription-quota-order.d.ts.map +1 -0
  210. package/dist/lib/runtime/subscription-quota-order.js +31 -0
  211. package/dist/lib/runtime/workspace-model-scopes.d.ts +15 -0
  212. package/dist/lib/runtime/workspace-model-scopes.d.ts.map +1 -0
  213. package/dist/lib/runtime/workspace-model-scopes.js +34 -0
  214. package/dist/lib/runtime-constants.d.ts +3 -0
  215. package/dist/lib/runtime-constants.d.ts.map +1 -1
  216. package/dist/lib/runtime-constants.js +5 -0
  217. package/dist/lib/runtime-paths.d.ts.map +1 -1
  218. package/dist/lib/runtime-paths.js +4 -1
  219. package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
  220. package/dist/lib/runtime-rotation-proxy.js +855 -46
  221. package/dist/lib/schemas.d.ts +20 -0
  222. package/dist/lib/schemas.d.ts.map +1 -1
  223. package/dist/lib/schemas.js +3 -0
  224. package/dist/lib/storage/credential-sidecars.d.ts +13 -0
  225. package/dist/lib/storage/credential-sidecars.d.ts.map +1 -0
  226. package/dist/lib/storage/credential-sidecars.js +52 -0
  227. package/dist/lib/storage/file-lock.d.ts +9 -0
  228. package/dist/lib/storage/file-lock.d.ts.map +1 -0
  229. package/dist/lib/storage/file-lock.js +186 -0
  230. package/dist/lib/storage/flagged-storage.d.ts.map +1 -1
  231. package/dist/lib/storage/flagged-storage.js +12 -0
  232. package/dist/lib/storage/path-state.d.ts +2 -0
  233. package/dist/lib/storage/path-state.d.ts.map +1 -1
  234. package/dist/lib/storage/path-state.js +9 -0
  235. package/dist/lib/storage/paths.js +4 -4
  236. package/dist/lib/storage/pending-auth.d.ts +17 -0
  237. package/dist/lib/storage/pending-auth.d.ts.map +1 -0
  238. package/dist/lib/storage/pending-auth.js +153 -0
  239. package/dist/lib/storage/public-types.d.ts +13 -0
  240. package/dist/lib/storage/public-types.d.ts.map +1 -1
  241. package/dist/lib/storage/snapshot-merge.d.ts +16 -0
  242. package/dist/lib/storage/snapshot-merge.d.ts.map +1 -0
  243. package/dist/lib/storage/snapshot-merge.js +206 -0
  244. package/dist/lib/storage/transactions.d.ts.map +1 -1
  245. package/dist/lib/storage/transactions.js +5 -4
  246. package/dist/lib/storage.d.ts +6 -0
  247. package/dist/lib/storage.d.ts.map +1 -1
  248. package/dist/lib/storage.js +77 -7
  249. package/dist/lib/ui/auth-menu-builder.d.ts +2 -0
  250. package/dist/lib/ui/auth-menu-builder.d.ts.map +1 -1
  251. package/dist/lib/ui/auth-menu-builder.js +1 -0
  252. package/dist/lib/ui/auth-menu.d.ts.map +1 -1
  253. package/dist/lib/ui/auth-menu.js +1 -0
  254. package/dist/lib/ui/check-progress.d.ts +8 -0
  255. package/dist/lib/ui/check-progress.d.ts.map +1 -0
  256. package/dist/lib/ui/check-progress.js +30 -0
  257. package/dist/lib/ui/format.d.ts +3 -1
  258. package/dist/lib/ui/format.d.ts.map +1 -1
  259. package/dist/lib/ui/format.js +8 -0
  260. package/dist/lib/ui/ui-copy.d.ts +2 -2
  261. package/dist/lib/ui/ui-copy.js +2 -2
  262. package/dist/lib/usage/pricing.d.ts +19 -2
  263. package/dist/lib/usage/pricing.d.ts.map +1 -1
  264. package/dist/lib/usage/pricing.js +101 -40
  265. package/dist/lib/usage/usage-extraction.d.ts +3 -1
  266. package/dist/lib/usage/usage-extraction.d.ts.map +1 -1
  267. package/dist/lib/usage/usage-extraction.js +46 -9
  268. package/package.json +7 -4
  269. package/scripts/codex-app-router.js +7 -0
  270. package/scripts/codex-bin-resolver.js +40 -8
  271. package/scripts/codex-routing.js +1 -0
  272. package/scripts/codex.js +209 -126
@@ -52,7 +52,21 @@ const TOOL_CAPABILITIES = {
52
52
  compaction: false,
53
53
  },
54
54
  };
55
- export const CURRENT_CODEX_MODEL = "gpt-5.3-codex";
55
+ /**
56
+ * Where every codex-named id routes. No codex model is left: upstream Codex
57
+ * dropped `gpt-5.3-codex` from its catalog on 2026-07-08, and OpenAI's
58
+ * deprecations page names `gpt-5.6-sol` as the replacement for every retired
59
+ * codex id (`gpt-5-codex`, `gpt-5.1-codex*`, `gpt-5.2-codex`). The export
60
+ * keeps its name so callers that mean "the model a codex request runs on"
61
+ * still read naturally.
62
+ */
63
+ export const CURRENT_CODEX_MODEL = "gpt-5.6-sol";
64
+ /**
65
+ * The retired codex mini ids (`gpt-5.1-codex-mini`, `gpt-5-codex-mini`,
66
+ * `codex-mini-latest`) go to Terra, OpenAI's named replacement for
67
+ * `gpt-5.1-codex-mini`, rather than up to Sol.
68
+ */
69
+ const CODEX_MINI_REPLACEMENT_MODEL = "gpt-5.6-terra";
56
70
  export const DEFAULT_MODEL = "gpt-5.5";
57
71
  // Model used for diagnostic live/quota probes (`check`, `report`, `best`).
58
72
  // Deliberately distinct from DEFAULT_MODEL: GPT-5.6 is the latest general family
@@ -70,18 +84,18 @@ export const DEFAULT_MODEL = "gpt-5.5";
70
84
  export const DEFAULT_PROBE_MODEL = "gpt-5.6-sol";
71
85
  // Single source of truth for the live/quota probe fallback chain. Both the
72
86
  // manager probe (lib/quota-probe.ts) and the runtime probe (lib/runtime/quota-probe.ts)
73
- // import this so the ordered candidate list cannot drift between them. It leads
74
- // with GPT-5.6 and steps down so accounts without 5.6 entitlement still resolve
75
- // a working probe model.
87
+ // import this so the ordered candidate list cannot drift between them.
88
+ //
89
+ // Every entry must be a model the Codex backend still serves. The chain used to
90
+ // end on `gpt-5.4` and three codex models; all four are gone from the upstream
91
+ // catalog (`gpt-5.4` carries `retirement_at: 2026-08-31`), so a probe that
92
+ // reached them spent requests on guaranteed failures. `gpt-6-luna` closes it
93
+ // because it is offered on the most plans of any catalog model (24).
76
94
  export const QUOTA_PROBE_MODEL_CHAIN = [
77
95
  DEFAULT_PROBE_MODEL,
78
96
  DEFAULT_MODEL,
79
- "gpt-5.4",
80
- "gpt-5.3-codex",
81
- "gpt-5.2-codex",
82
- "gpt-5-codex",
97
+ "gpt-6-luna",
83
98
  ];
84
- const LEGACY_CODEX_MODEL = "gpt-5-codex";
85
99
  /**
86
100
  * GPT-5.6 tiers, per the upstream Codex catalog
87
101
  * (openai/codex `codex-rs/models-manager/models.json`).
@@ -112,8 +126,8 @@ const GPT_5_6_LUNA_EFFORTS = [
112
126
  /**
113
127
  * GPT-6 Astra, OpenAI's 2026-09-03 frontier release.
114
128
  *
115
- * There is no Sol/Terra/Luna split this generation: the announced lineup is the
116
- * flagship plus `aeon`, a long-horizon variant built for runs measured in days.
129
+ * The launch lineup was the flagship plus `aeon`, a long-horizon variant built
130
+ * for runs measured in days; Sol and Luna followed on 2026-09-22 (below).
117
131
  * `gpt-6-astra` is the API model name OpenAI published at launch;
118
132
  * `gpt-6-astra-aeon` is the second slug that shipped beside it in the Codex
119
133
  * model list. "Astra Pro" is a plan tier, not a separate slug we have seen, so
@@ -139,6 +153,24 @@ const GPT_6_ASTRA_EFFORTS = [
139
153
  "max",
140
154
  "ultra",
141
155
  ];
156
+ /**
157
+ * GPT-6 Sol and Luna, added to the upstream Codex catalog on 2026-09-22
158
+ * (openai/codex #47332) beside Astra. Sol is the everyday workhorse and Luna
159
+ * the small, cheap tier; there is no GPT-6 Terra. Upstream migrates `gpt-5.5`,
160
+ * `gpt-5.6-sol` and `gpt-5.6-terra` users to Sol and `gpt-5.6-luna` users to
161
+ * Luna. Ladders and defaults below are the catalog's own values: Sol reaches
162
+ * `ultra`, Luna stops at `max` (same split as 5.6), both default to `medium`.
163
+ */
164
+ const GPT_6_SOL_MODEL = "gpt-6-sol";
165
+ const GPT_6_LUNA_MODEL = "gpt-6-luna";
166
+ const GPT_6_SOL_EFFORTS = GPT_6_ASTRA_EFFORTS;
167
+ const GPT_6_LUNA_EFFORTS = [
168
+ "low",
169
+ "medium",
170
+ "high",
171
+ "xhigh",
172
+ "max",
173
+ ];
142
174
  /**
143
175
  * Cyber-specialty models from the upstream Codex catalog
144
176
  * (openai/codex `codex-rs/models-manager/models.json`).
@@ -166,33 +198,43 @@ const GPT_5_5_RELEASE_MODEL = "gpt-5.5-2026-04-23";
166
198
  const GPT_5_5_PRO_RELEASE_MODEL = "gpt-5.5-pro-2026-04-23";
167
199
  const GPT_5_5_RELEASE_COMPAT_MODEL = "gpt-5.5-20260423";
168
200
  const GPT_5_5_PRO_RELEASE_COMPAT_MODEL = "gpt-5.5-pro-20260423";
201
+ /**
202
+ * Where an unrecognised `gpt-5.<minor>` id lands. Every minor below 5.5 is
203
+ * retired (OpenAI deprecations page, upstream catalog removals), so each maps
204
+ * to the replacement OpenAI names for it rather than to a model that no longer
205
+ * answers: 5.1/5.2 to Sol, 5.4 to GPT-6 Sol/Luna as upstream Codex migrates it,
206
+ * and every `pro` to the one live pro model.
207
+ */
169
208
  const GENERAL_GPT5_VERSION_CATALOG = {
170
209
  1: {
171
- base: "gpt-5.1",
210
+ base: GPT_5_6_SOL_MODEL,
211
+ pro: GPT_5_5_PRO_CANONICAL_MODEL,
172
212
  },
173
213
  2: {
174
- base: "gpt-5.2",
175
- pro: "gpt-5.2-pro",
214
+ base: GPT_5_6_SOL_MODEL,
215
+ pro: GPT_5_5_PRO_CANONICAL_MODEL,
176
216
  },
177
217
  4: {
178
- base: DEFAULT_MODEL,
179
- pro: "gpt-5.4-pro",
180
- mini: "gpt-5.4-mini",
181
- nano: "gpt-5.4-nano",
218
+ base: GPT_6_SOL_MODEL,
219
+ pro: GPT_5_5_PRO_CANONICAL_MODEL,
220
+ mini: GPT_6_LUNA_MODEL,
221
+ nano: GPT_6_LUNA_MODEL,
182
222
  },
183
223
  5: {
184
224
  base: GPT_5_5_CANONICAL_MODEL,
185
225
  pro: GPT_5_5_PRO_CANONICAL_MODEL,
186
- mini: "gpt-5-mini",
187
- nano: "gpt-5-nano",
226
+ mini: GPT_5_6_TERRA_MODEL,
227
+ nano: GPT_5_6_LUNA_MODEL,
188
228
  },
189
229
  };
190
230
  const GENERAL_GPT5_STABLE_VARIANTS = GENERAL_GPT5_VERSION_CATALOG[5];
231
+ // `gpt-5-mini`/`gpt-5-nano` point at snapshots OpenAI retires on 2026-12-11;
232
+ // the deprecations page names Terra and Luna as their replacements.
191
233
  const GENERAL_GPT5_GENERIC_VARIANTS = {
192
234
  base: DEFAULT_MODEL,
193
235
  pro: GPT_5_5_PRO_CANONICAL_MODEL,
194
- mini: "gpt-5-mini",
195
- nano: "gpt-5-nano",
236
+ mini: GPT_5_6_TERRA_MODEL,
237
+ nano: GPT_5_6_LUNA_MODEL,
196
238
  };
197
239
  /**
198
240
  * Effective model profiles keyed by canonical model name.
@@ -203,41 +245,6 @@ const GENERAL_GPT5_GENERIC_VARIANTS = {
203
245
  * present in the latest upstream release.
204
246
  */
205
247
  export const MODEL_PROFILES = {
206
- [CURRENT_CODEX_MODEL]: {
207
- normalizedModel: CURRENT_CODEX_MODEL,
208
- promptFamily: "gpt-5-codex",
209
- defaultReasoningEffort: "high",
210
- supportedReasoningEfforts: ["low", "medium", "high", "xhigh"],
211
- capabilities: TOOL_CAPABILITIES.basic,
212
- },
213
- "gpt-5.4": {
214
- normalizedModel: "gpt-5.4",
215
- promptFamily: "gpt-5.2",
216
- defaultReasoningEffort: "none",
217
- supportedReasoningEfforts: ["none", "low", "medium", "high", "xhigh"],
218
- capabilities: TOOL_CAPABILITIES.full,
219
- },
220
- "gpt-5.4-pro": {
221
- normalizedModel: "gpt-5.4-pro",
222
- promptFamily: "gpt-5.2",
223
- defaultReasoningEffort: "high",
224
- supportedReasoningEfforts: ["medium", "high", "xhigh"],
225
- capabilities: TOOL_CAPABILITIES.computerAndCompact,
226
- },
227
- "gpt-5.4-mini": {
228
- normalizedModel: "gpt-5.4-mini",
229
- promptFamily: "gpt-5.2",
230
- defaultReasoningEffort: "medium",
231
- supportedReasoningEfforts: ["medium"],
232
- capabilities: TOOL_CAPABILITIES.compactOnly,
233
- },
234
- "gpt-5.4-nano": {
235
- normalizedModel: "gpt-5.4-nano",
236
- promptFamily: "gpt-5.2",
237
- defaultReasoningEffort: "medium",
238
- supportedReasoningEfforts: ["medium"],
239
- capabilities: TOOL_CAPABILITIES.compactOnly,
240
- },
241
248
  // Like GPT-5.6, GPT-6 Astra ships its base instructions inline in the
242
249
  // upstream model catalog rather than as a `gpt_6_prompt.md`, so it stays on
243
250
  // the GPT-5.2 prompt family with every other post-5.2 general model. Adding
@@ -258,6 +265,20 @@ export const MODEL_PROFILES = {
258
265
  supportedReasoningEfforts: GPT_6_ASTRA_EFFORTS,
259
266
  capabilities: TOOL_CAPABILITIES.full,
260
267
  },
268
+ [GPT_6_SOL_MODEL]: {
269
+ normalizedModel: GPT_6_SOL_MODEL,
270
+ promptFamily: "gpt-5.2",
271
+ defaultReasoningEffort: "medium",
272
+ supportedReasoningEfforts: GPT_6_SOL_EFFORTS,
273
+ capabilities: TOOL_CAPABILITIES.full,
274
+ },
275
+ [GPT_6_LUNA_MODEL]: {
276
+ normalizedModel: GPT_6_LUNA_MODEL,
277
+ promptFamily: "gpt-5.2",
278
+ defaultReasoningEffort: "medium",
279
+ supportedReasoningEfforts: GPT_6_LUNA_EFFORTS,
280
+ capabilities: TOOL_CAPABILITIES.full,
281
+ },
261
282
  [DAYBREAK_BLUE_MODEL]: {
262
283
  normalizedModel: DAYBREAK_BLUE_MODEL,
263
284
  promptFamily: "gpt-5.2",
@@ -310,41 +331,12 @@ export const MODEL_PROFILES = {
310
331
  supportedReasoningEfforts: ["medium", "high", "xhigh"],
311
332
  capabilities: TOOL_CAPABILITIES.computerAndCompact,
312
333
  },
313
- "gpt-5.2-pro": {
314
- normalizedModel: "gpt-5.2-pro",
315
- promptFamily: "gpt-5.2",
316
- defaultReasoningEffort: "high",
317
- supportedReasoningEfforts: ["medium", "high", "xhigh"],
318
- capabilities: TOOL_CAPABILITIES.basic,
319
- },
320
- "gpt-5.2": {
321
- normalizedModel: "gpt-5.2",
322
- promptFamily: "gpt-5.2",
323
- defaultReasoningEffort: "none",
324
- supportedReasoningEfforts: ["none", "low", "medium", "high", "xhigh"],
325
- capabilities: TOOL_CAPABILITIES.basic,
326
- },
327
- "gpt-5.1": {
328
- normalizedModel: "gpt-5.1",
329
- promptFamily: "gpt-5.1",
330
- defaultReasoningEffort: "none",
331
- supportedReasoningEfforts: ["none", "low", "medium", "high"],
332
- capabilities: TOOL_CAPABILITIES.basic,
333
- },
334
- "gpt-5-mini": {
335
- normalizedModel: "gpt-5-mini",
336
- promptFamily: "gpt-5.2",
337
- defaultReasoningEffort: "medium",
338
- supportedReasoningEfforts: ["medium"],
339
- capabilities: TOOL_CAPABILITIES.compactOnly,
340
- },
341
- "gpt-5-nano": {
342
- normalizedModel: "gpt-5-nano",
343
- promptFamily: "gpt-5.2",
344
- defaultReasoningEffort: "medium",
345
- supportedReasoningEfforts: ["medium"],
346
- capabilities: TOOL_CAPABILITIES.compactOnly,
347
- },
334
+ // Every model older than 5.5 is retired: `gpt-5.1`, `gpt-5.2` and the whole
335
+ // 5.4 family left the upstream Codex catalog, the codex models and the
336
+ // chat-latest snapshots are past their shutdown date on OpenAI's
337
+ // deprecations page, and `gpt-5-mini`/`gpt-5-nano` shut down 2026-12-11.
338
+ // Their ids stay accepted as aliases of the named replacement (below) so an
339
+ // old config keeps working, but no request is sent under a dead name.
348
340
  };
349
341
  const MODEL_MAP = {};
350
342
  function addAlias(alias, normalizedModel) {
@@ -382,6 +374,11 @@ function addGpt6Aliases() {
382
374
  // rather than letting it fall through to GPT-5.5.
383
375
  addEffortAliases("astra", GPT_6_ASTRA_MODEL, GPT_6_ASTRA_EFFORTS);
384
376
  addEffortAliases("astra-aeon", GPT_6_ASTRA_AEON_MODEL, GPT_6_ASTRA_EFFORTS);
377
+ // No bare `sol`/`luna` aliases: those names already mean the 5.6 tiers to
378
+ // anyone who used them before 2026-09-22, and re-pointing them would swap a
379
+ // user's model generation without asking.
380
+ addEffortAliases(GPT_6_SOL_MODEL, GPT_6_SOL_MODEL, GPT_6_SOL_EFFORTS);
381
+ addEffortAliases(GPT_6_LUNA_MODEL, GPT_6_LUNA_MODEL, GPT_6_LUNA_EFFORTS);
385
382
  }
386
383
  function addDaybreakAliases() {
387
384
  addEffortAliases(DAYBREAK_BLUE_MODEL, DAYBREAK_BLUE_MODEL, DAYBREAK_EFFORTS);
@@ -396,35 +393,61 @@ function addGeneralAliases() {
396
393
  addReasoningAliases(GPT_5_5_PRO_CANONICAL_MODEL, GPT_5_5_PRO_CANONICAL_MODEL);
397
394
  addReasoningAliases(GPT_5_5_PRO_RELEASE_MODEL, GPT_5_5_PRO_CANONICAL_MODEL);
398
395
  addReasoningAliases(GPT_5_5_PRO_RELEASE_COMPAT_MODEL, GPT_5_5_PRO_CANONICAL_MODEL);
399
- addReasoningAliases("gpt-5.4", "gpt-5.4");
400
- addReasoningAliases("gpt-5.4-pro", "gpt-5.4-pro");
401
- addReasoningAliases("gpt-5.4-mini", "gpt-5.4-mini");
402
- addReasoningAliases("gpt-5.4-nano", "gpt-5.4-nano");
403
- addReasoningAliases("gpt-5.2-pro", "gpt-5.2-pro");
404
396
  addReasoningAliases("gpt-5-pro", GPT_5_5_PRO_CANONICAL_MODEL);
405
- addReasoningAliases("gpt-5.2", "gpt-5.2");
406
- addReasoningAliases("gpt-5.1", "gpt-5.1");
407
397
  addReasoningAliases("gpt-5", DEFAULT_MODEL);
408
- addReasoningAliases("gpt-5-mini", "gpt-5-mini");
409
- addReasoningAliases("gpt-5-nano", "gpt-5-nano");
410
- addReasoningAliases("gpt-5.1-chat-latest", "gpt-5.1");
411
- addReasoningAliases("gpt-5-chat-latest", DEFAULT_MODEL);
412
398
  }
413
- function addCodexAliases() {
414
- addReasoningAliases(CURRENT_CODEX_MODEL, CURRENT_CODEX_MODEL);
415
- addReasoningAliases("gpt-5.3-codex-spark", CURRENT_CODEX_MODEL);
416
- addReasoningAliases(LEGACY_CODEX_MODEL, CURRENT_CODEX_MODEL);
417
- addReasoningAliases("gpt-5.2-codex", CURRENT_CODEX_MODEL);
418
- addReasoningAliases("gpt-5.1-codex", CURRENT_CODEX_MODEL);
399
+ /**
400
+ * Retired general ids, each kept as an alias of the replacement OpenAI names
401
+ * for it: the upstream Codex catalog's migration target where it has one
402
+ * (`gpt-5.4` -> GPT-6 Sol, `gpt-5.4-mini` -> GPT-6 Luna), otherwise the
403
+ * deprecations page's recommended replacement. The effort-suffixed forms
404
+ * (`gpt-5.4-high`, `gpt-5.1-none`, ...) come along so old configs resolve;
405
+ * efforts the replacement does not accept are coerced as for any request.
406
+ */
407
+ const RETIRED_GENERAL_MODEL_REPLACEMENTS = {
408
+ "gpt-5.4": GPT_6_SOL_MODEL,
409
+ "gpt-5.4-mini": GPT_6_LUNA_MODEL,
410
+ "gpt-5.4-nano": GPT_6_LUNA_MODEL,
411
+ "gpt-5.4-pro": GPT_5_5_PRO_CANONICAL_MODEL,
412
+ "gpt-5.2": GPT_5_6_SOL_MODEL,
413
+ "gpt-5.2-pro": GPT_5_5_PRO_CANONICAL_MODEL,
414
+ "gpt-5.1": GPT_5_6_SOL_MODEL,
415
+ "gpt-5-mini": GPT_5_6_TERRA_MODEL,
416
+ "gpt-5-nano": GPT_5_6_LUNA_MODEL,
417
+ "gpt-5-chat-latest": GPT_5_6_SOL_MODEL,
418
+ "gpt-5.1-chat-latest": GPT_5_6_SOL_MODEL,
419
+ "gpt-5.2-chat-latest": GPT_5_6_SOL_MODEL,
420
+ "gpt-5.3-chat-latest": GPT_5_6_SOL_MODEL,
421
+ };
422
+ /**
423
+ * Retired codex ids. All shut down on OpenAI's deprecations page or left the
424
+ * upstream Codex catalog; OpenAI names `gpt-5.6-sol` as the replacement for
425
+ * the full-size ones and `gpt-5.6-terra` for `gpt-5.1-codex-mini`.
426
+ */
427
+ const RETIRED_CODEX_MODEL_REPLACEMENTS = {
428
+ "gpt-5.3-codex": CURRENT_CODEX_MODEL,
429
+ "gpt-5.3-codex-spark": CURRENT_CODEX_MODEL,
430
+ "gpt-5.2-codex": CURRENT_CODEX_MODEL,
431
+ "gpt-5.1-codex": CURRENT_CODEX_MODEL,
432
+ "gpt-5.1-codex-max": CURRENT_CODEX_MODEL,
433
+ "gpt-5-codex": CURRENT_CODEX_MODEL,
434
+ "codex-max": CURRENT_CODEX_MODEL,
435
+ "gpt-5.1-codex-mini": CODEX_MINI_REPLACEMENT_MODEL,
436
+ "gpt-5-codex-mini": CODEX_MINI_REPLACEMENT_MODEL,
437
+ "codex-mini-latest": CODEX_MINI_REPLACEMENT_MODEL,
438
+ };
439
+ /** Every retired id and its replacement, for diagnostics and tests. */
440
+ export const RETIRED_MODEL_REPLACEMENTS = {
441
+ ...RETIRED_GENERAL_MODEL_REPLACEMENTS,
442
+ ...RETIRED_CODEX_MODEL_REPLACEMENTS,
443
+ };
444
+ function addRetiredAliases() {
445
+ for (const [retired, replacement] of Object.entries(RETIRED_MODEL_REPLACEMENTS)) {
446
+ addReasoningAliases(retired, replacement);
447
+ }
419
448
  addAlias("gpt_5_codex", CURRENT_CODEX_MODEL);
420
- addReasoningAliases("codex-max", CURRENT_CODEX_MODEL);
421
- addReasoningAliases("gpt-5.1-codex-max", CURRENT_CODEX_MODEL);
422
- addAlias("codex-max", CURRENT_CODEX_MODEL);
423
- addAlias("codex-mini-latest", CURRENT_CODEX_MODEL);
424
- addReasoningAliases("gpt-5-codex-mini", CURRENT_CODEX_MODEL);
425
- addReasoningAliases("gpt-5.1-codex-mini", CURRENT_CODEX_MODEL);
426
449
  }
427
- addCodexAliases();
450
+ addRetiredAliases();
428
451
  addGeneralAliases();
429
452
  addGpt56Aliases();
430
453
  addGpt6Aliases();
@@ -461,39 +484,21 @@ function resolveStableGeneralGpt5Variant(variant) {
461
484
  }
462
485
  throw new Error(`Stable GPT-5 fallback is missing for variant ${variant}`);
463
486
  }
487
+ /**
488
+ * Any id carrying a `codex` token. Every codex model is retired, so this only
489
+ * picks the replacement: a `mini` codex id goes to Terra, everything else to
490
+ * Sol (see RETIRED_CODEX_MODEL_REPLACEMENTS).
491
+ */
464
492
  function resolveCodexCatalogModel(modelId) {
465
493
  const normalized = modelId.toLowerCase();
466
- if (normalized.includes("gpt-5.3-codex-spark") ||
467
- normalized.includes("gpt 5.3 codex spark")) {
468
- return CURRENT_CODEX_MODEL;
469
- }
470
- if (normalized.includes("gpt-5.3-codex") ||
471
- normalized.includes("gpt 5.3 codex")) {
472
- return CURRENT_CODEX_MODEL;
473
- }
474
- if (normalized.includes("gpt-5.2-codex") ||
475
- normalized.includes("gpt 5.2 codex")) {
476
- return CURRENT_CODEX_MODEL;
477
- }
478
- if (normalized.includes("gpt-5.1-codex-max") ||
479
- normalized.includes("gpt 5.1 codex max")) {
480
- return CURRENT_CODEX_MODEL;
481
- }
482
- if (normalized.includes("gpt-5.1-codex-mini") ||
483
- normalized.includes("gpt 5.1 codex mini") ||
484
- normalized.includes("codex-mini-latest") ||
485
- normalized.includes("gpt-5-codex-mini") ||
486
- normalized.includes("gpt 5 codex mini")) {
487
- return CURRENT_CODEX_MODEL;
494
+ if (!normalized.includes("codex")) {
495
+ return undefined;
488
496
  }
489
- if (normalized.includes("gpt-5-codex") ||
490
- normalized.includes("gpt 5 codex") ||
491
- normalized.includes("gpt-5.1-codex") ||
492
- normalized.includes("gpt 5.1 codex") ||
493
- normalized.includes("codex")) {
494
- return CURRENT_CODEX_MODEL;
497
+ // Anchored so `codex-minimal` (an effort suffix) is not read as a mini.
498
+ if (/codex[- ]mini(?!mal)/.test(normalized)) {
499
+ return CODEX_MINI_REPLACEMENT_MODEL;
495
500
  }
496
- return undefined;
501
+ return CURRENT_CODEX_MODEL;
497
502
  }
498
503
  /**
499
504
  * Resolve GPT-5.6 identifiers that are not exact aliases (for example a future
@@ -514,8 +519,9 @@ function resolveCodexCatalogModel(modelId) {
514
519
  * `gpt 5` token pair) and every unrecognised GPT-6 id lands on `DEFAULT_MODEL`,
515
520
  * running GPT-5.5 for a caller who asked for the frontier model. `aeon` keeps
516
521
  * its own canonical id because it is a behaviourally different model (long
517
- * horizon), not a rename of the flagship; everything else resolves to the
518
- * flagship, matching OpenAI's bare `gpt-6` alias.
522
+ * horizon), not a rename of the flagship. A `sol`/`luna` tier token picks that
523
+ * tier; everything else resolves to the flagship, matching OpenAI's bare
524
+ * `gpt-6` alias.
519
525
  *
520
526
  * Ids carrying a `codex` token are left to `resolveCodexCatalogModel`, exactly
521
527
  * as the 5.6 resolver defers them.
@@ -547,6 +553,16 @@ function resolveGpt6CatalogModel(modelId) {
547
553
  }
548
554
  if (tokens.includes("aeon"))
549
555
  return GPT_6_ASTRA_AEON_MODEL;
556
+ if (isAstra)
557
+ return GPT_6_ASTRA_MODEL;
558
+ // Before Sol and Luna existed every non-Astra GPT-6 id fell to the line
559
+ // below, so `gpt-6-luna` silently ran Astra at 100x Luna's price. `terra`
560
+ // goes to Sol because there is no GPT-6 Terra and upstream migrates
561
+ // `gpt-5.6-terra` users to Sol.
562
+ if (tokens.includes("luna"))
563
+ return GPT_6_LUNA_MODEL;
564
+ if (tokens.includes("sol") || tokens.includes("terra"))
565
+ return GPT_6_SOL_MODEL;
550
566
  return GPT_6_ASTRA_MODEL;
551
567
  }
552
568
  /**
@@ -647,6 +663,17 @@ export function resolveNormalizedModel(model) {
647
663
  if (mappedModel) {
648
664
  return mappedModel;
649
665
  }
666
+ // `max`/`ultra` are not generated as aliases for the pre-5.6 ids, so
667
+ // `gpt-5.3-chat-latest-max` missed the retired table and the general GPT-5
668
+ // resolver sent it to 5.5 instead of its replacement. Retry the lookup
669
+ // without the suffix before any fuzzy resolver runs.
670
+ const withoutTopEffort = modelId.replace(/-(max|ultra)$/i, "");
671
+ if (withoutTopEffort !== modelId) {
672
+ const mappedWithoutEffort = lookupMappedModel(withoutTopEffort);
673
+ if (mappedWithoutEffort) {
674
+ return mappedWithoutEffort;
675
+ }
676
+ }
650
677
  // Daybreak first: its slugs carry neither a `codex` nor a `gpt 5` token, so
651
678
  // every other resolver declines them and they would reach DEFAULT_MODEL.
652
679
  const daybreakCatalogModel = resolveDaybreakCatalogModel(modelId);
@@ -0,0 +1,25 @@
1
+ export interface StreamCompletion {
2
+ success: boolean;
3
+ errorCode: string | null;
4
+ missingTerminal: boolean;
5
+ }
6
+ /** Protocol completion, separate from socket delivery. Never retain output or error messages. */
7
+ export declare class ResponseOutcome {
8
+ private readonly requireTerminal;
9
+ private terminal;
10
+ rejection: {
11
+ error: {
12
+ code?: string;
13
+ param?: string;
14
+ };
15
+ } | undefined;
16
+ constructor(requireTerminal: boolean);
17
+ observe(value: unknown): void;
18
+ /**
19
+ * `response.incomplete` (e.g. max_output_tokens) is a delivered response, not an
20
+ * account failure: it counts as success for health and affinity, and its terminal
21
+ * type survives only as the usage annotation in `errorCode`.
22
+ */
23
+ finish(): StreamCompletion;
24
+ }
25
+ //# sourceMappingURL=response-outcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-outcome.d.ts","sourceRoot":"","sources":["../../../lib/request/response-outcome.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;CACzB;AAED,iGAAiG;AACjG,qBAAa,eAAe;IAIf,OAAO,CAAC,QAAQ,CAAC,eAAe;IAH5C,OAAO,CAAC,QAAQ,CAAkE;IAClF,SAAS,EAAE;QAAE,KAAK,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GAAG,SAAS,CAAC;gBAEvC,eAAe,EAAE,OAAO;IAErD,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAuB7B;;;;OAIG;IACH,MAAM,IAAI,gBAAgB;CAS1B"}
@@ -0,0 +1,49 @@
1
+ import { isRecord } from "../utils.js";
2
+ /** Protocol completion, separate from socket delivery. Never retain output or error messages. */
3
+ export class ResponseOutcome {
4
+ requireTerminal;
5
+ terminal;
6
+ rejection;
7
+ constructor(requireTerminal) {
8
+ this.requireTerminal = requireTerminal;
9
+ }
10
+ observe(value) {
11
+ if (!isRecord(value))
12
+ return;
13
+ let type = value.type ?? (value.object === "response" && typeof value.status === "string" ? `response.${value.status}` : undefined);
14
+ // SSE `response.done` carries its outcome in the nested status.
15
+ if (type === "response.done") {
16
+ const status = isRecord(value.response) ? value.response.status : undefined;
17
+ type = typeof status === "string" ? `response.${status}` : "response.completed";
18
+ }
19
+ if (type === "response.completed") {
20
+ if (!this.terminal)
21
+ this.terminal = "completed";
22
+ return;
23
+ }
24
+ const failure = type === "response.failed" || type === "error";
25
+ if (!failure && type !== "response.incomplete" && type !== "response.cancelled")
26
+ return;
27
+ this.terminal = failure ? "failed" : type === "response.incomplete" ? "incomplete" : "cancelled";
28
+ const response = isRecord(value.response) ? value.response : value;
29
+ const error = isRecord(response.error) ? response.error : type === "error" ? value : undefined;
30
+ if (error) {
31
+ const safe = (v) => typeof v === "string" && /^[A-Za-z0-9._-]{1,100}$/.test(v) ? v : undefined;
32
+ this.rejection = { error: { code: safe(error.code), param: safe(error.param) } };
33
+ }
34
+ }
35
+ /**
36
+ * `response.incomplete` (e.g. max_output_tokens) is a delivered response, not an
37
+ * account failure: it counts as success for health and affinity, and its terminal
38
+ * type survives only as the usage annotation in `errorCode`.
39
+ */
40
+ finish() {
41
+ const missingTerminal = this.requireTerminal && !this.terminal;
42
+ const success = !missingTerminal && (!this.terminal || this.terminal === "completed" || this.terminal === "incomplete");
43
+ return {
44
+ success,
45
+ missingTerminal,
46
+ errorCode: missingTerminal ? "upstream_missing_terminal" : this.terminal && this.terminal !== "completed" ? `upstream_response_${this.terminal}` : null,
47
+ };
48
+ }
49
+ }
@@ -1,5 +1,6 @@
1
1
  import type { ServerResponse } from "node:http";
2
2
  import type { RuntimeRotationProxyStatus } from "../runtime/rotation-server-types.js";
3
+ import type { StreamCompletion } from "./response-outcome.js";
3
4
  export declare const HOP_BY_HOP_HEADERS: Set<string>;
4
5
  export declare function responseHeadersForClient(upstreamHeaders: Headers): Record<string, string>;
5
6
  export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, onTimeout: () => void, message: string): Promise<T>;
@@ -13,5 +14,5 @@ export declare function forwardStreamingResponse(upstream: Response, res: Server
13
14
  */
14
15
  onChunk?: (chunk: Uint8Array) => void,
15
16
  /** Additional response headers, applied after (so they can override) the forwarded upstream ones. */
16
- extraHeaders?: Record<string, string>): Promise<boolean>;
17
+ extraHeaders?: Record<string, string>, completion?: () => StreamCompletion): Promise<boolean>;
17
18
  //# sourceMappingURL=stream-failover-runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream-failover-runtime.d.ts","sourceRoot":"","sources":["../../../lib/request/stream-failover-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AAEtF,eAAO,MAAM,kBAAkB,aAW7B,CAAC;AAWH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUzF;AAED,wBAAsB,WAAW,CAAC,CAAC,EAClC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,IAAI,EACrB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,CAAC,CAmBZ;AAED,wBAAsB,aAAa,CAClC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,SAAc,GACpB,OAAO,CAAC,MAAM,CAAC,CAuDjB;AAoBD,wBAAsB,wBAAwB,CAC7C,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,0BAA0B,EAClC,aAAa,EAAE,MAAM,IAAI,EACzB,oBAAoB,EAAE,MAAM;AAC5B;;;;;GAKG;AACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;AACrC,qGAAqG;AACrG,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,OAAO,CAAC,OAAO,CAAC,CAsDlB"}
1
+ {"version":3,"file":"stream-failover-runtime.d.ts","sourceRoot":"","sources":["../../../lib/request/stream-failover-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,eAAO,MAAM,kBAAkB,aAW7B,CAAC;AAWH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUzF;AAED,wBAAsB,WAAW,CAAC,CAAC,EAClC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,IAAI,EACrB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,CAAC,CAmBZ;AAED,wBAAsB,aAAa,CAClC,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,SAAc,GACpB,OAAO,CAAC,MAAM,CAAC,CAuDjB;AAoBD,wBAAsB,wBAAwB,CAC7C,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,0BAA0B,EAClC,aAAa,EAAE,MAAM,IAAI,EACzB,oBAAoB,EAAE,MAAM;AAC5B;;;;;GAKG;AACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;AACrC,qGAAqG;AACrG,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,UAAU,CAAC,EAAE,MAAM,gBAAgB,GACjC,OAAO,CAAC,OAAO,CAAC,CAmElB"}
@@ -1,3 +1,4 @@
1
+ import { ClientCancellationError } from "./client-cancellation.js";
1
2
  export const HOP_BY_HOP_HEADERS = new Set([
2
3
  "connection",
3
4
  "content-length",
@@ -137,19 +138,34 @@ export async function forwardStreamingResponse(upstream, res, status, onStreamEr
137
138
  */
138
139
  onChunk,
139
140
  /** Additional response headers, applied after (so they can override) the forwarded upstream ones. */
140
- extraHeaders) {
141
+ extraHeaders, completion) {
141
142
  status.streamsStarted += 1;
142
143
  res.writeHead(upstream.status, {
143
144
  ...responseHeadersForClient(upstream.headers),
144
145
  ...extraHeaders,
145
146
  });
146
- if (!upstream.body) {
147
+ let clientDisconnected = false;
148
+ const finish = () => {
149
+ if (clientDisconnected || res.destroyed)
150
+ return false;
151
+ const result = completion?.();
152
+ // Already ended by a concurrent close path: never write after end.
153
+ if (res.writableEnded)
154
+ return false;
155
+ if (result && !result.success) {
156
+ status.lastError = result.errorCode;
157
+ if (result.missingTerminal)
158
+ res.write(Buffer.from(`data: ${JSON.stringify({ type: "error", error: { code: result.errorCode, message: "Upstream ended before completing the response." } })}\n\n`));
159
+ }
147
160
  res.end();
148
- return true;
149
- }
161
+ return result?.success ?? true;
162
+ };
163
+ if (!upstream.body)
164
+ return finish();
150
165
  const reader = upstream.body.getReader();
151
166
  res.on("close", () => {
152
167
  if (!res.writableEnded) {
168
+ clientDisconnected = true;
153
169
  void reader.cancel().catch(() => undefined);
154
170
  }
155
171
  });
@@ -163,10 +179,9 @@ extraHeaders) {
163
179
  if (value && value.byteLength > 0) {
164
180
  onChunk?.(value);
165
181
  // If the response is already finished (clean end by a concurrent
166
- // close-then-reader-cancel path), stop writing. Do NOT guard on
167
- // res.destroyed here: a socket-error-during-backpressure scenario sets
168
- // destroyed=true and then lets the next res.write() throw so the catch
169
- // block can record the error and fire onStreamError correctly.
182
+ // close-then-reader-cancel path), stop writing. A destroyed response
183
+ // is left to the next res.write(), which throws into the catch below;
184
+ // that path returns false without penalizing the upstream account.
170
185
  if (res.writableEnded)
171
186
  break;
172
187
  // Respect backpressure: when the client's socket buffer is full,
@@ -177,10 +192,14 @@ extraHeaders) {
177
192
  }
178
193
  }
179
194
  }
180
- res.end();
181
- return true;
195
+ return finish();
182
196
  }
183
197
  catch (error) {
198
+ if (clientDisconnected || res.destroyed || (error instanceof ClientCancellationError)) {
199
+ if (!res.destroyed)
200
+ res.destroy();
201
+ return false;
202
+ }
184
203
  status.lastError = error instanceof Error ? error.message : String(error);
185
204
  onStreamError();
186
205
  if (!res.destroyed) {
@@ -1 +1 @@
1
- {"version":3,"file":"account-check.d.ts","sourceRoot":"","sources":["../../../lib/runtime/account-check.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EACN,KAAK,gBAAgB,EAErB,KAAK,wBAAwB,EAE7B,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,wBAAsB,sBAAsB,CAC3C,SAAS,EAAE,OAAO,EAClB,IAAI,EAAE;IACL,aAAa,EAAE,CACd,OAAO,EAAE,gBAAgB,GAAG,IAAI,KAC5B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACtC,YAAY,EAAE,MAAM,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACrD,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;IAC3C,mBAAmB,EAAE,MAAM,OAAO,CAAC;QAClC,OAAO,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE,wBAAwB,EAAE,CAAC;KACrC,CAAC,CAAC;IACH,8BAA8B,EAAE,CAAC,cAAc,EAAE;QAChD,OAAO,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE,wBAAwB,EAAE,CAAC;KACrC,KAAK,wBAAwB,CAAC;IAC/B,2BAA2B,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAChE;QACA,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KAClB,GACD,IAAI,GACJ,SAAS,CACX,CAAC;IACF,gBAAgB,EAAE,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,GAAG,SAAS,CAAC;IAC1E,8BAA8B,EAAE,CAC/B,MAAM,EAAE,eAAe,GAAG,SAAS,EACnC,gBAAgB,EAAE,MAAM,GAAG,SAAS,KAChC,OAAO,CAAC;IACb,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,GAAG,SAAS,CAAC;IACjE,mBAAmB,EAAE,CACpB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,KACxB,MAAM,GAAG,SAAS,CAAC;IACxB,aAAa,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D,yBAAyB,EAAE,CAC1B,OAAO,EAAE,OAAO,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC,KAC7C,OAAO,CAAC;IACb,uBAAuB,EAAE,CAAC,MAAM,EAAE;QACjC,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;KACpB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAClC,uBAAuB,EAAE,CACxB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,eAAe,EAAE,eAAe,GAAG,SAAS,EAC5C,cAAc,EAAE,MAAM,GAAG,SAAS,KAC9B,MAAM,GAAG,SAAS,CAAC;IACxB,oBAAoB,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,MAAM,CAAC;IAC/D,yBAAyB,EAAE,CAC1B,OAAO,EAAE,gBAAgB,EACzB,aAAa,EAAE,SAAS,WAAW,EAAE,KACjC,IAAI,CAAC;IACV,cAAc,EAAE,SAAS,WAAW,EAAE,CAAC;IACvC,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,6BAA6B,EAAE,MAAM,IAAI,CAAC;IAC1C,mBAAmB,EAAE,CAAC,OAAO,EAAE;QAC9B,OAAO,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE,wBAAwB,EAAE,CAAC;KACrC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB,+BAA+B,CAAC,EAAE,CACjC,cAAc,EAAE,gBAAgB,EAChC,cAAc,EAAE;QACf,OAAO,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE,wBAAwB,EAAE,CAAC;KACrC,KACG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,GACC,OAAO,CAAC,IAAI,CAAC,CA2Sf"}
1
+ {"version":3,"file":"account-check.d.ts","sourceRoot":"","sources":["../../../lib/runtime/account-check.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,11 @@
1
1
  import { maskEmail } from "../logger.js";
2
2
  import { CODEX_UNAVAILABLE_PROBE_NOTE } from "../quota-probe.js";
3
3
  import { isCodexUnavailableError } from "../errors.js";
4
- import { bumpStorageAffinityGeneration, reconcilePinnedAccountIndex, } from "../storage.js";
4
+ import { cloneTrackedAccountStorage, bumpStorageAffinityGeneration, reconcilePinnedAccountIndex, } from "../storage.js";
5
5
  export async function runRuntimeAccountCheck(deepProbe, deps) {
6
6
  const loadedStorage = await deps.hydrateEmails(await deps.loadAccounts());
7
7
  const workingStorage = loadedStorage
8
- ? {
9
- ...loadedStorage,
10
- accounts: loadedStorage.accounts.map((account) => ({ ...account })),
11
- activeIndexByFamily: loadedStorage.activeIndexByFamily
12
- ? { ...loadedStorage.activeIndexByFamily }
13
- : {},
14
- }
8
+ ? cloneTrackedAccountStorage(loadedStorage)
15
9
  : deps.createEmptyStorage();
16
10
  if (workingStorage.accounts.length === 0) {
17
11
  deps.showLine("\nNo accounts to check.\n");