@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
@@ -30,6 +30,7 @@ import {
30
30
  providerForwardClientHeadersConfigError,
31
31
  reasoningSummaryDeliveryRecordConfigError,
32
32
  upstreamHttpVersionConfigError,
33
+ credentialPinnedProviderConfigError,
33
34
  } from "../config/provider-validation";
34
35
  import { providerDestinationConfigError } from "../lib/destination-policy";
35
36
  import { providerEgressConfigError } from "../lib/provider-egress";
@@ -784,6 +785,8 @@ export function providerManagementConfigError(
784
785
  delete canonicalCandidate.pinnedReasoningEffort;
785
786
  delete canonicalCandidate.modelPinnedReasoningEfforts;
786
787
  delete canonicalCandidate.responsesSnapshotRepair;
788
+ // Explicit history-loss opt-in changes request content, never auth or transport identity.
789
+ delete canonicalCandidate.projectResponsesLiteHostedSearchHistory;
787
790
  // modelCosts is a user-owned display overlay, not part of the canonical
788
791
  // forward seed; it is validated separately below (providerModelCostsConfigError).
789
792
  delete canonicalCandidate.modelCosts;
@@ -912,6 +915,8 @@ export function providerManagementConfigError(
912
915
  if (reasoningSummaryDeliveryError) return `provider ${name} ${reasoningSummaryDeliveryError}`;
913
916
  const modelAdaptersError = modelAdapterRecordConfigError(raw.modelAdapters, "modelAdapters", name, typed);
914
917
  if (modelAdaptersError) return `provider ${name} ${modelAdaptersError}`;
918
+ const credentialPinError = credentialPinnedProviderConfigError(name, typed);
919
+ if (credentialPinError) return `provider ${name} ${credentialPinError}`;
915
920
  const preferHostedToolsError = modelPreferHostedToolsConfigError(
916
921
  raw.modelPreferHostedTools,
917
922
  "modelPreferHostedTools",
@@ -919,6 +924,9 @@ export function providerManagementConfigError(
919
924
  typed,
920
925
  );
921
926
  if (preferHostedToolsError) return `provider ${name} ${preferHostedToolsError}`;
927
+ if (raw.projectResponsesLiteHostedSearchHistory !== undefined && typeof raw.projectResponsesLiteHostedSearchHistory !== "boolean") {
928
+ return `provider ${name} projectResponsesLiteHostedSearchHistory must be a boolean`;
929
+ }
922
930
  if (raw.responsesSnapshotRepair !== undefined && typeof raw.responsesSnapshotRepair !== "boolean") {
923
931
  return `provider ${name} responsesSnapshotRepair must be a boolean`;
924
932
  }
@@ -1053,9 +1061,12 @@ const PROVIDER_CONFIG_FIELD_POLICY = {
1053
1061
  preserveResponsesReasoningContent: "editor",
1054
1062
  preserveResponsesInputItemIds: "editor",
1055
1063
  preserveResponsesMessageMetadata: "editor",
1064
+ projectResponsesLiteHostedSearchHistory: "editor",
1056
1065
  dropResponsesReasoningItems: "editor",
1057
1066
  modelReasoningEffortsAuthoritative: "editor",
1058
1067
  decodesNativeCompactionBlobs: "editor",
1068
+ supportsNativeCompactionTrigger: "editor",
1069
+ supportsNativeCompactEndpoint: "editor",
1059
1070
  allowEncryptedV2AgentTasks: "editor",
1060
1071
  allowPrivateNetwork: "editor",
1061
1072
  // A proxy URL routinely embeds `user:password@`, so it never reaches the dashboard DTO and
@@ -54,6 +54,7 @@ import {
54
54
  } from "./request-log";
55
55
  import { createFinalRequestLog } from "./inference/final-log";
56
56
  import { clientWireLogOf, clientWireOf } from "./inference/client-wire";
57
+ import { attachAdvisorReasoning } from "./inference/advisor-diagnostics";
57
58
  import { directEncodersApply } from "./inference/client-encoder-delivery";
58
59
  import { responseWithDeferredRequestLog } from "./relay";
59
60
  import { handleResponses } from "./responses";
@@ -114,8 +115,10 @@ export async function handleChatCompletions(
114
115
  ): Promise<Response> {
115
116
  const translatorBudget = createTranslatorBudget();
116
117
  try {
118
+ let response = await handleChatCompletionsWithBudget(req, config, logCtx, translatorBudget, logIds);
119
+ if (isInternalCallCapability(req.headers.get(ADVISOR_INTERNAL_CAPABILITY_HEADER))) response = attachAdvisorReasoning(response, logCtx);
117
120
  return finalizeTranslatorBudgetResponse(
118
- await handleChatCompletionsWithBudget(req, config, logCtx, translatorBudget, logIds),
121
+ response,
119
122
  translatorBudget,
120
123
  req.signal,
121
124
  );
@@ -601,6 +604,9 @@ async function handleChatCompletionsWithBudget(
601
604
  // below could never restore this one -- the translated client was told the provider
602
605
  // throttled the turn, and handed a two-second wait to send it again.
603
606
  classified.code = UPSTREAM_RESET_REPLAY_REFUSED_CODE;
607
+ } else if (upstreamCode === "claude_subscription_cooldown") {
608
+ classified.code = "claude_subscription_cooldown";
609
+ classified.type = "rate_limit_error";
604
610
  } else if (upstreamCode === "model_not_found") {
605
611
  // Structured model_not_found must win over classifyError's generic remaps.
606
612
  classified.code = "model_not_found";
@@ -0,0 +1,123 @@
1
+ import type { OcxProviderConfig, OcxReasoningReplayScopeRef } from "../types";
2
+ import type { TranslatorBudget } from "../lib/translator-budget";
3
+ import { chatReasoningReplayPolicy, isChatRecord } from "../adapters/openai-chat/reasoning-replay";
4
+ import { bindReasoningReplayScope, reasoningReplayDestinationIdentity,
5
+ reasoningReplayKeyCredentialIdentity, rememberReasoningForCall } from "../responses/reasoning-replay-cache";
6
+ import { reasoningReplayConversationIdFromResponsesRequest, sessionIdHeaderFromRequest } from "./request-log-conversation";
7
+
8
+ type Rec = Record<string, unknown>;
9
+
10
+ export function nativeChatReplayScope(headers: Headers): OcxReasoningReplayScopeRef | undefined {
11
+ const clientThreadId = reasoningReplayConversationIdFromResponsesRequest({
12
+ threadIdHeader: headers.get("thread-id"), sessionIdHeader: sessionIdHeaderFromRequest(headers),
13
+ });
14
+ return clientThreadId ? { clientThreadId } : undefined;
15
+ }
16
+
17
+ /** Rebind before EVERY build: a key rotation must not retrieve another credential's reasoning. */
18
+ export function bindNativeChatReplayScope(
19
+ scope: OcxReasoningReplayScopeRef | undefined,
20
+ provider: OcxProviderConfig,
21
+ providerName: string,
22
+ modelId: string,
23
+ ): void {
24
+ const providerDestinationIdentity = reasoningReplayDestinationIdentity(provider.baseUrl);
25
+ const credentialIdentity = reasoningReplayKeyCredentialIdentity(provider);
26
+ bindReasoningReplayScope(scope, providerDestinationIdentity && credentialIdentity ? {
27
+ providerName, modelId, adapterName: "openai-chat",
28
+ providerDestinationIdentity, credentialIdentity,
29
+ } : undefined);
30
+ }
31
+
32
+ /** Observe the native wire, never translate it or retain tool arguments/content. */
33
+ export function nativeChatReasoningCapture(
34
+ provider: OcxProviderConfig,
35
+ modelId: string,
36
+ scope: OcxReasoningReplayScopeRef | undefined,
37
+ budget: TranslatorBudget,
38
+ ) {
39
+ const choices = new Map<number, { text: string; calls: Map<number, string> }>();
40
+ const accounting = { kind: "retained_collectors" as const };
41
+ // This optional fallback cannot retain more than the cache it feeds (256 KiB / 64 calls).
42
+ const maxBytes = 256 * 1024;
43
+ let bytes = 0;
44
+ let callCount = 0;
45
+ let disabled = !scope?.current || !chatReasoningReplayPolicy(provider, modelId).preserve;
46
+ const discard = () => {
47
+ budget.releaseRetained(bytes, accounting);
48
+ bytes = 0;
49
+ choices.clear();
50
+ disabled = true;
51
+ };
52
+ const remember = (text: string, calls: Iterable<string>) => {
53
+ for (const id of calls) rememberReasoningForCall(id, text, scope);
54
+ };
55
+ const observe = (value: Rec) => {
56
+ if (disabled || !Array.isArray(value.choices)) return;
57
+ for (const [ordinal, raw] of value.choices.entries()) {
58
+ if (!isChatRecord(raw) || !isChatRecord(raw.delta)) continue;
59
+ const index = typeof raw.index === "number" ? raw.index : ordinal;
60
+ if (!choices.has(index)) {
61
+ if (choices.size >= 64) { discard(); return; }
62
+ choices.set(index, { text: "", calls: new Map() });
63
+ }
64
+ const state = choices.get(index)!;
65
+ const delta = raw.delta;
66
+ const append = (previous: string, fragment: string): string | undefined => {
67
+ const added = Buffer.byteLength(fragment) * 2;
68
+ if (bytes + added > maxBytes) { discard(); return undefined; }
69
+ // Account the new retained fragment before concatenation; the transient reservation
70
+ // covers the old string while its replacement is allocated.
71
+ const reservation = budget.reserveTransient(Buffer.byteLength(previous) * 2, accounting);
72
+ try {
73
+ budget.chargeRetained(added, accounting);
74
+ bytes += added;
75
+ return previous + fragment;
76
+ } finally { reservation.release(); }
77
+ };
78
+ if (typeof delta.reasoning_content === "string" && delta.reasoning_content.length > 0) {
79
+ const text = append(state.text, delta.reasoning_content);
80
+ if (text === undefined) return;
81
+ state.text = text;
82
+ }
83
+ if (Array.isArray(delta.tool_calls)) {
84
+ for (const [toolOrdinal, tool] of delta.tool_calls.entries()) {
85
+ if (!isChatRecord(tool) || typeof tool.id !== "string" || tool.id.length === 0) continue;
86
+ const toolIndex = typeof tool.index === "number" ? tool.index : toolOrdinal;
87
+ if (!state.calls.has(toolIndex)) {
88
+ if (callCount >= 64) { discard(); return; }
89
+ callCount += 1;
90
+ }
91
+ const previous = state.calls.get(toolIndex) ?? "";
92
+ if (previous === tool.id) continue;
93
+ const id = append(previous, tool.id);
94
+ if (id === undefined) return;
95
+ state.calls.set(toolIndex, id);
96
+ }
97
+ }
98
+ // The completed choice is valid even if a caller dispatches its tool before [DONE].
99
+ if (typeof raw.finish_reason === "string" && raw.finish_reason.length > 0) {
100
+ remember(state.text, state.calls.values());
101
+ }
102
+ }
103
+ };
104
+ return {
105
+ observe,
106
+ finish(success: boolean) {
107
+ if (success && !disabled) {
108
+ for (const state of choices.values()) remember(state.text, state.calls.values());
109
+ }
110
+ discard();
111
+ },
112
+ json(value: Rec) {
113
+ if (disabled || !Array.isArray(value.choices)) return;
114
+ for (const choice of value.choices) {
115
+ if (!isChatRecord(choice) || !isChatRecord(choice.message)) continue;
116
+ const message = choice.message;
117
+ if (typeof message.reasoning_content !== "string" || !Array.isArray(message.tool_calls)) continue;
118
+ remember(message.reasoning_content, message.tool_calls.filter(isChatRecord)
119
+ .flatMap(tool => typeof tool.id === "string" ? [tool.id] : []));
120
+ }
121
+ },
122
+ };
123
+ }
@@ -1,5 +1,5 @@
1
1
  import { chatCompletionsErrorBody } from "../chat/outbound";
2
- import { classifyError, cyberPolicyErrorType, CYBER_POLICY_ERROR_CODE, isCyberPolicyCode } from "../lib/errors";
2
+ import { classifyError, cyberPolicyErrorType, CYBER_POLICY_ERROR_CODE, isCyberPolicyCode, UNDECLARED_TOOL_CALL_ERROR_CODE } from "../lib/errors";
3
3
  import { redactSecretString } from "../lib/redact";
4
4
  import {
5
5
  isTranslatorBudgetExceededError,
@@ -16,6 +16,39 @@ function isRec(value: unknown): value is Rec {
16
16
  return value !== null && typeof value === "object" && !Array.isArray(value);
17
17
  }
18
18
 
19
+ export const UNDECLARED_CHAT_TOOL_MESSAGE = "Upstream emitted a client tool call outside this request's declared tool catalog.";
20
+
21
+ function* chatToolCalls(value: Rec): Generator<{ key: string; name: string; snapshot: boolean; invalid?: boolean }> {
22
+ const choices = Array.isArray(value.choices) ? value.choices : [];
23
+ for (const [position, choice] of choices.entries()) {
24
+ if (!isRec(choice)) continue;
25
+ const choiceIndex = typeof choice.index === "number" ? choice.index : position;
26
+ for (const [payload, snapshot] of [[choice.delta, false], [choice.message, true]] as const) {
27
+ if (!isRec(payload)) continue;
28
+ const tools = Array.isArray(payload.tool_calls) ? payload.tool_calls : [];
29
+ for (const [index, tool] of tools.entries()) {
30
+ const fn = isRec(tool) && isRec(tool.function) ? tool.function : {};
31
+ const toolIndex = isRec(tool) && typeof tool.index === "number" ? tool.index : index;
32
+ yield {
33
+ key: `${choiceIndex}:tool:${toolIndex}`, name: typeof fn.name === "string" ? fn.name : "", snapshot,
34
+ invalid: !isRec(tool) || (tool.type !== undefined && tool.type !== "function"),
35
+ };
36
+ }
37
+ if (payload.function_call !== undefined && payload.function_call !== null) {
38
+ const fn = isRec(payload.function_call) ? payload.function_call : {};
39
+ yield { key: `${choiceIndex}:legacy`, name: typeof fn.name === "string" ? fn.name : "", snapshot };
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ export function chatResponseHasUndeclaredToolCalls(value: Rec, declared: ReadonlySet<string>): boolean {
46
+ for (const call of chatToolCalls(value)) {
47
+ if (call.invalid || !declared.has(call.name)) return true;
48
+ }
49
+ return false;
50
+ }
51
+
19
52
  export function usageFromChat(value: unknown): OcxUsage | undefined {
20
53
  if (!isRec(value)) return undefined;
21
54
  const prompt = typeof value.prompt_tokens === "number" ? value.prompt_tokens : undefined;
@@ -134,8 +167,11 @@ interface NativeChatSseOptions {
134
167
  * `stallTimeoutSec` then resolves to disabled so a slow local model is not cut mid-turn.
135
168
  */
136
169
  localUpstream?: boolean;
170
+ clientDeclaredEmptyToolCatalog?: boolean;
171
+ declaredLegacyFunctionNames?: ReadonlySet<string>;
137
172
  onFirstOutput?: () => void;
138
173
  onUsage: (usage: OcxUsage) => void;
174
+ onChunk?: (value: Rec) => void;
139
175
  onTerminal?: (status: number, message?: string) => void;
140
176
  onCancel?: () => void;
141
177
  }
@@ -154,6 +190,29 @@ export function nativeChatSse(
154
190
  }
155
191
  });
156
192
  let queuedBytes = 0;
193
+ const declared = options.declaredLegacyFunctionNames ?? new Set<string>();
194
+ const toolNames = new Map<string, string>();
195
+ const pendingToolNames = new Set<string>();
196
+ const heldFrames: string[] = [];
197
+ let heldBytes = 0;
198
+ let toolNameBytes = 0;
199
+ const hasPendingToolName = () => pendingToolNames.size > 0;
200
+ const inspectToolCalls = (value: Rec): boolean => {
201
+ for (const call of chatToolCalls(value)) {
202
+ if (call.invalid) return false;
203
+ const previous = toolNames.get(call.key);
204
+ const name = call.snapshot ? call.name : (previous ?? "") + call.name;
205
+ if (!declared.has(name) && ![...declared].some(allowed => allowed.startsWith(name))) return false;
206
+ const bytes = previous === undefined ? 128 + Buffer.byteLength(call.key) * 2 + Buffer.byteLength(name) * 2
207
+ : Math.max(0, Buffer.byteLength(name) - Buffer.byteLength(previous)) * 2;
208
+ options.translatorBudget.chargeRetained(bytes, scope);
209
+ toolNameBytes += bytes;
210
+ toolNames.set(call.key, name);
211
+ if (declared.has(name)) pendingToolNames.delete(call.key);
212
+ else pendingToolNames.add(call.key);
213
+ }
214
+ return true;
215
+ };
157
216
  let sawFinish = false;
158
217
  let sawDone = false;
159
218
  let firstOutput = false;
@@ -191,7 +250,31 @@ export function nativeChatSse(
191
250
  throw error;
192
251
  }
193
252
  };
194
- const releaseBuffer = () => buffer.clear();
253
+ const releaseHeld = () => {
254
+ options.translatorBudget.releaseRetained(heldBytes, scope);
255
+ heldBytes = 0;
256
+ heldFrames.length = 0;
257
+ };
258
+ const relay = (controller: ReadableStreamDefaultController<Uint8Array>, text: string) => {
259
+ if (hasPendingToolName()) {
260
+ const bytes = Buffer.byteLength(text) * 2;
261
+ options.translatorBudget.chargeRetained(bytes, scope);
262
+ heldBytes += bytes;
263
+ heldFrames.push(text);
264
+ return;
265
+ }
266
+ for (const frame of heldFrames) enqueue(controller, frame);
267
+ releaseHeld();
268
+ enqueue(controller, text);
269
+ };
270
+ const releaseBuffer = () => {
271
+ buffer.clear();
272
+ releaseHeld();
273
+ options.translatorBudget.releaseRetained(toolNameBytes, scope);
274
+ toolNameBytes = 0;
275
+ toolNames.clear();
276
+ pendingToolNames.clear();
277
+ };
195
278
  const settle = (status: number, message?: string) => {
196
279
  if (settled) return;
197
280
  settled = true;
@@ -206,12 +289,12 @@ export function nativeChatSse(
206
289
  type = "upstream_error",
207
290
  ) => {
208
291
  const safeMessage = redactSecretString(message);
292
+ releaseBuffer();
209
293
  try {
210
294
  const frame = `data: ${JSON.stringify(chatCompletionsErrorBody(status, safeMessage, type, code))}\n\n`;
211
295
  if (code === "translation_buffer_limit") controller.enqueue(encoder.encode(frame));
212
296
  else enqueue(controller, frame);
213
297
  } catch { /* controller may already be closed */ }
214
- releaseBuffer();
215
298
  settle(status, safeMessage);
216
299
  try { void reader.cancel(new Error(safeMessage)).catch(() => {}); } catch { /* already closed */ }
217
300
  try { controller.close(); } catch { /* already closed */ }
@@ -224,16 +307,20 @@ export function nativeChatSse(
224
307
  const payload = sseDataPayload(block);
225
308
  if (payload === null) {
226
309
  if (performance.now() >= pullDeadline) throw stalled;
227
- enqueue(controller, block + delimiter);
310
+ relay(controller, block + delimiter);
228
311
  return;
229
312
  }
230
313
  const trimmed = payload.trim();
231
314
  if (trimmed === "") {
232
315
  if (performance.now() >= pullDeadline) throw stalled;
233
- enqueue(controller, block + delimiter);
316
+ relay(controller, block + delimiter);
234
317
  return;
235
318
  }
236
319
  if (trimmed === "[DONE]") {
320
+ if (hasPendingToolName()) {
321
+ fail(controller, UNDECLARED_CHAT_TOOL_MESSAGE, UNDECLARED_TOOL_CALL_ERROR_CODE);
322
+ return;
323
+ }
237
324
  sawDone = true;
238
325
  enqueue(controller, replaceSseDataPayload(block, "[DONE]") + delimiter);
239
326
  releaseBuffer();
@@ -272,9 +359,20 @@ export function nativeChatSse(
272
359
  return;
273
360
  }
274
361
  const usage = usageFromChat(parsed.usage);
362
+ options.onChunk?.(parsed);
275
363
  if (usage) options.onUsage(usage);
364
+ if (options.clientDeclaredEmptyToolCatalog && !inspectToolCalls(parsed)) {
365
+ fail(controller, UNDECLARED_CHAT_TOOL_MESSAGE, UNDECLARED_TOOL_CALL_ERROR_CODE);
366
+ return;
367
+ }
276
368
  const choices = Array.isArray(parsed.choices) ? parsed.choices : [];
277
369
  const finished = choices.some(choice => isRec(choice) && typeof choice.finish_reason === "string" && choice.finish_reason.length > 0);
370
+ if (hasPendingToolName() && choices.some((choice, position) => isRec(choice)
371
+ && typeof choice.finish_reason === "string" && choice.finish_reason.length > 0
372
+ && [...pendingToolNames].some(key => key.startsWith(`${typeof choice.index === "number" ? choice.index : position}:`)))) {
373
+ fail(controller, UNDECLARED_CHAT_TOOL_MESSAGE, UNDECLARED_TOOL_CALL_ERROR_CODE);
374
+ return;
375
+ }
278
376
  if (finished) sawFinish = true;
279
377
  const hasText = choices.some(choice => {
280
378
  if (!isRec(choice) || !isRec(choice.delta)) return false;
@@ -302,11 +400,11 @@ export function nativeChatSse(
302
400
  const hasProgress = hasText || hasTool;
303
401
  if (hasProgress || finished) pullDeadline = performance.now() + stallMs;
304
402
  else if (performance.now() >= pullDeadline) throw stalled;
305
- if (!firstOutput && hasProgress) {
403
+ if (!firstOutput && hasProgress && !hasPendingToolName()) {
306
404
  firstOutput = true;
307
405
  options.onFirstOutput?.();
308
406
  }
309
- enqueue(controller, replaceSseDataPayload(block, JSON.stringify(normalizedChunk(parsed, options.requestedModel))) + delimiter);
407
+ relay(controller, replaceSseDataPayload(block, JSON.stringify(normalizedChunk(parsed, options.requestedModel))) + delimiter);
310
408
  };
311
409
 
312
410
  function onAbort() {
@@ -336,6 +434,7 @@ export function nativeChatSse(
336
434
  if (next) {
337
435
  buffer.compact();
338
436
  processBlock(controller, next.block, next.delimiter);
437
+ if (heldFrames.length > 0 && !settled) continue;
339
438
  return;
340
439
  }
341
440
  if (performance.now() >= pullDeadline) throw stalled;
@@ -370,6 +469,10 @@ export function nativeChatSse(
370
469
  continue;
371
470
  }
372
471
  buffer.append(decoder.decode());
472
+ if (hasPendingToolName()) {
473
+ fail(controller, UNDECLARED_CHAT_TOOL_MESSAGE, UNDECLARED_TOOL_CALL_ERROR_CODE);
474
+ return;
475
+ }
373
476
  if (buffer.tail().trim().length > 0) {
374
477
  fail(controller, "upstream SSE ended with an unterminated event", "upstream_sse_unterminated");
375
478
  return;