@bitkyc08/opencodex 2.55.0 → 2.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/bin/ocx.mjs +10 -0
  2. package/gui/dist/assets/{index-BBOZWGB6.css → index-C5-RdDmD.css} +1 -1
  3. package/gui/dist/assets/{index-VuoiWj9J.js → index-Cz7CLdif.js} +21 -21
  4. package/gui/dist/index.html +2 -2
  5. package/package.json +4 -3
  6. package/src/adapters/base.ts +21 -0
  7. package/src/adapters/codebuddy/adapter.ts +2 -1
  8. package/src/adapters/codebuddy/scaffold-guard.ts +248 -0
  9. package/src/adapters/command-code.ts +1 -1
  10. package/src/adapters/cursor/envelope-echo.ts +8 -2
  11. package/src/adapters/cursor/transport-retry.ts +46 -1
  12. package/src/adapters/cursor.ts +4 -0
  13. package/src/adapters/google.ts +7 -7
  14. package/src/adapters/kiro/adapter.ts +42 -1
  15. package/src/adapters/kiro/payload.ts +17 -3
  16. package/src/adapters/kiro/reasoning.ts +70 -7
  17. package/src/adapters/kiro/stream.ts +8 -2
  18. package/src/adapters/kiro/wire.ts +2 -1
  19. package/src/adapters/kiro-events.ts +21 -13
  20. package/src/adapters/kiro-retry.ts +23 -4
  21. package/src/adapters/openai-chat/errors.ts +116 -0
  22. package/src/adapters/openai-chat/messages.ts +346 -0
  23. package/src/adapters/openai-chat/passthrough.ts +146 -0
  24. package/src/adapters/openai-chat/response-events.ts +117 -0
  25. package/src/adapters/openai-chat/tool-call-validation.ts +200 -0
  26. package/src/adapters/openai-chat/tool-name-registry.ts +166 -0
  27. package/src/adapters/openai-chat/tool-schema.ts +495 -0
  28. package/src/adapters/openai-chat/wire.ts +50 -0
  29. package/src/adapters/openai-chat.ts +40 -1452
  30. package/src/adapters/openai-responses/canonical-forward.ts +202 -0
  31. package/src/adapters/openai-responses/image-gen.ts +406 -0
  32. package/src/adapters/openai-responses/internal.ts +3 -0
  33. package/src/adapters/openai-responses/passthrough.ts +642 -0
  34. package/src/adapters/openai-responses/prompt-cache.ts +83 -0
  35. package/src/adapters/openai-responses/reasoning.ts +220 -0
  36. package/src/adapters/openai-responses/request-strips.ts +185 -0
  37. package/src/adapters/openai-responses/tool-output-recovery.ts +509 -0
  38. package/src/adapters/openai-responses/tool-schema.ts +293 -0
  39. package/src/adapters/openai-responses/web-search.ts +156 -0
  40. package/src/adapters/openai-responses.ts +4 -2625
  41. package/src/bridge/errors.ts +58 -0
  42. package/src/bridge/internal.ts +174 -0
  43. package/src/bridge/response-json.ts +630 -0
  44. package/src/bridge/sse.ts +1462 -0
  45. package/src/bridge.ts +5 -2204
  46. package/src/chat/inbound.ts +12 -1
  47. package/src/claude/desktop-profile.ts +66 -9
  48. package/src/claude/outbound.ts +18 -0
  49. package/src/cli/account-main.ts +1 -1
  50. package/src/cli/capabilities.ts +2 -2
  51. package/src/cli/combo.ts +10 -1
  52. package/src/cli/index.ts +48 -5
  53. package/src/cli/registry.ts +2 -1
  54. package/src/cli/system-command.ts +4 -4
  55. package/src/clients/config-export.ts +7 -3
  56. package/src/codex/account-label.ts +14 -3
  57. package/src/codex/account-lifecycle.ts +3 -0
  58. package/src/codex/account-store.ts +184 -35
  59. package/src/codex/account-usability.ts +21 -0
  60. package/src/codex/auth-api/account-list.ts +507 -0
  61. package/src/codex/auth-api/http.ts +32 -0
  62. package/src/codex/auth-api/login-flow.ts +566 -0
  63. package/src/codex/auth-api/login-state.ts +64 -0
  64. package/src/codex/auth-api/main-account-probe.ts +331 -0
  65. package/src/codex/auth-api/pool-mode-gate.ts +274 -0
  66. package/src/codex/auth-api/pool-quota-probe.ts +512 -0
  67. package/src/codex/auth-api/reset-credit-service.ts +431 -0
  68. package/src/codex/auth-api/routes.ts +425 -0
  69. package/src/codex/auth-api/runtime-config.ts +48 -0
  70. package/src/codex/auth-api.ts +27 -3118
  71. package/src/codex/auth-context.ts +252 -35
  72. package/src/codex/catalog/aggregation.ts +80 -1
  73. package/src/codex/catalog/auto-review.ts +507 -0
  74. package/src/codex/catalog/build-entries.ts +981 -0
  75. package/src/codex/catalog/combo-member.ts +375 -0
  76. package/src/codex/catalog/derive-entry.ts +229 -0
  77. package/src/codex/catalog/effort.ts +0 -1
  78. package/src/codex/catalog/gated-native-warn.ts +63 -0
  79. package/src/codex/catalog/gather-capture.ts +533 -0
  80. package/src/codex/catalog/model-hints.ts +691 -0
  81. package/src/codex/catalog/model-visibility.ts +305 -0
  82. package/src/codex/catalog/provider-fetch.ts +52 -2942
  83. package/src/codex/catalog/provider-models.ts +685 -0
  84. package/src/codex/catalog/remote.ts +30 -0
  85. package/src/codex/catalog/restore.ts +132 -0
  86. package/src/codex/catalog/retained-sync.ts +714 -0
  87. package/src/codex/catalog/routed-gather.ts +895 -0
  88. package/src/codex/catalog/subagent-roster.ts +176 -0
  89. package/src/codex/catalog/sync.ts +52 -2698
  90. package/src/codex/cli-install-provenance.ts +7 -1
  91. package/src/codex/convergence.ts +7 -2
  92. package/src/codex/desktop-app/types.ts +11 -2
  93. package/src/codex/desktop-app/windows.ts +5 -5
  94. package/src/codex/inject/config-toml.ts +563 -0
  95. package/src/codex/inject/remove.ts +192 -0
  96. package/src/codex/inject/restore.ts +567 -0
  97. package/src/codex/inject/routing-classify.ts +109 -0
  98. package/src/codex/inject/routing-target.ts +125 -0
  99. package/src/codex/inject.ts +89 -1444
  100. package/src/codex/lineage.ts +458 -0
  101. package/src/codex/model-entitlements.ts +152 -15
  102. package/src/codex/pool-refresh-backoff.ts +161 -0
  103. package/src/codex/quota-rejection.ts +104 -15
  104. package/src/codex/routing/active-account.ts +194 -0
  105. package/src/codex/routing/cache-affinity.ts +70 -0
  106. package/src/codex/routing/cooldown-math.ts +285 -0
  107. package/src/codex/routing/health-store.ts +402 -0
  108. package/src/codex/routing/probe-lease.ts +358 -0
  109. package/src/codex/routing/selection.ts +780 -0
  110. package/src/codex/routing/thread-affinity.ts +586 -0
  111. package/src/codex/routing/transient-hold-dispatch.ts +141 -0
  112. package/src/codex/routing.ts +370 -2271
  113. package/src/codex/shim-fingerprint.ts +223 -0
  114. package/src/codex/shim-inspect.ts +175 -0
  115. package/src/codex/shim-probe.ts +367 -0
  116. package/src/codex/shim-restore-lock.ts +169 -0
  117. package/src/codex/shim-state-file.ts +151 -0
  118. package/src/codex/shim-templates.ts +265 -0
  119. package/src/codex/shim.ts +48 -1268
  120. package/src/codex/warmup.ts +1 -1
  121. package/src/combos/failover.ts +85 -0
  122. package/src/combos/request.ts +17 -10
  123. package/src/combos/types.ts +23 -2
  124. package/src/config/diagnostics.ts +705 -0
  125. package/src/config/feature-flags.ts +55 -0
  126. package/src/config/live-reconcile.ts +403 -0
  127. package/src/config/load-degrade.ts +880 -0
  128. package/src/config/mutation-lock.ts +244 -0
  129. package/src/config/openai-tier-backup.ts +268 -0
  130. package/src/config/pending-teardown.ts +31 -0
  131. package/src/config/persist-unlocked.ts +92 -0
  132. package/src/config/proxy-env.ts +188 -0
  133. package/src/config/salvage.ts +244 -0
  134. package/src/config/schema/config-schema.ts +640 -0
  135. package/src/config/schema/leaf-validators.ts +855 -0
  136. package/src/config/warn-memo.ts +28 -0
  137. package/src/config.ts +234 -4481
  138. package/src/generated/compatibility-version.json +649 -121
  139. package/src/images/loop.ts +1 -1
  140. package/src/lib/errors.ts +17 -0
  141. package/src/lib/request-execution-budget.ts +198 -23
  142. package/src/lib/spend-reservation-ledger.ts +958 -0
  143. package/src/lib/state-store-registrations.ts +6 -2
  144. package/src/lib/test-home-guard.ts +85 -1
  145. package/src/lib/upstream-retry.ts +132 -21
  146. package/src/lib/windows-elevation.ts +76 -14
  147. package/src/lib/workflow-budget.ts +553 -30
  148. package/src/oauth/index.ts +2 -2
  149. package/src/oauth/key-providers.ts +2 -2
  150. package/src/providers/kiro-models.ts +4 -3
  151. package/src/providers/label.ts +19 -1
  152. package/src/providers/model-discovery.ts +16 -0
  153. package/src/providers/quota/account-cache.ts +441 -0
  154. package/src/providers/quota/antigravity.ts +295 -0
  155. package/src/providers/quota/report-cache.ts +320 -0
  156. package/src/providers/quota/vendor-probes-key.ts +1243 -0
  157. package/src/providers/quota/vendor-probes-oauth.ts +590 -0
  158. package/src/providers/quota.ts +324 -3079
  159. package/src/providers/registry/entries-core.ts +1228 -0
  160. package/src/providers/registry/entries-extended.ts +1213 -0
  161. package/src/providers/registry/model-seeds.ts +912 -0
  162. package/src/providers/registry/types.ts +352 -0
  163. package/src/providers/registry.ts +24 -3536
  164. package/src/responses/continuation-ownership.ts +29 -0
  165. package/src/responses/reasoning-envelope.ts +6 -3
  166. package/src/responses/state/replay-fingerprint.ts +80 -0
  167. package/src/responses/state/snapshot-codec.ts +104 -0
  168. package/src/responses/state/spill-failure.ts +118 -0
  169. package/src/responses/state/spill-queue.ts +665 -0
  170. package/src/responses/state/temp-recovery.ts +257 -0
  171. package/src/responses/state.ts +82 -1143
  172. package/src/routing/identity-domains.ts +456 -0
  173. package/src/routing/probe-lease.ts +613 -0
  174. package/src/server/chat-completions.ts +3 -1
  175. package/src/server/chat-native.ts +37 -9
  176. package/src/server/index/bounded-request.ts +88 -0
  177. package/src/server/index/live-sideband.ts +601 -0
  178. package/src/server/index/serve-options.ts +1766 -0
  179. package/src/server/index/startup-warnings.ts +213 -0
  180. package/src/server/index/websocket-handler.ts +339 -0
  181. package/src/server/index.ts +45 -2552
  182. package/src/server/inspection-tee.ts +107 -0
  183. package/src/server/live.ts +46 -1
  184. package/src/server/management/combo-routes.ts +10 -1
  185. package/src/server/management/route-registry.ts +26 -23
  186. package/src/server/management/shared.ts +8 -5
  187. package/src/server/management/workflow-budget-routes.ts +133 -0
  188. package/src/server/management-api.ts +12 -0
  189. package/src/server/relay-eager.ts +2 -0
  190. package/src/server/relay.ts +14 -19
  191. package/src/server/request-log-conversation.ts +9 -7
  192. package/src/server/request-log.ts +372 -4
  193. package/src/server/response-log-body.ts +153 -0
  194. package/src/server/responses/account-change-state.ts +307 -0
  195. package/src/server/responses/adapter-continuation.ts +540 -0
  196. package/src/server/responses/adapter-delivery.ts +208 -0
  197. package/src/server/responses/adapter-dispatch.ts +1042 -0
  198. package/src/server/responses/codex-ws-wire.ts +5 -0
  199. package/src/server/responses/collaboration.ts +74 -4
  200. package/src/server/responses/combo-session-recall.ts +68 -8
  201. package/src/server/responses/compact.ts +113 -17
  202. package/src/server/responses/completion-policy.ts +33 -0
  203. package/src/server/responses/core-auth.ts +529 -0
  204. package/src/server/responses/core-codex-account.ts +907 -0
  205. package/src/server/responses/core-combo-failure.ts +210 -0
  206. package/src/server/responses/core-combo.ts +787 -0
  207. package/src/server/responses/core-errors.ts +170 -0
  208. package/src/server/responses/core-lifetime.ts +95 -0
  209. package/src/server/responses/core-normalize.ts +350 -0
  210. package/src/server/responses/core-opaque-recovery.ts +380 -0
  211. package/src/server/responses/core-options.ts +159 -0
  212. package/src/server/responses/core-replay.ts +298 -0
  213. package/src/server/responses/core.ts +192 -8893
  214. package/src/server/responses/encrypted-payload.ts +0 -1
  215. package/src/server/responses/input-admission.ts +126 -6
  216. package/src/server/responses/passthrough-delivery.ts +869 -0
  217. package/src/server/responses/passthrough-dispatch.ts +1494 -0
  218. package/src/server/responses/passthrough-error.ts +38 -2
  219. package/src/server/responses/passthrough-execution.ts +54 -0
  220. package/src/server/responses/request-prepare.ts +1080 -0
  221. package/src/server/responses/request-send-budget.ts +259 -0
  222. package/src/server/responses/request-sidecar-auth.ts +149 -0
  223. package/src/server/responses/request-spend.ts +147 -0
  224. package/src/server/responses/request-transport.ts +803 -0
  225. package/src/server/responses/response-effects.ts +157 -0
  226. package/src/server/responses/run-turn-execution.ts +476 -0
  227. package/src/server/responses/sidecar-execution.ts +463 -0
  228. package/src/server/responses/terminal-guard.ts +65 -4
  229. package/src/server/responses-image-gen-repair.ts +1 -1
  230. package/src/server/responses-undeclared-tool-guard.ts +9 -5
  231. package/src/server/workflow-refusal.ts +84 -0
  232. package/src/service/windows-ops.ts +210 -16
  233. package/src/service/windows-scheduler.ts +28 -21
  234. package/src/service.ts +1 -1
  235. package/src/types/config.ts +34 -1
  236. package/src/types/request.ts +8 -5
  237. package/src/types/tools.ts +24 -0
  238. package/src/types.ts +2 -0
  239. package/src/update/index.ts +10 -0
  240. package/src/update/stop-contract.d.mts +1 -0
  241. package/src/update/stop-contract.mjs +19 -0
  242. package/src/update/stop-decision.d.mts +1 -1
  243. package/src/update/stop-decision.mjs +12 -3
  244. package/src/usage/log.ts +147 -1
  245. package/src/usage/summary.ts +171 -21
  246. package/src/vision/anthropic-describe.ts +1 -1
  247. package/src/vision/describe.ts +5 -5
  248. package/src/web-search/anthropic-executor.ts +1 -1
  249. package/src/web-search/exa-executor.ts +1 -1
  250. package/src/web-search/executor.ts +1 -1
  251. package/src/web-search/gemini-executor.ts +1 -1
  252. package/src/web-search/loop.ts +1 -1
  253. package/src/web-search/ollama-executor.ts +1 -1
  254. package/src/web-search/parse.ts +67 -14
  255. package/src/web-search/passthrough-bridge.ts +64 -31
  256. package/src/web-search/xai-executor.ts +1 -1
