@bitkyc08/opencodex 2.52.0-preview.20260911 → 2.52.0-preview.20260912

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 (166) hide show
  1. package/gui/dist/assets/index-D_t6sCWs.js +115 -0
  2. package/gui/dist/assets/index-EdoPnm9_.css +1 -0
  3. package/gui/dist/index.html +2 -2
  4. package/gui/dist/provider-icons/devin.svg +49 -0
  5. package/gui/dist/provider-icons/omo.svg +42 -0
  6. package/package.json +3 -1
  7. package/src/AGENTS.md +1 -1
  8. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +0 -1
  9. package/src/adapters/command-code.ts +0 -1
  10. package/src/adapters/cursor/checkpoint-store.ts +37 -0
  11. package/src/adapters/cursor/live-transport.ts +74 -2
  12. package/src/adapters/cursor.ts +6 -0
  13. package/src/adapters/devin/cloud-direct/auth.ts +264 -0
  14. package/src/adapters/devin/cloud-direct/catalog.ts +306 -0
  15. package/src/adapters/devin/cloud-direct/chat.ts +1274 -0
  16. package/src/adapters/devin/cloud-direct/index.ts +65 -0
  17. package/src/adapters/devin/cloud-direct/metadata.ts +134 -0
  18. package/src/adapters/devin/cloud-direct/wire.ts +206 -0
  19. package/src/adapters/devin/live-models.ts +133 -0
  20. package/src/adapters/devin-cli/acp.ts +204 -0
  21. package/src/adapters/devin-cli/adapter.ts +345 -0
  22. package/src/adapters/devin-cli/binary.ts +69 -0
  23. package/src/adapters/devin-cli/models.ts +57 -0
  24. package/src/adapters/devin.ts +326 -0
  25. package/src/adapters/google.ts +1 -1
  26. package/src/adapters/openai-chat.ts +31 -10
  27. package/src/adapters/openai-responses.ts +16 -1
  28. package/src/adapters/registry.ts +25 -1
  29. package/src/bridge.ts +8 -2
  30. package/src/claude/inbound-cache-stabilize.ts +130 -0
  31. package/src/claude/inbound.ts +45 -5
  32. package/src/cli/account-auth.ts +60 -1
  33. package/src/cli/account-extended.ts +23 -30
  34. package/src/cli/account.ts +2 -1
  35. package/src/cli/capabilities.ts +50 -8
  36. package/src/cli/config-command.ts +2 -2
  37. package/src/cli/dispatch.ts +14 -2
  38. package/src/cli/export-command.ts +11 -25
  39. package/src/cli/help.ts +2 -2
  40. package/src/cli/opencode.ts +5 -0
  41. package/src/cli/registry.ts +15 -4
  42. package/src/clients/config-export/cline.ts +71 -0
  43. package/src/clients/config-export/contracts.ts +10 -1
  44. package/src/clients/config-export/model-metadata.ts +33 -0
  45. package/src/clients/config-export/zcode.ts +23 -12
  46. package/src/clients/config-export.ts +156 -4
  47. package/src/codex/account-store.ts +7 -2
  48. package/src/codex/auth-context.ts +1 -1
  49. package/src/codex/catalog/effort.ts +4 -3
  50. package/src/codex/catalog/metadata.ts +8 -4
  51. package/src/codex/catalog/native-models.ts +24 -4
  52. package/src/codex/catalog/parsing.ts +19 -1
  53. package/src/codex/catalog/provider-fetch.ts +57 -0
  54. package/src/codex/catalog/sync.ts +1 -1
  55. package/src/codex/context-compat.ts +97 -0
  56. package/src/codex/context-owner.ts +201 -0
  57. package/src/codex/history-provider.ts +161 -14
  58. package/src/codex/inject-coordination.ts +3 -2
  59. package/src/codex/inject.ts +128 -9
  60. package/src/codex/pool-rotation.ts +8 -292
  61. package/src/codex/quota.ts +41 -12
  62. package/src/codex/retired-model-migration.ts +41 -0
  63. package/src/codex/routing.ts +327 -22
  64. package/src/codex/warmup.ts +2 -2
  65. package/src/combos/failover.ts +5 -0
  66. package/src/combos/resolve.ts +11 -15
  67. package/src/config.ts +46 -14
  68. package/src/generated/compatibility-version.json +293 -113
  69. package/src/grok/grpc-web.ts +120 -0
  70. package/src/grok/reset-coupon-ledger.ts +139 -0
  71. package/src/grok/reset-coupons.ts +278 -0
  72. package/src/integrations/catalog-refresh.ts +1 -1
  73. package/src/integrations/cline-document.ts +73 -0
  74. package/src/integrations/cline-io.ts +149 -0
  75. package/src/integrations/cline-transaction.ts +42 -0
  76. package/src/integrations/config-io.ts +21 -2
  77. package/src/integrations/journal.ts +43 -1
  78. package/src/integrations/omp-yaml-source.ts +123 -4
  79. package/src/integrations/ownership-policy.ts +7 -0
  80. package/src/integrations/ownership.ts +36 -0
  81. package/src/integrations/registry.ts +27 -0
  82. package/src/integrations/state.ts +5 -2
  83. package/src/integrations/store.ts +6 -0
  84. package/src/integrations/writer.ts +53 -9
  85. package/src/lab/subject/behavior-fingerprint.ts +1 -1
  86. package/src/lib/abort.ts +36 -0
  87. package/src/lib/local-destinations.ts +1 -1
  88. package/src/lib/upstream-retry.ts +36 -1
  89. package/src/oauth/account-quota-rank.ts +11 -0
  90. package/src/oauth/callback-server.ts +10 -5
  91. package/src/oauth/devin/api-base.ts +63 -0
  92. package/src/oauth/devin/login.ts +1 -0
  93. package/src/oauth/devin/register-user.ts +186 -0
  94. package/src/oauth/devin/types.ts +71 -0
  95. package/src/oauth/devin-cli.ts +149 -0
  96. package/src/oauth/devin.ts +170 -0
  97. package/src/oauth/generic-account-failover.ts +169 -1
  98. package/src/oauth/index.ts +20 -1
  99. package/src/oauth/login-cli.ts +19 -5
  100. package/src/oauth/pool-kernel.ts +321 -0
  101. package/src/oauth/pool-settings-capability.ts +127 -9
  102. package/src/oauth/store.ts +7 -3
  103. package/src/oauth/token-guardian.ts +1 -1
  104. package/src/providers/codebuddy-models.ts +0 -3
  105. package/src/providers/command-code-efforts.ts +23 -4
  106. package/src/providers/default-aliases.ts +4 -0
  107. package/src/providers/derive.ts +8 -0
  108. package/src/providers/devin-cli-authmode-migration.ts +57 -0
  109. package/src/providers/key-failover.ts +175 -0
  110. package/src/providers/model-rename-startup.ts +21 -1
  111. package/src/providers/qoder-models.ts +0 -1
  112. package/src/providers/quota-key-accounts.ts +50 -0
  113. package/src/providers/quota-routing-cache.ts +65 -6
  114. package/src/providers/quota-types.ts +7 -0
  115. package/src/providers/quota.ts +113 -30
  116. package/src/providers/registry.ts +237 -77
  117. package/src/providers/stale-context-window-migration.ts +92 -0
  118. package/src/providers/zai-responses-migration.ts +45 -0
  119. package/src/quota/reset-observer.ts +2 -1
  120. package/src/quota/reset-seen-store.ts +9 -1
  121. package/src/remote-control/crypto.ts +442 -0
  122. package/src/remote-control/host.ts +175 -0
  123. package/src/remote-control/index.ts +100 -0
  124. package/src/remote-control/protocol.ts +200 -0
  125. package/src/remote-control/relay.ts +162 -0
  126. package/src/remote-control/workspace-agent-protocol.ts +246 -0
  127. package/src/remote-control/workspace-rpc-framing.ts +128 -0
  128. package/src/remote-control/workspace-tools.ts +237 -0
  129. package/src/remote-control/workspace-utf8.ts +24 -0
  130. package/src/responses/custom-tool-compat.ts +23 -0
  131. package/src/router.ts +6 -1
  132. package/src/routing/compatibility/behavior.ts +3 -0
  133. package/src/server/adapter-resolve.ts +6 -2
  134. package/src/server/auth-cors.ts +71 -6
  135. package/src/server/chat-completions.ts +5 -3
  136. package/src/server/chat-native.ts +9 -0
  137. package/src/server/claude-messages.ts +25 -30
  138. package/src/server/context-history.ts +207 -0
  139. package/src/server/images.ts +28 -1
  140. package/src/server/index.ts +42 -22
  141. package/src/server/live.ts +2 -1
  142. package/src/server/management/agent-settings-routes.ts +7 -1
  143. package/src/server/management/config-routes.ts +3 -3
  144. package/src/server/management/grok-coupon-routes.ts +287 -0
  145. package/src/server/management/integration-routes.ts +6 -1
  146. package/src/server/management/oauth-account-routes.ts +124 -7
  147. package/src/server/management/provider-routes.ts +77 -2
  148. package/src/server/management/route-registry.ts +6 -1
  149. package/src/server/management-api.ts +7 -0
  150. package/src/server/request-log.ts +4 -0
  151. package/src/server/responses/codex-ws-exchange.ts +90 -14
  152. package/src/server/responses/codex-ws-wire.ts +51 -1
  153. package/src/server/responses/compact.ts +8 -1
  154. package/src/server/responses/core.ts +188 -22
  155. package/src/server/responses/ws-upstream.ts +1 -1
  156. package/src/server/responses-undeclared-tool-guard.ts +261 -12
  157. package/src/server/zai-responses-startup.ts +21 -0
  158. package/src/types/config.ts +33 -3
  159. package/src/types/provider.ts +54 -4
  160. package/src/types/request.ts +1 -1
  161. package/src/types/tools.ts +36 -6
  162. package/src/update/job.ts +33 -11
  163. package/src/vision/plan.ts +40 -37
  164. package/src/web-search/index.ts +1 -0
  165. package/gui/dist/assets/index-BoBRSehJ.css +0 -1
  166. package/gui/dist/assets/index-Dx0xv2EA.js +0 -115
