codex-multi-auth 2.16.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 (256) hide show
  1. package/.codex-plugin/plugin.json +1 -1
  2. package/README.md +22 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +8 -3
  5. package/dist/lib/account-policy.d.ts +4 -0
  6. package/dist/lib/account-policy.d.ts.map +1 -1
  7. package/dist/lib/account-policy.js +8 -0
  8. package/dist/lib/accounts/rate-limits.d.ts.map +1 -1
  9. package/dist/lib/accounts/rate-limits.js +2 -0
  10. package/dist/lib/accounts.d.ts +21 -3
  11. package/dist/lib/accounts.d.ts.map +1 -1
  12. package/dist/lib/accounts.js +229 -17
  13. package/dist/lib/api-route-store.d.ts +24 -0
  14. package/dist/lib/api-route-store.d.ts.map +1 -0
  15. package/dist/lib/api-route-store.js +145 -0
  16. package/dist/lib/auth/account-access.d.ts +115 -0
  17. package/dist/lib/auth/account-access.d.ts.map +1 -0
  18. package/dist/lib/auth/account-access.js +214 -0
  19. package/dist/lib/auth/token-utils.d.ts +54 -1
  20. package/dist/lib/auth/token-utils.d.ts.map +1 -1
  21. package/dist/lib/auth/token-utils.js +92 -7
  22. package/dist/lib/cli.d.ts +1 -1
  23. package/dist/lib/cli.d.ts.map +1 -1
  24. package/dist/lib/cli.js +4 -0
  25. package/dist/lib/codex-cli/state.d.ts +7 -0
  26. package/dist/lib/codex-cli/state.d.ts.map +1 -1
  27. package/dist/lib/codex-cli/state.js +18 -0
  28. package/dist/lib/codex-cli/writer.d.ts.map +1 -1
  29. package/dist/lib/codex-cli/writer.js +60 -8
  30. package/dist/lib/codex-manager/account-manager-commands.d.ts.map +1 -1
  31. package/dist/lib/codex-manager/account-manager-commands.js +1 -0
  32. package/dist/lib/codex-manager/account-pool-write.d.ts +3 -1
  33. package/dist/lib/codex-manager/account-pool-write.d.ts.map +1 -1
  34. package/dist/lib/codex-manager/account-pool-write.js +4 -0
  35. package/dist/lib/codex-manager/api-login-menu.d.ts +14 -0
  36. package/dist/lib/codex-manager/api-login-menu.d.ts.map +1 -0
  37. package/dist/lib/codex-manager/api-login-menu.js +224 -0
  38. package/dist/lib/codex-manager/commands/account.d.ts.map +1 -1
  39. package/dist/lib/codex-manager/commands/account.js +27 -0
  40. package/dist/lib/codex-manager/commands/best.d.ts.map +1 -1
  41. package/dist/lib/codex-manager/commands/best.js +6 -2
  42. package/dist/lib/codex-manager/commands/check.d.ts +7 -1
  43. package/dist/lib/codex-manager/commands/check.d.ts.map +1 -1
  44. package/dist/lib/codex-manager/commands/check.js +24 -3
  45. package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
  46. package/dist/lib/codex-manager/commands/forecast.js +5 -1
  47. package/dist/lib/codex-manager/commands/report.d.ts.map +1 -1
  48. package/dist/lib/codex-manager/commands/report.js +5 -1
  49. package/dist/lib/codex-manager/commands/resets.d.ts +2 -0
  50. package/dist/lib/codex-manager/commands/resets.d.ts.map +1 -0
  51. package/dist/lib/codex-manager/commands/resets.js +67 -0
  52. package/dist/lib/codex-manager/commands/rotation.d.ts +2 -2
  53. package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -1
  54. package/dist/lib/codex-manager/commands/rotation.js +63 -12
  55. package/dist/lib/codex-manager/commands/status.d.ts +12 -1
  56. package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
  57. package/dist/lib/codex-manager/commands/status.js +166 -22
  58. package/dist/lib/codex-manager/commands/uninstall.js +1 -1
  59. package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +1 -1
  60. package/dist/lib/codex-manager/formatters/quota-formatters.js +3 -2
  61. package/dist/lib/codex-manager/health-check.d.ts +3 -0
  62. package/dist/lib/codex-manager/health-check.d.ts.map +1 -1
  63. package/dist/lib/codex-manager/health-check.js +56 -6
  64. package/dist/lib/codex-manager/help.d.ts.map +1 -1
  65. package/dist/lib/codex-manager/help.js +4 -2
  66. package/dist/lib/codex-manager/login-flow.d.ts.map +1 -1
  67. package/dist/lib/codex-manager/login-flow.js +69 -7
  68. package/dist/lib/codex-manager/login-menu-data.d.ts.map +1 -1
  69. package/dist/lib/codex-manager/login-menu-data.js +14 -5
  70. package/dist/lib/codex-manager/login-oauth.d.ts +3 -0
  71. package/dist/lib/codex-manager/login-oauth.d.ts.map +1 -1
  72. package/dist/lib/codex-manager/login-oauth.js +6 -1
  73. package/dist/lib/codex-manager/login-workspace-choice.d.ts +11 -0
  74. package/dist/lib/codex-manager/login-workspace-choice.d.ts.map +1 -0
  75. package/dist/lib/codex-manager/login-workspace-choice.js +37 -0
  76. package/dist/lib/codex-manager/persist-selected-account.d.ts.map +1 -1
  77. package/dist/lib/codex-manager/persist-selected-account.js +2 -1
  78. package/dist/lib/codex-manager/repair-commands.d.ts +13 -0
  79. package/dist/lib/codex-manager/repair-commands.d.ts.map +1 -1
  80. package/dist/lib/codex-manager/repair-commands.js +143 -8
  81. package/dist/lib/codex-manager.d.ts.map +1 -1
  82. package/dist/lib/codex-manager.js +25 -6
  83. package/dist/lib/concurrency.d.ts +3 -0
  84. package/dist/lib/concurrency.d.ts.map +1 -0
  85. package/dist/lib/concurrency.js +31 -0
  86. package/dist/lib/model-route-policy.d.ts +52 -0
  87. package/dist/lib/model-route-policy.d.ts.map +1 -0
  88. package/dist/lib/model-route-policy.js +159 -0
  89. package/dist/lib/policy/runtime-policy.d.ts +1 -0
  90. package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
  91. package/dist/lib/policy/runtime-policy.js +3 -0
  92. package/dist/lib/preemptive-quota-scheduler.d.ts +2 -0
  93. package/dist/lib/preemptive-quota-scheduler.d.ts.map +1 -1
  94. package/dist/lib/preemptive-quota-scheduler.js +4 -0
  95. package/dist/lib/quota-probe.d.ts +5 -0
  96. package/dist/lib/quota-probe.d.ts.map +1 -1
  97. package/dist/lib/quota-probe.js +26 -2
  98. package/dist/lib/request/client-cancellation.d.ts +5 -0
  99. package/dist/lib/request/client-cancellation.d.ts.map +1 -0
  100. package/dist/lib/request/client-cancellation.js +7 -0
  101. package/dist/lib/request/response-outcome.d.ts +25 -0
  102. package/dist/lib/request/response-outcome.d.ts.map +1 -0
  103. package/dist/lib/request/response-outcome.js +49 -0
  104. package/dist/lib/request/stream-failover-runtime.d.ts +2 -1
  105. package/dist/lib/request/stream-failover-runtime.d.ts.map +1 -1
  106. package/dist/lib/request/stream-failover-runtime.js +29 -10
  107. package/dist/lib/runtime/account-check.d.ts.map +1 -1
  108. package/dist/lib/runtime/account-check.js +2 -8
  109. package/dist/lib/runtime/account-model-catalog.d.ts +64 -0
  110. package/dist/lib/runtime/account-model-catalog.d.ts.map +1 -0
  111. package/dist/lib/runtime/account-model-catalog.js +154 -0
  112. package/dist/lib/runtime/account-pool.d.ts +3 -1
  113. package/dist/lib/runtime/account-pool.d.ts.map +1 -1
  114. package/dist/lib/runtime/account-pool.js +4 -0
  115. package/dist/lib/runtime/account-reset-credits.d.ts +42 -0
  116. package/dist/lib/runtime/account-reset-credits.d.ts.map +1 -0
  117. package/dist/lib/runtime/account-reset-credits.js +82 -0
  118. package/dist/lib/runtime/api-model-capabilities.d.ts +30 -0
  119. package/dist/lib/runtime/api-model-capabilities.d.ts.map +1 -0
  120. package/dist/lib/runtime/api-model-capabilities.js +434 -0
  121. package/dist/lib/runtime/api-model-runtime.d.ts +42 -0
  122. package/dist/lib/runtime/api-model-runtime.d.ts.map +1 -0
  123. package/dist/lib/runtime/api-model-runtime.js +358 -0
  124. package/dist/lib/runtime/app-bind.d.ts +19 -1
  125. package/dist/lib/runtime/app-bind.d.ts.map +1 -1
  126. package/dist/lib/runtime/app-bind.js +79 -9
  127. package/dist/lib/runtime/automatic-account-checks.d.ts +31 -0
  128. package/dist/lib/runtime/automatic-account-checks.d.ts.map +1 -0
  129. package/dist/lib/runtime/automatic-account-checks.js +113 -0
  130. package/dist/lib/runtime/automatic-subscription-checks.d.ts +7 -0
  131. package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +1 -0
  132. package/dist/lib/runtime/automatic-subscription-checks.js +57 -0
  133. package/dist/lib/runtime/catalog-capabilities.d.ts +8 -0
  134. package/dist/lib/runtime/catalog-capabilities.d.ts.map +1 -0
  135. package/dist/lib/runtime/catalog-capabilities.js +61 -0
  136. package/dist/lib/runtime/inference-activity.d.ts +15 -0
  137. package/dist/lib/runtime/inference-activity.d.ts.map +1 -0
  138. package/dist/lib/runtime/inference-activity.js +95 -0
  139. package/dist/lib/runtime/model-discovery-status.d.ts +100 -0
  140. package/dist/lib/runtime/model-discovery-status.d.ts.map +1 -0
  141. package/dist/lib/runtime/model-discovery-status.js +387 -0
  142. package/dist/lib/runtime/native-account-storage.d.ts +11 -0
  143. package/dist/lib/runtime/native-account-storage.d.ts.map +1 -0
  144. package/dist/lib/runtime/native-account-storage.js +50 -0
  145. package/dist/lib/runtime/native-account-sync.d.ts +19 -0
  146. package/dist/lib/runtime/native-account-sync.d.ts.map +1 -0
  147. package/dist/lib/runtime/native-account-sync.js +62 -0
  148. package/dist/lib/runtime/native-binding-lock.d.ts +3 -0
  149. package/dist/lib/runtime/native-binding-lock.d.ts.map +1 -0
  150. package/dist/lib/runtime/native-binding-lock.js +5 -0
  151. package/dist/lib/runtime/native-client-auth.d.ts +3 -0
  152. package/dist/lib/runtime/native-client-auth.d.ts.map +1 -0
  153. package/dist/lib/runtime/native-client-auth.js +42 -0
  154. package/dist/lib/runtime/native-provider-config.d.ts +4 -0
  155. package/dist/lib/runtime/native-provider-config.d.ts.map +1 -0
  156. package/dist/lib/runtime/native-provider-config.js +52 -0
  157. package/dist/lib/runtime/native-rate-limits.d.ts +18 -0
  158. package/dist/lib/runtime/native-rate-limits.d.ts.map +1 -0
  159. package/dist/lib/runtime/native-rate-limits.js +135 -0
  160. package/dist/lib/runtime/reset-credit-routing.d.ts +41 -0
  161. package/dist/lib/runtime/reset-credit-routing.d.ts.map +1 -0
  162. package/dist/lib/runtime/reset-credit-routing.js +66 -0
  163. package/dist/lib/runtime/reset-credits.d.ts +101 -0
  164. package/dist/lib/runtime/reset-credits.d.ts.map +1 -0
  165. package/dist/lib/runtime/reset-credits.js +162 -0
  166. package/dist/lib/runtime/response-output-history.d.ts +17 -0
  167. package/dist/lib/runtime/response-output-history.d.ts.map +1 -0
  168. package/dist/lib/runtime/response-output-history.js +85 -0
  169. package/dist/lib/runtime/responses-websocket.d.ts +31 -0
  170. package/dist/lib/runtime/responses-websocket.d.ts.map +1 -0
  171. package/dist/lib/runtime/responses-websocket.js +636 -0
  172. package/dist/lib/runtime/resume-picker.d.ts +41 -0
  173. package/dist/lib/runtime/resume-picker.d.ts.map +1 -0
  174. package/dist/lib/runtime/resume-picker.js +169 -0
  175. package/dist/lib/runtime/rotation-account-selection.d.ts +6 -0
  176. package/dist/lib/runtime/rotation-account-selection.d.ts.map +1 -1
  177. package/dist/lib/runtime/rotation-account-selection.js +63 -0
  178. package/dist/lib/runtime/rotation-proxy-state.d.ts +33 -0
  179. package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
  180. package/dist/lib/runtime/rotation-server-types.d.ts +18 -0
  181. package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
  182. package/dist/lib/runtime/runtime-capability-failures.d.ts +14 -0
  183. package/dist/lib/runtime/runtime-capability-failures.d.ts.map +1 -0
  184. package/dist/lib/runtime/runtime-capability-failures.js +76 -0
  185. package/dist/lib/runtime/runtime-observability.d.ts +7 -0
  186. package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
  187. package/dist/lib/runtime/runtime-observability.js +42 -2
  188. package/dist/lib/runtime/subscription-first-use.d.ts +10 -0
  189. package/dist/lib/runtime/subscription-first-use.d.ts.map +1 -0
  190. package/dist/lib/runtime/subscription-first-use.js +64 -0
  191. package/dist/lib/runtime/subscription-quota-event.d.ts +6 -0
  192. package/dist/lib/runtime/subscription-quota-event.d.ts.map +1 -0
  193. package/dist/lib/runtime/subscription-quota-event.js +31 -0
  194. package/dist/lib/runtime/subscription-quota-order.d.ts +17 -0
  195. package/dist/lib/runtime/subscription-quota-order.d.ts.map +1 -0
  196. package/dist/lib/runtime/subscription-quota-order.js +31 -0
  197. package/dist/lib/runtime/workspace-model-scopes.d.ts +15 -0
  198. package/dist/lib/runtime/workspace-model-scopes.d.ts.map +1 -0
  199. package/dist/lib/runtime/workspace-model-scopes.js +34 -0
  200. package/dist/lib/runtime-constants.d.ts +3 -0
  201. package/dist/lib/runtime-constants.d.ts.map +1 -1
  202. package/dist/lib/runtime-constants.js +5 -0
  203. package/dist/lib/runtime-paths.d.ts.map +1 -1
  204. package/dist/lib/runtime-paths.js +4 -1
  205. package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
  206. package/dist/lib/runtime-rotation-proxy.js +852 -42
  207. package/dist/lib/schemas.d.ts +20 -0
  208. package/dist/lib/schemas.d.ts.map +1 -1
  209. package/dist/lib/schemas.js +3 -0
  210. package/dist/lib/storage/credential-sidecars.d.ts +13 -0
  211. package/dist/lib/storage/credential-sidecars.d.ts.map +1 -0
  212. package/dist/lib/storage/credential-sidecars.js +52 -0
  213. package/dist/lib/storage/file-lock.d.ts +9 -0
  214. package/dist/lib/storage/file-lock.d.ts.map +1 -0
  215. package/dist/lib/storage/file-lock.js +186 -0
  216. package/dist/lib/storage/flagged-storage.d.ts.map +1 -1
  217. package/dist/lib/storage/flagged-storage.js +12 -0
  218. package/dist/lib/storage/path-state.d.ts +2 -0
  219. package/dist/lib/storage/path-state.d.ts.map +1 -1
  220. package/dist/lib/storage/path-state.js +9 -0
  221. package/dist/lib/storage/paths.js +4 -4
  222. package/dist/lib/storage/pending-auth.d.ts +17 -0
  223. package/dist/lib/storage/pending-auth.d.ts.map +1 -0
  224. package/dist/lib/storage/pending-auth.js +153 -0
  225. package/dist/lib/storage/public-types.d.ts +13 -0
  226. package/dist/lib/storage/public-types.d.ts.map +1 -1
  227. package/dist/lib/storage/snapshot-merge.d.ts +16 -0
  228. package/dist/lib/storage/snapshot-merge.d.ts.map +1 -0
  229. package/dist/lib/storage/snapshot-merge.js +206 -0
  230. package/dist/lib/storage/transactions.d.ts.map +1 -1
  231. package/dist/lib/storage/transactions.js +5 -4
  232. package/dist/lib/storage.d.ts +6 -0
  233. package/dist/lib/storage.d.ts.map +1 -1
  234. package/dist/lib/storage.js +77 -7
  235. package/dist/lib/ui/auth-menu-builder.d.ts +2 -0
  236. package/dist/lib/ui/auth-menu-builder.d.ts.map +1 -1
  237. package/dist/lib/ui/auth-menu-builder.js +1 -0
  238. package/dist/lib/ui/auth-menu.d.ts.map +1 -1
  239. package/dist/lib/ui/auth-menu.js +1 -0
  240. package/dist/lib/ui/check-progress.d.ts +8 -0
  241. package/dist/lib/ui/check-progress.d.ts.map +1 -0
  242. package/dist/lib/ui/check-progress.js +30 -0
  243. package/dist/lib/ui/format.d.ts +3 -1
  244. package/dist/lib/ui/format.d.ts.map +1 -1
  245. package/dist/lib/ui/format.js +8 -0
  246. package/dist/lib/ui/ui-copy.d.ts +2 -2
  247. package/dist/lib/ui/ui-copy.js +2 -2
  248. package/dist/lib/usage/pricing.js +2 -2
  249. package/dist/lib/usage/usage-extraction.d.ts +3 -1
  250. package/dist/lib/usage/usage-extraction.d.ts.map +1 -1
  251. package/dist/lib/usage/usage-extraction.js +46 -9
  252. package/package.json +7 -4
  253. package/scripts/codex-app-router.js +7 -0
  254. package/scripts/codex-bin-resolver.js +40 -8
  255. package/scripts/codex-routing.js +1 -0
  256. package/scripts/codex.js +100 -22
