@bitkyc08/opencodex 2.86.0 → 2.88.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 (400) hide show
  1. package/gui/dist/assets/App-CHC89EXQ.js +58 -0
  2. package/gui/dist/assets/App-wT3mXqFz.css +1 -0
  3. package/gui/dist/assets/{Tray-DyR9yBee.js → Tray-B5bC7AWL.js} +1 -1
  4. package/gui/dist/assets/index-B5bsvxor.js +94 -0
  5. package/gui/dist/assets/index-DPeB9HpV.css +1 -0
  6. package/gui/dist/assets/quota-summary-D8y2wTsB.js +1 -0
  7. package/gui/dist/index.html +2 -2
  8. package/package.json +1 -1
  9. package/src/adapters/anthropic/beta-allowlist.ts +9 -8
  10. package/src/adapters/anthropic/beta-body-pairs.ts +93 -0
  11. package/src/adapters/anthropic/passthrough.ts +7 -23
  12. package/src/adapters/anthropic-progress.ts +84 -0
  13. package/src/adapters/anthropic-rejection-memo.ts +71 -0
  14. package/src/adapters/anthropic-replay.ts +135 -0
  15. package/src/adapters/anthropic-tool-catalog.ts +11 -0
  16. package/src/adapters/anthropic.ts +151 -33
  17. package/src/adapters/base.ts +2 -0
  18. package/src/adapters/claude-cli/adapter.ts +111 -23
  19. package/src/adapters/claude-cli/profiles.ts +2 -1
  20. package/src/adapters/claude-cli/stable-replay.ts +108 -0
  21. package/src/adapters/claude-cli/usage-admission.ts +230 -0
  22. package/src/adapters/coding-agent/protocol.ts +1 -1
  23. package/src/adapters/coding-agent/turn.ts +18 -2
  24. package/src/adapters/dsh-account.ts +97 -0
  25. package/src/adapters/google-progress-history.ts +53 -0
  26. package/src/adapters/google.ts +52 -9
  27. package/src/adapters/openai-chat/messages.ts +4 -3
  28. package/src/adapters/openai-chat/passthrough.ts +8 -2
  29. package/src/adapters/openai-chat/reasoning-replay.ts +52 -0
  30. package/src/adapters/openai-responses/compaction-search-history.ts +14 -7
  31. package/src/adapters/openai-responses/passthrough.ts +57 -125
  32. package/src/adapters/openai-responses/request-strips.ts +25 -3
  33. package/src/adapters/openai-responses/transport.ts +81 -0
  34. package/src/adapters/qoder/adapter.ts +4 -2
  35. package/src/adapters/registry.ts +5 -0
  36. package/src/adapters/zed.ts +26 -1
  37. package/src/advisor/activity.ts +55 -0
  38. package/src/advisor/budget.ts +62 -0
  39. package/src/advisor/consult.ts +4 -1
  40. package/src/advisor/context.ts +16 -4
  41. package/src/advisor/evidence-tool.ts +21 -0
  42. package/src/advisor/evidence.ts +117 -0
  43. package/src/advisor/runtime.ts +79 -31
  44. package/src/advisor/settings.ts +11 -2
  45. package/src/bridge/errors.ts +19 -1
  46. package/src/bridge/internal.ts +7 -1
  47. package/src/bridge/response-json.ts +18 -3
  48. package/src/bridge/sse.ts +59 -8
  49. package/src/bridge/terminal-refusal.ts +59 -0
  50. package/src/claude/desktop-3p-library.ts +32 -7
  51. package/src/claude/desktop-3p.ts +55 -13
  52. package/src/claude/desktop-first-party.ts +1 -1
  53. package/src/claude/desktop-picker-platform.ts +4 -0
  54. package/src/claude/desktop-picker.ts +15 -8
  55. package/src/claude/desktop-system-proxy.ts +50 -4
  56. package/src/claude/inbound-content-options.ts +77 -0
  57. package/src/claude/inbound.ts +33 -0
  58. package/src/claude/intercept/picker-ca-startup.ts +2 -1
  59. package/src/claude/intercept/picker-runtime.ts +6 -5
  60. package/src/claude/intercept/picker-trust-windows.ts +338 -0
  61. package/src/claude/intercept/picker-trust.ts +19 -0
  62. package/src/claude/intercept/port-policy.ts +30 -0
  63. package/src/claude/intercept/runtime.ts +97 -94
  64. package/src/claude/outbound.ts +46 -13
  65. package/src/cli/account-api.ts +1 -0
  66. package/src/cli/account-policy-dto.ts +6 -0
  67. package/src/cli/account-policy.ts +34 -5
  68. package/src/cli/account-preservation.ts +44 -0
  69. package/src/cli/account.ts +8 -2
  70. package/src/cli/advisor.ts +17 -3
  71. package/src/cli/capabilities-accounts.ts +20 -1
  72. package/src/cli/capabilities-agents-routing.ts +5 -2
  73. package/src/cli/capabilities-base.ts +38 -10
  74. package/src/cli/capabilities-observe-system.ts +63 -3
  75. package/src/cli/capabilities-provider-models.ts +11 -0
  76. package/src/cli/codex-cli-update.ts +151 -41
  77. package/src/cli/codex-provider.ts +44 -0
  78. package/src/cli/combo-input.ts +10 -1
  79. package/src/cli/combo-result.ts +1 -1
  80. package/src/cli/combo.ts +2 -1
  81. package/src/cli/cross-home-owner.ts +33 -16
  82. package/src/cli/dispatch.ts +25 -4
  83. package/src/cli/doctor.ts +6 -1
  84. package/src/cli/ensure-desktop-cold-start.ts +60 -7
  85. package/src/cli/help.ts +3 -2
  86. package/src/cli/index.ts +1 -1
  87. package/src/cli/integration-plan-dto.ts +1 -0
  88. package/src/cli/log-history.ts +172 -0
  89. package/src/cli/loopback-family.ts +31 -0
  90. package/src/cli/models-runtime-subcommands.ts +1 -0
  91. package/src/cli/models-runtime.ts +72 -8
  92. package/src/cli/observe-stream.ts +2 -0
  93. package/src/cli/observe.ts +16 -4
  94. package/src/cli/provider.ts +27 -5
  95. package/src/cli/registry.ts +28 -8
  96. package/src/cli/runtime-api.ts +5 -3
  97. package/src/cli/system-command.ts +40 -8
  98. package/src/cli/uninstall-client-state.ts +32 -0
  99. package/src/cli/usage-compare.ts +309 -0
  100. package/src/cli/usage-model-search.ts +4 -4
  101. package/src/cli/usage-report.ts +2 -2
  102. package/src/cli/v2.ts +1 -1
  103. package/src/client/machine-listener.ts +1 -3
  104. package/src/client/runtime.ts +1 -0
  105. package/src/clients/client-path.ts +51 -0
  106. package/src/clients/config-export/contracts.ts +2 -1
  107. package/src/clients/config-export.ts +18 -44
  108. package/src/clients/gentle-shell-path.ts +87 -0
  109. package/src/codex/account-auto-switch.ts +2 -0
  110. package/src/codex/account-identity.ts +29 -0
  111. package/src/codex/account-label.ts +1 -1
  112. package/src/codex/account-lifecycle.ts +21 -5
  113. package/src/codex/account-preservation.ts +28 -0
  114. package/src/codex/account-use-remaining.ts +23 -0
  115. package/src/codex/app-server-processes.ts +97 -7
  116. package/src/codex/app-server-restart-service.ts +55 -4
  117. package/src/codex/auth-api/account-list.ts +4 -0
  118. package/src/codex/auth-api/account-pause-group.ts +6 -50
  119. package/src/codex/auth-api/account-preservation.ts +57 -0
  120. package/src/codex/auth-api/routes.ts +8 -0
  121. package/src/codex/auth-api/use-remaining-route.ts +36 -0
  122. package/src/codex/auth-api.ts +0 -1
  123. package/src/codex/auth-context.ts +2 -2
  124. package/src/codex/catalog/auto-review.ts +20 -3
  125. package/src/codex/catalog/build-entries.ts +9 -1
  126. package/src/codex/catalog/combo-member.ts +14 -5
  127. package/src/codex/catalog/configured-tiers.ts +1 -1
  128. package/src/codex/catalog/gather-capture.ts +2 -0
  129. package/src/codex/catalog/metadata.ts +11 -9
  130. package/src/codex/catalog/model-hints.ts +21 -16
  131. package/src/codex/catalog/model-visibility.ts +3 -1
  132. package/src/codex/catalog/parsing.ts +30 -86
  133. package/src/codex/catalog/provider-models.ts +36 -34
  134. package/src/codex/catalog/routed-gather.ts +14 -13
  135. package/src/codex/cli-install-provenance.ts +105 -17
  136. package/src/codex/cli-update-plan.ts +545 -0
  137. package/src/codex/config-write-lock.ts +23 -2
  138. package/src/codex/desktop-app/picker-freshness.ts +96 -0
  139. package/src/codex/desktop-app-restart.ts +21 -0
  140. package/src/codex/desktop-compatibility/installed-build.ts +24 -6
  141. package/src/codex/desktop-compatibility/routing-preflight.ts +1 -1
  142. package/src/codex/desktop-compatibility/runtime.ts +12 -3
  143. package/src/codex/desktop-compatibility/windows-key-protection.ts +115 -9
  144. package/src/codex/features.ts +85 -45
  145. package/src/codex/inject/history-failure.ts +27 -0
  146. package/src/codex/inject/restore.ts +24 -2
  147. package/src/codex/inject/routing-classify.ts +4 -3
  148. package/src/codex/inject.ts +18 -27
  149. package/src/codex/main-account-hard-lock.ts +30 -1
  150. package/src/codex/native-profile-startup.ts +1 -1
  151. package/src/codex/ocx-compaction-history.ts +12 -10
  152. package/src/codex/paths.ts +86 -1
  153. package/src/codex/provider-routing.ts +174 -0
  154. package/src/codex/refresh.ts +2 -2
  155. package/src/codex/routing/health-store.ts +1 -1
  156. package/src/codex/routing/selection.ts +4 -3
  157. package/src/codex/routing/thread-affinity.ts +1 -1
  158. package/src/codex/signed-in-identity.ts +43 -0
  159. package/src/codex/subagent-model-fallback.ts +1 -1
  160. package/src/codex/sync.ts +6 -1
  161. package/src/codex/user-identity.ts +16 -5
  162. package/src/codex/websocket-activity.ts +161 -0
  163. package/src/codex/websocket-registry.ts +25 -1
  164. package/src/codex/windows-local-appdata.ts +84 -0
  165. package/src/combos/failover.ts +6 -1
  166. package/src/combos/index.ts +1 -0
  167. package/src/combos/resolve.ts +46 -10
  168. package/src/combos/types.ts +15 -0
  169. package/src/config/diagnostics.ts +33 -6
  170. package/src/config/live-reconcile.ts +38 -2
  171. package/src/config/load-degrade.ts +17 -0
  172. package/src/config/opencode-wire-upgrade.ts +54 -0
  173. package/src/config/opencode-zen-upgrade.ts +53 -0
  174. package/src/config/owner-registry.ts +22 -17
  175. package/src/config/provider-validation.ts +45 -2
  176. package/src/config/schema/config-schema.ts +22 -0
  177. package/src/config/schema/leaf-validators.ts +38 -9
  178. package/src/config/schema/main-account-hard-lock-fallback.ts +26 -0
  179. package/src/config/schema/native-reasoning-retention.ts +26 -0
  180. package/src/config.ts +2 -0
  181. package/src/generated/compatibility-version.json +657 -297
  182. package/src/grok/sync.ts +1 -1
  183. package/src/images/loop.ts +116 -27
  184. package/src/integrations/catalog-refresh.ts +1 -1
  185. package/src/integrations/mutation-plan.ts +1 -0
  186. package/src/integrations/registry.ts +8 -0
  187. package/src/lib/codex-restart-contract.ts +15 -0
  188. package/src/lib/desktop-upstream-tunnel.ts +18 -53
  189. package/src/lib/empty-tool-catalog.ts +62 -0
  190. package/src/lib/errors.ts +19 -3
  191. package/src/lib/gcp-adc.ts +96 -9
  192. package/src/lib/gcp-credential-input.ts +12 -0
  193. package/src/lib/lab-live-route-production.ts +5 -0
  194. package/src/lib/opaque-proxy-tunnel.ts +217 -0
  195. package/src/lib/redact.ts +2 -2
  196. package/src/lib/request-failure-model.ts +2 -0
  197. package/src/oauth/account-quota-rank.ts +69 -2
  198. package/src/oauth/anthropic-account-refusal.ts +20 -2
  199. package/src/oauth/anthropic-oauth-definitions.ts +3 -1
  200. package/src/oauth/anthropic-routing.ts +1 -21
  201. package/src/oauth/anthropic.ts +38 -7
  202. package/src/oauth/callback-server.ts +27 -1
  203. package/src/oauth/chatgpt-device.ts +1 -1
  204. package/src/oauth/chatgpt-shared.ts +83 -0
  205. package/src/oauth/chatgpt.ts +8 -72
  206. package/src/oauth/dsh.ts +203 -0
  207. package/src/oauth/generic-account-failover.ts +40 -11
  208. package/src/oauth/generic-session-affinity.ts +125 -0
  209. package/src/oauth/index.ts +184 -109
  210. package/src/oauth/local-token-detect.ts +21 -1
  211. package/src/oauth/login-cli-errors.ts +44 -0
  212. package/src/oauth/login-cli.ts +69 -7
  213. package/src/oauth/login-flow-state.ts +371 -23
  214. package/src/oauth/meta-muse-errors.ts +41 -0
  215. package/src/oauth/meta-muse-keychain.ts +52 -0
  216. package/src/oauth/meta-muse.ts +51 -84
  217. package/src/oauth/model-discovery-auth.ts +3 -0
  218. package/src/oauth/pool-settings-capability.ts +4 -2
  219. package/src/oauth/refresh-flight-retirement.ts +48 -0
  220. package/src/oauth/session-affinity-key.ts +23 -0
  221. package/src/oauth/store-anthropic-instance.ts +9 -2
  222. package/src/oauth/store.ts +12 -5
  223. package/src/protocols/encoders/adapter-events.ts +6 -5
  224. package/src/protocols/encoders/messages.ts +9 -6
  225. package/src/protocols/provider-summary.ts +2 -1
  226. package/src/providers/api-key-cooldowns.ts +49 -0
  227. package/src/providers/api-key-resolve.ts +11 -6
  228. package/src/providers/api-key-response-ownership.ts +57 -0
  229. package/src/providers/api-key-selection.ts +31 -6
  230. package/src/providers/api-keys.ts +214 -3
  231. package/src/providers/claude-cli-usage.ts +96 -0
  232. package/src/providers/dsh-account-destination.ts +31 -0
  233. package/src/providers/dsh-account-models.ts +41 -0
  234. package/src/providers/gcp-credential-cleanup.ts +59 -0
  235. package/src/providers/key-failover.ts +54 -50
  236. package/src/providers/key-store.ts +7 -2
  237. package/src/providers/model-rename-fields.ts +3 -0
  238. package/src/providers/model-rename-migration.ts +2 -2
  239. package/src/providers/openai-tiers-destination.ts +11 -2
  240. package/src/providers/openai-tiers.ts +5 -12
  241. package/src/providers/opencode-go-transport.ts +3 -1
  242. package/src/providers/opencode-zen-rate-limit.ts +7 -2
  243. package/src/providers/quota/account-cache.ts +6 -5
  244. package/src/providers/quota/account-row.ts +34 -0
  245. package/src/providers/quota/antigravity.ts +28 -7
  246. package/src/providers/quota/dsh-account.ts +70 -0
  247. package/src/providers/quota/vendor-probes-oauth.ts +1 -93
  248. package/src/providers/quota-types.ts +2 -0
  249. package/src/providers/quota.ts +14 -20
  250. package/src/providers/registry/entries-core.ts +37 -8
  251. package/src/providers/registry/types.ts +1 -1
  252. package/src/providers/request-pacing.ts +77 -19
  253. package/src/providers/routed-config.ts +339 -0
  254. package/src/providers/service-tier.ts +2 -1
  255. package/src/quota/window-mapping.ts +5 -2
  256. package/src/responses/anthropic-progress.ts +34 -0
  257. package/src/responses/assistant-replay.ts +35 -0
  258. package/src/responses/compaction-history-framing.ts +65 -0
  259. package/src/responses/compaction.ts +6 -1
  260. package/src/responses/incomplete-reason.ts +31 -0
  261. package/src/responses/parser.ts +50 -5
  262. package/src/responses/reasoning-envelope.ts +4 -0
  263. package/src/responses/reasoning-replay-cache.ts +74 -6
  264. package/src/responses/reasoning-retention.ts +173 -0
  265. package/src/responses/retained-compaction.ts +46 -0
  266. package/src/responses/schema.ts +23 -0
  267. package/src/router.ts +8 -321
  268. package/src/routing/analytics.ts +7 -15
  269. package/src/routing/health.ts +37 -22
  270. package/src/routing/history/indexer.ts +6 -5
  271. package/src/routing/history/ingest.ts +6 -2
  272. package/src/routing/profile.ts +1 -1
  273. package/src/server/admission-model-scope.ts +17 -0
  274. package/src/server/auth-cors.ts +11 -0
  275. package/src/server/chat-completions.ts +7 -1
  276. package/src/server/chat-native-reasoning.ts +123 -0
  277. package/src/server/chat-native-sse.ts +110 -7
  278. package/src/server/chat-native.ts +76 -17
  279. package/src/server/claude-messages.ts +56 -414
  280. package/src/server/effort-policy.ts +1 -1
  281. package/src/server/images.ts +15 -2
  282. package/src/server/index/live-sideband.ts +3 -2
  283. package/src/server/index/model-alias-id.ts +36 -0
  284. package/src/server/index/optional-listeners.ts +2 -0
  285. package/src/server/index/serve-options.ts +20 -6
  286. package/src/server/index/startup-warnings.ts +2 -0
  287. package/src/server/index/websocket-handler.ts +18 -4
  288. package/src/server/index.ts +8 -8
  289. package/src/server/inference/advisor-diagnostics.ts +31 -0
  290. package/src/server/lifecycle.ts +13 -1
  291. package/src/server/management/advisor-routes.ts +15 -4
  292. package/src/server/management/claude-desktop-picker-routes.ts +1 -1
  293. package/src/server/management/combo-routes.ts +176 -50
  294. package/src/server/management/companion-routes.ts +1 -1
  295. package/src/server/management/config-routes.ts +75 -4
  296. package/src/server/management/cursor-integration-routes.ts +1 -1
  297. package/src/server/management/model-routes.ts +11 -6
  298. package/src/server/management/model-rows.ts +14 -0
  299. package/src/server/management/native-integration-routes.ts +2 -7
  300. package/src/server/management/native-reasoning-retention-routes.ts +41 -0
  301. package/src/server/management/oauth-account-routes.ts +87 -14
  302. package/src/server/management/provider-gcp-credential-routes.ts +29 -0
  303. package/src/server/management/provider-key-pacing-routes.ts +31 -0
  304. package/src/server/management/provider-overwrite-carry.ts +7 -0
  305. package/src/server/management/provider-routes.ts +25 -30
  306. package/src/server/management/route-registry.ts +10 -1
  307. package/src/server/management-api.ts +3 -1
  308. package/src/server/messages-native-tool-guard.ts +185 -0
  309. package/src/server/messages-native.ts +117 -24
  310. package/src/server/messages-shared.ts +431 -0
  311. package/src/server/relay.ts +1 -1
  312. package/src/server/request-log-terminal-status.ts +1 -1
  313. package/src/server/request-log.ts +6 -1
  314. package/src/server/responses/account-change-state.ts +8 -2
  315. package/src/server/responses/adapter-continuation.ts +47 -19
  316. package/src/server/responses/adapter-delivery.ts +72 -12
  317. package/src/server/responses/adapter-dispatch.ts +46 -3
  318. package/src/server/responses/advisor-retention.ts +117 -0
  319. package/src/server/responses/advisor-slot.ts +73 -41
  320. package/src/server/responses/anthropic-thinking-recovery.ts +153 -0
  321. package/src/server/responses/codex-ws-wire.ts +15 -8
  322. package/src/server/responses/combo-stream-preflight.ts +3 -2
  323. package/src/server/responses/compact.ts +303 -125
  324. package/src/server/responses/compaction-recovery.ts +20 -10
  325. package/src/server/responses/compaction-retention.ts +61 -0
  326. package/src/server/responses/context-overflow.ts +11 -6
  327. package/src/server/responses/core-auth.ts +6 -0
  328. package/src/server/responses/core-codex-account.ts +11 -1
  329. package/src/server/responses/core-combo-failure.ts +2 -0
  330. package/src/server/responses/core-combo.ts +121 -36
  331. package/src/server/responses/core-errors.ts +3 -3
  332. package/src/server/responses/core-lifetime.ts +8 -4
  333. package/src/server/responses/core-opaque-recovery.ts +35 -0
  334. package/src/server/responses/core-options.ts +7 -0
  335. package/src/server/responses/core-pipeline.ts +141 -0
  336. package/src/server/responses/core-replay.ts +23 -3
  337. package/src/server/responses/core.ts +2 -115
  338. package/src/server/responses/fetch-helpers.ts +73 -19
  339. package/src/server/responses/main-hard-lock-routing.ts +109 -0
  340. package/src/server/responses/native-response-control.ts +4 -2
  341. package/src/server/responses/passthrough-delivery.ts +3 -1
  342. package/src/server/responses/passthrough-dispatch.ts +15 -13
  343. package/src/server/responses/passthrough-execution.ts +3 -2
  344. package/src/server/responses/request-prepare.ts +77 -12
  345. package/src/server/responses/request-sidecar-auth.ts +2 -2
  346. package/src/server/responses/request-transport.ts +104 -27
  347. package/src/server/responses/response-effects.ts +2 -0
  348. package/src/server/responses/response-tool-ownership.ts +21 -0
  349. package/src/server/responses/run-turn-execution.ts +96 -30
  350. package/src/server/responses/sidecar-execution.ts +63 -9
  351. package/src/server/responses/sidecar-send-budget.ts +2 -2
  352. package/src/server/responses/terminal-guard.ts +2 -16
  353. package/src/server/responses-undeclared-tool-guard.ts +1 -1
  354. package/src/server/ws-bridge.ts +2 -0
  355. package/src/service/auth-preflight.ts +71 -0
  356. package/src/service/cli.ts +4 -2
  357. package/src/service/definition.ts +97 -0
  358. package/src/service/guards.ts +1 -61
  359. package/src/service/health-sentinel-linux.ts +112 -0
  360. package/src/service/health-sentinel-main.ts +76 -57
  361. package/src/service/health.ts +5 -89
  362. package/src/service/launchd.ts +27 -7
  363. package/src/service/logging.ts +72 -9
  364. package/src/service/repair.ts +2 -1
  365. package/src/service/state.ts +7 -8
  366. package/src/service/systemd.ts +1 -1
  367. package/src/service/windows-guarded-manager.ts +2 -1
  368. package/src/service/windows-ops.ts +1 -1
  369. package/src/service/windows-scheduler.ts +2 -7
  370. package/src/service/windows-taskxml.ts +2 -2
  371. package/src/service/windows-wscript.ts +14 -0
  372. package/src/service.ts +4 -2
  373. package/src/sidecar/auth.ts +2 -0
  374. package/src/types/config.ts +64 -3
  375. package/src/types/opencode-go.ts +61 -0
  376. package/src/types/opencode-zen.ts +35 -0
  377. package/src/types/provider.ts +32 -6
  378. package/src/types/request.ts +31 -2
  379. package/src/types/wire.ts +31 -37
  380. package/src/types.ts +2 -0
  381. package/src/update/npm-invocation.mjs +12 -2
  382. package/src/usage/cost.ts +48 -12
  383. package/src/usage/expected-prices.ts +3 -0
  384. package/src/usage/ledger-retention.ts +2 -1
  385. package/src/usage/ledger-scanner.ts +6 -5
  386. package/src/usage/log.ts +17 -8
  387. package/src/usage/summary.ts +30 -11
  388. package/src/usage/telemetry-contract.ts +1 -0
  389. package/src/usage/user-cost-overlays.ts +14 -19
  390. package/src/usage/user-cost-validation.ts +38 -0
  391. package/src/vision/eligibility.ts +13 -0
  392. package/src/web-search/anthropic-history.ts +59 -0
  393. package/src/web-search/loop.ts +236 -73
  394. package/src/web-search/progress-stream.ts +15 -2
  395. package/src/web-search/run-turn-loop.ts +9 -1
  396. package/gui/dist/assets/App-BjlttVLy.js +0 -58
  397. package/gui/dist/assets/App-CSJvmjNs.css +0 -1
  398. package/gui/dist/assets/index-BB6uK6tU.css +0 -1
  399. package/gui/dist/assets/index-BMssP4k3.js +0 -94
  400. package/gui/dist/assets/quota-summary-D8M1bc_R.js +0 -1
