@bitkyc08/opencodex 2.56.0 → 2.58.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 (206) hide show
  1. package/bin/ocx.mjs +10 -0
  2. package/gui/dist/assets/{index-D4zuyIxQ.js → index-BbrHOIY0.js} +21 -21
  3. package/gui/dist/assets/{index-BBOZWGB6.css → index-C5-RdDmD.css} +1 -1
  4. package/gui/dist/index.html +2 -2
  5. package/package.json +4 -4
  6. package/src/adapters/codebuddy/adapter.ts +2 -1
  7. package/src/adapters/codebuddy/scaffold-guard.ts +249 -0
  8. package/src/adapters/command-code.ts +12 -3
  9. package/src/adapters/cursor/cursor-errors.ts +15 -0
  10. package/src/adapters/cursor/discovery.ts +65 -1
  11. package/src/adapters/cursor/envelope-echo.ts +8 -2
  12. package/src/adapters/cursor/live-transport.ts +5 -1
  13. package/src/adapters/cursor/protobuf-events.ts +110 -11
  14. package/src/adapters/cursor/protobuf-request.ts +19 -1
  15. package/src/adapters/cursor/text-toolcall.ts +230 -0
  16. package/src/adapters/cursor/thread-continuity.ts +67 -0
  17. package/src/adapters/cursor/types.ts +5 -0
  18. package/src/adapters/cursor.ts +55 -5
  19. package/src/adapters/google-http.ts +38 -13
  20. package/src/adapters/google.ts +7 -7
  21. package/src/adapters/kiro/payload.ts +17 -3
  22. package/src/adapters/kiro/reasoning.ts +70 -7
  23. package/src/adapters/kiro/stream.ts +8 -2
  24. package/src/adapters/kiro/wire.ts +2 -1
  25. package/src/adapters/kiro-events.ts +21 -13
  26. package/src/adapters/mimo-free.ts +32 -17
  27. package/src/adapters/ollama-native.ts +42 -8
  28. package/src/adapters/openai-chat/tool-name-registry.ts +166 -0
  29. package/src/adapters/openai-chat/tool-schema.ts +25 -7
  30. package/src/adapters/openai-chat.ts +8 -8
  31. package/src/adapters/openai-responses/passthrough.ts +62 -5
  32. package/src/adapters/openai-responses/request-strips.ts +43 -0
  33. package/src/adapters/physical-send.ts +50 -0
  34. package/src/bridge/errors.ts +26 -2
  35. package/src/bridge/response-json.ts +8 -2
  36. package/src/bridge/sse.ts +20 -2
  37. package/src/claude/desktop-profile.ts +66 -9
  38. package/src/claude/outbound.ts +32 -4
  39. package/src/cli/account-main.ts +1 -1
  40. package/src/cli/capabilities.ts +2 -2
  41. package/src/cli/combo.ts +10 -1
  42. package/src/cli/config-command.ts +35 -18
  43. package/src/cli/dispatch.ts +17 -4
  44. package/src/cli/index.ts +92 -7
  45. package/src/cli/registry.ts +2 -1
  46. package/src/cli/system-command.ts +74 -5
  47. package/src/cli/uninstall-client-state.ts +12 -0
  48. package/src/clients/config-export.ts +7 -3
  49. package/src/codex/account-label.ts +14 -3
  50. package/src/codex/account-store.ts +113 -26
  51. package/src/codex/account-usability.ts +21 -0
  52. package/src/codex/auth-api/login-flow.ts +14 -2
  53. package/src/codex/auth-api/reset-credit-service.ts +11 -2
  54. package/src/codex/auth-context.ts +199 -15
  55. package/src/codex/catalog/aggregation.ts +80 -1
  56. package/src/codex/catalog/model-visibility.ts +1 -0
  57. package/src/codex/catalog/remote.ts +30 -0
  58. package/src/codex/catalog/retained-sync.ts +9 -1
  59. package/src/codex/catalog/routed-gather.ts +38 -1
  60. package/src/codex/cli-install-provenance.ts +7 -1
  61. package/src/codex/convergence.ts +7 -2
  62. package/src/codex/desktop-app/types.ts +11 -2
  63. package/src/codex/desktop-app/windows.ts +5 -5
  64. package/src/codex/desktop-switches.ts +145 -0
  65. package/src/codex/history-job.ts +5 -1
  66. package/src/codex/history-provider.ts +33 -4
  67. package/src/codex/history-worker.ts +14 -1
  68. package/src/codex/inject/remove.ts +145 -7
  69. package/src/codex/inject/restore.ts +231 -32
  70. package/src/codex/inject.ts +12 -16
  71. package/src/codex/loopback-target.ts +9 -0
  72. package/src/codex/model-entitlements.ts +152 -15
  73. package/src/codex/native-profile-startup.ts +64 -20
  74. package/src/codex/pool-refresh-backoff.ts +12 -3
  75. package/src/codex/quota-rejection.ts +104 -15
  76. package/src/codex/routing/cache-affinity.ts +70 -0
  77. package/src/codex/routing/cooldown-math.ts +10 -0
  78. package/src/codex/routing/selection.ts +79 -2
  79. package/src/codex/routing/thread-affinity.ts +50 -2
  80. package/src/codex/routing/transient-hold-dispatch.ts +141 -0
  81. package/src/codex/routing.ts +29 -49
  82. package/src/codex/warmup.ts +1 -1
  83. package/src/combos/failover.ts +85 -0
  84. package/src/combos/request.ts +17 -10
  85. package/src/combos/types.ts +23 -2
  86. package/src/config/atomic-write.ts +83 -8
  87. package/src/config/pending-teardown.ts +31 -0
  88. package/src/config/schema/config-schema.ts +2 -0
  89. package/src/config/schema/leaf-validators.ts +1 -0
  90. package/src/generated/compatibility-version.json +272 -180
  91. package/src/images/loop.ts +1 -1
  92. package/src/lib/bounded-subprocess.ts +62 -10
  93. package/src/lib/errors.ts +17 -0
  94. package/src/lib/request-execution-budget.ts +147 -21
  95. package/src/lib/spend-reservation-ledger.ts +18 -0
  96. package/src/lib/state-store-registrations.ts +6 -2
  97. package/src/lib/test-home-guard.ts +85 -1
  98. package/src/lib/upstream-retry.ts +77 -10
  99. package/src/lib/windows-elevation.ts +76 -14
  100. package/src/lib/windows-secret-acl.ts +151 -15
  101. package/src/lib/windows-user-principal.ts +5 -1
  102. package/src/oauth/index.ts +2 -2
  103. package/src/oauth/key-providers.ts +2 -2
  104. package/src/providers/derive.ts +6 -0
  105. package/src/providers/kiro-models.ts +4 -3
  106. package/src/providers/label.ts +19 -1
  107. package/src/providers/model-discovery.ts +35 -7
  108. package/src/providers/registry/entries-core.ts +18 -0
  109. package/src/providers/registry/entries-extended.ts +59 -28
  110. package/src/providers/registry/model-seeds.ts +71 -17
  111. package/src/providers/registry/types.ts +9 -0
  112. package/src/responses/reasoning-envelope.ts +6 -3
  113. package/src/responses/spill-store.ts +17 -0
  114. package/src/responses/state/body-policy.ts +25 -0
  115. package/src/responses/state/spill-queue.ts +8 -6
  116. package/src/responses/state.ts +3 -22
  117. package/src/router.ts +4 -0
  118. package/src/routing/identity-domains.ts +21 -14
  119. package/src/routing/probe-lease.ts +103 -1
  120. package/src/server/auth-cors.ts +1 -0
  121. package/src/server/chat-completions.ts +3 -1
  122. package/src/server/chat-native.ts +37 -9
  123. package/src/server/index/live-sideband.ts +37 -1
  124. package/src/server/index/websocket-handler.ts +54 -3
  125. package/src/server/index.ts +5 -5
  126. package/src/server/inspection-tee.ts +107 -0
  127. package/src/server/live.ts +46 -1
  128. package/src/server/management/combo-routes.ts +10 -1
  129. package/src/server/management/config-routes.ts +27 -5
  130. package/src/server/models-capabilities.ts +24 -3
  131. package/src/server/relay-eager.ts +2 -0
  132. package/src/server/relay.ts +14 -19
  133. package/src/server/request-log.ts +127 -3
  134. package/src/server/response-log-body.ts +153 -0
  135. package/src/server/responses/account-change-state.ts +74 -0
  136. package/src/server/responses/adapter-continuation.ts +33 -7
  137. package/src/server/responses/adapter-delivery.ts +5 -11
  138. package/src/server/responses/adapter-dispatch.ts +84 -13
  139. package/src/server/responses/codex-ws-exchange.ts +65 -4
  140. package/src/server/responses/codex-ws-wire.ts +5 -0
  141. package/src/server/responses/collaboration.ts +74 -4
  142. package/src/server/responses/combo-session-recall.ts +68 -8
  143. package/src/server/responses/combo-stream-preflight.ts +68 -5
  144. package/src/server/responses/compact.ts +54 -13
  145. package/src/server/responses/core-auth.ts +2 -0
  146. package/src/server/responses/core-codex-account.ts +51 -3
  147. package/src/server/responses/core-combo.ts +129 -23
  148. package/src/server/responses/core-errors.ts +18 -0
  149. package/src/server/responses/core-options.ts +3 -0
  150. package/src/server/responses/core-replay.ts +105 -32
  151. package/src/server/responses/core.ts +3 -3
  152. package/src/server/responses/encrypted-payload.ts +0 -1
  153. package/src/server/responses/fetch-helpers.ts +4 -1
  154. package/src/server/responses/input-admission.ts +126 -6
  155. package/src/server/responses/native-injection-protocol.ts +42 -0
  156. package/src/server/responses/native-injection-replay.ts +105 -0
  157. package/src/server/responses/native-injection.ts +242 -0
  158. package/src/server/responses/native-response-control.ts +56 -0
  159. package/src/server/responses/native-response-json.ts +14 -0
  160. package/src/server/responses/native-response-output.ts +37 -0
  161. package/src/server/responses/native-steering-log.ts +44 -0
  162. package/src/server/responses/native-steering-policy.ts +49 -0
  163. package/src/server/responses/native-steering-replay.ts +126 -0
  164. package/src/server/responses/native-steering-settings.ts +76 -0
  165. package/src/server/responses/native-steering.ts +400 -0
  166. package/src/server/responses/native-tool-results.ts +130 -0
  167. package/src/server/responses/passthrough-delivery.ts +30 -6
  168. package/src/server/responses/passthrough-dispatch.ts +61 -11
  169. package/src/server/responses/passthrough-error.ts +38 -2
  170. package/src/server/responses/request-prepare.ts +173 -22
  171. package/src/server/responses/request-send-budget.ts +97 -2
  172. package/src/server/responses/request-spend.ts +147 -0
  173. package/src/server/responses/request-transport.ts +62 -3
  174. package/src/server/responses/run-turn-execution.ts +59 -31
  175. package/src/server/responses/sidecar-execution.ts +7 -13
  176. package/src/server/responses/terminal-guard.ts +65 -4
  177. package/src/server/responses/ws-upstream.ts +21 -1
  178. package/src/server/responses-undeclared-tool-guard.ts +9 -5
  179. package/src/server/stop-teardown.ts +8 -1
  180. package/src/server/ws-bridge.ts +16 -1
  181. package/src/service/cli.ts +13 -1
  182. package/src/service/windows-ops.ts +210 -16
  183. package/src/service/windows-scheduler.ts +28 -21
  184. package/src/service.ts +1 -1
  185. package/src/types/config.ts +8 -1
  186. package/src/types/provider.ts +13 -0
  187. package/src/types/request.ts +8 -5
  188. package/src/types/tools.ts +24 -0
  189. package/src/types.ts +2 -0
  190. package/src/update/index.ts +10 -0
  191. package/src/update/stop-contract.d.mts +1 -0
  192. package/src/update/stop-contract.mjs +19 -0
  193. package/src/update/stop-decision.d.mts +1 -1
  194. package/src/update/stop-decision.mjs +12 -3
  195. package/src/usage/log.ts +1 -1
  196. package/src/vision/anthropic-describe.ts +1 -1
  197. package/src/vision/describe.ts +5 -5
  198. package/src/web-search/anthropic-executor.ts +1 -1
  199. package/src/web-search/exa-executor.ts +1 -1
  200. package/src/web-search/executor.ts +1 -1
  201. package/src/web-search/gemini-executor.ts +1 -1
  202. package/src/web-search/loop.ts +1 -1
  203. package/src/web-search/ollama-executor.ts +1 -1
  204. package/src/web-search/parse.ts +67 -14
  205. package/src/web-search/passthrough-bridge.ts +64 -31
  206. package/src/web-search/xai-executor.ts +1 -1
