@slkiser/opencode-quota 4.0.1 → 4.2.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 (358) hide show
  1. package/README.md +94 -28
  2. package/dist/bin/opencode-quota.d.ts.map +1 -1
  3. package/dist/bin/opencode-quota.js +8 -0
  4. package/dist/bin/opencode-quota.js.map +1 -1
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/lib/anthropic.d.ts.map +1 -1
  8. package/dist/lib/anthropic.js +78 -72
  9. package/dist/lib/anthropic.js.map +1 -1
  10. package/dist/lib/api-key-resolver.d.ts +73 -22
  11. package/dist/lib/api-key-resolver.d.ts.map +1 -1
  12. package/dist/lib/api-key-resolver.js +116 -39
  13. package/dist/lib/api-key-resolver.js.map +1 -1
  14. package/dist/lib/atomic-json.d.ts +3 -1
  15. package/dist/lib/atomic-json.d.ts.map +1 -1
  16. package/dist/lib/atomic-json.js +23 -9
  17. package/dist/lib/atomic-json.js.map +1 -1
  18. package/dist/lib/chutes-config.d.ts.map +1 -1
  19. package/dist/lib/chutes-config.js +2 -4
  20. package/dist/lib/chutes-config.js.map +1 -1
  21. package/dist/lib/chutes.d.ts.map +1 -1
  22. package/dist/lib/chutes.js +28 -23
  23. package/dist/lib/chutes.js.map +1 -1
  24. package/dist/lib/cli-show.d.ts +9 -0
  25. package/dist/lib/cli-show.d.ts.map +1 -1
  26. package/dist/lib/cli-show.js +34 -5
  27. package/dist/lib/cli-show.js.map +1 -1
  28. package/dist/lib/cli-status.d.ts +8 -0
  29. package/dist/lib/cli-status.d.ts.map +1 -0
  30. package/dist/lib/cli-status.js +125 -0
  31. package/dist/lib/cli-status.js.map +1 -0
  32. package/dist/lib/config.d.ts +1 -1
  33. package/dist/lib/config.d.ts.map +1 -1
  34. package/dist/lib/config.js +47 -12
  35. package/dist/lib/config.js.map +1 -1
  36. package/dist/lib/copilot.d.ts +11 -5
  37. package/dist/lib/copilot.d.ts.map +1 -1
  38. package/dist/lib/copilot.js +378 -79
  39. package/dist/lib/copilot.js.map +1 -1
  40. package/dist/lib/deepseek-auth.d.ts.map +1 -1
  41. package/dist/lib/deepseek-auth.js +3 -7
  42. package/dist/lib/deepseek-auth.js.map +1 -1
  43. package/dist/lib/deepseek.d.ts.map +1 -1
  44. package/dist/lib/deepseek.js +22 -17
  45. package/dist/lib/deepseek.js.map +1 -1
  46. package/dist/lib/display-sanitize.d.ts.map +1 -1
  47. package/dist/lib/display-sanitize.js +8 -0
  48. package/dist/lib/display-sanitize.js.map +1 -1
  49. package/dist/lib/entries.d.ts +14 -0
  50. package/dist/lib/entries.d.ts.map +1 -1
  51. package/dist/lib/entries.js.map +1 -1
  52. package/dist/lib/format-utils.d.ts +7 -0
  53. package/dist/lib/format-utils.d.ts.map +1 -1
  54. package/dist/lib/format-utils.js +18 -0
  55. package/dist/lib/format-utils.js.map +1 -1
  56. package/dist/lib/format.d.ts +1 -0
  57. package/dist/lib/format.d.ts.map +1 -1
  58. package/dist/lib/format.js +22 -7
  59. package/dist/lib/format.js.map +1 -1
  60. package/dist/lib/glm-coding-plan.d.ts +18 -0
  61. package/dist/lib/glm-coding-plan.d.ts.map +1 -0
  62. package/dist/lib/glm-coding-plan.js +68 -0
  63. package/dist/lib/glm-coding-plan.js.map +1 -0
  64. package/dist/lib/google-agy-companion.d.ts +4 -25
  65. package/dist/lib/google-agy-companion.d.ts.map +1 -1
  66. package/dist/lib/google-agy-companion.js +47 -272
  67. package/dist/lib/google-agy-companion.js.map +1 -1
  68. package/dist/lib/google-agy.d.ts.map +1 -1
  69. package/dist/lib/google-agy.js +204 -111
  70. package/dist/lib/google-agy.js.map +1 -1
  71. package/dist/lib/google-antigravity-companion.d.ts +4 -25
  72. package/dist/lib/google-antigravity-companion.d.ts.map +1 -1
  73. package/dist/lib/google-antigravity-companion.js +44 -283
  74. package/dist/lib/google-antigravity-companion.js.map +1 -1
  75. package/dist/lib/google-companion-credentials.d.ts +70 -0
  76. package/dist/lib/google-companion-credentials.d.ts.map +1 -0
  77. package/dist/lib/google-companion-credentials.js +265 -0
  78. package/dist/lib/google-companion-credentials.js.map +1 -0
  79. package/dist/lib/google-gemini-cli-companion.d.ts +4 -25
  80. package/dist/lib/google-gemini-cli-companion.d.ts.map +1 -1
  81. package/dist/lib/google-gemini-cli-companion.js +47 -258
  82. package/dist/lib/google-gemini-cli-companion.js.map +1 -1
  83. package/dist/lib/google-gemini-cli.d.ts.map +1 -1
  84. package/dist/lib/google-gemini-cli.js +55 -61
  85. package/dist/lib/google-gemini-cli.js.map +1 -1
  86. package/dist/lib/google-token-cache.d.ts.map +1 -1
  87. package/dist/lib/google-token-cache.js +87 -34
  88. package/dist/lib/google-token-cache.js.map +1 -1
  89. package/dist/lib/google.d.ts.map +1 -1
  90. package/dist/lib/google.js +80 -84
  91. package/dist/lib/google.js.map +1 -1
  92. package/dist/lib/grouped-entry-normalization.d.ts.map +1 -1
  93. package/dist/lib/grouped-entry-normalization.js +7 -1
  94. package/dist/lib/grouped-entry-normalization.js.map +1 -1
  95. package/dist/lib/http.d.ts +12 -7
  96. package/dist/lib/http.d.ts.map +1 -1
  97. package/dist/lib/http.js +28 -15
  98. package/dist/lib/http.js.map +1 -1
  99. package/dist/lib/init-installer.d.ts +2 -1
  100. package/dist/lib/init-installer.d.ts.map +1 -1
  101. package/dist/lib/init-installer.js +29 -2
  102. package/dist/lib/init-installer.js.map +1 -1
  103. package/dist/lib/kimi-auth.d.ts +3 -26
  104. package/dist/lib/kimi-auth.d.ts.map +1 -1
  105. package/dist/lib/kimi-auth.js +24 -91
  106. package/dist/lib/kimi-auth.js.map +1 -1
  107. package/dist/lib/kimi.d.ts.map +1 -1
  108. package/dist/lib/kimi.js +20 -15
  109. package/dist/lib/kimi.js.map +1 -1
  110. package/dist/lib/maintainer-announcements.d.ts.map +1 -1
  111. package/dist/lib/maintainer-announcements.js +5 -0
  112. package/dist/lib/maintainer-announcements.js.map +1 -1
  113. package/dist/lib/map-with-concurrency.d.ts +2 -0
  114. package/dist/lib/map-with-concurrency.d.ts.map +1 -0
  115. package/dist/lib/map-with-concurrency.js +17 -0
  116. package/dist/lib/map-with-concurrency.js.map +1 -0
  117. package/dist/lib/mimo-config.d.ts +29 -0
  118. package/dist/lib/mimo-config.d.ts.map +1 -0
  119. package/dist/lib/mimo-config.js +147 -0
  120. package/dist/lib/mimo-config.js.map +1 -0
  121. package/dist/lib/mimo.d.ts +35 -0
  122. package/dist/lib/mimo.d.ts.map +1 -0
  123. package/dist/lib/mimo.js +236 -0
  124. package/dist/lib/mimo.js.map +1 -0
  125. package/dist/lib/modelsdev-pricing.d.ts.map +1 -1
  126. package/dist/lib/modelsdev-pricing.js +39 -27
  127. package/dist/lib/modelsdev-pricing.js.map +1 -1
  128. package/dist/lib/nanogpt-config.d.ts.map +1 -1
  129. package/dist/lib/nanogpt-config.js +2 -4
  130. package/dist/lib/nanogpt-config.js.map +1 -1
  131. package/dist/lib/nanogpt.d.ts.map +1 -1
  132. package/dist/lib/nanogpt.js +40 -30
  133. package/dist/lib/nanogpt.js.map +1 -1
  134. package/dist/lib/ollama-cloud.d.ts +1 -1
  135. package/dist/lib/ollama-cloud.d.ts.map +1 -1
  136. package/dist/lib/ollama-cloud.js +73 -68
  137. package/dist/lib/ollama-cloud.js.map +1 -1
  138. package/dist/lib/openai.d.ts.map +1 -1
  139. package/dist/lib/openai.js +53 -48
  140. package/dist/lib/openai.js.map +1 -1
  141. package/dist/lib/opencode-config-providers.d.ts.map +1 -1
  142. package/dist/lib/opencode-config-providers.js +13 -16
  143. package/dist/lib/opencode-config-providers.js.map +1 -1
  144. package/dist/lib/opencode-config-read.d.ts +23 -0
  145. package/dist/lib/opencode-config-read.d.ts.map +1 -0
  146. package/dist/lib/opencode-config-read.js +30 -0
  147. package/dist/lib/opencode-config-read.js.map +1 -0
  148. package/dist/lib/opencode-go.d.ts.map +1 -1
  149. package/dist/lib/opencode-go.js +44 -39
  150. package/dist/lib/opencode-go.js.map +1 -1
  151. package/dist/lib/opencode-zen-config.d.ts +34 -0
  152. package/dist/lib/opencode-zen-config.d.ts.map +1 -0
  153. package/dist/lib/opencode-zen-config.js +103 -0
  154. package/dist/lib/opencode-zen-config.js.map +1 -0
  155. package/dist/lib/opencode-zen.d.ts +27 -0
  156. package/dist/lib/opencode-zen.d.ts.map +1 -0
  157. package/dist/lib/opencode-zen.js +143 -0
  158. package/dist/lib/opencode-zen.js.map +1 -0
  159. package/dist/lib/openrouter.d.ts +13 -0
  160. package/dist/lib/openrouter.d.ts.map +1 -0
  161. package/dist/lib/openrouter.js +41 -0
  162. package/dist/lib/openrouter.js.map +1 -0
  163. package/dist/lib/provider-add-command.d.ts.map +1 -1
  164. package/dist/lib/provider-add-command.js +4 -12
  165. package/dist/lib/provider-add-command.js.map +1 -1
  166. package/dist/lib/provider-add-json-v1-questionnaire.d.ts +32 -0
  167. package/dist/lib/provider-add-json-v1-questionnaire.d.ts.map +1 -0
  168. package/dist/lib/provider-add-json-v1-questionnaire.js +336 -0
  169. package/dist/lib/provider-add-json-v1-questionnaire.js.map +1 -0
  170. package/dist/lib/provider-availability.d.ts +2 -2
  171. package/dist/lib/provider-availability.d.ts.map +1 -1
  172. package/dist/lib/provider-availability.js +2 -3
  173. package/dist/lib/provider-availability.js.map +1 -1
  174. package/dist/lib/provider-metadata.d.ts +300 -1
  175. package/dist/lib/provider-metadata.d.ts.map +1 -1
  176. package/dist/lib/provider-metadata.js +332 -227
  177. package/dist/lib/provider-metadata.js.map +1 -1
  178. package/dist/lib/quota-command-format.d.ts.map +1 -1
  179. package/dist/lib/quota-command-format.js +12 -16
  180. package/dist/lib/quota-command-format.js.map +1 -1
  181. package/dist/lib/quota-dialog-commands.d.ts +59 -2
  182. package/dist/lib/quota-dialog-commands.d.ts.map +1 -1
  183. package/dist/lib/quota-dialog-commands.js +73 -39
  184. package/dist/lib/quota-dialog-commands.js.map +1 -1
  185. package/dist/lib/quota-entry-display.d.ts +2 -0
  186. package/dist/lib/quota-entry-display.d.ts.map +1 -1
  187. package/dist/lib/quota-entry-display.js +27 -13
  188. package/dist/lib/quota-entry-display.js.map +1 -1
  189. package/dist/lib/quota-providers-remote.d.ts +0 -1
  190. package/dist/lib/quota-providers-remote.d.ts.map +1 -1
  191. package/dist/lib/quota-providers-remote.js +3 -16
  192. package/dist/lib/quota-providers-remote.js.map +1 -1
  193. package/dist/lib/quota-render-data.d.ts +4 -0
  194. package/dist/lib/quota-render-data.d.ts.map +1 -1
  195. package/dist/lib/quota-render-data.js +118 -127
  196. package/dist/lib/quota-render-data.js.map +1 -1
  197. package/dist/lib/quota-runtime-context.d.ts +9 -1
  198. package/dist/lib/quota-runtime-context.d.ts.map +1 -1
  199. package/dist/lib/quota-runtime-context.js +5 -0
  200. package/dist/lib/quota-runtime-context.js.map +1 -1
  201. package/dist/lib/quota-state.d.ts.map +1 -1
  202. package/dist/lib/quota-state.js +25 -1
  203. package/dist/lib/quota-state.js.map +1 -1
  204. package/dist/lib/quota-stats.d.ts +1 -0
  205. package/dist/lib/quota-stats.d.ts.map +1 -1
  206. package/dist/lib/quota-stats.js +14 -4
  207. package/dist/lib/quota-stats.js.map +1 -1
  208. package/dist/lib/quota-status.d.ts +7 -17
  209. package/dist/lib/quota-status.d.ts.map +1 -1
  210. package/dist/lib/quota-status.js +123 -948
  211. package/dist/lib/quota-status.js.map +1 -1
  212. package/dist/lib/runtime-provider-ids.d.ts +4 -0
  213. package/dist/lib/runtime-provider-ids.d.ts.map +1 -0
  214. package/dist/lib/runtime-provider-ids.js +10 -0
  215. package/dist/lib/runtime-provider-ids.js.map +1 -0
  216. package/dist/lib/session-tokens.d.ts +2 -0
  217. package/dist/lib/session-tokens.d.ts.map +1 -1
  218. package/dist/lib/session-tokens.js +4 -2
  219. package/dist/lib/session-tokens.js.map +1 -1
  220. package/dist/lib/synthetic-config.d.ts.map +1 -1
  221. package/dist/lib/synthetic-config.js +2 -4
  222. package/dist/lib/synthetic-config.js.map +1 -1
  223. package/dist/lib/synthetic.d.ts.map +1 -1
  224. package/dist/lib/synthetic.js +37 -32
  225. package/dist/lib/synthetic.js.map +1 -1
  226. package/dist/lib/toast-format-grouped.d.ts +1 -0
  227. package/dist/lib/toast-format-grouped.d.ts.map +1 -1
  228. package/dist/lib/toast-format-grouped.js +33 -29
  229. package/dist/lib/toast-format-grouped.js.map +1 -1
  230. package/dist/lib/tui-refresh-lifecycle.d.ts +17 -0
  231. package/dist/lib/tui-refresh-lifecycle.d.ts.map +1 -0
  232. package/dist/lib/tui-refresh-lifecycle.js +83 -0
  233. package/dist/lib/tui-refresh-lifecycle.js.map +1 -0
  234. package/dist/lib/tui-runtime.d.ts +0 -5
  235. package/dist/lib/tui-runtime.d.ts.map +1 -1
  236. package/dist/lib/tui-runtime.js +1 -6
  237. package/dist/lib/tui-runtime.js.map +1 -1
  238. package/dist/lib/tui-sidebar-format.d.ts +1 -1
  239. package/dist/lib/tui-sidebar-format.d.ts.map +1 -1
  240. package/dist/lib/tui-sidebar-format.js +1 -0
  241. package/dist/lib/tui-sidebar-format.js.map +1 -1
  242. package/dist/lib/types.d.ts +72 -8
  243. package/dist/lib/types.d.ts.map +1 -1
  244. package/dist/lib/types.js +2 -0
  245. package/dist/lib/types.js.map +1 -1
  246. package/dist/lib/xai.d.ts +39 -0
  247. package/dist/lib/xai.d.ts.map +1 -0
  248. package/dist/lib/xai.js +153 -0
  249. package/dist/lib/xai.js.map +1 -0
  250. package/dist/lib/zai-auth.d.ts +3 -26
  251. package/dist/lib/zai-auth.d.ts.map +1 -1
  252. package/dist/lib/zai-auth.js +24 -94
  253. package/dist/lib/zai-auth.js.map +1 -1
  254. package/dist/lib/zai.d.ts +1 -8
  255. package/dist/lib/zai.d.ts.map +1 -1
  256. package/dist/lib/zai.js +11 -91
  257. package/dist/lib/zai.js.map +1 -1
  258. package/dist/lib/zhipu-auth.d.ts +3 -26
  259. package/dist/lib/zhipu-auth.d.ts.map +1 -1
  260. package/dist/lib/zhipu-auth.js +24 -94
  261. package/dist/lib/zhipu-auth.js.map +1 -1
  262. package/dist/lib/zhipu.d.ts +1 -8
  263. package/dist/lib/zhipu.d.ts.map +1 -1
  264. package/dist/lib/zhipu.js +10 -84
  265. package/dist/lib/zhipu.js.map +1 -1
  266. package/dist/plugin.d.ts.map +1 -1
  267. package/dist/plugin.js +20 -145
  268. package/dist/plugin.js.map +1 -1
  269. package/dist/providers/alibaba-coding-plan.d.ts.map +1 -1
  270. package/dist/providers/alibaba-coding-plan.js +33 -6
  271. package/dist/providers/alibaba-coding-plan.js.map +1 -1
  272. package/dist/providers/anthropic.d.ts.map +1 -1
  273. package/dist/providers/anthropic.js +35 -7
  274. package/dist/providers/anthropic.js.map +1 -1
  275. package/dist/providers/chutes.d.ts.map +1 -1
  276. package/dist/providers/chutes.js +10 -3
  277. package/dist/providers/chutes.js.map +1 -1
  278. package/dist/providers/copilot.d.ts.map +1 -1
  279. package/dist/providers/copilot.js +102 -31
  280. package/dist/providers/copilot.js.map +1 -1
  281. package/dist/providers/cursor.d.ts.map +1 -1
  282. package/dist/providers/cursor.js +34 -6
  283. package/dist/providers/cursor.js.map +1 -1
  284. package/dist/providers/deepseek.d.ts.map +1 -1
  285. package/dist/providers/deepseek.js +10 -3
  286. package/dist/providers/deepseek.js.map +1 -1
  287. package/dist/providers/glm-coding-plan-provider.d.ts +44 -0
  288. package/dist/providers/glm-coding-plan-provider.d.ts.map +1 -0
  289. package/dist/providers/glm-coding-plan-provider.js +62 -0
  290. package/dist/providers/glm-coding-plan-provider.js.map +1 -0
  291. package/dist/providers/google-agy.d.ts.map +1 -1
  292. package/dist/providers/google-agy.js +83 -42
  293. package/dist/providers/google-agy.js.map +1 -1
  294. package/dist/providers/google-antigravity.d.ts.map +1 -1
  295. package/dist/providers/google-antigravity.js +31 -6
  296. package/dist/providers/google-antigravity.js.map +1 -1
  297. package/dist/providers/google-gemini-cli.d.ts.map +1 -1
  298. package/dist/providers/google-gemini-cli.js +24 -6
  299. package/dist/providers/google-gemini-cli.js.map +1 -1
  300. package/dist/providers/kimi-code.d.ts.map +1 -1
  301. package/dist/providers/kimi-code.js +27 -8
  302. package/dist/providers/kimi-code.js.map +1 -1
  303. package/dist/providers/mimo.d.ts +3 -0
  304. package/dist/providers/mimo.d.ts.map +1 -0
  305. package/dist/providers/mimo.js +127 -0
  306. package/dist/providers/mimo.js.map +1 -0
  307. package/dist/providers/minimax-coding-plan.d.ts.map +1 -1
  308. package/dist/providers/minimax-coding-plan.js +68 -32
  309. package/dist/providers/minimax-coding-plan.js.map +1 -1
  310. package/dist/providers/nanogpt.d.ts.map +1 -1
  311. package/dist/providers/nanogpt.js +41 -4
  312. package/dist/providers/nanogpt.js.map +1 -1
  313. package/dist/providers/openai.d.ts.map +1 -1
  314. package/dist/providers/openai.js +20 -3
  315. package/dist/providers/openai.js.map +1 -1
  316. package/dist/providers/opencode-go.d.ts.map +1 -1
  317. package/dist/providers/opencode-go.js +33 -15
  318. package/dist/providers/opencode-go.js.map +1 -1
  319. package/dist/providers/opencode-zen.d.ts +3 -0
  320. package/dist/providers/opencode-zen.d.ts.map +1 -0
  321. package/dist/providers/opencode-zen.js +99 -0
  322. package/dist/providers/opencode-zen.js.map +1 -0
  323. package/dist/providers/openrouter.d.ts +6 -0
  324. package/dist/providers/openrouter.d.ts.map +1 -0
  325. package/dist/providers/openrouter.js +25 -0
  326. package/dist/providers/openrouter.js.map +1 -0
  327. package/dist/providers/quota-providers.d.ts.map +1 -1
  328. package/dist/providers/quota-providers.js +3 -3
  329. package/dist/providers/quota-providers.js.map +1 -1
  330. package/dist/providers/qwen-code.d.ts.map +1 -1
  331. package/dist/providers/qwen-code.js +19 -5
  332. package/dist/providers/qwen-code.js.map +1 -1
  333. package/dist/providers/registry.d.ts.map +1 -1
  334. package/dist/providers/registry.js +8 -0
  335. package/dist/providers/registry.js.map +1 -1
  336. package/dist/providers/result-helpers.d.ts +29 -1
  337. package/dist/providers/result-helpers.d.ts.map +1 -1
  338. package/dist/providers/result-helpers.js +69 -0
  339. package/dist/providers/result-helpers.js.map +1 -1
  340. package/dist/providers/synthetic.d.ts.map +1 -1
  341. package/dist/providers/synthetic.js +10 -3
  342. package/dist/providers/synthetic.js.map +1 -1
  343. package/dist/providers/xai.d.ts +6 -0
  344. package/dist/providers/xai.d.ts.map +1 -0
  345. package/dist/providers/xai.js +51 -0
  346. package/dist/providers/xai.js.map +1 -0
  347. package/dist/providers/zai.d.ts +1 -7
  348. package/dist/providers/zai.d.ts.map +1 -1
  349. package/dist/providers/zai.js +11 -46
  350. package/dist/providers/zai.js.map +1 -1
  351. package/dist/providers/zhipu.d.ts +1 -7
  352. package/dist/providers/zhipu.d.ts.map +1 -1
  353. package/dist/providers/zhipu.js +11 -46
  354. package/dist/providers/zhipu.js.map +1 -1
  355. package/dist/tui.d.ts.map +1 -1
  356. package/dist/tui.js +47 -136
  357. package/dist/tui.tsx +62 -179
  358. package/package.json +1 -1