@@ -10,7 +10,7 @@ import {
10
10
  type PersistedUsageEntry,
11
11
  type UsageStatus,
12
12
  } from "./log";
13
- import { type AttemptCostEstimate, type CostEstimate, estimateAttemptCost, estimateRequestCost, serviceTierContext, type ServiceTierContext, tokensPerSecond } from "./cost";
13
+ import { type AttemptCostEstimate, type CostEstimate, estimateAttemptCost, estimateRequestCost, isMeasuredStatus, serviceTierContext, type ServiceTierContext, tokensPerSecond } from "./cost";
14
14
 
15
15
  /**
16
16
  * Canonical range members. The warm-up loop in the management usage route
@@ -303,7 +303,10 @@ export function computeEntryCost(entry: PersistedUsageEntry): EntryCostInfo {
303
303
  isPriced = true;
304
304
  }
305
305
  }
306
- return { tier, estimate: null, attemptEstimates, costTotal, isPriced };
306
+ // An unmeasured leg that may have generated billed tokens leaves the total unknown, not short.
307
+ const unknownCost = entry.attempts.some((attempt, index) =>
308
+ !attemptEstimates[index] && (!attempt.usage || !isMeasuredStatus(attempt.usageStatus)) && !spentNothing(attempt));
309
+ return { tier, estimate: null, attemptEstimates, costTotal, isPriced: isPriced && !unknownCost };
307
310
  }
308
311
  const estimate = estimateRequestCost({
309
312
  ...usageModelPriceOptions(entry, entry),
@@ -428,10 +431,6 @@ function blankTotals(): UsageSummaryTotals {
428
431
  };
429
432
  }
430
433
 
431
- function isMeasuredStatus(status: UsageStatus): boolean {
432
- return status === "reported" || status === "estimated";
433
- }
434
-
435
434
  export interface UsageAttribution {
436
435
  requestId: string;
437
436
  provider: string;
@@ -666,8 +665,12 @@ function addEstimatedCost(
666
665
  entry: Pick<PersistedUsageEntry, "usageStatus" | "usage" | "attempts">,
667
666
  costInfo: EntryCostInfo,
668
667
  ): void {
669
- if (entry.usageStatus === "unreported" || entry.usageStatus === "unsupported"
670
- || (!entry.usage && !entry.attempts?.length)) {
668
+ // A row of attempts reads `unreported` when any leg lacks usage. Once one leg is measured the row
669
+ // is metered and the attempt-level pricing decides, matching the model and provider breakdowns.
670
+ const measuredAttempt = entry.attempts?.some(attempt => attempt.usage && isMeasuredStatus(attempt.usageStatus));
671
+ if (!measuredAttempt
672
+ && (entry.usageStatus === "unreported" || entry.usageStatus === "unsupported"
673
+ || (!entry.usage && !entry.attempts?.length))) {
671
674
  totals.unmeteredRequests += 1;
672
675
  return;
673
676
  }
@@ -814,14 +817,30 @@ function blankRequestCounts(): UsageRequestCounts {
814
817
  };
815
818
  }
816
819
 
820
+ /**
821
+ * A usage-less attempt that provably cost nothing: it never reached upstream, or upstream refused it
822
+ * with an HTTP error before any output (providers do not bill a pre-generation 429/401/5xx). One
823
+ * whose stream began, aborted, or ended without a status may have generated billed tokens, so it
824
+ * stays an unknown cost. A request made only of such zeros carries neither fact and counts unpriced.
825
+ */
826
+ function spentNothing(attempt: NonNullable<PersistedUsageEntry["attempts"]>[number] | undefined): boolean {
827
+ if (!attempt || attempt.usage) return false;
828
+ if (attempt.sendCount === 0 || attempt.locallyAnswered === true) return true;
829
+ // A 499 is the client hanging up on a send upstream may already be generating for.
830
+ return attempt.status >= 400 && attempt.status !== 499
831
+ && attempt.streamAborted !== true && attempt.firstOutputMs === undefined;
832
+ }
833
+
817
834
  function bumpRequestCounts(counts: UsageRequestCounts, facts: number, amount = 1): void {
818
835
  counts.requests += amount;
819
836
  const status = statusFromRequestFacts(facts);
820
837
  if (isMeasuredStatus(status)) counts.measuredRequests += amount;
821
838
  if (status === "reported") counts.reportedRequests += amount;
822
839
  else if (status === "estimated") counts.estimatedRequests += amount;
823
- if ((facts & REQUEST_PRICED) !== 0) counts.pricedRequests += amount;
824
- if ((facts & REQUEST_UNPRICED) !== 0) counts.unpricedRequests += amount;
840
+ // Unpriced dominates: one unpriceable part makes the request's cost unknown, and counting it
841
+ // on both sides overstated price coverage.
842
+ if ((facts & REQUEST_PRICED) !== 0 && (facts & REQUEST_UNPRICED) === 0) counts.pricedRequests += amount;
843
+ else counts.unpricedRequests += amount;
825
844
  }
