@bitkyc08/opencodex 2.35.0 → 2.36.0-preview.20260830

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 (155) hide show
  1. package/gui/dist/assets/index-Cy7Z_pl0.css +1 -0
  2. package/gui/dist/assets/index-DPl4nBMA.js +112 -0
  3. package/gui/dist/index.html +2 -2
  4. package/package.json +2 -1
  5. package/src/AGENTS.md +2 -1
  6. package/src/adapters/agentrouter.ts +50 -0
  7. package/src/adapters/anthropic.ts +1 -51
  8. package/src/adapters/cursor/call-id.ts +76 -8
  9. package/src/adapters/cursor/checkpoint-store.ts +6 -1
  10. package/src/adapters/cursor/cursor-errors.ts +44 -0
  11. package/src/adapters/cursor/native-exec.ts +13 -0
  12. package/src/adapters/cursor/protobuf-request.ts +651 -29
  13. package/src/adapters/cursor/tool-result-normalize.ts +3 -3
  14. package/src/adapters/cursor/transport-retry.ts +5 -1
  15. package/src/adapters/cursor.ts +15 -1
  16. package/src/adapters/empty-tool-output-annotation.ts +43 -0
  17. package/src/adapters/exec-tool-result-normalize.ts +70 -5
  18. package/src/adapters/google.ts +22 -2
  19. package/src/adapters/kiro.ts +26 -2
  20. package/src/adapters/ollama-native-url.ts +111 -0
  21. package/src/adapters/ollama-native.ts +1131 -0
  22. package/src/adapters/openai-chat.ts +30 -7
  23. package/src/adapters/openai-responses.ts +72 -4
  24. package/src/adapters/registry.ts +7 -0
  25. package/src/adapters/xai-web-search.ts +58 -0
  26. package/src/claude/desktop-3p.ts +21 -1
  27. package/src/claude/desktop-policy.ts +149 -0
  28. package/src/cli/account.ts +16 -2
  29. package/src/cli/claude-desktop.ts +13 -3
  30. package/src/cli/combo.ts +8 -5
  31. package/src/cli/doctor.ts +77 -11
  32. package/src/cli/help.ts +1 -1
  33. package/src/cli/index.ts +16 -0
  34. package/src/cli/models.ts +20 -3
  35. package/src/cli/registry.ts +2 -1
  36. package/src/cli/status.ts +140 -2
  37. package/src/cli/storage.ts +10 -1
  38. package/src/codex/account-runtime-state.ts +39 -5
  39. package/src/codex/account-store.ts +393 -13
  40. package/src/codex/account-usability.ts +11 -4
  41. package/src/codex/app-server-processes.ts +46 -5
  42. package/src/codex/auth-context.ts +160 -32
  43. package/src/codex/catalog/bundled.ts +7 -5
  44. package/src/codex/catalog/metadata.ts +1 -1
  45. package/src/codex/catalog/parsing.ts +57 -1
  46. package/src/codex/catalog/provider-fetch.ts +61 -4
  47. package/src/codex/catalog/sync.ts +4 -3
  48. package/src/codex/convergence.ts +3 -2
  49. package/src/codex/data/upstream-models.json +40 -8
  50. package/src/codex/inject-coordination.ts +111 -14
  51. package/src/codex/integration-record.ts +12 -2
  52. package/src/codex/main-account.ts +225 -1
  53. package/src/codex/model-entitlements.ts +339 -27
  54. package/src/codex/prompt-layers.ts +346 -7
  55. package/src/codex/prompt-text-probe.ts +272 -21
  56. package/src/codex/routing.ts +693 -132
  57. package/src/codex/runtime.ts +12 -0
  58. package/src/codex/subagent-model-fallback.ts +62 -24
  59. package/src/codex/user-identity.ts +33 -25
  60. package/src/combos/index.ts +1 -0
  61. package/src/combos/reset-window.ts +46 -0
  62. package/src/combos/resolve.ts +84 -2
  63. package/src/combos/types.ts +5 -2
  64. package/src/config/atomic-write.ts +104 -22
  65. package/src/config/provider-validation.ts +11 -0
  66. package/src/config.ts +75 -3
  67. package/src/generated/compatibility-version.json +207 -131
  68. package/src/generated/model-metadata.ts +1 -1
  69. package/src/grok/catalog.ts +71 -0
  70. package/src/grok/effort.ts +83 -0
  71. package/src/grok/inject.ts +952 -127
  72. package/src/grok/models.ts +56 -0
  73. package/src/grok/status.ts +21 -8
  74. package/src/grok/sync.ts +10 -18
  75. package/src/images/loop.ts +6 -3
  76. package/src/integrations/native/ownership-preflight.ts +4 -1
  77. package/src/lab/fabric/producer-isolate.ts +36 -3
  78. package/src/lib/destination-policy.ts +93 -7
  79. package/src/lib/redact.ts +6 -1
  80. package/src/lib/shadow-call.ts +38 -3
  81. package/src/lib/test-home-guard.ts +18 -3
  82. package/src/lib/upstream-retry.ts +43 -6
  83. package/src/lib/windows-secret-acl.ts +66 -0
  84. package/src/lib/windows-text.ts +28 -2
  85. package/src/lib/windows-user-principal.ts +35 -23
  86. package/src/oauth/account-quota-rank.ts +107 -0
  87. package/src/oauth/anthropic-routing.ts +125 -30
  88. package/src/oauth/chatgpt.ts +5 -1
  89. package/src/oauth/generic-account-failover.ts +114 -7
  90. package/src/oauth/index.ts +15 -8
  91. package/src/oauth/store.ts +16 -0
  92. package/src/providers/account-quota-disk.ts +79 -0
  93. package/src/providers/command-code-efforts.ts +24 -0
  94. package/src/providers/derive.ts +6 -0
  95. package/src/providers/key-failover.ts +33 -1
  96. package/src/providers/kiro-usage.ts +272 -0
  97. package/src/providers/ollama-show.ts +311 -0
  98. package/src/providers/openai-sidecar.ts +5 -0
  99. package/src/providers/quota-routing-cache.ts +32 -0
  100. package/src/providers/quota-types.ts +36 -0
  101. package/src/providers/quota-wire.ts +102 -0
  102. package/src/providers/quota.ts +208 -147
  103. package/src/providers/registry.ts +68 -8
  104. package/src/providers/slug-codec.ts +12 -4
  105. package/src/providers/vercel-gateway-routing.ts +108 -0
  106. package/src/router.ts +22 -12
  107. package/src/server/auth-cors.ts +26 -0
  108. package/src/server/catalog-download.ts +73 -0
  109. package/src/server/chat-native.ts +12 -2
  110. package/src/server/gui-static.ts +4 -1
  111. package/src/server/index.ts +132 -9
  112. package/src/server/management/agent-settings-routes.ts +38 -5
  113. package/src/server/management/codex-prompt-routes.ts +7 -1
  114. package/src/server/management/combo-routes.ts +10 -1
  115. package/src/server/management/config-routes.ts +9 -1
  116. package/src/server/management/context.ts +5 -0
  117. package/src/server/management/model-routes.ts +16 -6
  118. package/src/server/management/native-integration-routes.ts +12 -17
  119. package/src/server/management/oauth-account-routes.ts +13 -0
  120. package/src/server/management/provider-routes.ts +32 -5
  121. package/src/server/management/routing-profile-routes.ts +15 -0
  122. package/src/server/management/shadow-call-validation.ts +29 -0
  123. package/src/server/management-api.ts +7 -3
  124. package/src/server/request-log.ts +3 -5
  125. package/src/server/responses/agent-task-recovery-cache.ts +8 -0
  126. package/src/server/responses/agent-task-recovery.ts +52 -20
  127. package/src/server/responses/codex-auth-error.ts +26 -0
  128. package/src/server/responses/compact.ts +345 -10
  129. package/src/server/responses/core.ts +736 -108
  130. package/src/server/responses/empty-completion-guard.ts +16 -0
  131. package/src/server/responses/fetch-helpers.ts +42 -0
  132. package/src/server/responses/policy-fallback.ts +11 -6
  133. package/src/server/responses-undeclared-tool-guard.ts +16 -3
  134. package/src/server/startup-health-cache.ts +59 -13
  135. package/src/service-manager-probe.ts +115 -9
  136. package/src/service.ts +139 -40
  137. package/src/storage/cleanup.ts +10 -0
  138. package/src/storage/storage-mutation-coordinator.ts +14 -3
  139. package/src/tray/windows-tray.ps1 +10 -4
  140. package/src/tray/windows.ts +30 -2
  141. package/src/types/config.ts +27 -14
  142. package/src/types/provider.ts +54 -0
  143. package/src/types/tools.ts +13 -3
  144. package/src/types.ts +4 -0
  145. package/src/usage/summary.ts +421 -177
  146. package/src/vision/anthropic-describe.ts +3 -3
  147. package/src/vision/describe.ts +5 -3
  148. package/src/web-search/anthropic-executor.ts +9 -2
  149. package/src/web-search/exa-executor.ts +3 -3
  150. package/src/web-search/executor.ts +8 -3
  151. package/src/web-search/gemini-executor.ts +3 -3
  152. package/src/web-search/loop.ts +11 -3
  153. package/src/web-search/xai-executor.ts +3 -3
  154. package/gui/dist/assets/index-DNdRKXK9.js +0 -112
  155. package/gui/dist/assets/index-DQ-Ie18T.css +0 -1