@@ -128,6 +128,22 @@ const MAX_QUERIES_PER_CALL = 3;
128
128
  const MAX_RETAINED_OUTPUT_ITEMS = 500;
129
129
  /** Refuse to buffer an unbounded partial SSE event from a misbehaving upstream. */
130
130
  const MAX_SSE_BUFFER_CHARS = 8 * 1024 * 1024;
131
+ /** UTF-16 code units in SSE data payloads, not a byte or total-heap measurement. */
132
+ const MAX_HELD_CALL_CHARS = 8 * 1024 * 1024;
133
+ /**
134
+ * Derived from MAX_HELD_CALL_CHARS rather than picked, so the two bounds bind at the same
135
+ * scale. The character budget is the real memory guard; this count only adds the per-event
136
+ * object overhead the character budget cannot see. A fine-grained argument delta serializes
137
+ * to roughly 128 code units -- an envelope of about 110 characters carrying the item id and
138
+ * output index, plus a token-sized fragment -- so 8 MiB of them is 65,536 events. The count
139
+ * therefore bites only for events smaller than that average. A flat 1,000 discarded a
140
+ * legitimate client-executed tool call: a sizeable apply_patch streamed as fine-grained
141
+ * deltas is ordinary, not exotic, and failing its leg trades one failure for another.
142
+ */
143
+ export const MAX_HELD_CALL_EVENTS = MAX_HELD_CALL_CHARS / 128;
144
+
145
+ /** A proxy-side admission bound, never an upstream transport failure. */
146
+ class HeldCallBudgetExceededError extends Error {}
131
147
 