@@ -1,7 +1,6 @@
1
1
  import type { OcxComboTarget, OcxConfig } from "../types";
2
- import { getCachedProviderQuota } from "../providers/quota-routing-cache";
2
+ import { getCachedProviderRoutingQuota } from "../providers/quota-routing-cache";
3
3
  import type { ProviderQuota } from "../providers/quota-types";
4
- import { isCanonicalOpenAiForwardProvider } from "../providers/openai-tiers";
5
4
  import { sleepWithAbort } from "../lib/upstream-retry";
6
5
  import {
7
6
  coolComboTarget,
@@ -65,9 +64,7 @@ function targetProviderIsUsable(config: OcxConfig, target: OcxComboTarget, now:
65
64
  if (!Object.hasOwn(config.providers, target.provider)) return false;
66
65
  const provider = config.providers[target.provider];
67
66
  if (!provider || provider.disabled === true) return false;
68
- // Native account selection owns model-scoped quota; a provider summary cannot veto it.
69
- return isCanonicalOpenAiForwardProvider(provider)
70
- || !cachedProviderQuotaIsExhausted(getCachedProviderQuota(target.provider, now), now);
67
+ return !cachedProviderQuotaIsExhausted(getCachedProviderRoutingQuota(target.provider, provider, now), now);
71
68
  }
72
69
 
73
70
  function quotaWindowExhausted(percent: number | undefined, resetAt: number | undefined, now: number): boolean {
@@ -104,11 +101,8 @@ export type QuotaInactiveReason = "no_credit";
104
101
  * `"no_credit"` when every USABLE target of a catalog row has positive exhaustion evidence
105
102
  * (#1711), otherwise undefined.
106
103
  *
107
- * This deliberately reuses the runtime rules in `targetProviderIsUsable` above rather than the
108
- * Dashboard's `quotaStateFromReport`, which is harsher: it treats `remaining <= 0` as exhausted
109
- * without requiring `percent >= 100` and ignores an elapsed `resetAt`. A catalog row marked
110
- * inactive on the harsher rule would contradict the router, which would still happily send the
111
- * request.
104
+ * This reuses the credential-scoped evidence and exhaustion rules used by runtime selection.
105
+ * Display-only account, model-group and service windows cannot mark a whole provider inactive.
112
106
  *
113
107
  * Three rules carry the correctness, all inherited rather than restated:
114
108
  *
@@ -117,7 +111,7 @@ export type QuotaInactiveReason = "no_credit";
117
111
  * reason rather than a quota one, so this returns undefined.
118
112
  * - The canonical ChatGPT forward provider is exempt. Native account selection owns model-scoped
119
113
  * quota, and a provider-level summary cannot veto it.
120
- * - A stale cache is NOT exhaustion. `getCachedProviderQuota` returns null past its 30-minute
114
+ * - A stale cache is NOT exhaustion. `getCachedProviderRoutingQuota` returns null past its 30-minute
121
115
  * window, and a null reading ends the vote rather than counting as evidence, so an unprobed
122
116
  * provider is never marked inactive.
123
117
  *
@@ -137,8 +131,7 @@ export function quotaInactiveReason(
137
131
  if (usable.length === 0) return undefined;
138
132
  for (const target of usable) {
139
133
  const provider = config.providers[target.provider]!;
140
- if (isCanonicalOpenAiForwardProvider(provider)) return undefined;
141
- const quota = getCachedProviderQuota(target.provider, now);
134
+ const quota = getCachedProviderRoutingQuota(target.provider, provider, now);
142
135
  if (!quota || !cachedProviderQuotaIsExhausted(quota, now)) return undefined;
143
136
  }
144
137
  return "no_credit";
@@ -181,6 +174,7 @@ function smoothWeightedIndex(
181
174
  * unknown (Infinity).
182
175
  */
183
176
  function resetWindowIndex(
177
+ config: OcxConfig,
184
178
  targets: Required<OcxComboTarget>[],
185
179
  eligible: (target: Required<OcxComboTarget>) => boolean,
186
180
  now = Date.now(),
@@ -190,7 +184,9 @@ function resetWindowIndex(
190
184
  for (let index = 0; index < targets.length; index++) {
191
185
  const target = targets[index]!;
192
186
  if (!eligible(target)) continue;
193
- const remaining = quotaResetRemainingMs(getCachedProviderQuota(target.provider, now), now);
187
+ const remaining = quotaResetRemainingMs(
188
+ getCachedProviderRoutingQuota(target.provider, config.providers[target.provider], now), now,
189
+ );
194
190
  // Strict comparison deliberately retains configured order for ties,
195
191
  // including the no-snapshot fallback where every value is Infinity.
196
192
  if (selected < 0 || remaining < smallestRemaining) {
@@ -276,7 +272,7 @@ export function pickComboTarget(
276
272
  }
277
273
  }
278
274
  } else if (combo.strategy === "reset-window") {
279
- targetIndex = resetWindowIndex(combo.targets, eligible, now);
275
+ targetIndex = resetWindowIndex(config, combo.targets, eligible, now);
280
276
  } else {
281
277
  targetIndex = combo.targets.findIndex(eligible);
282
278
  }
package/src/config.ts CHANGED
@@ -580,6 +580,10 @@ const modelPinnedEffortsSchema = z.unknown().superRefine((value, ctx) => {
580
580
  const providerConfigSchema = z.object({
581
581
  pinnedReasoningEffort: pinnedReasoningEffortSchema.optional(),
582
582
  modelPinnedReasoningEfforts: modelPinnedEffortsSchema.optional(),
583
+ // Validated rather than left to passthrough: an unrecognized strategy would otherwise
584
+ // load silently and then be ignored at selection time, which reads as a broken feature
585
+ // rather than a rejected setting.
586
+ apiKeyPoolStrategy: z.enum(["round-robin", "fill-first", "quota"]).optional(),
583
587
  adapter: z.string().min(1),
584
588
  baseUrl: z.string().min(1),
585
589
  alias: z.string().optional(),
@@ -598,6 +602,7 @@ const providerConfigSchema = z.object({
598
602
  mcpMaxResultBytes: z.number().int().positive().optional(),
599
603
  apiKeyTransport: z.enum(["x-api-key", "bearer"]).optional(),
600
604
  responsesPath: z.string().min(1).optional(),
605
+ chatCompletionsPath: z.string().min(1).optional(),
601
606
  statelessResponses: z.boolean().optional(),
602
607
  requiresAdjacentResponsesToolResults: z.boolean().optional(),
603
608
  annotateEmptyToolOutputs: z.boolean().optional(),
@@ -622,6 +627,9 @@ const providerConfigSchema = z.object({
622
627
  noStructuredOutputModels: z.array(z.string().min(1))
623
628
  .transform(normalizeNonBlankStringArray)
624
629
  .optional(),
630
+ noJsonSchemaModels: z.array(z.string().min(1))
631
+ .transform(normalizeNonBlankStringArray)
632
+ .optional(),
625
633
  retainModels: z.array(z.string().min(1))
626
634
  .transform(normalizeNonBlankStringArray)
627
635
  .optional(),
@@ -649,6 +657,7 @@ const providerConfigSchema = z.object({
649
657
  webSearchBridge: providerWebSearchBridgeSchema.optional().catch(undefined),
650
658
  xaiResponsesXSearch: z.boolean().optional(),
651
659
  xaiResponsesDefaultVersion: z.number().int().positive().optional().catch(undefined),
660
+ zaiResponsesDefaultVersion: z.number().int().positive().optional().catch(undefined),
652
661
  }).passthrough();
653
662
 
654
663
  export { isValidProviderName, hasOwnProvider } from "./config/provider-name";
@@ -667,14 +676,18 @@ export {
667
676
  upstreamHttpVersionConfigError,
668
677
  } from "./config/provider-validation";
669
678
 
670
- function providerResponsesPathConfigError(responsesPath: string | undefined): string | null {
671
- if (responsesPath === undefined) return null;
672
- if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(responsesPath) || responsesPath.includes("://")) {
673
- return "responsesPath must be a relative path without a URL scheme";
679
+ /**
680
+ * Shared shape check for the two relative send-path overrides. `field` names the
681
+ * offending key so the message stays specific to what the user actually wrote.
682
+ */
683
+ function providerRelativeSendPathConfigError(field: string, value: string | undefined): string | null {
684
+ if (value === undefined) return null;
685
+ if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(value) || value.includes("://")) {
686
+ return `${field} must be a relative path without a URL scheme`;
674
687
  }
675
- if (!responsesPath.startsWith("/")) return "responsesPath must start with /";
676
- if (responsesPath.includes("?") || responsesPath.includes("#")) {
677
- return "responsesPath must not include query strings or fragments";
688
+ if (!value.startsWith("/")) return `${field} must start with /`;
689
+ if (value.includes("?") || value.includes("#")) {
690
+ return `${field} must not include query strings or fragments`;
678
691
  }
679
692
  return null;
680
693
  }
@@ -1298,6 +1311,12 @@ const configSchema = z.object({
1298
1311
  enabled: z.boolean().optional(),
1299
1312
  leadTimeMinutes: z.number().int().min(1).max(60).optional(),
1300
1313
  }).optional().catch(undefined),
1314
+ // Same degrade-to-off rule as the flags above: a hand-edited typo in an opt-in pool
1315
+ // feature must never cost the operator their providers.
1316
+ pool: z.object({
1317
+ kernel: z.boolean().optional(),
1318
+ cacheAffinity: z.boolean().optional(),
1319
+ }).optional().catch(undefined),
1301
1320
  // Model ids excluded from the Grok Build managed block (dashboard switches).
1302
1321
  grokExcludedModels: z.array(z.string()).optional(),
1303
1322
  // Invalid values degrade to undefined ("auto") instead of failing the whole
@@ -1443,13 +1462,15 @@ const configSchema = z.object({
1443
1462
  });
1444
1463
  }
1445
1464
  }
1446
- const responsesPathError = providerResponsesPathConfigError(provider.responsesPath);
1447
- if (responsesPathError) {
1448
- ctx.addIssue({
1449
- code: "custom",
1450
- path: ["providers", redactSecretString(name), "responsesPath"],
1451
- message: responsesPathError,
1452
- });
1465
+ for (const field of ["responsesPath", "chatCompletionsPath"] as const) {
1466
+ const sendPathError = providerRelativeSendPathConfigError(field, provider[field]);
1467
+ if (sendPathError) {
1468
+ ctx.addIssue({
1469
+ code: "custom",
1470
+ path: ["providers", redactSecretString(name), field],
1471
+ message: sendPathError,
1472
+ });
1473
+ }
1453
1474
  }
1454
1475
  const headersError = providerHeadersConfigError((provider as { headers?: unknown }).headers);
1455
1476
  if (headersError) {
@@ -1612,6 +1633,17 @@ const configSchema = z.object({
1612
1633
  message: structuredOutputOptOutError,
1613
1634
  });
1614
1635
  }
1636
+ const jsonSchemaOptOutError = nonBlankStringArrayConfigError(
1637
+ (provider as { noJsonSchemaModels?: unknown }).noJsonSchemaModels,
1638
+ "noJsonSchemaModels",
1639
+ );
1640
+ if (jsonSchemaOptOutError) {
1641
+ ctx.addIssue({
1642
+ code: "custom",
1643
+ path: ["providers", redactSecretString(name), "noJsonSchemaModels"],
1644
+ message: jsonSchemaOptOutError,
1645
+ });
1646
+ }
1615
1647
  const retainModelsError = nonBlankStringArrayConfigError(
1616
1648
  (provider as { retainModels?: unknown }).retainModels,
1617
1649
  "retainModels",