@bitkyc08/opencodex 2.58.0 → 2.59.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 (188) hide show
  1. package/README.md +28 -10
  2. package/gui/dist/assets/index-C5IebErG.js +136 -0
  3. package/gui/dist/assets/{index-C5-RdDmD.css → index-OESInAjC.css} +1 -1
  4. package/gui/dist/index.html +2 -2
  5. package/gui/dist/provider-icons/crusoe.svg +1 -0
  6. package/gui/dist/provider-icons/opper.svg +3 -0
  7. package/package.json +1 -1
  8. package/src/adapters/base.ts +11 -1
  9. package/src/adapters/cursor/catalog.ts +11 -0
  10. package/src/adapters/cursor/effort-map.ts +16 -2
  11. package/src/adapters/cursor/envelope-echo.ts +55 -2
  12. package/src/adapters/cursor/message-mapper.ts +3 -2
  13. package/src/adapters/cursor/protobuf-request.ts +8 -5
  14. package/src/adapters/cursor/request-builder.ts +14 -3
  15. package/src/adapters/cursor/thread-continuity.ts +105 -31
  16. package/src/adapters/cursor/tool-guidance.ts +5 -4
  17. package/src/adapters/cursor.ts +42 -1
  18. package/src/adapters/devin/cloud-direct/chat.ts +11 -2
  19. package/src/adapters/devin/cloud-direct/index.ts +7 -0
  20. package/src/adapters/devin/cloud-direct/stated-reset-retry.ts +103 -0
  21. package/src/adapters/devin.ts +75 -13
  22. package/src/adapters/google-antigravity-wire.ts +29 -2
  23. package/src/adapters/google-http.ts +8 -1
  24. package/src/adapters/google.ts +23 -4
  25. package/src/adapters/openai-chat/response-events.ts +61 -0
  26. package/src/adapters/openai-chat.ts +5 -10
  27. package/src/adapters/openai-responses/passthrough.ts +10 -1
  28. package/src/adapters/openai-responses/tool-output-recovery.ts +75 -0
  29. package/src/adapters/openai-responses/tool-schema.ts +19 -7
  30. package/src/adapters/responses-tool-schema.ts +76 -46
  31. package/src/adapters/run-turn-queue.ts +17 -4
  32. package/src/bridge/response-json.ts +1 -1
  33. package/src/bridge/sse.ts +165 -24
  34. package/src/claude/context-windows.ts +22 -0
  35. package/src/claude/outbound.ts +35 -4
  36. package/src/cli/account-api.ts +4 -3
  37. package/src/cli/account-extended.ts +22 -2
  38. package/src/cli/account-orca-import.ts +63 -0
  39. package/src/cli/account.ts +32 -4
  40. package/src/cli/capabilities.ts +40 -0
  41. package/src/cli/claude.ts +29 -1
  42. package/src/cli/codex-cli-update.ts +97 -2
  43. package/src/cli/dispatch.ts +54 -0
  44. package/src/cli/doctor.ts +197 -2
  45. package/src/cli/help.ts +4 -1
  46. package/src/cli/index.ts +88 -20
  47. package/src/cli/models-runtime.ts +33 -4
  48. package/src/cli/registry.ts +11 -1
  49. package/src/cli/runtime-api.ts +44 -0
  50. package/src/cli/start-args.ts +94 -0
  51. package/src/cli/system-command.ts +2 -0
  52. package/src/client/machine-api.ts +4 -3
  53. package/src/client/machine-listener.ts +14 -1
  54. package/src/clients/config-export/constants.ts +2 -3
  55. package/src/clients/config-export.ts +5 -5
  56. package/src/codex/account-store.ts +81 -5
  57. package/src/codex/auth-api/pool-quota-probe.ts +14 -3
  58. package/src/codex/auth-api/routes.ts +17 -2
  59. package/src/codex/auth-context.ts +16 -12
  60. package/src/codex/catalog/build-entries.ts +25 -4
  61. package/src/codex/catalog/derive-entry.ts +8 -1
  62. package/src/codex/catalog/effort.ts +10 -6
  63. package/src/codex/catalog/gather-capture.ts +1 -0
  64. package/src/codex/catalog/model-hints.ts +37 -5
  65. package/src/codex/catalog/parsing.ts +83 -5
  66. package/src/codex/catalog/reserve-warn.ts +96 -0
  67. package/src/codex/catalog/retained-sync.ts +19 -0
  68. package/src/codex/catalog/routed-gather.ts +42 -3
  69. package/src/codex/cli-installation-identity.ts +210 -0
  70. package/src/codex/cli-installation-targets.ts +158 -0
  71. package/src/codex/convergence.ts +5 -0
  72. package/src/codex/history-provider.ts +4 -1
  73. package/src/codex/history-state-open.ts +105 -0
  74. package/src/codex/inject/config-toml.ts +44 -2
  75. package/src/codex/inject.ts +3 -2
  76. package/src/codex/lineage.ts +83 -32
  77. package/src/codex/loopback-target.ts +31 -0
  78. package/src/codex/main-account-hard-lock.ts +2 -1
  79. package/src/codex/main-account.ts +10 -3
  80. package/src/codex/main-device-reauth.ts +17 -9
  81. package/src/codex/model-entitlements.ts +60 -1
  82. package/src/codex/observed-model-denials.ts +137 -0
  83. package/src/codex/orca-auth-source.ts +94 -0
  84. package/src/codex/orca-import.ts +219 -0
  85. package/src/codex/prompt-text-probe.ts +282 -12
  86. package/src/codex/quota-401-recovery.ts +12 -0
  87. package/src/codex/quota-types.ts +65 -0
  88. package/src/codex/quota.ts +24 -19
  89. package/src/codex/routing/cooldown-math.ts +8 -47
  90. package/src/codex/routing/pin-drain.ts +57 -0
  91. package/src/codex/routing.ts +13 -15
  92. package/src/codex/subagent-model-fallback.ts +94 -0
  93. package/src/codex/windows-installation-files.ts +224 -0
  94. package/src/combos/failover.ts +122 -5
  95. package/src/config/diagnostics.ts +21 -0
  96. package/src/config/load-degrade.ts +15 -0
  97. package/src/config/pending-teardown.ts +8 -0
  98. package/src/config/process-state.ts +36 -3
  99. package/src/config/provider-relative-send-path.ts +16 -0
  100. package/src/config/proxy-env.ts +23 -5
  101. package/src/config/schema/config-schema.ts +21 -0
  102. package/src/config/schema/leaf-validators.ts +64 -17
  103. package/src/generated/compatibility-version.json +235 -163
  104. package/src/generated/model-metadata.ts +1 -1
  105. package/src/lib/bounded-body.ts +4 -2
  106. package/src/lib/destination-policy.ts +48 -6
  107. package/src/lib/errors.ts +3 -15
  108. package/src/lib/local-destinations.ts +32 -5
  109. package/src/lib/provider-outbound.ts +3 -3
  110. package/src/lib/proxy-env.ts +70 -3
  111. package/src/lib/request-execution-budget.ts +11 -3
  112. package/src/lib/response-body-inactivity.ts +193 -0
  113. package/src/lib/retry-delay.ts +69 -0
  114. package/src/lib/socks5-fetch.ts +631 -0
  115. package/src/lib/spend-reservation-ledger.ts +115 -9
  116. package/src/lib/workflow-budget.ts +145 -8
  117. package/src/oauth/account-quota-rank.ts +72 -15
  118. package/src/oauth/generic-account-failover.ts +40 -27
  119. package/src/oauth/orcarouter.ts +15 -2
  120. package/src/oauth/store.ts +8 -0
  121. package/src/providers/codex-capacity.ts +9 -0
  122. package/src/providers/devin-provider-merge-migration.ts +33 -12
  123. package/src/providers/free-directory.ts +20 -2
  124. package/src/providers/key-failover.ts +261 -7
  125. package/src/providers/model-rename-migration.ts +1 -0
  126. package/src/providers/openai-sidecar.ts +4 -0
  127. package/src/providers/opencode-go-transport.ts +14 -5
  128. package/src/providers/quota/report-cache.ts +3 -0
  129. package/src/providers/registry/entries-extended.ts +96 -0
  130. package/src/providers/registry/model-seeds.ts +78 -21
  131. package/src/responses/apply-patch-envelope.ts +44 -11
  132. package/src/responses/bridge-search-replay-cache.ts +152 -0
  133. package/src/responses/code-mode-helper-compat.ts +26 -16
  134. package/src/responses/custom-tool-compat.ts +1 -1
  135. package/src/responses/hosted-tool-policy.ts +85 -2
  136. package/src/responses/schema.ts +9 -2
  137. package/src/server/auth-cors.ts +26 -0
  138. package/src/server/chat-completions.ts +9 -4
  139. package/src/server/chat-native-sse.ts +26 -9
  140. package/src/server/chat-native.ts +10 -4
  141. package/src/server/claude-messages.ts +24 -2
  142. package/src/server/gui-static.ts +36 -2
  143. package/src/server/inbound-body-admission.ts +187 -0
  144. package/src/server/index.ts +15 -19
  145. package/src/server/management/api-access.ts +3 -4
  146. package/src/server/management/config-routes.ts +31 -6
  147. package/src/server/management/provider-capability-config.ts +35 -7
  148. package/src/server/management/provider-routes.ts +70 -18
  149. package/src/server/proxy-liveness.ts +97 -2
  150. package/src/server/relay.ts +17 -24
  151. package/src/server/request-log.ts +25 -1
  152. package/src/server/responses/adapter-continuation.ts +71 -27
  153. package/src/server/responses/adapter-delivery.ts +39 -8
  154. package/src/server/responses/adapter-dispatch.ts +52 -24
  155. package/src/server/responses/compact.ts +60 -11
  156. package/src/server/responses/core-codex-account.ts +83 -22
  157. package/src/server/responses/core-normalize.ts +12 -5
  158. package/src/server/responses/fetch-helpers.ts +68 -2
  159. package/src/server/responses/passthrough-delivery.ts +10 -1
  160. package/src/server/responses/passthrough-dispatch.ts +113 -48
  161. package/src/server/responses/passthrough-execution.ts +11 -1
  162. package/src/server/responses/request-prepare.ts +29 -0
  163. package/src/server/responses/request-send-budget.ts +84 -7
  164. package/src/server/responses/request-sidecar-auth.ts +16 -8
  165. package/src/server/responses/request-spend.ts +38 -9
  166. package/src/server/responses/request-transport.ts +13 -10
  167. package/src/server/responses/run-turn-execution.ts +20 -5
  168. package/src/server/responses/sidecar-execution.ts +2 -0
  169. package/src/server/responses/ws-upstream.ts +2 -1
  170. package/src/server/responses-custom-tool-repair.ts +2 -2
  171. package/src/server/sse-frame-buffer.ts +12 -10
  172. package/src/server/sse-payload-rewrite.ts +36 -9
  173. package/src/server/system-env-shell.ts +5 -1
  174. package/src/server/system-env.ts +7 -1
  175. package/src/server/workflow-refusal.ts +56 -2
  176. package/src/service/cli.ts +16 -6
  177. package/src/service/guards.ts +10 -0
  178. package/src/service/health.ts +43 -0
  179. package/src/service/state.ts +7 -2
  180. package/src/types/accounts.ts +4 -0
  181. package/src/types/config.ts +100 -3
  182. package/src/types/provider.ts +19 -0
  183. package/src/types/request.ts +7 -1
  184. package/src/types/wire.ts +9 -1
  185. package/src/usage/expected-prices.ts +28 -0
  186. package/src/usage/log.ts +87 -4
  187. package/src/web-search/passthrough-bridge.ts +39 -5
  188. package/gui/dist/assets/index-BbrHOIY0.js +0 -128