@@ -0,0 +1,31 @@
1
+ import { type AccountPolicyStore } from "../account-policy.js";
2
+ import type { AccountStorageV3 } from "../storage.js";
3
+ export declare const AUTOMATIC_CHECK_INTERVAL_MS: number;
4
+ /** First tick after router start, so a short CLI session still gets its check. */
5
+ export declare const AUTOMATIC_CHECK_INITIAL_DELAY_MS = 5000;
6
+ export interface AutomaticAccountCheckOptions {
7
+ path: string;
8
+ loadAccounts: () => Promise<AccountStorageV3 | null>;
9
+ loadPolicies: () => Promise<AccountPolicyStore>;
10
+ check: (storage: AccountStorageV3, index: number, signal: AbortSignal) => Promise<void>;
11
+ now?: () => number;
12
+ signal?: AbortSignal;
13
+ }
14
+ /** A durable attempt precedes network I/O, so failures and competing routers cannot double-prime. */
15
+ export declare function runAutomaticAccountChecks(options: AutomaticAccountCheckOptions): Promise<void>;
16
+ /**
17
+ * No overlapping ticks; shutdown cancels the active probe and waits for its cleanup.
18
+ * The first tick runs shortly after start, off the startup path; the durable
19
+ * per-account attempts in runAutomaticAccountChecks keep it from repeating work
20
+ * this or another router did recently, and it does nothing without an opt-in.
21
+ *
22
+ * Each later tick is scheduled one interval after the previous run finishes.
23
+ * A run records its attempts before it finishes, so the next tick is never
24
+ * inside the durable per-account limit. A fixed setInterval ticked just inside
25
+ * it (by the initial delay plus the run's own duration), skipped every
26
+ * account, and stretched the cadence to two intervals.
27
+ */
28
+ export declare function startAutomaticAccountChecks(run: (signal: AbortSignal) => Promise<void>): {
29
+ stop(): Promise<void>;
30
+ };
31
+ //# sourceMappingURL=automatic-account-checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automatic-account-checks.d.ts","sourceRoot":"","sources":["../../../lib/runtime/automatic-account-checks.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKtD,eAAO,MAAM,2BAA2B,QAAa,CAAC;AACtD,kFAAkF;AAClF,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAKrD,MAAM,WAAW,4BAA4B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChD,KAAK,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACxB;AAwBD,qGAAqG;AACrG,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCpG;AACD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC;;EAwBtF"}
@@ -0,0 +1,113 @@
1
+ import { promises as fs } from "node:fs";
2
+ import { z } from "zod";
3
+ import { getAccountPolicyKey } from "../account-policy.js";
4
+ import { withFileTransactionLock } from "../storage/file-lock.js";
5
+ import { withRetry } from "../fs-retry.js";
6
+ import { tempPathFor } from "../temp-path.js";
7
+ import { logWarn } from "../logger.js";
8
+ export const AUTOMATIC_CHECK_INTERVAL_MS = 15 * 60000;
9
+ /** First tick after router start, so a short CLI session still gets its check. */
10
+ export const AUTOMATIC_CHECK_INITIAL_DELAY_MS = 5000;
11
+ /** An attempt stamped further ahead than this predates a backwards clock step: treat it as expired. */
12
+ const FUTURE_SKEW_MS = 5 * 60000;
13
+ const schema = z.record(z.string().regex(/^sha256:[a-f0-9]{64}$/), z.number().finite().nonnegative());
14
+ const retry = { maxAttempts: 6, backoffMs: 25 };
15
+ async function readAttempts(path) {
16
+ try {
17
+ const raw = await withRetry(() => fs.readFile(path, "utf8"), retry);
18
+ if (Buffer.byteLength(raw) > 1024 * 1024)
19
+ throw Error("Automatic-check history exceeds its size limit");
20
+ return schema.parse(JSON.parse(raw));
21
+ }
22
+ catch (error) {
23
+ if (error.code === "ENOENT")
24
+ return {};
25
+ throw error;
26
+ }
27
+ }
28
+ async function saveAttempts(path, attempts) {
29
+ const temp = tempPathFor(path);
30
+ try {
31
+ await fs.writeFile(temp, JSON.stringify(attempts) + "\n", { mode: 0o600, flag: "wx" });
32
+ await withRetry(() => fs.rename(temp, path), retry);
33
+ }
34
+ finally {
35
+ await withRetry(() => fs.rm(temp, { force: true }), retry);
36
+ }
37
+ }
38
+ /** A durable attempt precedes network I/O, so failures and competing routers cannot double-prime. */
39
+ export async function runAutomaticAccountChecks(options) {
40
+ const signal = options.signal ?? new AbortController().signal;
41
+ if (signal.aborted || !Object.values((await options.loadPolicies()).accounts).some(p => p.autoPrime))
42
+ return;
43
+ await withFileTransactionLock(options.path, async () => {
44
+ const policies = await options.loadPolicies();
45
+ const storage = await options.loadAccounts();
46
+ if (!storage || signal.aborted)
47
+ return;
48
+ const attempts = await readAttempts(options.path);
49
+ const keys = new Set(storage.accounts.map(a => getAccountPolicyKey(a)));
50
+ for (const key of Object.keys(attempts))
51
+ if (!keys.has(key))
52
+ delete attempts[key];
53
+ for (let index = 0; index < storage.accounts.length; index++) {
54
+ if (signal.aborted)
55
+ break;
56
+ const account = storage.accounts[index];
57
+ if (!account)
58
+ continue;
59
+ const key = getAccountPolicyKey(account), policy = policies.accounts[key], now = options.now?.() ?? Date.now();
60
+ if (!policy?.autoPrime || policy.paused || policy.drained || account.enabled === false || account.authInvalidatedAt || (account.coolingDownUntil ?? 0) > now)
61
+ continue;
62
+ const lastAttempt = attempts[key];
63
+ if (lastAttempt !== undefined && lastAttempt <= now + FUTURE_SKEW_MS && now - lastAttempt < AUTOMATIC_CHECK_INTERVAL_MS)
64
+ continue;
65
+ attempts[key] = now;
66
+ await saveAttempts(options.path, attempts);
67
+ try {
68
+ await options.check(storage, index, signal);
69
+ }
70
+ catch {
71
+ if (!signal.aborted)
72
+ logWarn("Automatic subscription check failed; retry deferred until the next interval.");
73
+ }
74
+ }
75
+ }, { waitMs: 0 });
76
+ }
77
+ /**
78
+ * No overlapping ticks; shutdown cancels the active probe and waits for its cleanup.
79
+ * The first tick runs shortly after start, off the startup path; the durable
80
+ * per-account attempts in runAutomaticAccountChecks keep it from repeating work
81
+ * this or another router did recently, and it does nothing without an opt-in.
82
+ *
83
+ * Each later tick is scheduled one interval after the previous run finishes.
84
+ * A run records its attempts before it finishes, so the next tick is never
85
+ * inside the durable per-account limit. A fixed setInterval ticked just inside
86
+ * it (by the initial delay plus the run's own duration), skipped every
87
+ * account, and stretched the cadence to two intervals.
88
+ */
89
+ export function startAutomaticAccountChecks(run) {
90
+ const controller = new AbortController();
91
+ let pending;
92
+ let timer;
93
+ const schedule = (delayMs) => {
94
+ if (controller.signal.aborted)
95
+ return;
96
+ timer = setTimeout(tick, delayMs);
97
+ timer.unref();
98
+ };
99
+ const tick = () => {
100
+ timer = undefined;
101
+ if (controller.signal.aborted)
102
+ return;
103
+ pending = run(controller.signal).catch(() => {
104
+ if (!controller.signal.aborted)
105
+ logWarn("Automatic subscription checks unavailable; no unchecked retry was started.");
106
+ }).finally(() => {
107
+ pending = undefined;
108
+ schedule(AUTOMATIC_CHECK_INTERVAL_MS);
109
+ });
110
+ };
111
+ schedule(AUTOMATIC_CHECK_INITIAL_DELAY_MS);
112
+ return { async stop() { clearTimeout(timer); controller.abort(); await pending; } };
113
+ }
@@ -0,0 +1,7 @@
1
+ import { type AccountMetadataV3 } from "../storage.js";
2
+ import { type CodexQuotaSnapshot } from "../quota-probe.js";
3
+ type Observer = (account: AccountMetadataV3, snapshot: CodexQuotaSnapshot, accounts: AccountMetadataV3[]) => Promise<void> | void;
4
+ /** Captures this router's pool; reads only verified primary credentials, never API/ZDR entries. */
5
+ export declare function createAutomaticSubscriptionCheck(observe?: Observer): (signal: AbortSignal) => Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=automatic-subscription-checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automatic-subscription-checks.d.ts","sourceRoot":"","sources":["../../../lib/runtime/automatic-subscription-checks.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAUrF,KAAK,QAAQ,GAAG,CAAC,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAClI,mGAAmG;AACnG,wBAAgB,gCAAgC,CAAC,OAAO,CAAC,EAAE,QAAQ,IASvD,QAAQ,WAAW,mBA+B9B"}
@@ -0,0 +1,57 @@
1
+ import { getStoragePathState, runWithStoragePathState } from "../storage/path-state.js";
2
+ import { join } from "node:path";
3
+ import { AccountManager, resolveAccountRecordId } from "../accounts.js";
4
+ import { getAccountPolicyKey, loadAccountPolicyStore } from "../account-policy.js";
5
+ import { getStoragePath } from "../storage.js";
6
+ import { fetchCodexQuotaSnapshot } from "../quota-probe.js";
7
+ import { loadQuotaCache, saveQuotaCache } from "../quota-cache.js";
8
+ import { updateQuotaCacheForAccount } from "../codex-manager/quota-cache-helpers.js";
9
+ import { getCodexMultiAuthDir } from "../runtime-paths.js";
10
+ import { withFileTransactionLock } from "../storage/file-lock.js";
11
+ import { createNativeAccountStorageReader } from "./native-account-storage.js";
12
+ import { ensureFreshAccessToken } from "./rotation-token-refresh.js";
13
+ import { workspaceModelScopes } from "./workspace-model-scopes.js";
14
+ import { runAutomaticAccountChecks } from "./automatic-account-checks.js";
15
+ import { logWarn } from "../logger.js";
16
+ /** Captures this router's pool; reads only verified primary credentials, never API/ZDR entries. */
17
+ export function createAutomaticSubscriptionCheck(observe) {
18
+ const path = getStoragePath(), storageState = getStoragePathState();
19
+ const read = createNativeAccountStorageReader(undefined, path);
20
+ const quotaPath = join(getCodexMultiAuthDir(), "quota-cache.json");
21
+ const onQuota = observe ?? (async (account, snapshot, accounts) => withFileTransactionLock(quotaPath, async () => {
22
+ const cache = await loadQuotaCache();
23
+ updateQuotaCacheForAccount(cache, account, snapshot, accounts);
24
+ await saveQuotaCache(cache);
25
+ }));
26
+ return (signal) => runWithStoragePathState(storageState, () => runAutomaticAccountChecks({
27
+ path: `${path}.automatic-checks.json`, signal, loadPolicies: loadAccountPolicyStore,
28
+ loadAccounts: async () => { const snapshot = await read(); return snapshot.verified ? snapshot.storage : null; },
29
+ check: async (storage, index) => {
30
+ const manager = new AccountManager(undefined, storage);
31
+ const account = manager.getAccountByIndex(index);
32
+ if (!account || !workspaceModelScopes(account).some(s => s.bound && s.routable) || signal.aborted)
33
+ return;
34
+ const fresh = await ensureFreshAccessToken({ accountManager: manager, account, family: "codex", model: null, now: Date.now(), tokenRefreshSkewMs: 60000, tokenInvalidationCooldownMs: 300000 });
35
+ try {
36
+ if (!fresh.ok || signal.aborted)
37
+ return;
38
+ // A refresh is an I/O boundary: revalidate removal, policy, auth and workspace changes.
39
+ const disk = await read();
40
+ const current = disk.verified ? disk.storage?.accounts.find(row => resolveAccountRecordId(row) === resolveAccountRecordId(fresh.account)) : undefined;
41
+ const policy = current ? (await loadAccountPolicyStore()).accounts[getAccountPolicyKey(current)] : undefined;
42
+ if (!disk.storage || !current || current.refreshToken !== fresh.account.refreshToken || current.accessToken !== fresh.accessToken || !policy?.autoPrime || policy.paused || policy.drained || current.enabled === false || current.authInvalidatedAt || (current.coolingDownUntil ?? 0) > Date.now())
43
+ return;
44
+ const bound = workspaceModelScopes(fresh.account).find(s => s.bound && s.routable);
45
+ if (!bound || (current.accountId && current.accountId !== bound.accountId) || current.workspaces?.some(w => w.id === bound.accountId && w.enabled === false) || signal.aborted)
46
+ return;
47
+ const snapshot = await fetchCodexQuotaSnapshot({ accountId: bound.accountId, accessToken: fresh.accessToken, primeUnusedSubscription: true, signal });
48
+ if (snapshot.primingFailure)
49
+ logWarn("Automatic first-use completion was not confirmed; retry deferred until the next check.");
50
+ await onQuota(current, snapshot, disk.storage.accounts);
51
+ }
52
+ finally {
53
+ await manager.flushPendingSave();
54
+ }
55
+ },
56
+ }));
57
+ }
@@ -0,0 +1,8 @@
1
+ import type { CatalogModel } from "./account-model-catalog.js";
2
+ /** Aggregate complete source records so advertised controls never invent a pair. */
3
+ export declare function mergeCatalogModels(models: readonly CatalogModel[]): CatalogModel | undefined;
4
+ /** Two-source convenience; multi-account callers must retain all original records. */
5
+ export declare function mergeCatalogModel(a: CatalogModel, b: CatalogModel): CatalogModel;
6
+ export declare function clampCatalogContext(a: CatalogModel, b: CatalogModel): CatalogModel;
7
+ export declare function supportsCatalogSettings(model: CatalogModel, effort?: string, tier?: string): boolean;
8
+ //# sourceMappingURL=catalog-capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-capabilities.d.ts","sourceRoot":"","sources":["../../../lib/runtime/catalog-capabilities.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG/D,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,YAAY,GAAG,SAAS,CA4B5F;AACD,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,YAAY,CAEhF;AACD,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,YAAY,CAWlF;AACD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAMpG"}
@@ -0,0 +1,61 @@
1
+ import { isRecord } from "../utils.js";
2
+ const contextLimits = ["context_window", "max_context_window", "auto_compact_token_limit"];
3
+ const canonicalTier = (value) => value === "priority" ? "fast" : value;
4
+ /** Aggregate complete source records so advertised controls never invent a pair. */
5
+ export function mergeCatalogModels(models) {
6
+ const first = models[0];
7
+ if (!first)
8
+ return undefined;
9
+ let result = { ...first };
10
+ for (const [field, key] of [["supported_reasoning_levels", "effort"], ["service_tiers", "id"]]) {
11
+ const options = new Map();
12
+ for (const model of models)
13
+ for (const option of Array.isArray(model[field]) ? model[field] : []) {
14
+ if (isRecord(option) && typeof option[key] === "string")
15
+ options.set(field === "service_tiers" ? canonicalTier(option[key]) : option[key], option);
16
+ }
17
+ if (options.size)
18
+ result[field] = [...options.values()];
19
+ }
20
+ const efforts = Array.isArray(result.supported_reasoning_levels)
21
+ ? result.supported_reasoning_levels.flatMap(level => isRecord(level) && typeof level.effort === "string" ? [level.effort] : []) : [];
22
+ if (Array.isArray(result.service_tiers)) {
23
+ // Native clients expose independent effort/speed controls, not a pair matrix.
24
+ // Every selectable pair therefore needs a witness in an original catalog.
25
+ result.service_tiers = result.service_tiers.filter(tier => {
26
+ if (!isRecord(tier) || typeof tier.id !== "string")
27
+ return false;
28
+ const id = tier.id;
29
+ return (efforts.length ? efforts : [undefined]).every(effort => models.some(model => supportsCatalogSettings(model, effort, id)));
30
+ });
31
+ }
32
+ if (typeof result.default_service_tier === "string" && !["default", "auto"].includes(result.default_service_tier) &&
33
+ !supportsCatalogSettings(result, undefined, result.default_service_tier))
34
+ result.default_service_tier = "default";
35
+ for (const model of models.slice(1))
36
+ result = clampCatalogContext(result, model);
37
+ return result;
38
+ }
39
+ /** Two-source convenience; multi-account callers must retain all original records. */
40
+ export function mergeCatalogModel(a, b) {
41
+ return mergeCatalogModels([a, b]) ?? a;
42
+ }
43
+ export function clampCatalogContext(a, b) {
44
+ const result = { ...a };
45
+ // Context is not a selectable setting sent on requests. Advertise the safe
46
+ // shared limit instead of letting the first account overstate another's limit.
47
+ for (const field of contextLimits) {
48
+ if (typeof a[field] === "number" && typeof b[field] === "number")
49
+ result[field] = Math.min(a[field], b[field]);
50
+ else
51
+ delete result[field];
52
+ }
53
+ return result;
54
+ }
55
+ export function supportsCatalogSettings(model, effort, tier) {
56
+ if (effort && (!Array.isArray(model.supported_reasoning_levels) || !model.supported_reasoning_levels.some(level => isRecord(level) && level.effort === effort)))
57
+ return false;
58
+ if (tier && tier !== "default" && tier !== "auto" && (!Array.isArray(model.service_tiers) || !model.service_tiers.some(level => isRecord(level) && typeof level.id === "string" && canonicalTier(level.id) === canonicalTier(tier))))
59
+ return false;
60
+ return true;
61
+ }
@@ -0,0 +1,15 @@
1
+ import { getAccountIdentityKey } from "../storage/identity.js";
2
+ export declare function inferenceAccountKey(account: Parameters<typeof getAccountIdentityKey>[0]): string;
3
+ /** Separate from shared diagnostic snapshots: only inference dispatches write these files. */
4
+ export declare function saveInferenceRequestTime(key: string, at: number): Promise<void>;
5
+ /**
6
+ * Per-request dispatches only need the latest time per key on disk. Keep the
7
+ * newest pending time per key and write them together after a short debounce,
8
+ * instead of chaining one mkdir/read/write/rename per request.
9
+ */
10
+ export declare function createInferenceActivityWriter(save?: (key: string, at: number) => Promise<void>, delayMs?: number, onError?: (error: unknown) => void): {
11
+ record(key: string, at: number): void;
12
+ flush(): Promise<void>;
13
+ };
14
+ export declare function loadInferenceRequestTimes(keys: string[]): Promise<Record<string, number>>;
15
+ //# sourceMappingURL=inference-activity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference-activity.d.ts","sourceRoot":"","sources":["../../../lib/runtime/inference-activity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAS/D,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAEhG;AAmBD,8FAA8F;AAC9F,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBrF;AACD;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC5C,IAAI,GAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAA4B,EAC3E,OAAO,SAAO,EACd,OAAO,GAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAsB,GACjD;IAAE,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAwBnE;AACD,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAG/F"}
@@ -0,0 +1,95 @@
1
+ import { createHash } from "node:crypto";
2
+ import { getAccountIdentityKey } from "../storage/identity.js";
3
+ import { promises as fs } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { getCodexMultiAuthDir } from "../runtime-paths.js";
6
+ import { tempPathFor } from "../temp-path.js";
7
+ import { withRetry } from "../fs-retry.js";
8
+ import { withFileTransactionLock } from "../storage/file-lock.js";
9
+ import { mapWithConcurrency } from "../concurrency.js";
10
+ export function inferenceAccountKey(account) {
11
+ return `sha256:${createHash("sha256").update(getAccountIdentityKey(account) ?? "unknown").digest("hex")}`;
12
+ }
13
+ const validKey = (key) => /^sha256:[a-f0-9]{64}$/.test(key);
14
+ function activityPath(key) {
15
+ return join(getCodexMultiAuthDir(), "inference-activity", `${key.slice(7)}.json`);
16
+ }
17
+ async function readTimestamp(key) {
18
+ try {
19
+ const handle = await fs.open(activityPath(key), "r");
20
+ try {
21
+ const bytes = Buffer.alloc(64);
22
+ const { bytesRead } = await handle.read(bytes, 0, bytes.length, 0);
23
+ if (bytesRead === bytes.length)
24
+ return null;
25
+ const value = JSON.parse(bytes.subarray(0, bytesRead).toString("utf8"));
26
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : null;
27
+ }
28
+ finally {
29
+ await handle.close();
30
+ }
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ /** Separate from shared diagnostic snapshots: only inference dispatches write these files. */
37
+ export async function saveInferenceRequestTime(key, at) {
38
+ if (!validKey(key) || !Number.isFinite(at) || at <= 0)
39
+ return;
40
+ const path = activityPath(key);
41
+ await fs.mkdir(join(getCodexMultiAuthDir(), "inference-activity"), { recursive: true, mode: 0o700 });
42
+ // Read-max-write under the cross-process lock, so a concurrent writer (app
43
+ // router and a wrapper proxy) cannot replace a newer time with an older one.
44
+ await withFileTransactionLock(path, async () => {
45
+ const temp = tempPathFor(path);
46
+ const timestamp = Math.max(at, await readTimestamp(key) ?? 0);
47
+ try {
48
+ await fs.writeFile(temp, JSON.stringify(timestamp) + "\n", { mode: 0o600, flag: "wx" });
49
+ await withRetry(() => fs.rename(temp, path), { maxAttempts: 6, backoffMs: 25 });
50
+ }
51
+ finally {
52
+ await withRetry(() => fs.unlink(temp), { maxAttempts: 6, backoffMs: 25 }).catch(error => { if (error.code !== "ENOENT")
53
+ throw error; });
54
+ }
55
+ });
56
+ }
57
+ /**
58
+ * Per-request dispatches only need the latest time per key on disk. Keep the
59
+ * newest pending time per key and write them together after a short debounce,
60
+ * instead of chaining one mkdir/read/write/rename per request.
61
+ */
62
+ export function createInferenceActivityWriter(save = saveInferenceRequestTime, delayMs = 1000, onError = () => undefined) {
63
+ const pending = new Map();
64
+ let timer;
65
+ let flushing = Promise.resolve();
66
+ const flush = () => {
67
+ if (timer) {
68
+ clearTimeout(timer);
69
+ timer = undefined;
70
+ }
71
+ const batch = [...pending];
72
+ pending.clear();
73
+ flushing = flushing.then(async () => {
74
+ for (const [key, at] of batch)
75
+ await save(key, at).catch(onError);
76
+ });
77
+ return flushing;
78
+ };
79
+ return {
80
+ record(key, at) {
81
+ if (!validKey(key) || !Number.isFinite(at) || at <= 0)
82
+ return;
83
+ pending.set(key, Math.max(pending.get(key) ?? 0, at));
84
+ if (!timer) {
85
+ timer = setTimeout(() => void flush(), delayMs);
86
+ timer.unref?.();
87
+ }
88
+ },
89
+ flush,
90
+ };
91
+ }
92
+ export async function loadInferenceRequestTimes(keys) {
93
+ const entries = await mapWithConcurrency([...new Set(keys)].filter(validKey).slice(0, 1000), 4, async (key) => ({ key, at: await readTimestamp(key) }));
94
+ return Object.fromEntries(entries.flatMap(entry => entry.at === null ? [] : [[entry.key, entry.at]]));
95
+ }
@@ -0,0 +1,100 @@
1
+ import { z } from "zod";
2
+ import { type AccountStorageV3 } from "../storage.js";
3
+ import { type ApiRouteCredential, updateApiModelDiscovery } from "../api-route-store.js";
4
+ declare const schema: z.ZodObject<{
5
+ apiConfigurationUnavailable: z.ZodOptional<z.ZodBoolean>;
6
+ version: z.ZodLiteral<1>;
7
+ checkedAt: z.ZodNumber;
8
+ clientVersion: z.ZodOptional<z.ZodString>;
9
+ entries: z.ZodArray<z.ZodObject<{
10
+ id: z.ZodOptional<z.ZodString>;
11
+ routable: z.ZodOptional<z.ZodBoolean>;
12
+ bound: z.ZodOptional<z.ZodBoolean>;
13
+ selected: z.ZodOptional<z.ZodBoolean>;
14
+ changes: z.ZodOptional<z.ZodObject<{
15
+ observedAt: z.ZodNumber;
16
+ added: z.ZodArray<z.ZodString>;
17
+ removed: z.ZodArray<z.ZodString>;
18
+ capabilities: z.ZodArray<z.ZodString>;
19
+ }, z.core.$strip>>;
20
+ lastSuccessful: z.ZodOptional<z.ZodObject<{
21
+ models: z.ZodArray<z.ZodString>;
22
+ entitlements: z.ZodOptional<z.ZodArray<z.ZodObject<{
23
+ model: z.ZodString;
24
+ checkedAt: z.ZodOptional<z.ZodNumber>;
25
+ probes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
26
+ unsupported: "unsupported";
27
+ verified: "verified";
28
+ unverified: "unverified";
29
+ downgraded: "downgraded";
30
+ }>>>;
31
+ serviceTiers: z.ZodArray<z.ZodObject<{
32
+ id: z.ZodString;
33
+ name: z.ZodString;
34
+ }, z.core.$strip>>;
35
+ reasoningLevels: z.ZodArray<z.ZodString>;
36
+ accessPrograms: z.ZodArray<z.ZodString>;
37
+ }, z.core.$strip>>>;
38
+ }, z.core.$strip>>;
39
+ label: z.ZodString;
40
+ kind: z.ZodEnum<{
41
+ oauth: "oauth";
42
+ api: "api";
43
+ zdr: "zdr";
44
+ }>;
45
+ enabled: z.ZodBoolean;
46
+ checkedAt: z.ZodNumber;
47
+ error: z.ZodBoolean;
48
+ models: z.ZodArray<z.ZodString>;
49
+ visibleModels: z.ZodArray<z.ZodString>;
50
+ entitlements: z.ZodOptional<z.ZodArray<z.ZodObject<{
51
+ model: z.ZodString;
52
+ checkedAt: z.ZodOptional<z.ZodNumber>;
53
+ probes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
54
+ unsupported: "unsupported";
55
+ verified: "verified";
56
+ unverified: "unverified";
57
+ downgraded: "downgraded";
58
+ }>>>;
59
+ serviceTiers: z.ZodArray<z.ZodObject<{
60
+ id: z.ZodString;
61
+ name: z.ZodString;
62
+ }, z.core.$strip>>;
63
+ reasoningLevels: z.ZodArray<z.ZodString>;
64
+ accessPrograms: z.ZodArray<z.ZodString>;
65
+ }, z.core.$strip>>>;
66
+ }, z.core.$strip>>;
67
+ }, z.core.$strip>;
68
+ export type ModelInventory = z.infer<typeof schema>;
69
+ export declare function discoverModelInventory(storage: AccountStorageV3 | null, routes: ApiRouteCredential[], options?: {
70
+ fetchImpl?: typeof fetch;
71
+ now?: () => number;
72
+ clientVersion?: string;
73
+ updateApiDiscovery?: typeof updateApiModelDiscovery;
74
+ /** Send billable API probes even when a result is inside the 15-minute cache. */
75
+ forceProbes?: boolean;
76
+ /** Share probe results with later CLI processes through the multi-auth directory. */
77
+ persistProbes?: boolean;
78
+ }): Promise<ModelInventory>;
79
+ export declare function loadModelInventory(): Promise<ModelInventory | null>;
80
+ export declare function saveModelInventory(value: ModelInventory): Promise<void>;
81
+ export declare function formatModelInventory(inventory: ModelInventory | null, now?: number): string[];
82
+ export declare function refreshAndPrintModelInventory(log: (message: string) => void, deps?: {
83
+ getBinding?: () => Promise<{
84
+ running: boolean;
85
+ state: {
86
+ nativeOpenai?: boolean;
87
+ baseUrl: string;
88
+ clientApiKey: string;
89
+ } | null;
90
+ }>;
91
+ fetchImpl?: typeof fetch;
92
+ loadInventory?: typeof loadModelInventory;
93
+ now?: () => number;
94
+ /** Only an explicit `check capabilities` bypasses the 15-minute probe cache. */
95
+ forceProbes?: boolean;
96
+ }): Promise<boolean>;
97
+ /** Compare stable credential/workspace scopes, keeping the last successful baseline through outages. */
98
+ export declare function withInventoryChanges(current: ModelInventory, previous: ModelInventory | null): ModelInventory;
99
+ export {};
100
+ //# sourceMappingURL=model-discovery-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-discovery-status.d.ts","sourceRoot":"","sources":["../../../lib/runtime/model-discovery-status.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AACpE,OAAO,EACN,KAAK,kBAAkB,EAEvB,uBAAuB,EACvB,MAAM,uBAAuB,CAAC;AAgC/B,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAUV,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAkBpD,wBAAsB,sBAAsB,CAC3C,OAAO,EAAE,gBAAgB,GAAG,IAAI,EAChC,MAAM,EAAE,kBAAkB,EAAE,EAC5B,OAAO,GAAE;IACR,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,uBAAuB,CAAC;IACpD,iFAAiF;IACjF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qFAAqF;IACrF,aAAa,CAAC,EAAE,OAAO,CAAC;CACnB,GACJ,OAAO,CAAC,cAAc,CAAC,CAuGzB;AAID,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAgBzE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvE;AA2BD,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,cAAc,GAAG,IAAI,EAChC,GAAG,SAAa,GACd,MAAM,EAAE,CAyBV;AACD,wBAAsB,6BAA6B,CAClD,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EAC9B,IAAI,GAAE;IACL,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;QAC1B,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,EAAE;YACN,YAAY,CAAC,EAAE,OAAO,CAAC;YACvB,OAAO,EAAE,MAAM,CAAC;YAChB,YAAY,EAAE,MAAM,CAAC;SACrB,GAAG,IAAI,CAAC;KACT,CAAC,CAAC;IACH,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,kBAAkB,CAAC;IAC1C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,gFAAgF;IAChF,WAAW,CAAC,EAAE,OAAO,CAAC;CACjB,GACJ,OAAO,CAAC,OAAO,CAAC,CAwElB;AAUD,wGAAwG;AACxG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,GAAG,cAAc,CAmB7G"}