@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
@@ -27,10 +27,10 @@ import {
27
27
  anthropicRoutingFor,
28
28
  AnthropicAccountCooldownError,
29
29
  formatAnthropicProviderForLog,
30
- anthropicSessionKeyFromParts,
31
30
  } from "../../oauth/anthropic-routing";
32
31
  import {
33
32
  OAuthAccountPausedError,
33
+ OAuthTokenRefreshBusyError,
34
34
  getValidAccessSnapshotForAccount,
35
35
  forceRefreshOAuthAccessSnapshot,
36
36
  getValidAccessTokenSnapshot,
@@ -49,6 +49,9 @@ import {
49
49
  refusalAwareInitialKiroAccount,
50
50
  noteGenericPoolSelection,
51
51
  } from "../../oauth/generic-account-failover";
52
+ import { admitGenericSessionAccount, bindGenericSessionAccount, genericSessionAccount, genericSessionAccountEligible, genericSessionAffinityEnabled, preferredGenericSessionAccount } from "../../oauth/generic-session-affinity";
53
+ import { oauthSessionKeyFromParts } from "../../oauth/session-affinity-key";
54
+ import { resolveContextPrincipal } from "../auth-cors";
52
55
  import { tryKiroAlternateAfterTerminalRefresh } from "../../oauth/kiro-terminal-failover";
53
56
  import { classifyModelFamilyForQuota } from "../../oauth/account-quota-rank";
54
57
  import { expandInferenceOAuthSendBudget } from "../inference/context";
@@ -78,6 +81,7 @@ import { bindRouteReasoningReplayScope } from "./core-replay";
78
81
  import { sessionIdHeaderFromRequest, normalizeLogConversationId } from "../request-log-conversation";
79
82
  import { redactSecretString } from "../../lib/redact";
80
83
  import { selectProactiveApiKeyTransport } from "../../providers/key-failover";
84
+ import { distributedKeyPhysicalFetch } from "../../providers/api-key-response-ownership";
81
85
  import { isCanonicalOpenAiForwardProvider } from "../../providers/openai-tiers";
82
86
  import { providerConsumesCallerAuthorization } from "../../providers/caller-authorization";
83
87
  import { releaseCodexAuthContextProbeLease, stripCodexRuntimeProviderFields } from "../../codex/auth-context";
@@ -120,6 +124,7 @@ export async function prepareResponsesTransport(
120
124
  ) {
121
125
  const { config, logCtx, options, req } = requestContext;
122
126
  const { route, parsed, inboundWire, translatorBudget } = requestState;
127
+ const genericAffinityMode = genericSessionAffinityEnabled(config, route.providerName);
123
128
  const anthropicInstance = route.provider.authMode === "oauth"
124
129
  ? configuredAnthropicInstance(config, route.providerName) : undefined;
125
130
  // Refuse custom/orphan B OAuth before any generic resolver can observe its auth row.
@@ -176,6 +181,7 @@ export async function prepareResponsesTransport(
176
181
  || route.providerName === "orcarouter-oauth"
177
182
  // runTurn transport: the replay runs on the first-event preflight in run-turn-execution.
178
183
  || route.providerName === "devin"
184
+ || route.providerName === "dsh-account"
179
185
  ) && route.provider.authMode === "oauth";
180
186
  let sentOAuthSnapshot: OAuthAccessSnapshot | undefined;
181
187
  // One inference-401 replay belongs to this request, even when Auto changes exchange wire.
@@ -217,6 +223,8 @@ export async function prepareResponsesTransport(
217
223
  for (let attempt = 0; attempt < maxSelectionAttempts; attempt++) {
218
224
  requireAnthropicAdmission();
219
225
  if (candidate.provider !== route.providerName) return null;
226
+ if (genericAffinityMode && route.provider.googleMode === "cloud-code-assist" && !candidate.projectId)
227
+ throw new OAuthLoginRequiredError(route.providerName);
220
228
  if (anthropicInstance) anthropicRouteDecision = currentAnthropicRouteDecision();
221
229
  if (!oauthSelection) return null;
222
230
  const proactiveEnabled = anthropicInstance !== undefined
@@ -234,7 +242,9 @@ export async function prepareResponsesTransport(
234
242
  if (candidate.provider !== route.providerName) return null;
235
243
  if (anthropicInstance) anthropicRouteDecision = currentAnthropicRouteDecision();
236
244
  if (anthropicRouteDecision && !routeCandidates(anthropicRouting!.getEligibleAnthropicAccounts(Date.now(), route.modelId), anthropicRouteDecision).includes(candidate.accountId)) return null;
237
- const committed = await commitOAuthAccountSelection(route.providerName, candidate.accountId, {
245
+ const committed = genericAffinityMode
246
+ ? admitGenericSessionAccount(config, route.providerName, oauthSelection, candidate, route.modelId, genericAffinityMode)
247
+ : await commitOAuthAccountSelection(route.providerName, candidate.accountId, {
238
248
  expectedSelection: oauthSelection,
239
249
  expectedCredentialGeneration: candidate.generation,
240
250
  requireUsableAccount: true,
@@ -248,14 +258,18 @@ export async function prepareResponsesTransport(
248
258
  )) return null;
249
259
  oauthSelection = committed;
250
260
  servingOAuthSnapshot = candidate;
261
+ bindGenericSessionAccount(config, route.providerName, genericSessionKey, candidate.accountId, route.modelId);
251
262
  if (anthropicInstance) replayOAuthCredentialSnapshot = { accountId: candidate.accountId, generation: candidate.generation };
252
263
  forgetGenericFailoverRoster(route.providerName);
253
264
  return candidate;
254
265
  }
255
266
  // A newer manual choice wins over this request's old proposal, including A→B→A.
256
267
  // Resolve that choice, not the rejected candidate, before trying admission again.
268
+ const previousSelection = oauthSelection;
257
269
  oauthSelection = captureOAuthAccountSelection(route.providerName);
258
270
  if (!oauthSelection) return null;
271
+ const selectionChanged = oauthSelection.accountId !== previousSelection.accountId
272
+ || oauthSelection.revision !== previousSelection.revision;
259
273
  // A revision also changes on per-account policy edits. Re-evaluate the selector
260
274
  // after credential waits even without a model route, rather than reusing stale active.
261
275
  const revisedAnthropic = anthropicInstance !== undefined
@@ -263,9 +277,15 @@ export async function prepareResponsesTransport(
263
277
  const revisedAnthropicId = revisedAnthropic?.accountId;
264
278
  if (anthropicInstance !== undefined && !revisedAnthropicId) return null;
265
279
  if (revisedAnthropic) anthropicReason = revisedAnthropic.reason;
280
+ const genericAccountId = genericAffinityMode && !selectionChanged
281
+ ? (genericSessionAccountEligible(config, route.providerName, candidate.accountId, route.modelId, Date.now(), true)
282
+ ? candidate.accountId : (preferredGenericSessionAccount(config, route.providerName, genericSessionKey, route.modelId)
283
+ ?? oauthSelection.accountId))
284
+ : oauthSelection.accountId;
285
+ if (!genericAccountId && !anthropicInstance) return null;
266
286
  candidate = anthropicInstance !== undefined
267
287
  ? await anthropicRouting!.getAnthropicPoolAccessSnapshot(revisedAnthropicId ?? oauthSelection.accountId)
268
- : await getValidAccessSnapshotForAccount(route.providerName, oauthSelection.accountId, { requireUsableAccount: true });
288
+ : await getValidAccessSnapshotForAccount(route.providerName, genericAccountId!, { requireUsableAccount: true });
269
289
  if (route.provider.googleMode === "cloud-code-assist" && !candidate.projectId) return null;
270
290
  }
271
291
  return null;
@@ -275,7 +295,10 @@ export async function prepareResponsesTransport(
275
295
  // Keyed on the account, not the selection revision: a selection that moved away and back
276
296
  // (A -> B -> A) before the 401 landed still serves the rejected credential, and skipping
277
297
  // the refresh would replay it and spend the one recovery attempt.
278
- const candidate = current?.accountId === sent.accountId ? await forceRefreshOAuthAccessSnapshot(sent) : sent;
298
+ const candidate = (current?.accountId === sent.accountId
299
+ || (genericAffinityMode && current?.revision === oauthSelection?.revision
300
+ && current?.accountId === oauthSelection?.accountId && servingOAuthSnapshot?.accountId === sent.accountId))
301
+ ? await forceRefreshOAuthAccessSnapshot(sent) : sent;
279
302
  const admitted = await commitResolvedOAuthSelection(candidate);
280
303
  if (!admitted) throw new Error("OAuth selection changed during credential recovery");
281
304
  if (kiroLoadEnabled && options.accountLoad?.lease?.accountId !== admitted.accountId) {
@@ -519,6 +542,8 @@ export async function prepareResponsesTransport(
519
542
  return selected?.accountId === binding.selection.accountId && selected?.revision === binding.selection.revision
520
543
  && !!row && !row.paused && !row.needsReauth && row.credential.expires > Date.now()
521
544
  && (anthropicInstance === undefined || !anthropicRouting!.getAnthropicAccountHealthSnapshot(binding.snapshot.accountId) && !anthropicRatePolicy!.anthropicRatePauseUntil(binding.snapshot.accountId) && !anthropicQuota!.anthropicFamilyRejected(binding.snapshot.accountId, route.modelId))
545
+ && (!genericAffinityMode
546
+ || genericSessionAccountEligible(config, route.providerName, binding.snapshot.accountId, route.modelId, Date.now(), true))
522
547
  && credentialGeneration(row.credential) === binding.snapshot.generation;
523
548
  };
524
549
  /** Bind the negotiated wire adapter and its built requests to the serving credential's authority. */
@@ -592,12 +617,23 @@ export async function prepareResponsesTransport(
592
617
  const accountId = await anthropicRouting!.resolveAnthropicDispatchAccountId(config, anthropicSessionKey, anthropicRouteDecision, route.modelId);
593
618
  candidate = await anthropicRouting!.getAnthropicPoolAccessSnapshot(accountId);
594
619
  }
620
+ if (genericAffinityMode
621
+ && (!candidate || !genericSessionAccountEligible(config, route.providerName, candidate.accountId, route.modelId, Date.now(), true))) {
622
+ const accountId = preferredGenericSessionAccount(config, route.providerName, genericSessionKey, route.modelId)
623
+ ?? captureOAuthAccountSelection(route.providerName)?.accountId;
624
+ candidate = accountId ? await getValidAccessSnapshotForAccount(route.providerName, accountId, { requireUsableAccount: true }) : undefined;
625
+ }
595
626
  if (!candidate || !await applyFailoverSnapshot(candidate, requestParsed, true)) {
596
627
  if (anthropicInstance !== undefined) await anthropicRouting!.resolveAnthropicDispatchAccountId(config, anthropicSessionKey, anthropicRouteDecision, route.modelId);
597
628
  throw new Error("OAuth account selection changed before dispatch");
598
629
  }
599
630
  } else {
600
- const current = resolveCurrentProviderApiKeyTransport(config, route.providerName, route.provider);
631
+ let current = resolveCurrentProviderApiKeyTransport(config, route.providerName, route.provider);
632
+ if (!current && (route.provider._apiKeyAttempt?.distributed || (route.provider.requestPacing?.enabled
633
+ && (route.provider.requestPacing.keys || route.provider.requestPacing.keySelection === "round-robin")))) {
634
+ const fresh = resolveCurrentProviderApiKeyTransport(config, route.providerName, { ...route.provider, _apiKeyAttempt: undefined });
635
+ if (fresh) current = selectProactiveApiKeyTransport(config, route.providerName, fresh) ?? fresh;
636
+ }
601
637
  if (!current) throw new Error("API key selection is unavailable before dispatch");
602
638
  route.provider = current;
603
639
  await resolveCopilotSelection(requestParsed, true);
@@ -625,7 +661,10 @@ export async function prepareResponsesTransport(
625
661
  ? (options.sendBudget as import("../../lib/request-execution-budget").RequestExecutionBudget).beginSpendProducer?.() : undefined;
626
662
  try {
627
663
  for (let attempt = 0; attempt < 3; attempt++) {
628
- if (!selectionIsCurrent(adapterBindings.get(selectedAdapter))) selectedAdapter = await refreshRunTurnAdapter(requestParsed);
664
+ incoming.abortSignal?.throwIfAborted();
665
+ const selectionRefreshed = !selectionIsCurrent(adapterBindings.get(selectedAdapter));
666
+ if (attempt === 0 && selectionRefreshed) releaseProviderRequestSlot(incoming.pacingSlot);
667
+ if (selectionRefreshed) selectedAdapter = await refreshRunTurnAdapter(requestParsed);
629
668
  const binding = adapterBindings.get(selectedAdapter);
630
669
  const run = rawRunTurns.get(selectedAdapter);
631
670
  if (!run) throw new Error("Selected provider no longer supports this turn transport");
@@ -635,24 +674,39 @@ export async function prepareResponsesTransport(
635
674
  // Both main and image-loop callers already acquired the initial pacing slot.
636
675
  // Subsequent physical messages retain this adapter/credential and are paced normally.
637
676
  try {
638
- attemptSlot = attempt === 0
639
- ? incoming.pacingSlot ?? await waitForProviderRequestSlot(route.providerName, route.provider, route.modelId, incoming.abortSignal)
677
+ // A pre-acquired lease belongs to the original selection, never its replacement.
678
+ attemptSlot = attempt === 0 && !selectionRefreshed && incoming.pacingSlot
679
+ ? incoming.pacingSlot
640
680
  : await waitForProviderRequestSlot(route.providerName, route.provider, route.modelId, incoming.abortSignal);
681
+ incoming.abortSignal?.throwIfAborted();
682
+ // Every admission can queue, including a replacement's. Never enter an
683
+ // adapter on a lease whose credential changed while it waited.
684
+ if (!selectionIsCurrent(binding)) {
685
+ refused = true;
686
+ throw new Error("Account selection changed before turn admission");
687
+ }
688
+ const beforePhysicalSend = (): void => {
689
+ incoming.abortSignal?.throwIfAborted();
690
+ if (sent) {
691
+ if (binding?.kind === "api-key" && binding.provider._apiKeyAttempt?.distributed
692
+ && !selectionIsCurrent(binding)) throw new Error("API key became unavailable during the turn");
693
+ return;
694
+ }
695
+ if (!selectionIsCurrent(binding)) {
696
+ refused = true;
697
+ throw new Error("Account selection changed before the first turn dispatch");
698
+ }
699
+ incoming.beforePhysicalSend?.();
700
+ commitKeyAttemptSend();
701
+ sent = true;
702
+ };
641
703
  const fetch = providerFetch(route.provider, options.codexWsRuntimeIdentity, {
642
704
  providerName: route.providerName, modelId: route.modelId, pacingSlotAcquired: true,
643
705
  pacingSlot: attemptSlot,
644
706
  turnScopedPacing: true,
645
- beforeDispatch: () => {
646
- if (sent) return;
647
- if (!selectionIsCurrent(binding)) {
648
- refused = true;
649
- throw new Error("Account selection changed before the first turn dispatch");
650
- }
651
- commitKeyAttemptSend();
652
- sent = true;
653
- },
707
+ beforeDispatch: beforePhysicalSend,
654
708
  });
655
- await run(requestParsed, { ...incoming, providerFetch: fetch }, event => { if (!refused) emit(event); });
709
+ await run(requestParsed, { ...incoming, pacingSlot: attemptSlot, providerFetch: fetch, beforePhysicalSend }, event => { if (!refused) emit(event); });
656
710
  } catch (error) {
657
711
  if (!refused) throw error;
658
712
  } finally {
@@ -661,7 +715,7 @@ export async function prepareResponsesTransport(
661
715
  if (!refused) return;
662
716
  // The adapter may map the guard's exception to an error event. Neither that
663
717
  // event nor a refused send may escape before retrying the newly selected account.
664
- selectedAdapter = await refreshRunTurnAdapter(requestParsed);
718
+ if (attempt < 2) selectedAdapter = await refreshRunTurnAdapter(requestParsed);
665
719
  }
666
720
  throw new Error("Account selection changed repeatedly before turn dispatch");
667
721
  } finally { producer?.close(); }
@@ -669,10 +723,16 @@ export async function prepareResponsesTransport(
669
723
  /** Fence the physical send, with bounded credential/session rebuilds and safe negotiated refusals. */
670
724
  const oauthDispatch = (wireRequest: AdapterRequest, requestParsed = parsed, owner: "adapter" | "passthrough" = "adapter"): ProviderFetchOptions["dispatchOverride"] => {
671
725
  if (route.provider.authMode === "forward") return undefined;
672
- return /** Dispatch with the current binding and session, rebuilding at most three times before returning a safe refusal. */ async (input, init, execute) => {
726
+ return /** Dispatch with the current binding and session, rebuilding at most three times before returning a safe refusal. */ async (input, init, execute, reacquirePacing) => {
673
727
  let destination = input;
674
728
  let dispatchInit = init;
729
+ let pacingChanged = false;
675
730
  for (let attempt = 0; attempt < 3; attempt++) {
731
+ if (pacingChanged) {
732
+ if (!reacquirePacing) throw new Error("Refreshed dispatch requires pacing readmission");
733
+ await reacquirePacing(route.provider, route.modelId);
734
+ pacingChanged = false;
735
+ }
676
736
  if (selectionIsCurrent(requestBindings.get(wireRequest)) && copilotSessionExpiresAt > Date.now() + 1000) {
677
737
  const fetchImpl = (route.provider as OcxProviderConfig & { fetch?: typeof globalThis.fetch }).fetch ?? execute;
678
738
  const binding = requestBindings.get(wireRequest);
@@ -713,7 +773,7 @@ export async function prepareResponsesTransport(
713
773
  }
714
774
  commitKeyAttemptSend();
715
775
  response = await sendWithConnectionPolicy(
716
- anthropicBillingPhysicalFetch(fetchImpl, route.providerName, route.provider),
776
+ distributedKeyPhysicalFetch(anthropicBillingPhysicalFetch(fetchImpl, route.providerName, route.provider), route.providerName, route.provider, target),
717
777
  destination,
718
778
  { ...dispatchInit, redirect: "manual" },
719
779
  { providerName: route.providerName, provider: route.provider },
@@ -775,13 +835,15 @@ export async function prepareResponsesTransport(
775
835
  sameTargetToken = transportToken;
776
836
  destination = rebuilt.url;
777
837
  dispatchInit = { ...dispatchInit, method: rebuilt.method, headers, body: rebuilt.body };
778
- // The next iteration validates synchronously and calls fetch in that same turn.
838
+ pacingChanged = route.provider.requestPacing?.enabled === true
839
+ && (!!route.provider.requestPacing.keys || route.provider.requestPacing.keySelection === "round-robin");
840
+ // A refreshed key must reacquire admission before the next synchronous send guard.
779
841
  }
780
842
  throw new Error("OAuth account selection changed repeatedly before dispatch");
781
843
  };
782
844
  };
783
- const anthropicSessionKey = anthropicInstance !== undefined && route.provider.authMode === "oauth"
784
- ? anthropicSessionKeyFromParts({
845
+ const oauthSessionKey = route.provider.authMode === "oauth"
846
+ ? oauthSessionKeyFromParts({
785
847
  sessionIdHeader: sessionIdHeaderFromRequest(req.headers),
786
848
  threadIdHeader: req.headers.get("thread-id"),
787
849
  promptCacheKey: typeof parsed.options.promptCacheKey === "string" ? parsed.options.promptCacheKey : null,
@@ -789,6 +851,9 @@ export async function prepareResponsesTransport(
789
851
  promptCacheKeyIsSharedCohort: options.promptCacheKeyIsSharedCohort === true,
790
852
  })
791
853
  : null;
854
+ const anthropicSessionKey = anthropicInstance ? oauthSessionKey : null;
855
+ const genericSessionKey = genericAffinityMode && oauthSessionKey
856
+ ? JSON.stringify([resolveContextPrincipal(req, config, options.admission) ?? "loopback", oauthSessionKey]) : null;
792
857
  if (route.provider.authMode === "oauth") {
793
858
  try {
794
859
  if (anthropicInstance !== undefined && anthropicRouting!.isAnthropicAccountPoolEnabled(config)) {
@@ -821,10 +886,17 @@ export async function prepareResponsesTransport(
821
886
  // without quota evidence keeps the resolution it has today.
822
887
  const refusalAwareId = route.providerName === "kiro" && oauthSelection?.accountId
823
888
  ? refusalAwareInitialKiroAccount(config, oauthSelection.accountId, Date.now(), route.modelId) : null;
824
- const preferredAccountId = refusalAwareId ?? (isGenericFailoverProvider(route.providerName, route.provider)
889
+ const affinityAccountId = genericSessionAccount(config, route.providerName, genericSessionKey, route.modelId);
890
+ const proposedAccountId = affinityAccountId
891
+ ?? preferredGenericSessionAccount(config, route.providerName, genericSessionKey, route.modelId)
892
+ ?? refusalAwareId ?? (isGenericFailoverProvider(route.providerName, route.provider)
825
893
  ? preferredInitialAccount(config, route.providerName, Date.now(), route.modelId)
826
894
  : null);
827
- let safetyAlternateId: string | null = refusalAwareId;
895
+ // An unchanged active choice must retain the ordinary resolver's terminal-refresh
896
+ // recovery (not the speculative-preference fallback that resolves the same dead grant).
897
+ const preferredAccountId = genericAffinityMode && proposedAccountId === oauthSelection?.accountId
898
+ ? null : proposedAccountId;
899
+ let safetyAlternateId: string | null = !affinityAccountId && preferredAccountId === refusalAwareId ? refusalAwareId : null;
828
900
  // Resolved account-scoped, NOT through failoverAccountSnapshot: that helper marks a
829
901
  // rotation site, and rotation sites must apply their credential through
830
902
  // applyFailoverSnapshot's pairing rules. This is initial resolution — the code below
@@ -926,7 +998,8 @@ export async function prepareResponsesTransport(
926
998
  // Advance the pool cursor only now that this account is actually admitted. The
927
999
  // helper returns immediately unless the kernel is on AND the strategy is
928
1000
  // round-robin, so quota and fill-first pools reach it without being touched.
929
- noteGenericPoolSelection(config, route.providerName, resolved.accountId, route.modelId);
1001
+ if (!affinityAccountId || affinityAccountId !== resolved.accountId)
1002
+ noteGenericPoolSelection(config, route.providerName, resolved.accountId, route.modelId);
930
1003
  }
931
1004
  // Anthropic is excluded from isGenericFailoverProvider -- its own pool owns affinity and
932
1005
  // a fail-closed local-cli credential rule -- so without this stamp its identity is
@@ -964,6 +1037,10 @@ export async function prepareResponsesTransport(
964
1037
  `${redactSecretString(err.message)}. Remove or reconfigure provider '${safeProviderName}' in the OpenCodex configuration.`,
965
1038
  );
966
1039
  }
1040
+ if (err instanceof OAuthTokenRefreshBusyError) {
1041
+ return options.abortSignal?.aborted || req.signal.aborted ? clientCancelledResponse()
1042
+ : formatErrorResponse(503, "server_error", err.message, { retryAfter: "1" });
1043
+ }
967
1044
  if (err instanceof OAuthAccountPausedError) {
968
1045
  return formatErrorResponse(403, "permission_error", publicOAuthAuthenticationErrorMessage(err));
969
1046
  }
@@ -89,6 +89,8 @@ export function createResponsesEffects(
89
89
  if (routedCompaction) {
90
90
  delete parsed.context.tools;
91
91
  delete parsed._webSearch;
92
+ delete parsed._anthropicServerTools;
93
+ delete parsed._anthropicServerReplay;
92
94
  delete parsed.options.toolChoice;
93
95
  delete parsed.options.parallelToolCalls;
94
96
  // The compaction turn is a plain prose summary; a surviving structured-output format
@@ -0,0 +1,21 @@
1
+ import type { ProviderExecutedCallType } from "../responses-undeclared-tool-guard";
2
+
3
+ // Route-authorized execution ownership follows only the response selected for delivery.
4
+ // It never becomes a wire header or mutable state shared by competing route attempts.
5
+ const providerCalls = new WeakMap<Response, ReadonlySet<ProviderExecutedCallType>>();
6
+
7
+ export function attachResponseToolOwnership(response: Response, types: ReadonlySet<ProviderExecutedCallType>): Response {
8
+ if (types.size > 0) providerCalls.set(response, new Set(types));
9
+ return response;
10
+ }
11
+
12
+ export function responseToolOwnership(response: Response): ReadonlySet<ProviderExecutedCallType> | undefined {
13
+ return providerCalls.get(response);
14
+ }
15
+
16
+ /** Carry ownership only when rebuilding the same selected response body. */
17
+ export function carryResponseToolOwnership(source: Response, target: Response): Response {
18
+ const types = providerCalls.get(source);
19
+ if (types) providerCalls.set(target, types);
20
+ return target;
21
+ }