826
845
 
827
846
  function mergeRequestCounts(target: UsageRequestCounts, source: UsageRequestCounts): void {
@@ -1557,7 +1576,7 @@ class StreamingUsageSummaryAccumulator implements UsageSummaryAccumulator {
1557
1576
  : costInfo.estimate;
1558
1577
  const ordinal = this.nextOrdinal++;
1559
1578
  const facts = requestStatusFact(attribution.usageStatus)
1560
- | (estimate ? REQUEST_PRICED : REQUEST_UNPRICED);
1579
+ | (estimate ? REQUEST_PRICED : spentNothing(entry.attempts?.[index]) ? 0 : REQUEST_UNPRICED);
1561
1580
  const modelKey = this.addModelAttribution(partition, attribution, estimate, ordinal);
1562
1581
  modelFacts.set(modelKey, (modelFacts.get(modelKey) ?? 0) | facts);
1563
1582
  if (this.mode === "row-unique") {
@@ -32,6 +32,7 @@ export const ATTEMPT_RECOVERY_KIND_ROSTER = Object.freeze([
32
32
  "rate-limit-429",
33
33
  "anthropic-oauth-429",
34
34
  "oauth-account-429",
35
+ "oauth-account-402",
35
36
  "image-413",
36
37
  "console-go-upload-retry",
37
38
  "opaque-blob-rejection",
@@ -18,8 +18,10 @@
18
18
  *
19
19
  * Display-time estimation only — these rows never affect billing.
20
20
  */
21
- import type { OcxConfig, OcxProviderConfig, ProviderCostOverlay } from "../types";
22
- import { MAX_COST4_RATE, type ExpectedPriceOverlay } from "./expected-prices";
21
+ import type { OcxConfig, OcxProviderConfig, ProviderCostOverlay, PromptLengthPricing } from "../types";
22
+ import type { ExpectedPriceOverlay } from "./expected-prices";
23
+ import { validCost4 } from "./user-cost-validation";
24
+ export { COST4_RATE_KEYS, isValidCost4Rate, validCost4, isValidPromptLengthPricing } from "./user-cost-validation";
23
25
  import { redactSecretString } from "../lib/redact";
24
26
  import { isSelectableCodexPoolAccount, MAIN_CODEX_ACCOUNT_ID } from "../codex/account-id";
25
27
  import { codexAccountLogLabel } from "../codex/account-label";
@@ -236,22 +238,13 @@ export function resetPreservedDiskOnlyProvidersForTests(): void {
236
238
  preservationOwnerStates.clear();
237
239
  }
238
240
 
239
- /** Exact four fields accepted for a user-configured cost tuple. */
240
- export const COST4_RATE_KEYS = ["input", "output", "cacheRead", "cacheWrite"] as const;
241
-
242
- /** Shared per-rate predicate used by config validation, display sanitization, and runtime lifting. */
243
- export function isValidCost4Rate(rate: unknown): rate is number {
244
- return typeof rate === "number"
245
- && Number.isFinite(rate)
246
- && rate >= 0
247
- && rate <= MAX_COST4_RATE;
248
- }
249
-
250
- /** True when `value` is a complete cost entry: all four rates are non-negative finite numbers. */
251
- function validCost4(value: unknown): value is ProviderCostOverlay {
252
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
253
- const entry = value as Record<string, unknown>;
254
- return COST4_RATE_KEYS.every(key => isValidCost4Rate(entry[key]));
241
+ /** Copy a validated override; automatic is represented by absence. */
242
+ export function copyPromptLengthPricing(policy: PromptLengthPricing): PromptLengthPricing | undefined {
243
+ if (policy.mode === "automatic") return undefined;
244
+ if (policy.mode !== "custom") return { mode: policy.mode };
245
+ const { input, output, cacheRead, cacheWrite } = policy.rates;
246
+ return { mode: "custom", thresholdTokens: policy.thresholdTokens, comparison: policy.comparison,
247
+ rates: { input, output, cacheRead, cacheWrite } };
255
248
  }
256
249
 
257
250
  /**
@@ -273,10 +266,11 @@ export function refreshUserCostOverlays(config: OcxConfig): void {
273
266
  if (!costs || typeof costs !== "object" || Array.isArray(costs)) continue;
274
267
  for (const [modelId, cost4] of Object.entries(costs)) {
275
268
  if (!modelId.trim() || !validCost4(cost4)) continue;
269
+ const policy = cost4.promptLengthPricing && copyPromptLengthPricing(cost4.promptLengthPricing);
276
270
  rows.push({
277
271
  provider: providerName,
278
272
  modelId,
279
- // Copy ONLY the four validated rate fields: a hand-edited row may
273
+ // Copy only validated rates and policy: a hand-edited row may
280
274
  // carry extra properties (e.g. a misplaced apiKey) that must never
281
275
  // reach display estimates or /api/logs through the registry.
282
276
  cost4: {
@@ -285,6 +279,7 @@ export function refreshUserCostOverlays(config: OcxConfig): void {
285
279
  cacheRead: cost4.cacheRead,
286
280
  cacheWrite: cost4.cacheWrite,
287
281
  },
282
+ ...(policy ? { promptLengthPricing: policy } : {}),
288
283
  // Display provenance only: redact token-shaped provider/model ids so
289
284
  // the source string can never echo a pasted key. Matching still uses
290
285
  // the raw fields, and the change-detection signature below MUST keep
@@ -0,0 +1,38 @@
1
+ /** Pure model-cost validation shared by config, migration, and display lifting. */
2
+ import type { ProviderCostOverlay, PromptLengthPricing } from "../types";
3
+ import { MAX_COST4_RATE } from "./expected-prices";
4
+
5
+ /** Exact four fields accepted for a user-configured cost tuple. */
6
+ export const COST4_RATE_KEYS = ["input", "output", "cacheRead", "cacheWrite"] as const;
7
+
8
+ /** Shared per-rate predicate used by config validation, display sanitization, and runtime lifting. */
9
+ export function isValidCost4Rate(rate: unknown): rate is number {
10
+ return typeof rate === "number"
11
+ && Number.isFinite(rate)
12
+ && rate >= 0
13
+ && rate <= MAX_COST4_RATE;
14
+ }
15
+
16
+ /** Complete base rates with a valid optional policy; extra top-level fields are never copied. */
17
+ export function validCost4(value: unknown): value is ProviderCostOverlay {
18
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
19
+ const entry = value as Record<string, unknown>;
20
+ return COST4_RATE_KEYS.every(key => Object.hasOwn(entry, key) && isValidCost4Rate(entry[key]))
21
+ && (!Object.hasOwn(entry, "promptLengthPricing") || isValidPromptLengthPricing(entry.promptLengthPricing));
22
+ }
23
+
24
+ /** Strict nested policy boundary; diagnostics never echo untrusted policy fields. */
25
+ export function isValidPromptLengthPricing(value: unknown): value is PromptLengthPricing {
26
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
27
+ const policy = value as Record<string, unknown>;
28
+ if (!Object.hasOwn(policy, "mode")) return false;
29
+ if (policy.mode === "automatic" || policy.mode === "flat") return Object.keys(policy).length === 1;
30
+ if (policy.mode !== "custom" || Object.keys(policy).length !== 4
31
+ || !["mode", "thresholdTokens", "comparison", "rates"].every(key => Object.hasOwn(policy, key))
32
+ || typeof policy.thresholdTokens !== "number" || !Number.isSafeInteger(policy.thresholdTokens)
33
+ || policy.thresholdTokens <= 0 || (policy.comparison !== "gt" && policy.comparison !== "gte")) return false;
34
+ const rates = policy.rates;
35
+ return !!rates && typeof rates === "object" && !Array.isArray(rates)
36
+ && Object.keys(rates).length === COST4_RATE_KEYS.length
37
+ && COST4_RATE_KEYS.every(key => Object.hasOwn(rates, key) && isValidCost4Rate((rates as Record<string, unknown>)[key]));
38
+ }
@@ -226,6 +226,19 @@ export function isVisionSidecarConsumer(config: VisionCapabilityConfig, provider
226
226
  return isVisionSidecarConsumerWithCache(config, providerName, modelId, new Map());
227
227
  }
228
228
 
229
+ /**
230
+ * `isVisionSidecarConsumer` for many rows of one config. Rows of the same provider share one
231
+ * registry enrichment instead of rebuilding it per row, which matters for `/api/models`
232
+ * listings with thousands of rows. Bind it to a single config snapshot; it does not observe
233
+ * provider changes made after the first lookup.
234
+ */
235
+ export function visionSidecarConsumerClassifier(
236
+ config: VisionCapabilityConfig,
237
+ ): (providerName: string, modelId: string) => boolean {
238
+ const cache: EnrichedProviderCache = new Map();
239
+ return (providerName, modelId) => isVisionSidecarConsumerWithCache(config, providerName, modelId, cache);
240
+ }
241
+
229
242
  /**
230
243
  * Can this model accept an image on the wire? Sources are consulted in descending
231
244
  * trustworthiness; the first that speaks wins. `undefined` means nothing knows,
@@ -0,0 +1,59 @@
1
+ import type { AdapterEvent, OcxAssistantContentPart, OcxThinkingContent, OcxToolCall } from "../types";
2
+
3
+ /** Rebuild one validated Anthropic model response without changing its search arguments or order. */
4
+ export function anthropicSearchAssistantContent(events: readonly AdapterEvent[]): OcxAssistantContentPart[] {
5
+ const content: OcxAssistantContentPart[] = [];
6
+ let thinking: OcxThinkingContent | undefined;
7
+ let text: Extract<OcxAssistantContentPart, { type: "text" }> | undefined;
8
+ let call: OcxToolCall | undefined;
9
+ let argumentsText = "";
10
+ for (const event of events) {
11
+ if (event.type === "heartbeat") continue;
12
+ // A signature is a replacement snapshot until the next semantic block starts.
13
+ if (thinking?.signature !== undefined && event.type !== "thinking_signature") thinking = undefined;
14
+ if (event.type !== "text_delta") text = undefined;
15
+ switch (event.type) {
16
+ case "thinking_delta":
17
+ if (!thinking) { thinking = { type: "thinking", thinking: "" }; content.push(thinking); }
18
+ thinking.thinking += event.thinking;
19
+ break;
20
+ case "thinking_signature":
21
+ if (!thinking) { thinking = { type: "thinking", thinking: "" }; content.push(thinking); }
22
+ thinking.signature = event.signature;
23
+ break;
24
+ case "redacted_thinking":
25
+ thinking = undefined;
26
+ content.push({ type: "thinking", thinking: "", redacted: [event.data] });
27
+ break;
28
+ case "text_delta":
29
+ thinking = undefined;
30
+ if (event.anthropicThinkingSignature) {
31
+ text = undefined;
32
+ content.push({ type: "thinking", thinking: event.text, signature: event.anthropicThinkingSignature });
33
+ break;
34
+ }
35
+ if (!text) { text = { type: "text", text: "" }; content.push(text); }
36
+ text.text += event.text;
37
+ break;
38
+ case "tool_call_start":
39
+ thinking = undefined;
40
+ call = { type: "toolCall", id: event.id, name: event.name, arguments: {},
41
+ ...(event.providerMetadata ? { providerMetadata: event.providerMetadata } : {}) };
42
+ content.push(call);
43
+ argumentsText = "";
44
+ break;
45
+ case "tool_call_delta":
46
+ argumentsText += event.arguments;
47
+ break;
48
+ case "tool_call_end": {
49
+ if (!call) throw new Error("search history has an unpaired tool call");
50
+ const args: unknown = JSON.parse(argumentsText || "{}");
51
+ if (!args || typeof args !== "object" || Array.isArray(args)) throw new Error("search history tool input is not an object");
52
+ call.arguments = args as Record<string, unknown>;
53
+ call = undefined;
54
+ break;
55
+ }
56
+ }
57
+ }
58
+ return content;
59
+ }