@@ -13,6 +13,7 @@ import {
13
13
  quotaResetNotifySchema,
14
14
  remoteGuiConfigSchema,
15
15
  runtimeRoleSchema,
16
+ spendSchema,
16
17
  configuredCodexPoolAccountIds,
17
18
  apiKeyEntrySchema,
18
19
  asideProfileSyncSchema,
@@ -166,6 +167,11 @@ export const configSchema = z.object({
166
167
  quotaResetNotify: quotaResetNotifySchema.optional().catch(undefined),
167
168
  // Same rationale: a bad auto-refresh section must not cost the operator their providers.
168
169
  catalogAutoRefresh: catalogAutoRefreshSchema.optional().catch(undefined),
170
+ // Same rationale again, with the failure direction stated: a malformed spend section
171
+ // degrades to "no ceiling", which means observe-only accounting rather than an outage. That
172
+ // is the safe degrade for traffic and the dangerous one for the operator, so the write path
173
+ // rejects it and loadConfig warns -- the same pair codexPool uses below.
174
+ spend: spendSchema.optional().catch(undefined),
169
175
  // These selections pre-date schema validation and used to pass through as
170
176
  // unknown fields. Invalid hand edits must disable only the optional
171
177
  // delegation/native-default feature, not reject the whole config and hide
@@ -182,6 +188,10 @@ export const configSchema = z.object({
182
188
  codexShimAutoRestore: z.boolean().optional(),
183
189
  codexDesktopAuthless: z.boolean().optional().catch(undefined),
184
190
  codexClientCompaction: z.boolean().optional().catch(undefined),
191
+ // Presentation-only label for the injected provider. A malformed value degrades to undefined
192
+ // and the default label is emitted, rather than failing the parse or writing a config Codex
193
+ // would refuse to load — the provider id routing depends on is never derived from it.
194
+ codexProviderDisplayName: z.string().trim().min(1).max(128).optional().catch(undefined),
185
195
  pausedCodexAccountIds: z.array(z.string().regex(/^[a-zA-Z0-9._-]{1,64}$/)).optional(),
186
196
  // A malformed policy degrades to "no policy" rather than failing the parse, so a hand-edited
187
197
  // typo cannot trip the backup-and-defaults repair path and wipe providers or pool accounts.
@@ -464,6 +474,17 @@ export const configSchema = z.object({
464
474
  message: reasoningSummariesError,
465
475
  });
466
476
  }
477
+ const suppressSyntheticMaxError = booleanRecordConfigError(
478
+ (provider as { modelSuppressSyntheticMax?: unknown }).modelSuppressSyntheticMax,
479
+ "modelSuppressSyntheticMax",
480
+ );
481
+ if (suppressSyntheticMaxError) {
482
+ ctx.addIssue({
483
+ code: "custom",
484
+ path: ["providers", redactSecretString(name), "modelSuppressSyntheticMax"],
485
+ message: suppressSyntheticMaxError,
486
+ });
487
+ }
467
488
  const verbositySupportError = booleanRecordConfigError(
468
489
  (provider as { modelSupportsVerbosity?: unknown }).modelSupportsVerbosity,
469
490
  "modelSupportsVerbosity",
@@ -32,7 +32,11 @@ import { getProviderRegistryEntry, providerMatchesRegistryTransport, providerMod
32
32
  import { resolveOpenAiVirtualModel } from "../../providers/openai-virtual-models";
33
33
  import { COST4_RATE_KEYS, isValidCost4Rate } from "../../usage/user-cost-overlays";
34
34
  import { MAX_COST4_RATE } from "../../usage/expected-prices";
35
- import { isHostedToolUnsupportedForModel } from "../../responses/hosted-tool-policy";
35
+ import {
36
+ DECLARABLE_HOSTED_TOOL_TYPES,
37
+ declaredUnsupportedHostedTools,
38
+ isHostedToolUnsupportedForModel,
39
+ } from "../../responses/hosted-tool-policy";
36
40
  import { getConfigDir } from "../paths";
37
41
 
38
42
  /** One definition of "usable secret", shared by the schema and the warnings. */
@@ -248,6 +252,7 @@ export const providerConfigSchema = z.object({
248
252
  fastWire: fastWireSchema.nullable().optional(),
249
253
  supportsServiceTier: z.boolean().optional(),
250
254
  modelSupportsServiceTier: z.record(z.string().min(1), z.boolean()).optional(),
255
+ modelSuppressSyntheticMax: z.record(z.string().min(1), z.boolean()).optional(),
251
256
  preserveResponsesReasoningContent: z.boolean().optional(),
252
257
  decodesNativeCompactionBlobs: z.boolean().optional(),
253
258
  allowEncryptedV2AgentTasks: z.boolean().optional(),
@@ -275,6 +280,18 @@ export const providerConfigSchema = z.object({
275
280
  omitReasoningEffortWithToolsModels: z.array(z.string().min(1))
276
281
  .transform(normalizeNonBlankStringArray)
277
282
  .optional(),
283
+ // Validated against a closed vocabulary rather than accepted as free strings. This
284
+ // schema ends in `.passthrough()`, so a misspelled `web_serch` would otherwise be
285
+ // accepted, persisted, and strip nothing -- leaving the operator with the upstream 400
286
+ // the field was set to prevent, and no message saying why (the `codexToolMode` lesson,
287
+ // #2106).
288
+ unsupportedHostedTools: z.array(z.string().min(1))
289
+ .transform(normalizeNonBlankStringArray)
290
+ .refine(
291
+ tools => tools.every(tool => DECLARABLE_HOSTED_TOOL_TYPES.has(tool)),
292
+ { message: `unsupportedHostedTools accepts only hosted tool types: ${[...DECLARABLE_HOSTED_TOOL_TYPES].join(", ")}` },
293
+ )
294
+ .optional(),
278
295
  retryOn429: retryOn429PolicySchema.optional(),
279
296
  transientRetryOn5xx: transientRetryOn5xxPolicySchema.optional(),
280
297
  codexAccountMode: z.enum(["pool", "direct"]).optional(),
@@ -300,21 +317,7 @@ export const providerConfigSchema = z.object({
300
317
  }).passthrough();
301
318
 
302
319
 
303
- /**
304
- * Shared shape check for the two relative send-path overrides. `field` names the
305
- * offending key so the message stays specific to what the user actually wrote.
306
- */
307
- export function providerRelativeSendPathConfigError(field: string, value: string | undefined): string | null {
308
- if (value === undefined) return null;
309
- if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(value) || value.includes("://")) {
310
- return `${field} must be a relative path without a URL scheme`;
311
- }
312
- if (!value.startsWith("/")) return `${field} must start with /`;
313
- if (value.includes("?") || value.includes("#")) {
314
- return `${field} must not include query strings or fragments`;
315
- }
316
- return null;
317
- }
320
+ export { providerRelativeSendPathConfigError } from "../provider-relative-send-path";
318
321
 
319
322
  /**
320
323
  * Validate `providers.<name>.modelCosts`: a plain object keyed by exact model
@@ -391,7 +394,13 @@ export function modelPreferHostedToolsConfigError(
391
394
  value: unknown,
392
395
  field: string,
393
396
  providerName: string,
394
- provider: { adapter?: unknown; authMode?: unknown; modelAdapters?: unknown; baseUrl?: unknown },
397
+ provider: {
398
+ adapter?: unknown;
399
+ authMode?: unknown;
400
+ modelAdapters?: unknown;
401
+ baseUrl?: unknown;
402
+ unsupportedHostedTools?: unknown;
403
+ },
395
404
  ): string | null {
396
405
  if (value === undefined) return null;
397
406
  if (!value || typeof value !== "object" || Array.isArray(value)) return `${field} must be a plain object`;
@@ -399,6 +408,12 @@ export function modelPreferHostedToolsConfigError(
399
408
  if (prototype !== Object.prototype && prototype !== null) return `${field} must be a plain object with own properties`;
400
409
  const entries = Object.entries(value);
401
410
  const registry = getProviderRegistryEntry(providerName);
411
+ // A provider that denies a hosted tool cannot also prefer it. Both keys are
412
+ // provider-owned capability statements about the same tool, and the denial wins at
413
+ // request time, so accepting the pair would silently ignore the preference.
414
+ const declaredUnsupported = declaredUnsupportedHostedTools(
415
+ provider as { unsupportedHostedTools?: readonly string[] },
416
+ );
402
417
  // Effective transport: a `preserveCustomDestination` registry row reused under a
403
418
  // different endpoint keeps its own adapter AND its own auth at runtime, because
404
419
  // `routedProviderConfig()` honors `providerMatchesRegistryTransport()`. Both the
@@ -459,6 +474,9 @@ export function modelPreferHostedToolsConfigError(
459
474
  if (typeof tool !== "string" || !SUPPORTED_PREFERRED_HOSTED_TOOLS.has(tool)) {
460
475
  return `${field}.${key} supports only image_generation`;
461
476
  }
477
+ if (declaredUnsupported.has(tool)) {
478
+ return `${field}.${key} cannot prefer ${tool}: unsupportedHostedTools declares it unsupported`;
479
+ }
462
480
  if (isHostedToolUnsupportedForModel(key, tool)) {
463
481
  return `${field}.${key} cannot prefer ${tool}: the model does not support it`;
464
482
  }
@@ -854,3 +872,32 @@ export const catalogAutoRefreshSchema = z.object({
854
872
  enabled: z.boolean().optional(),
855
873
  intervalMinutes: z.number().int().min(0).max(1440).optional(),
856
874
  }).strict();
875
+
876
+ /**
877
+ * One spend scope's ceiling.
878
+ *
879
+ * `.strict()` for the usual reason and one sharper one. Elsewhere a silently ignored key
880
+ * leaves a feature off that the operator believed was on; here it leaves a BUDGET off, and a
881
+ * budget nobody is enforcing looks exactly like a budget nobody has exceeded. That is #2106 --
882
+ * an undeclared option accepted, persisted, and then read as its default -- aimed at spend.
883
+ *
884
+ * Only positive integers: 0 would read as "no tokens at all" and refuse every request under
885
+ * the scope, which is never what writing a budget means. An operator who wants no ceiling
886
+ * removes the key.
887
+ */
888
+ const spendScopeSchema = z.object({
889
+ maxTokens: z.number().int().positive().optional(),
890
+ }).strict();
891
+
892
+ /**
893
+ * Durable spend ceilings (#4546).
894
+ *
895
+ * Absent, empty, and all-scopes-absent are the same thing: observe-only accounting. There is
896
+ * no default ceiling anywhere in this section, deliberately.
897
+ */
898
+ export const spendSchema = z.object({
899
+ root: spendScopeSchema.optional(),
900
+ identity: spendScopeSchema.optional(),
901
+ pool: spendScopeSchema.optional(),
902
+ retentionDays: z.number().int().min(1).max(365).optional(),
903
+ }).strict();