package/src/config.ts CHANGED
@@ -61,6 +61,7 @@ import { providerDestinationConfigError } from "./lib/destination-policy";
61
61
  import { redactSecretString } from "./lib/redact";
62
62
  import { openRouterRoutingConfigError } from "./providers/openrouter-routing";
63
63
  import { MODEL_ALIAS_PATTERN } from "./providers/default-aliases";
64
+ import { vercelGatewayRoutingConfigError } from "./providers/vercel-gateway-routing";
64
65
  import {
65
66
  MODEL_ADAPTER_OVERRIDE_ALLOWED,
66
67
  OPENAI_PROVIDER_TIER_VERSION,
@@ -445,6 +446,16 @@ const retryOn429PolicySchema = z.object({
445
446
  respectRetryAfter: z.boolean().optional(),
446
447
  }).strict();
447
448
 
449
+ /**
450
+ * `transientRetryOn5xx` accepts only these keys. `attempts` is a TOTAL send budget shared by
451
+ * both retry layers, so the ceiling is deliberately lower than `retryOn429`'s: 10 total sends
452
+ * against an already-failing provider is already generous.
453
+ */
454
+ const transientRetryOn5xxPolicySchema = z.object({
455
+ enabled: z.boolean().optional(),
456
+ attempts: z.number().int().min(1).max(10).optional(),
457
+ }).strict();
458
+
448
459
  const requestPacingRuleSchema = z.object({
449
460
  // Keep the RPM-derived timer within the same one-hour bound as minIntervalMs.
450
461
  requestsPerMinute: z.number().min(1 / 60).max(60_000).optional(),
@@ -500,6 +511,7 @@ const providerConfigSchema = z.object({
500
511
  responsesPath: z.string().min(1).optional(),
501
512
  statelessResponses: z.boolean().optional(),
502
513
  requiresAdjacentResponsesToolResults: z.boolean().optional(),
514
+ annotateEmptyToolOutputs: z.boolean().optional(),
503
515
  fastWire: fastWireSchema.nullable().optional(),
504
516
  supportsServiceTier: z.boolean().optional(),
505
517
  modelSupportsServiceTier: z.record(z.string().min(1), z.boolean()).optional(),
@@ -517,6 +529,7 @@ const providerConfigSchema = z.object({
517
529
  .transform(normalizeNonBlankStringArray)
518
530
  .optional(),
519
531
  retryOn429: retryOn429PolicySchema.optional(),
532
+ transientRetryOn5xx: transientRetryOn5xxPolicySchema.optional(),
520
533
  codexAccountMode: z.enum(["pool", "direct"]).optional(),
521
534
  // Validated rather than passed through: this schema ends in `.passthrough()`, so an
522
535
  // undeclared key survives verbatim. A misspelled `codexToolMode` therefore used to be
@@ -530,6 +543,7 @@ const providerConfigSchema = z.object({
530
543
  repairInvalidIds: z.boolean().optional(),
531
544
  }).strict().optional(),
532
545
  responsesSnapshotRepair: z.boolean().optional(),
546
+ xaiResponsesXSearch: z.boolean().optional(),
533
547
  }).passthrough();
534
548
 
535
549
  export { isValidProviderName, hasOwnProvider } from "./config/provider-name";
@@ -930,6 +944,7 @@ const configSchema = z.object({
930
944
  // parse: a hand-edited typo must never trip the backup-and-defaults repair
931
945
  // path below and wipe providers/pool accounts. Warning emitted in loadConfig.
932
946
  streamMode: z.enum(["auto", "legacy-tee", "eager-relay"]).optional().catch(undefined),
947
+ blockedModelRedirects: z.record(z.string(), z.string()).optional().catch(undefined),
933
948
  // Same degrade-don't-reject rationale as the fields above: a hand-edited
934
949
  // non-string must not trip the backup-and-defaults repair path. Unset then
935
950
  // takes the canonical sideband path (src/server/live.ts normalizeSidebandRoot).
@@ -1030,6 +1045,20 @@ const configSchema = z.object({
1030
1045
  message: openRouterRoutingError,
1031
1046
  });
1032
1047
  }
1048
+ const vercelRoutingError = vercelGatewayRoutingConfigError(provider);
1049
+ if (vercelRoutingError) {
1050
+ ctx.addIssue({
1051
+ code: "custom",
1052
+ path: [
1053
+ "providers",
1054
+ redactSecretString(name),
1055
+ vercelRoutingError.startsWith("modelVercelGatewayRouting")
1056
+ ? "modelVercelGatewayRouting"
1057
+ : "vercelGatewayRouting",
1058
+ ],
1059
+ message: vercelRoutingError,
1060
+ });
1061
+ }
1033
1062
  if (Object.hasOwn(provider, "virtualModels")) {
1034
1063
  ctx.addIssue({
1035
1064
  code: "custom",
@@ -3109,6 +3138,26 @@ export function resolveEnvValue(value: string | undefined): string | undefined {
3109
3138
  return value;
3110
3139
  }
3111
3140
 
3141
+ const warnedProxyConfigDiscards = new Set<"proxy" | "noProxy" | "noProxyElements">();
3142
+
3143
+ function warnProxyConfigDiscardOnce(kind: "proxy" | "noProxy" | "noProxyElements"): void {
3144
+ if (warnedProxyConfigDiscards.has(kind)) return;
3145
+ warnedProxyConfigDiscards.add(kind);
3146
+ if (kind === "proxy") {
3147
+ console.warn(
3148
+ "⚠️ config.json proxy was discarded because it is not a non-empty resolved string — configured proxy routing is disabled; existing proxy environment variables remain authoritative, otherwise outbound requests use direct egress",
3149
+ );
3150
+ } else if (kind === "noProxy") {
3151
+ console.warn(
3152
+ "⚠️ config.json noProxy was discarded because it is not a string, string array, or resolved environment reference — existing NO_PROXY and loopback bypasses remain",
3153
+ );
3154
+ } else {
3155
+ console.warn(
3156
+ "⚠️ config.json noProxy contains invalid elements — invalid elements were ignored; valid entries, existing NO_PROXY, and loopback bypasses remain",
3157
+ );
3158
+ }
3159
+ }
3160
+
3112
3161
  /**
3113
3162
  * Mirror `config.proxy` into HTTP(S)_PROXY env vars so Bun's native fetch routes every outbound
3114
3163
  * provider call through the proxy — no per-callsite changes (verified: Bun honors these plus
@@ -3117,8 +3166,18 @@ export function resolveEnvValue(value: string | undefined): string | undefined {
3117
3166
  * that makes outbound provider requests (server start, catalog sync).
3118
3167
  */
3119
3168
  export function applyProxyEnv(config: OcxConfig): void {
3120
- const proxy = resolveEnvValue(config.proxy);
3121
- if (!proxy) return;
3169
+ // `proxy` and `noProxy` are not declared in the top-level schema, which ends in
3170
+ // `.passthrough()`, so whatever is on disk arrives here verbatim. A non-string value
3171
+ // reached string-only methods and threw out of this function, and it runs once per
3172
+ // process entry point — the failure was a startup crash, not a degraded proxy. Ignore
3173
+ // malformed values with a privacy-safe warning instead: they cannot express a routing
3174
+ // intent, and refusing to start is a worse answer than starting without them.
3175
+ const rawProxy = config.proxy;
3176
+ const proxy = typeof rawProxy === "string" ? resolveEnvValue(rawProxy) : undefined;
3177
+ if (!proxy) {
3178
+ if (rawProxy !== undefined) warnProxyConfigDiscardOnce("proxy");
3179
+ return;
3180
+ }
3122
3181
  if (!process.env.HTTP_PROXY?.trim() && !process.env.http_proxy?.trim()) process.env.HTTP_PROXY = proxy;
3123
3182
  if (!process.env.HTTPS_PROXY?.trim() && !process.env.https_proxy?.trim()) process.env.HTTPS_PROXY = proxy;
3124
3183
  const existing = process.env.NO_PROXY ?? process.env.no_proxy ?? "";
@@ -3127,7 +3186,20 @@ export function applyProxyEnv(config: OcxConfig): void {
3127
3186
  // Configured entries first, then loopback: loopback is unconditional, so appending it last
3128
3187
  // keeps it present even when the operator lists a loopback host themselves.
3129
3188
  const raw = config.noProxy;
3130
- const configured = (Array.isArray(raw) ? raw : (resolveEnvValue(raw) ?? "").split(","))
3189
+ let configuredEntries: string[];
3190
+ if (Array.isArray(raw)) {
3191
+ // One unusable element must not discard the operator's other entries.
3192
+ if (raw.some(entry => typeof entry !== "string")) warnProxyConfigDiscardOnce("noProxyElements");
3193
+ configuredEntries = raw.filter((entry): entry is string => typeof entry === "string");
3194
+ } else if (typeof raw === "string") {
3195
+ const resolved = resolveEnvValue(raw);
3196
+ if (raw && resolved === undefined) warnProxyConfigDiscardOnce("noProxy");
3197
+ configuredEntries = (resolved ?? "").split(",");
3198
+ } else {
3199
+ if (raw !== undefined) warnProxyConfigDiscardOnce("noProxy");
3200
+ configuredEntries = [];
3201
+ }
3202
+ const configured = configuredEntries
3131
3203
  .map(entry => entry.trim())
3132
3204
  .filter(Boolean);
3133
3205
  for (const host of [...configured, "localhost", "127.0.0.1", "::1", "[::1]"]) {