@@ -0,0 +1,210 @@
1
+ import { parseRetryAfterMs } from "../../combos";
2
+ import type { ConsumedComboFailure, HandleResponsesOptions } from "./core-options";
3
+ import type { OcxUsage } from "../../types";
4
+ import { readBoundedResponseBody } from "../../lib/bounded-body";
5
+ import { codexQuotaFailureMessage, codexQuotaOutcomeMeta } from "./core-codex-account";
6
+ import {
7
+ isRateLimitOrQuotaFailureMessage,
8
+ isCyberPolicyCode,
9
+ isCyberPolicyMessage,
10
+ CYBER_POLICY_ERROR_CODE,
11
+ CYBER_POLICY_FALLBACK_MESSAGE,
12
+ } from "../../lib/errors";
13
+ import { normalizeUpstreamErrorText } from "./core-errors";
14
+ import { resolveClientRetryAfter } from "../../lib/retry-after";
15
+ import { formatErrorResponse } from "../../bridge";
16
+ import { usageFromResponsesPayload } from "../request-log";
17
+ import type { ResponsesTerminalStatus } from "../../bridge";
18
+
19
+ export function sanitizedRetryAfter(value: string | null, now: number): string | undefined {
20
+ const trimmed = value?.trim();
21
+ if (!trimmed || trimmed.length > 128) return undefined;
22
+ return parseRetryAfterMs(trimmed, now) !== undefined ? trimmed : undefined;
23
+ }
24
+
25
+
26
+
27
+
28
+ export async function consumeComboFailure(
29
+ response: Response,
30
+ signal?: AbortSignal,
31
+ now = Date.now(),
32
+ ): Promise<ConsumedComboFailure> {
33
+ const fallback = `Provider error ${response.status}`;
34
+ let classificationText = fallback;
35
+ let usage: OcxUsage | undefined;
36
+ let upstreamCode: string | undefined;
37
+ let upstreamMessage: string | undefined;
38
+ let upstreamType: string | undefined;
39
+ // Whether the body itself confirms a quota/rate-limit refusal, computed on the SAME read as
40
+ // the classification below. `shouldRetryCodexPoolAccountQuota` cannot be called here without
41
+ // a second body read, so this mirrors its normalization: raw 402/429, or a 5xx whose intact,
42
+ // display-safe body carries a recognized quota message.
43
+ let quotaConfirmedByBody = false;
44
+ try {
45
+ const body = await readBoundedResponseBody(response, {
46
+ signal,
47
+ // Match shouldRetryCodexPoolAccountQuota before treating a 5xx body as quota evidence.
48
+ fatalUtf8: response.status >= 500 && response.status < 600,
49
+ });
50
+ usage = usageFromComboFailureText(body.text);
51
+ if (
52
+ response.status >= 500 && response.status < 600
53
+ && body.displaySafe && !body.truncated
54
+ ) {
55
+ const quotaMessage = codexQuotaFailureMessage(body.text);
56
+ quotaConfirmedByBody = quotaMessage !== undefined
57
+ && isRateLimitOrQuotaFailureMessage(quotaMessage);
58
+ }
59
+ if (body.displaySafe) {
60
+ const normalized = normalizeUpstreamErrorText(body.text, fallback);
61
+ classificationText = normalized.safeText;
62
+ upstreamCode = normalized.code;
63
+ upstreamMessage = normalized.message;
64
+ upstreamType = normalized.type;
65
+ }
66
+ } catch (error) {
67
+ if (signal?.aborted) throw error;
68
+ classificationText = fallback;
69
+ }
70
+ const cyberFailure = isCyberPolicyCode(upstreamCode) || isCyberPolicyMessage(classificationText);
71
+ const normalizedUpstreamCode = cyberFailure ? CYBER_POLICY_ERROR_CODE : upstreamCode;
72
+ const message = cyberFailure
73
+ ? upstreamMessage
74
+ ?? (isCyberPolicyCode(upstreamCode) ? CYBER_POLICY_FALLBACK_MESSAGE : classificationText)
75
+ : classificationText === fallback
76
+ ? fallback
77
+ : `${fallback}: ${classificationText}`;
78
+ const upstreamRetryAfter = response.headers.get("retry-after");
79
+ // Past HTTP dates are an immediate retry directive, just like the numeric value zero.
80
+ // Normalize before the client helper discards them and substitutes a default delay.
81
+ const effectiveRetryAfter = parseRetryAfterMs(upstreamRetryAfter, now) === undefined
82
+ && parseRetryAfterMs(upstreamRetryAfter, now, { preserveImmediate: true }) !== undefined
83
+ ? "0"
84
+ : upstreamRetryAfter;
85
+ // Client response may get the synthetic "2" fallback; cooldown metadata must not —
86
+ // otherwise coolComboTarget treats it as a 2s cooldown instead of the 60s default.
87
+ const clientRetryAfter = resolveClientRetryAfter({
88
+ status: response.status,
89
+ message,
90
+ upstreamRetryAfter: effectiveRetryAfter,
91
+ now,
92
+ });
93
+ const cooldownRetryAfter = resolveClientRetryAfter({
94
+ status: response.status,
95
+ message,
96
+ upstreamRetryAfter: effectiveRetryAfter,
97
+ now,
98
+ includeDefault: false,
99
+ });
100
+ return {
101
+ response: formatErrorResponse(
102
+ response.status,
103
+ cyberFailure ? (upstreamType ?? CYBER_POLICY_ERROR_CODE) : "upstream_error",
104
+ message,
105
+ {
106
+ ...(normalizedUpstreamCode !== undefined ? { code: normalizedUpstreamCode } : {}),
107
+ ...(clientRetryAfter !== undefined ? { retryAfter: clientRetryAfter } : {}),
108
+ },
109
+ ),
110
+ classificationText,
111
+ ...(normalizedUpstreamCode !== undefined ? { upstreamCode: normalizedUpstreamCode } : {}),
112
+ ...(!cyberFailure && cooldownRetryAfter !== undefined ? { retryAfter: cooldownRetryAfter } : {}),
113
+ // The EFFECTIVE classification decides, not the raw status. An upstream that wraps a quota
114
+ // refusal in a 5xx still carries `x-codex-*-reset-at`, and gating on 402/429 alone threw
115
+ // those away, so the combo target came back up immediately instead of waiting for the
116
+ // window it was told about. `cyberFailure` stays excluded: a policy block is not a quota.
117
+ ...(!cyberFailure
118
+ && (response.status === 429 || response.status === 402 || quotaConfirmedByBody)
119
+ ? { resetAt: codexQuotaOutcomeMeta(response).resetAt }
120
+ : {}),
121
+ ...(usage ? { usage } : {}),
122
+ };
123
+ }
124
+
125
+
126
+
127
+
128
+ export function usageFromComboFailureText(text: string): OcxUsage | undefined {
129
+ try {
130
+ const payload = JSON.parse(text) as Record<string, unknown>;
131
+ const nested = payload.response;
132
+ const source = nested && typeof nested === "object" && !Array.isArray(nested)
133
+ ? nested as Record<string, unknown>
134
+ : payload;
135
+ return usageFromResponsesPayload(source.usage);
136
+ } catch {
137
+ return undefined;
138
+ }
139
+ }
140
+
141
+
142
+
143
+
144
+ export function createChildPassthroughCallbackGate(options: HandleResponsesOptions) {
145
+ type Pending =
146
+ | { kind: "terminal"; status: ResponsesTerminalStatus }
147
+ | { kind: "cancel" };
148
+ let state: "pending" | "committed" | "discarded" = "pending";
149
+ let pending: Pending | undefined;
150
+ let accepted = false;
151
+ let pendingModel: string | undefined;
152
+ let completionAccepted = false;
153
+ let completionRejected = false;
154
+ const publish = (value: Pending): void => {
155
+ if (value.kind === "terminal") options.onNativePassthroughTerminal?.(value.status);
156
+ else options.onNativePassthroughCancel?.();
157
+ };
158
+ const publishCompletion = (): void => {
159
+ if (state !== "committed" || completionRejected || pendingModel === undefined) return;
160
+ const model = pendingModel;
161
+ pendingModel = undefined;
162
+ options.onResponseComplete?.(model);
163
+ };
164
+ const receive = (value: Pending): void => {
165
+ if (state === "discarded" || accepted) return;
166
+ accepted = true;
167
+ if (value.kind === "cancel" || value.status !== "completed") {
168
+ completionRejected = true;
169
+ pendingModel = undefined;
170
+ }
171
+ if (state === "committed") return publish(value);
172
+ pending ??= value;
173
+ };
174
+ return {
175
+ onTerminal: (status: ResponsesTerminalStatus) => receive({ kind: "terminal", status }),
176
+ onCancel: () => receive({ kind: "cancel" }),
177
+ onResponseComplete: (model: string) => {
178
+ if (state === "discarded" || completionRejected || completionAccepted || !model.trim()) return;
179
+ completionAccepted = true;
180
+ pendingModel = model;
181
+ publishCompletion();
182
+ },
183
+ commit: () => {
184
+ if (state !== "pending") return;
185
+ state = "committed";
186
+ if (pending) publish(pending);
187
+ pending = undefined;
188
+ publishCompletion();
189
+ },
190
+ discard: () => {
191
+ state = "discarded";
192
+ pending = undefined;
193
+ pendingModel = undefined;
194
+ },
195
+ };
196
+ }
197
+
198
+
199
+
200
+ export function buildComboChildHeaders(parentHeaders: HeadersInit): Headers {
201
+ const childHeaders = new Headers(parentHeaders);
202
+ // A provisional caller credential is not authoritative for a Combo child.
203
+ childHeaders.delete("authorization");
204
+ childHeaders.delete("chatgpt-account-id");
205
+ // Combo children re-serialize already-decoded JSON. Keeping transport metadata from
206
+ // the parent would make the child decoder treat plain JSON as compressed bytes.
207
+ childHeaders.delete("content-length");
208
+ childHeaders.delete("content-encoding");
209
+ return childHeaders;
210
+ }