132
148
  /**
133
149
  * Retained for importers that pinned the first slice's contract: a leg mixing the search with
@@ -488,6 +504,7 @@ class BridgeStreamState {
488
504
  * failing the turn would let Codex start running a tool for a turn that never completes.
489
505
  */
490
506
  private heldCalls: HeldCallEvent[] = [];
507
+ private heldCallChars = 0;
491
508
  private heldIndexes = new Set<number>();
492
509
  private heldItemIds = new Set<string>();
493
510
  private terminalPayload: Record<string, unknown> | undefined;
@@ -497,9 +514,7 @@ class BridgeStreamState {
497
514
  this.suppressedSearches = new Map();
498
515
  this.suppressedItemIds = new Map();
499
516
  this.searches = [];
500
- this.heldCalls = [];
501
- this.heldIndexes = new Set();
502
- this.heldItemIds = new Set();
517
+ this.dropHeldCalls();
503
518
  this.terminalPayload = undefined;
504
519
  }
505
520
 
@@ -507,6 +522,17 @@ class BridgeStreamState {
507
522
  return this.heldCalls.length > 0;
508
523
  }
509
524
 
525
+ private holdCall(payload: Record<string, unknown>, dataChars: number, upstreamIndex?: number): void {
526
+ if (this.heldCalls.length >= MAX_HELD_CALL_EVENTS
527
+ || dataChars > MAX_HELD_CALL_CHARS - this.heldCallChars) {
528
+ throw new HeldCallBudgetExceededError(
529
+ "web-search bridge withheld more client tool events than its per-leg buffer bound allows",
530
+ );
531
+ }
532
+ this.heldCalls.push({ payload, ...(upstreamIndex === undefined ? {} : { upstreamIndex }) });
533
+ this.heldCallChars += dataChars;
534
+ }
535
+
510
536
  private clientIndexFor(upstreamIndex: number): number {
511
537
  const existing = this.indexMap.get(upstreamIndex);
512
538
  if (existing !== undefined) return existing;
@@ -626,7 +652,7 @@ class BridgeStreamState {
626
652
  if (isClientExecutedItem(item)) {
627
653
  if (upstreamIndex !== undefined) this.heldIndexes.add(upstreamIndex);
628
654
  if (typeof item.id === "string") this.heldItemIds.add(item.id);
629
- this.heldCalls.push({ payload, ...(upstreamIndex === undefined ? {} : { upstreamIndex }) });
655
+ this.holdCall(payload, data.length, upstreamIndex);
630
656
  return [];
631
657
  }
632
658
  }
@@ -648,7 +674,7 @@ class BridgeStreamState {
648
674
 
649
675
  if ((upstreamIndex !== undefined && this.heldIndexes.has(upstreamIndex))
650
676
  || (itemId !== undefined && this.heldItemIds.has(itemId))) {
651
- this.heldCalls.push({ payload, ...(upstreamIndex === undefined ? {} : { upstreamIndex }) });
677
+ this.holdCall(payload, data.length, upstreamIndex);
652
678
  return [];
653
679
  }
654
680
 
@@ -658,19 +684,20 @@ class BridgeStreamState {
658
684
  return [this.render(payload.type, rewritten)];
659
685
  }
660
686
 
661
- /** Release the withheld client tool calls once the turn is known to end here. */
662
- flushHeldCalls(): string[] {
663
- const blocks: string[] = [];
664
- for (const held of this.heldCalls) {
665
- const rewritten: Record<string, unknown> = { ...held.payload };
666
- if (held.upstreamIndex !== undefined) {
667
- rewritten.output_index = this.clientIndexFor(held.upstreamIndex);
687
+ /** Release lazily so flushing does not allocate a second full set of serialized events. */
688
+ *flushHeldCalls(): Generator<string> {
689
+ try {
690
+ for (const held of this.heldCalls) {
691
+ const rewritten: Record<string, unknown> = { ...held.payload };
692
+ if (held.upstreamIndex !== undefined) {
693
+ rewritten.output_index = this.clientIndexFor(held.upstreamIndex);
694
+ }
695
+ if (held.payload.type === "response.output_item.done") this.retain(held.payload.item);
696
+ yield this.render(String(held.payload.type), rewritten);
668
697
  }
669
- if (held.payload.type === "response.output_item.done") this.retain(held.payload.item);
670
- blocks.push(this.render(String(held.payload.type), rewritten));
698
+ } finally {
699
+ this.dropHeldCalls();
671
700
  }
672
- this.heldCalls = [];
673
- return blocks;
674
701
  }
675
702
 
676
703
  /**
@@ -680,6 +707,18 @@ class BridgeStreamState {
680
707
  */
681
708
  dropHeldCalls(): void {
682
709
  this.heldCalls = [];
710
+ this.heldCallChars = 0;
711
+ this.heldIndexes.clear();
712
+ this.heldItemIds.clear();
713
+ }
714
+
715
+ /** Fail before executing this leg's searches, closing every cell already shown to the client. */
716
+ *failLegFrames(code: string, message: string): Generator<string> {
717
+ this.dropHeldCalls();
718
+ for (const call of this.searches) {
719
+ yield* this.searchEndFrames(call, [], { text: "", sources: [], error: message });
720
+ }
721
+ yield* this.failureFrames(code, message);
683
722
  }
684
723
 
685
724
  /** Decide what the leg's terminal means once the whole leg has been read. */
@@ -979,7 +1018,7 @@ async function* bridgeStreamBlocks(
979
1018
  // One continuation leg per allowed search, plus one final leg for the answer itself.
980
1019
  let legsRemaining = options.plan.maxSearches + 1;
981
1020
 
982
- const emit = function* (blocks: readonly string[]): Generator<string> {
1021
+ const emit = function* (blocks: Iterable<string>): Generator<string> {
983
1022
  for (const block of blocks) yield block + "\n\n";
984
1023
  };
985
1024
 
@@ -991,10 +1030,15 @@ async function* bridgeStreamBlocks(
991
1030
  if (aborted()) return;
992
1031
  }
993
1032
  } catch (error) {
1033
+ if (aborted()) return;
994
1034
  const message = error instanceof Error ? error.message : String(error);
995
- yield* emit(state.failureFrames(
1035
+ // A held-event overflow is this proxy's own bound. Attributing it to an upstream read
1036
+ // failure would blame the provider for a refusal the bridge made.
1037
+ yield* emit(state.failLegFrames(
996
1038
  WEB_SEARCH_BRIDGE_ERROR_CODE,
997
- "web-search bridge upstream read failed: " + message,
1039
+ error instanceof HeldCallBudgetExceededError
1040
+ ? message
1041
+ : "web-search bridge upstream read failed: " + message,
998
1042
  ));
999
1043
  return;
1000
1044
  }
@@ -1003,18 +1047,7 @@ async function* bridgeStreamBlocks(
1003
1047
 
1004
1048
  const decision = state.decide(legsRemaining);
1005
1049
  if (decision.kind === "fail") {
1006
- // Close any cell this leg opened, or Codex keeps a "Searching the web" spinner running
1007
- // under a failed turn (the same reason src/bridge.ts closes a dangling search on teardown).
1008
- for (const call of decision.searches) {
1009
- yield* emit(state.searchEndFrames(call, [], {
1010
- text: "",
1011
- sources: [],
1012
- error: decision.message!,
1013
- }));
1014
- }
1015
- // The withheld client call is deliberately dropped: the turn is ending as failed, and
1016
- // releasing a tool call Codex would start executing is exactly what must not happen.
1017
- yield* emit(state.failureFrames(decision.code!, decision.message!));
1050
+ yield* emit(state.failLegFrames(decision.code!, decision.message!));
1018
1051
  return;
1019
1052
  }
1020
1053
  if (decision.kind === "end") {
@@ -110,7 +110,7 @@ export async function runXaiWebSearch(
110
110
  // Credential-bearing: never follow a redirect off the pinned origin.
111
111
  redirect: "manual",
112
112
  }, recovery)),
113
- { abortSignal: linkedSignal.signal, label: "xai-web-search-sidecar" },
113
+ { replaySafe: true, abortSignal: linkedSignal.signal, label: "xai-web-search-sidecar" },
114
114
  );
115
115
  const detachBodyGuard = cancelBodyOnAbort(res.body, linkedSignal.signal);
116
116
  if (!res.ok) {