@@ -0,0 +1,147 @@
1
+ import { readFile } from "fs/promises";
2
+ import { join } from "path";
3
+ import { getOpencodeRuntimeDirCandidates } from "./opencode-runtime-paths.js";
4
+ const MIMO_COOKIE_ENV = "MIMO_USAGE_COOKIE";
5
+ const RETAINED_COOKIE_NAMES = [
6
+ "api-platform_serviceToken",
7
+ "userId",
8
+ "api-platform_ph",
9
+ "api-platform_slh",
10
+ ];
11
+ const RETAINED_COOKIE_NAME_SET = new Set(RETAINED_COOKIE_NAMES);
12
+ const REQUIRED_COOKIE_NAMES = ["api-platform_serviceToken", "userId"];
13
+ function getConfigCandidatePaths() {
14
+ const { configDirs } = getOpencodeRuntimeDirCandidates();
15
+ return configDirs.map((dir) => join(dir, "opencode-quota", "mimo.json"));
16
+ }
17
+ export function normalizeMimoCookieHeader(raw) {
18
+ if (raw.includes("\r") || raw.includes("\n"))
19
+ return null;
20
+ const withoutPrefix = raw.trim().replace(/^cookie\s*:\s*/iu, "");
21
+ if (!withoutPrefix)
22
+ return null;
23
+ const retained = new Map();
24
+ for (const rawPair of withoutPrefix.split(";")) {
25
+ const pair = rawPair.trim();
26
+ if (!pair)
27
+ continue;
28
+ const separator = pair.indexOf("=");
29
+ if (separator <= 0)
30
+ return null;
31
+ const name = pair.slice(0, separator).trim();
32
+ const value = pair.slice(separator + 1).trim();
33
+ if (!name)
34
+ return null;
35
+ if (!RETAINED_COOKIE_NAME_SET.has(name))
36
+ continue;
37
+ if (!value || retained.has(name))
38
+ return null;
39
+ retained.set(name, value);
40
+ }
41
+ if (REQUIRED_COOKIE_NAMES.some((name) => !retained.has(name)))
42
+ return null;
43
+ return RETAINED_COOKIE_NAMES.flatMap((name) => {
44
+ const value = retained.get(name);
45
+ return value === undefined ? [] : [`${name}=${value}`];
46
+ }).join("; ");
47
+ }
48
+ async function readConfigFile(path) {
49
+ try {
50
+ const data = await readFile(path, "utf8");
51
+ let parsed;
52
+ try {
53
+ parsed = JSON.parse(data);
54
+ }
55
+ catch {
56
+ return { state: "invalid", error: "Failed to parse JSON" };
57
+ }
58
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
59
+ return { state: "invalid", error: "Config file must contain a JSON object" };
60
+ }
61
+ const record = parsed;
62
+ return { state: "loaded", cookie: record.cookie, keys: Object.keys(record) };
63
+ }
64
+ catch (error) {
65
+ if (error?.code === "ENOENT") {
66
+ return { state: "missing" };
67
+ }
68
+ return { state: "invalid", error: "Failed to read config file" };
69
+ }
70
+ }
71
+ export function resolveMimoConfigFromEnv(env = process.env) {
72
+ if (env[MIMO_COOKIE_ENV] === undefined)
73
+ return null;
74
+ const cookie = normalizeMimoCookieHeader(env[MIMO_COOKIE_ENV] ?? "");
75
+ if (!cookie) {
76
+ return {
77
+ state: "invalid",
78
+ source: `env:${MIMO_COOKIE_ENV}`,
79
+ error: "Invalid cookie header",
80
+ };
81
+ }
82
+ return {
83
+ state: "configured",
84
+ config: { cookie },
85
+ source: `env:${MIMO_COOKIE_ENV}`,
86
+ };
87
+ }
88
+ export async function resolveMimoConfig() {
89
+ const envResult = resolveMimoConfigFromEnv();
90
+ if (envResult)
91
+ return envResult;
92
+ for (const path of getConfigCandidatePaths()) {
93
+ const fileResult = await readConfigFile(path);
94
+ if (fileResult.state === "missing")
95
+ continue;
96
+ if (fileResult.state === "invalid") {
97
+ return { state: "invalid", source: path, error: fileResult.error };
98
+ }
99
+ if (fileResult.keys.length !== 1 || fileResult.keys[0] !== "cookie") {
100
+ return {
101
+ state: "invalid",
102
+ source: path,
103
+ error: "Config file must contain only the cookie field",
104
+ };
105
+ }
106
+ if (typeof fileResult.cookie !== "string") {
107
+ return {
108
+ state: "invalid",
109
+ source: path,
110
+ error: "Config cookie field must be a string",
111
+ };
112
+ }
113
+ const cookie = normalizeMimoCookieHeader(fileResult.cookie);
114
+ if (!cookie) {
115
+ return { state: "invalid", source: path, error: "Invalid cookie header" };
116
+ }
117
+ return {
118
+ state: "configured",
119
+ config: { cookie },
120
+ source: path,
121
+ };
122
+ }
123
+ return { state: "none" };
124
+ }
125
+ let cachedConfig = null;
126
+ let cachedAt = 0;
127
+ export const DEFAULT_MIMO_CONFIG_CACHE_MAX_AGE_MS = 30_000;
128
+ export async function resolveMimoConfigCached(params) {
129
+ const maxAgeMs = Math.max(0, params?.maxAgeMs ?? DEFAULT_MIMO_CONFIG_CACHE_MAX_AGE_MS);
130
+ const now = Date.now();
131
+ if (cachedConfig && now - cachedAt < maxAgeMs) {
132
+ return cachedConfig;
133
+ }
134
+ cachedConfig = await resolveMimoConfig();
135
+ cachedAt = now;
136
+ return cachedConfig;
137
+ }
138
+ export async function getMimoConfigDiagnostics() {
139
+ const resolved = await resolveMimoConfig();
140
+ return {
141
+ state: resolved.state,
142
+ source: "source" in resolved ? resolved.source : null,
143
+ error: "error" in resolved ? resolved.error : null,
144
+ checkedPaths: getConfigCandidatePaths(),
145
+ };
146
+ }
147
+ //# sourceMappingURL=mimo-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mimo-config.js","sourceRoot":"","sources":["../../src/lib/mimo-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export interface MimoMonthlyQuota {
2
+ used: number;
3
+ limit: number;
4
+ }
5
+ export interface MimoPlanDetail {
6
+ planName: string | null;
7
+ planCode: string | null;
8
+ expired: boolean;
9
+ }
10
+ export interface MimoBalance {
11
+ total: number | null;
12
+ cash: number | null;
13
+ gift: number | null;
14
+ currency: string | null;
15
+ }
16
+ export type MimoEndpointResult<T> = {
17
+ state: "success";
18
+ data: T;
19
+ } | {
20
+ state: "error";
21
+ error: string;
22
+ };
23
+ export interface MimoDashboardResult {
24
+ usage: MimoEndpointResult<MimoMonthlyQuota>;
25
+ detail: MimoEndpointResult<MimoPlanDetail>;
26
+ balance: MimoEndpointResult<MimoBalance>;
27
+ }
28
+ export declare function parseMimoUsageResponse(json: unknown): MimoMonthlyQuota;
29
+ export declare function parseMimoDetailResponse(json: unknown): MimoPlanDetail;
30
+ export declare function parseMimoBalanceResponse(json: unknown): MimoBalance;
31
+ export declare function formatMimoDashboardTimeZone(timezoneOffsetMinutes?: number): string;
32
+ export declare function queryMimoDashboard(cookie: string, options?: {
33
+ requestTimeoutMs?: number;
34
+ }): Promise<MimoDashboardResult>;
35
+ //# sourceMappingURL=mimo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mimo.d.ts","sourceRoot":"","sources":["../../src/lib/mimo.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC5B;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC7B;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IAC5C,MAAM,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;IAC3C,OAAO,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;CAC1C;AA0BD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAkBtE;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CASrE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CA8BnE;AA6CD,wBAAgB,2BAA2B,CAAC,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,CAQlF;AAiFD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1C,OAAO,CAAC,mBAAmB,CAAC,CA+B9B"}
@@ -0,0 +1,236 @@
1
+ import { sanitizeSingleLineDisplaySnippet } from "./display-sanitize.js";
2
+ import { fetchWithTimeout } from "./http.js";
3
+ const MIMO_USAGE_URL = "https://platform.xiaomimimo.com/api/v1/tokenPlan/usage";
4
+ const MIMO_DETAIL_URL = "https://platform.xiaomimimo.com/api/v1/tokenPlan/detail";
5
+ const MIMO_BALANCE_URL = "https://platform.xiaomimimo.com/api/v1/balance";
6
+ const MIMO_REQUEST_TIMEOUT_MS = 10_000;
7
+ const MIMO_RESPONSE_MAX_BYTES = 256 * 1024;
8
+ const MIMO_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36";
9
+ function isRecord(value) {
10
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
11
+ }
12
+ function parseEnvelope(json) {
13
+ if (!isRecord(json) || json.code !== 0 || !isRecord(json.data)) {
14
+ throw new Error("invalid envelope");
15
+ }
16
+ return json.data;
17
+ }
18
+ function parseNonNegativeNumber(value) {
19
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
20
+ }
21
+ function parseBalanceNumber(value) {
22
+ if (typeof value === "number") {
23
+ return Number.isFinite(value) && value >= 0 ? value : null;
24
+ }
25
+ if (typeof value !== "string" || !/^\d+(?:\.\d+)?$/u.test(value.trim()))
26
+ return null;
27
+ const parsed = Number(value);
28
+ return Number.isFinite(parsed) ? parsed : null;
29
+ }
30
+ export function parseMimoUsageResponse(json) {
31
+ const data = parseEnvelope(json);
32
+ if (!isRecord(data.monthUsage) || !Array.isArray(data.monthUsage.items)) {
33
+ throw new Error("missing monthly usage");
34
+ }
35
+ const item = data.monthUsage.items.find((candidate) => isRecord(candidate) && candidate.name === "month_total_token");
36
+ if (!isRecord(item))
37
+ throw new Error("missing monthly quota");
38
+ const used = parseNonNegativeNumber(item.used);
39
+ const limit = parseNonNegativeNumber(item.limit);
40
+ if (used === null || limit === null || limit <= 0) {
41
+ throw new Error("invalid monthly quota");
42
+ }
43
+ return { used, limit };
44
+ }
45
+ export function parseMimoDetailResponse(json) {
46
+ const data = parseEnvelope(json);
47
+ if (typeof data.expired !== "boolean")
48
+ throw new Error("invalid plan state");
49
+ return {
50
+ planName: typeof data.planName === "string" && data.planName.trim() ? data.planName : null,
51
+ planCode: typeof data.planCode === "string" && data.planCode.trim() ? data.planCode : null,
52
+ expired: data.expired,
53
+ };
54
+ }
55
+ export function parseMimoBalanceResponse(json) {
56
+ const data = parseEnvelope(json);
57
+ const fields = [
58
+ ["balance", data.balance],
59
+ ["cashBalance", data.cashBalance],
60
+ ["giftBalance", data.giftBalance],
61
+ ];
62
+ const parsed = new Map();
63
+ for (const [name, value] of fields) {
64
+ if (value === undefined || value === null || value === "") {
65
+ parsed.set(name, null);
66
+ continue;
67
+ }
68
+ const amount = parseBalanceNumber(value);
69
+ if (amount === null)
70
+ throw new Error("invalid balance");
71
+ parsed.set(name, amount);
72
+ }
73
+ const currency = typeof data.currency === "string" && /^[A-Za-z]{3}$/u.test(data.currency.trim())
74
+ ? data.currency.trim().toUpperCase()
75
+ : null;
76
+ return {
77
+ total: parsed.get("balance") ?? null,
78
+ cash: parsed.get("cashBalance") ?? null,
79
+ gift: parsed.get("giftBalance") ?? null,
80
+ currency,
81
+ };
82
+ }
83
+ async function readBoundedJson(response) {
84
+ if (!response.body)
85
+ throw new Error("empty response");
86
+ const reader = response.body.getReader();
87
+ const chunks = [];
88
+ let byteLength = 0;
89
+ try {
90
+ const contentLength = Number(response.headers.get("content-length"));
91
+ if (Number.isFinite(contentLength) && contentLength > MIMO_RESPONSE_MAX_BYTES) {
92
+ throw new Error("response too large");
93
+ }
94
+ while (true) {
95
+ const { done, value } = await reader.read();
96
+ if (done)
97
+ break;
98
+ byteLength += value.byteLength;
99
+ if (byteLength > MIMO_RESPONSE_MAX_BYTES) {
100
+ throw new Error("response too large");
101
+ }
102
+ chunks.push(value);
103
+ }
104
+ }
105
+ catch (error) {
106
+ try {
107
+ await reader.cancel();
108
+ }
109
+ catch {
110
+ // Preserve the original read or size-limit error.
111
+ }
112
+ throw error;
113
+ }
114
+ finally {
115
+ reader.releaseLock();
116
+ }
117
+ const body = new Uint8Array(byteLength);
118
+ let offset = 0;
119
+ for (const chunk of chunks) {
120
+ body.set(chunk, offset);
121
+ offset += chunk.byteLength;
122
+ }
123
+ return JSON.parse(new TextDecoder().decode(body));
124
+ }
125
+ export function formatMimoDashboardTimeZone(timezoneOffsetMinutes) {
126
+ const javascriptOffset = timezoneOffsetMinutes ?? new Date().getTimezoneOffset();
127
+ const utcOffset = -javascriptOffset;
128
+ const sign = utcOffset >= 0 ? "+" : "-";
129
+ const absoluteMinutes = Math.abs(utcOffset);
130
+ const hours = Math.floor(absoluteMinutes / 60);
131
+ const minutes = absoluteMinutes % 60;
132
+ return `UTC${sign}${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
133
+ }
134
+ function getCookieValues(cookie) {
135
+ return cookie
136
+ .split(";")
137
+ .map((part) => part.slice(part.indexOf("=") + 1).trim())
138
+ .filter(Boolean);
139
+ }
140
+ function sanitizeRequestError(error, cookie) {
141
+ let message = error instanceof Error ? error.message : String(error);
142
+ for (const secret of [cookie, ...getCookieValues(cookie)]) {
143
+ message = message.split(secret).join("[redacted]");
144
+ }
145
+ return sanitizeSingleLineDisplaySnippet(message, 120) || "request failed";
146
+ }
147
+ async function fetchMimoEndpoint(params) {
148
+ try {
149
+ return await fetchWithTimeout(params.url, {
150
+ request: {
151
+ method: "GET",
152
+ redirect: "manual",
153
+ headers: {
154
+ Accept: "application/json, text/plain, */*",
155
+ "Accept-Language": "en-US,en;q=0.9",
156
+ Cookie: params.cookie,
157
+ Origin: "https://platform.xiaomimimo.com",
158
+ Referer: "https://platform.xiaomimimo.com/#/console/balance",
159
+ "User-Agent": MIMO_USER_AGENT,
160
+ "x-timeZone": params.timeZone,
161
+ },
162
+ },
163
+ timeoutMs: params.requestTimeoutMs,
164
+ consume: async (response, timeoutSignal) => {
165
+ if (response.status >= 300 && response.status < 400) {
166
+ return { state: "error", error: `Xiaomi MiMo ${params.name} request requires login` };
167
+ }
168
+ if (!response.ok) {
169
+ return {
170
+ state: "error",
171
+ error: `Xiaomi MiMo ${params.name} request failed (HTTP ${response.status})`,
172
+ };
173
+ }
174
+ let json;
175
+ try {
176
+ json = await readBoundedJson(response);
177
+ }
178
+ catch (error) {
179
+ if (timeoutSignal.aborted)
180
+ throw error;
181
+ return {
182
+ state: "error",
183
+ error: `Xiaomi MiMo ${params.name} response could not be parsed`,
184
+ };
185
+ }
186
+ try {
187
+ return { state: "success", data: params.parse(json) };
188
+ }
189
+ catch {
190
+ return {
191
+ state: "error",
192
+ error: `Xiaomi MiMo ${params.name} response did not match the expected schema`,
193
+ };
194
+ }
195
+ },
196
+ });
197
+ }
198
+ catch (error) {
199
+ return {
200
+ state: "error",
201
+ error: `Xiaomi MiMo ${params.name} request failed: ${sanitizeRequestError(error, params.cookie)}`,
202
+ };
203
+ }
204
+ }
205
+ export async function queryMimoDashboard(cookie, options = {}) {
206
+ const requestTimeoutMs = options.requestTimeoutMs ?? MIMO_REQUEST_TIMEOUT_MS;
207
+ const timeZone = formatMimoDashboardTimeZone();
208
+ const [usage, detail, balance] = await Promise.all([
209
+ fetchMimoEndpoint({
210
+ name: "usage",
211
+ url: MIMO_USAGE_URL,
212
+ cookie,
213
+ requestTimeoutMs,
214
+ timeZone,
215
+ parse: parseMimoUsageResponse,
216
+ }),
217
+ fetchMimoEndpoint({
218
+ name: "detail",
219
+ url: MIMO_DETAIL_URL,
220
+ cookie,
221
+ requestTimeoutMs,
222
+ timeZone,
223
+ parse: parseMimoDetailResponse,
224
+ }),
225
+ fetchMimoEndpoint({
226
+ name: "balance",
227
+ url: MIMO_BALANCE_URL,
228
+ cookie,
229
+ requestTimeoutMs,
230
+ timeZone,
231
+ parse: parseMimoBalanceResponse,
232
+ }),
233
+ ]);
234
+ return { usage, detail, balance };
235
+ }
236
+ //# sourceMappingURL=mimo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mimo.js","sourceRoot":"","sources":["../../src/lib/mimo.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"modelsdev-pricing.d.ts","sourceRoot":"","sources":["../../src/lib/modelsdev-pricing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"modelsdev-pricing.d.ts","sourceRoot":"","sources":["../../src/lib/modelsdev-pricing.ts"],"names":[],"mappings":"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"}
@@ -230,7 +230,13 @@ function normalizeRefreshState(raw) {
230
230
  if (Number.isFinite(lastFailureAt) && lastFailureAt > 0)
231
231
  out.lastFailureAt = Math.trunc(lastFailureAt);
232
232
  if (typeof obj.lastResult === "string") {
233
- const allowed = new Set(["success", "not_modified", "skipped_fresh", "skipped_throttled", "failed"]);
233
+ const allowed = new Set([
234
+ "success",
235
+ "not_modified",
236
+ "skipped_fresh",
237
+ "skipped_throttled",
238
+ "failed",
239
+ ]);
234
240
  if (allowed.has(obj.lastResult)) {
235
241
  out.lastResult = obj.lastResult;
236
242
  }
@@ -321,20 +327,28 @@ async function fetchModelsDevSnapshot(params) {
321
327
  headers.set("If-None-Match", params.state.etag);
322
328
  if (params.state.lastModified)
323
329
  headers.set("If-Modified-Since", params.state.lastModified);
324
- if (!params.fetchFn) {
325
- return await fetchWithTimeout(SOURCE_URL, { headers }, params.timeoutMs);
326
- }
327
- const controller = new AbortController();
328
- const timeoutId = setTimeout(() => controller.abort(), params.timeoutMs);
329
- try {
330
- return await params.fetchFn(SOURCE_URL, {
331
- headers,
332
- signal: controller.signal,
333
- });
334
- }
335
- finally {
336
- clearTimeout(timeoutId);
337
- }
330
+ return await fetchWithTimeout(SOURCE_URL, {
331
+ request: { headers },
332
+ timeoutMs: params.timeoutMs,
333
+ fetchFn: params.fetchFn,
334
+ consume: async (response) => {
335
+ const responseMetadata = {
336
+ etag: response.headers.get("etag") ?? undefined,
337
+ lastModified: response.headers.get("last-modified") ?? undefined,
338
+ };
339
+ if (response.status === 304) {
340
+ return { kind: "not_modified", ...responseMetadata };
341
+ }
342
+ if (!response.ok) {
343
+ throw new Error(`Failed to fetch ${SOURCE_URL}: ${response.status} ${response.statusText}`);
344
+ }
345
+ return {
346
+ kind: "success",
347
+ api: await response.json(),
348
+ ...responseMetadata,
349
+ };
350
+ },
351
+ });
338
352
  }
339
353
  export async function maybeRefreshPricingSnapshot(opts = {}) {
340
354
  if (REFRESH_IN_FLIGHT)
@@ -403,7 +417,9 @@ export async function maybeRefreshPricingSnapshot(opts = {}) {
403
417
  },
404
418
  };
405
419
  }
406
- if (!force && previousState.lastAttemptAt && nowMs - previousState.lastAttemptAt < minAttemptIntervalMs) {
420
+ if (!force &&
421
+ previousState.lastAttemptAt &&
422
+ nowMs - previousState.lastAttemptAt < minAttemptIntervalMs) {
407
423
  return {
408
424
  attempted: false,
409
425
  updated: false,
@@ -422,12 +438,12 @@ export async function maybeRefreshPricingSnapshot(opts = {}) {
422
438
  lastAttemptAt: nowMs,
423
439
  };
424
440
  try {
425
- const response = await fetchModelsDevSnapshot({
441
+ const fetchResult = await fetchModelsDevSnapshot({
426
442
  timeoutMs,
427
443
  state: attemptingState,
428
444
  fetchFn: opts.fetchFn,
429
445
  });
430
- if (response.status === 304) {
446
+ if (fetchResult.kind === "not_modified") {
431
447
  const baseSnapshot = runtimeSnapshotBeforeRefresh ?? ensureLoaded();
432
448
  const refreshedSnapshot = {
433
449
  _meta: {
@@ -448,8 +464,8 @@ export async function maybeRefreshPricingSnapshot(opts = {}) {
448
464
  lastSuccessAt: nowMs,
449
465
  lastResult: "not_modified",
450
466
  lastError: undefined,
451
- etag: response.headers.get("etag") ?? attemptingState.etag,
452
- lastModified: response.headers.get("last-modified") ?? attemptingState.lastModified,
467
+ etag: fetchResult.etag ?? attemptingState.etag,
468
+ lastModified: fetchResult.lastModified ?? attemptingState.lastModified,
453
469
  };
454
470
  try {
455
471
  await writeJsonAtomic(statePath, nextState, { trailingNewline: true });
@@ -463,11 +479,7 @@ export async function maybeRefreshPricingSnapshot(opts = {}) {
463
479
  state: nextState,
464
480
  };
465
481
  }
466
- if (!response.ok) {
467
- throw new Error(`Failed to fetch ${SOURCE_URL}: ${response.status} ${response.statusText}`);
468
- }
469
- const api = await response.json();
470
- const snapshot = buildSnapshotFromApi(api, opts.providerAllowlist ?? DEFAULT_MODELSDEV_PROVIDERS, nowMs);
482
+ const snapshot = buildSnapshotFromApi(fetchResult.api, opts.providerAllowlist ?? DEFAULT_MODELSDEV_PROVIDERS, nowMs);
471
483
  if (countPricedModels(snapshot) === 0) {
472
484
  throw new Error("Refusing to persist empty pricing snapshot from models.dev");
473
485
  }
@@ -483,8 +495,8 @@ export async function maybeRefreshPricingSnapshot(opts = {}) {
483
495
  lastSuccessAt: nowMs,
484
496
  lastResult: "success",
485
497
  lastError: undefined,
486
- etag: response.headers.get("etag") ?? attemptingState.etag,
487
- lastModified: response.headers.get("last-modified") ?? attemptingState.lastModified,
498
+ etag: fetchResult.etag ?? attemptingState.etag,
499
+ lastModified: fetchResult.lastModified ?? attemptingState.lastModified,
488
500
  };
489
501
  try {
490
502
  await writeJsonAtomic(statePath, nextState, { trailingNewline: true });