@bitkyc08/opencodex 2.63.0 → 2.64.0-preview.20260923

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 (262) hide show
  1. package/AGENTS_INSTALL.md +4 -3
  2. package/README.md +46 -33
  3. package/assets/download-linux.svg +10 -0
  4. package/assets/download-macos.svg +10 -0
  5. package/assets/download-windows.svg +10 -0
  6. package/bin/ocx.mjs +12 -4
  7. package/gui/dist/assets/App-D5eN1TID.js +50 -0
  8. package/gui/dist/assets/App-I5AnaSLh.css +1 -0
  9. package/gui/dist/assets/{Tray-CncKDBTp.js → Tray-Bh_ErQDh.js} +1 -1
  10. package/gui/dist/assets/index-BEq4OCOz.js +86 -0
  11. package/gui/dist/assets/index-DiBRuK-d.css +1 -0
  12. package/gui/dist/assets/usage-companion-chart-DBG_37kQ.js +1 -0
  13. package/gui/dist/index.html +2 -2
  14. package/native/remote-workspace-helper/src/protocol.rs +5 -0
  15. package/package.json +4 -1
  16. package/src/adapters/anthropic.ts +66 -7
  17. package/src/adapters/codebuddy/adapter.ts +112 -16
  18. package/src/adapters/codebuddy/mcp-server.ts +180 -0
  19. package/src/adapters/codebuddy/scaffold-guard.ts +25 -8
  20. package/src/adapters/codebuddy/tool-bridge.ts +597 -0
  21. package/src/adapters/coding-agent/protocol.ts +123 -10
  22. package/src/adapters/coding-agent/turn.ts +324 -2
  23. package/src/adapters/command-code-restored-schema.ts +112 -0
  24. package/src/adapters/command-code-tool-text.ts +589 -0
  25. package/src/adapters/command-code.ts +80 -6
  26. package/src/adapters/cursor/catalog.ts +12 -0
  27. package/src/adapters/cursor/current-request.ts +46 -0
  28. package/src/adapters/cursor/discovery.ts +1 -1
  29. package/src/adapters/cursor/effort-map.ts +4 -0
  30. package/src/adapters/cursor/native-exec.ts +15 -0
  31. package/src/adapters/cursor/protobuf-events.ts +40 -12
  32. package/src/adapters/cursor/protobuf-request.ts +83 -18
  33. package/src/adapters/cursor/request-builder.ts +5 -4
  34. package/src/adapters/cursor/tool-guidance.ts +1 -1
  35. package/src/adapters/devin/live-models.ts +7 -0
  36. package/src/adapters/inline-think-tags.ts +251 -0
  37. package/src/adapters/kiro/adapter.ts +1 -0
  38. package/src/adapters/kiro/stream.ts +5 -3
  39. package/src/adapters/kiro/usage.ts +4 -3
  40. package/src/adapters/mimo-free.ts +37 -18
  41. package/src/adapters/openai-chat/messages.ts +5 -5
  42. package/src/adapters/openai-chat/tool-schema.ts +124 -2
  43. package/src/adapters/openai-chat.ts +13 -3
  44. package/src/adapters/openai-responses/passthrough.ts +15 -2
  45. package/src/adapters/openai-responses/reasoning.ts +14 -1
  46. package/src/adapters/openai-responses/request-strips.ts +29 -3
  47. package/src/adapters/openai-responses/tool-output-recovery.ts +9 -3
  48. package/src/adapters/qoder/adapter.ts +15 -12
  49. package/src/adapters/qoder/scaffold-guard.ts +45 -13
  50. package/src/bridge/internal.ts +20 -0
  51. package/src/bridge/sse.ts +14 -5
  52. package/src/claude/agents-inject.ts +2 -1
  53. package/src/claude/desktop-applied-marker.ts +44 -0
  54. package/src/claude/desktop-profile.ts +22 -12
  55. package/src/claude/inbound.ts +8 -3
  56. package/src/cli/access.ts +22 -5
  57. package/src/cli/account-api.ts +6 -0
  58. package/src/cli/account-auth.ts +5 -2
  59. package/src/cli/account.ts +5 -6
  60. package/src/cli/aside-profiles.ts +61 -1
  61. package/src/cli/claude-desktop.ts +3 -2
  62. package/src/cli/claude.ts +3 -1
  63. package/src/cli/codex-cli-update.ts +2 -2
  64. package/src/cli/codex-shim-autorestore.ts +3 -0
  65. package/src/cli/dispatch.ts +12 -4
  66. package/src/cli/index.ts +98 -10
  67. package/src/cli/registry.ts +1 -1
  68. package/src/cli/resolve.ts +113 -1
  69. package/src/cli/root.ts +5 -0
  70. package/src/cli/stop-approval.ts +186 -0
  71. package/src/cli/stop-report.ts +1 -1
  72. package/src/cli/system-restart-client.ts +19 -4
  73. package/src/client/hub-client.ts +25 -18
  74. package/src/clients/config-export.ts +12 -4
  75. package/src/codex/account-auto-switch.ts +59 -0
  76. package/src/codex/account-lifecycle.ts +7 -0
  77. package/src/codex/account-priority.ts +10 -0
  78. package/src/codex/account-usability.ts +9 -0
  79. package/src/codex/auth-api/account-list.ts +5 -0
  80. package/src/codex/auth-api/login-flow.ts +15 -5
  81. package/src/codex/auth-api/login-state.ts +5 -16
  82. package/src/codex/auth-api/pool-mode-gate.ts +30 -7
  83. package/src/codex/auth-api/routes.ts +39 -3
  84. package/src/codex/auth-context.ts +145 -17
  85. package/src/codex/catalog/build-entries.ts +2 -1
  86. package/src/codex/catalog/effort.ts +8 -2
  87. package/src/codex/catalog/metadata.ts +33 -7
  88. package/src/codex/catalog/native-models.ts +102 -5
  89. package/src/codex/catalog/parsing.ts +2 -0
  90. package/src/codex/catalog/provider-models.ts +19 -6
  91. package/src/codex/cli-installation-targets.ts +44 -40
  92. package/src/codex/codex-write-lock.ts +32 -2
  93. package/src/codex/inject/multi-agent-v2.ts +90 -0
  94. package/src/codex/inject/plan.ts +365 -0
  95. package/src/codex/inject.ts +237 -362
  96. package/src/codex/log-guard/maintenance.ts +30 -13
  97. package/src/codex/project-config-warnings.ts +47 -7
  98. package/src/codex/prompt-layers/encoding.ts +41 -0
  99. package/src/codex/prompt-layers/toml-read.ts +1 -1
  100. package/src/codex/prompt-layers.ts +17 -13
  101. package/src/codex/prompt-text-probe.ts +20 -10
  102. package/src/codex/quota-observation-freshness.ts +34 -0
  103. package/src/codex/quota-rejection.ts +8 -4
  104. package/src/codex/quota.ts +4 -2
  105. package/src/codex/routing/selection.ts +32 -9
  106. package/src/codex/routing.ts +53 -11
  107. package/src/codex/subagent-model-fallback.ts +4 -3
  108. package/src/codex/sync.ts +11 -0
  109. package/src/codex/windows-installation-files.ts +33 -11
  110. package/src/codex/write-coordination.ts +4 -0
  111. package/src/combos/request.ts +6 -2
  112. package/src/companion/settings.ts +6 -1
  113. package/src/config/atomic-write.ts +12 -1
  114. package/src/config/derived-registries.ts +29 -0
  115. package/src/config/diagnostics.ts +17 -0
  116. package/src/config/live-reconcile.ts +11 -2
  117. package/src/config/load-degrade.ts +9 -2
  118. package/src/config/persist-unlocked.ts +4 -3
  119. package/src/config/persisted-mutation.ts +94 -0
  120. package/src/config/provider-validation.ts +1 -1
  121. package/src/config/proxy-env.ts +62 -12
  122. package/src/config/rebase-provenance.ts +80 -1
  123. package/src/config/schema/config-schema.ts +5 -0
  124. package/src/config/schema/leaf-validators.ts +50 -1
  125. package/src/config/subagent-models.ts +41 -15
  126. package/src/config.ts +18 -95
  127. package/src/generated/compatibility-version.json +330 -218
  128. package/src/generated/model-metadata.ts +8 -5
  129. package/src/github/star-state.ts +46 -6
  130. package/src/grok/inject.ts +74 -40
  131. package/src/grok/status.ts +11 -4
  132. package/src/integrations/cursor-effort-table.ts +50 -13
  133. package/src/integrations/raycast-detect.ts +19 -4
  134. package/src/integrations/serialize.ts +11 -1
  135. package/src/lib/bounded-body.ts +30 -0
  136. package/src/lib/crash-guard.ts +52 -4
  137. package/src/lib/local-aside-sync-contract.ts +41 -0
  138. package/src/lib/package-tree-integrity.ts +181 -9
  139. package/src/lib/proxy-env.ts +18 -1
  140. package/src/lib/request-failure-attribution.ts +1 -0
  141. package/src/lib/request-failure-model.ts +3 -0
  142. package/src/lib/service-secrets.ts +99 -2
  143. package/src/lib/socks5-fetch.ts +43 -14
  144. package/src/lib/token-estimate.ts +17 -2
  145. package/src/oauth/command-code.ts +3 -2
  146. package/src/oauth/generic-account-failover.ts +29 -1
  147. package/src/oauth/index.ts +24 -16
  148. package/src/oauth/login-flow-state.ts +5 -5
  149. package/src/oauth/meta-muse-device.ts +49 -7
  150. package/src/oauth/store.ts +74 -9
  151. package/src/providers/alibaba-region-backup.ts +16 -1
  152. package/src/providers/anthropic-fast.ts +89 -0
  153. package/src/providers/anthropic-reset-grant-ledger.ts +288 -0
  154. package/src/providers/anthropic-reset-grants.ts +329 -0
  155. package/src/providers/claude-cli-identity.ts +12 -0
  156. package/src/providers/command-code-efforts.ts +184 -102
  157. package/src/providers/derive.ts +11 -3
  158. package/src/providers/fastwire.ts +16 -3
  159. package/src/providers/label.ts +8 -3
  160. package/src/providers/model-rename-fields.ts +1 -0
  161. package/src/providers/openai-virtual-models.ts +1 -0
  162. package/src/providers/quota/vendor-probes-oauth.ts +2 -1
  163. package/src/providers/reasoning-metadata.ts +38 -15
  164. package/src/providers/registry/entries-core.ts +95 -7
  165. package/src/providers/registry/entries-extended.ts +21 -10
  166. package/src/providers/registry/model-ids.ts +1 -0
  167. package/src/providers/registry/model-seeds.ts +31 -3
  168. package/src/providers/registry/types.ts +3 -1
  169. package/src/providers/resolved-model-policy-merge.ts +38 -8
  170. package/src/providers/resolved-model-policy.ts +4 -2
  171. package/src/providers/service-tier.ts +3 -1
  172. package/src/reasoning-effort.ts +6 -5
  173. package/src/responses/code-mode-helper-compat.ts +14 -4
  174. package/src/responses/code-mode-shell-input.ts +54 -0
  175. package/src/responses/custom-tool-compat.ts +173 -5
  176. package/src/responses/parser.ts +38 -2
  177. package/src/responses/reasoning-replay-cache.ts +26 -0
  178. package/src/router.ts +11 -1
  179. package/src/routing/history/indexer.ts +7 -2
  180. package/src/routing/history/schema.ts +3 -1
  181. package/src/server/adapter-resolve.ts +2 -2
  182. package/src/server/auth-cors.ts +3 -0
  183. package/src/server/chat-completions.ts +14 -1
  184. package/src/server/chat-native.ts +17 -0
  185. package/src/server/claude-messages.ts +4 -3
  186. package/src/server/direct-local-http.ts +45 -19
  187. package/src/server/gui-session.ts +6 -15
  188. package/src/server/index/package-tree-guard.ts +53 -0
  189. package/src/server/index/serve-options.ts +17 -3
  190. package/src/server/index/startup-warnings.ts +17 -0
  191. package/src/server/index.ts +15 -17
  192. package/src/server/lifecycle.ts +8 -0
  193. package/src/server/live.ts +54 -4
  194. package/src/server/management/agent-settings-routes.ts +44 -8
  195. package/src/server/management/anthropic-reset-grant-routes.ts +252 -0
  196. package/src/server/management/codex-prompt-routes.ts +5 -1
  197. package/src/server/management/config-routes.ts +14 -4
  198. package/src/server/management/oauth-account-routes.ts +17 -1
  199. package/src/server/management/provider-overwrite-carry.ts +164 -0
  200. package/src/server/management/provider-routes.ts +36 -6
  201. package/src/server/management/remote-workspace-routes.ts +2 -2
  202. package/src/server/management/route-registry.ts +2 -0
  203. package/src/server/management/shadow-call-validation.ts +39 -0
  204. package/src/server/management/system-restart.ts +72 -6
  205. package/src/server/management-api.ts +16 -2
  206. package/src/server/management-auth.ts +52 -8
  207. package/src/server/proxy-liveness.ts +110 -4
  208. package/src/server/request-log.ts +26 -9
  209. package/src/server/request-metrics.ts +5 -0
  210. package/src/server/responses/adapter-continuation.ts +6 -3
  211. package/src/server/responses/adapter-dispatch.ts +65 -1
  212. package/src/server/responses/compact.ts +31 -1
  213. package/src/server/responses/compaction-routing.ts +28 -3
  214. package/src/server/responses/core-codex-account.ts +85 -26
  215. package/src/server/responses/core-combo-failure.ts +16 -15
  216. package/src/server/responses/core-normalize.ts +5 -1
  217. package/src/server/responses/core-opaque-recovery.ts +50 -2
  218. package/src/server/responses/core-options.ts +2 -0
  219. package/src/server/responses/core-replay.ts +7 -0
  220. package/src/server/responses/core.ts +1 -1
  221. package/src/server/responses/encrypted-payload.ts +23 -9
  222. package/src/server/responses/passthrough-delivery.ts +55 -35
  223. package/src/server/responses/passthrough-dispatch.ts +12 -13
  224. package/src/server/responses/policy-fallback.ts +12 -1
  225. package/src/server/responses/request-prepare.ts +46 -7
  226. package/src/server/responses/request-spend.ts +31 -15
  227. package/src/server/responses/run-turn-execution.ts +6 -5
  228. package/src/server/responses/shadow-target-availability.ts +61 -0
  229. package/src/server/responses-custom-tool-repair.ts +2 -0
  230. package/src/service/claim.ts +185 -0
  231. package/src/service/cli.ts +10 -1
  232. package/src/service/guarded-manager-target.ts +151 -0
  233. package/src/service/guards.ts +47 -48
  234. package/src/service/managing-cli.ts +170 -0
  235. package/src/service/orchestration.ts +3 -1
  236. package/src/service/state.ts +4 -0
  237. package/src/service/systemd.ts +16 -1
  238. package/src/service.ts +1 -1
  239. package/src/types/config.ts +8 -0
  240. package/src/types/provider.ts +16 -0
  241. package/src/types/request.ts +10 -0
  242. package/src/types/tools.ts +9 -1
  243. package/src/types/wire.ts +68 -4
  244. package/src/types.ts +1 -0
  245. package/src/update/job.ts +10 -16
  246. package/src/update/npm-invocation.mjs +17 -16
  247. package/src/update/transactional-install.d.mts +22 -1
  248. package/src/update/transactional-install.mjs +176 -19
  249. package/src/update/update-failure-guidance.d.mts +8 -0
  250. package/src/update/update-failure-guidance.mjs +47 -0
  251. package/src/usage/expected-prices.ts +54 -12
  252. package/src/usage/log.ts +117 -3
  253. package/src/usage/telemetry-contract.ts +1 -0
  254. package/src/usage/timeline.ts +34 -6
  255. package/src/usage/user-cost-overlay-reconciler.ts +3 -3
  256. package/src/vision/reasoning.ts +2 -4
  257. package/src/web-search/xai-executor.ts +14 -4
  258. package/gui/dist/assets/App-BqrsSrIR.js +0 -50
  259. package/gui/dist/assets/index-C6SJrh0N.js +0 -86
  260. package/gui/dist/assets/index-DdDunwDb.css +0 -1
  261. package/gui/dist/assets/usage-companion-chart-CzAAAB1o.js +0 -1
  262. package/src/adapters/kiro-thinking.ts +0 -112
@@ -12,8 +12,8 @@
12
12
  * fallback ladder, so the Codex catalog AND the wire clamp agree with the model instead of a
13
13
  * hand-written guess.
14
14
  *
15
- * Failure policy: the network is never on the critical path. A missing, stale or corrupt
16
- * snapshot yields undefined, which leaves every hand-written contract untouched. The second
15
+ * Failure policy: a missing or corrupt snapshot yields undefined, and an expired snapshot still
16
+ * serves its last ladder while a best-effort refresh runs in the background. The second
17
17
  * cache records rungs the upstream actually rejected (400/403 naming reasoning_effort), so an
18
18
  * entitlement gap (muse-spark max needs an active Muse Code subscription) costs one rejected
19
19
  * request instead of failing every turn that selects that rung.
@@ -137,6 +137,11 @@ function metadataProviderKey(provider: OcxProviderConfig): string | undefined {
137
137
  return undefined;
138
138
  }
139
139
 
140
+ /** Whether catalog sync should bootstrap metadata for this destination. */
141
+ export function providerUsesReasoningMetadata(provider: OcxProviderConfig): boolean {
142
+ return metadataProviderKey(provider) !== undefined;
143
+ }
144
+
140
145
  /**
141
146
  * Local mirror of `modelRecordValue()` from `src/reasoning-effort.ts`, which imports this
142
147
  * module and so cannot be imported back. Exact id, then the `family:` prefix, then a
@@ -487,19 +492,36 @@ export function planReasoningEffortDowngrade(args: {
487
492
  * kept so the gate can be checked against real data and widened without another format change.
488
493
  * Non-reasoning models carry no ladder and are dropped.
489
494
  */
490
- export async function refreshReasoningMetadata(options: { force?: boolean } = {}): Promise<{
495
+ type RefreshOutcome = {
491
496
  ok: boolean;
492
497
  reason: string;
493
498
  providers?: number;
494
499
  models?: number;
495
- }> {
500
+ };
501
+
502
+ /** Bound a caller's wait without cancelling the shared refresh job. */
503
+ function waitForRefresh(work: Promise<RefreshOutcome>, waitMs: number | undefined): Promise<RefreshOutcome> {
504
+ if (waitMs === undefined) return work;
505
+ if (!Number.isSafeInteger(waitMs) || waitMs < 0) {
506
+ return Promise.resolve({ ok: false, reason: "invalid wait budget" });
507
+ }
508
+ let timer: ReturnType<typeof setTimeout> | undefined;
509
+ const deadline = new Promise<RefreshOutcome>(resolve => {
510
+ timer = setTimeout(() => resolve({ ok: false, reason: "wait budget exceeded" }), waitMs);
511
+ timer.unref?.();
512
+ });
513
+ return Promise.race([work, deadline]).finally(() => {
514
+ if (timer) clearTimeout(timer);
515
+ });
516
+ }
517
+
518
+ export async function refreshReasoningMetadata(options: { force?: boolean; waitMs?: number } = {}): Promise<RefreshOutcome> {
496
519
  const snapshot = loadSnapshot();
497
520
  if (!options.force && snapshot && Date.now() - snapshot.fetchedAt <= CACHE_TTL_MS) {
498
521
  return { ok: true, reason: "fresh" };
499
522
  }
500
523
  if (refreshInFlight) {
501
- await refreshInFlight;
502
- return { ok: true, reason: "coalesced" };
524
+ return waitForRefresh(refreshInFlight.then(() => ({ ok: true, reason: "coalesced" })), options.waitMs);
503
525
  }
504
526
  const job = (async () => {
505
527
  const response = await fetch(SOURCE_URL, {
@@ -548,21 +570,22 @@ export async function refreshReasoningMetadata(options: { force?: boolean } = {}
548
570
  return { ok: true, reason: "refreshed", providers: Object.keys(providers).length, models };
549
571
  })();
550
572
  refreshInFlight = job.catch(() => undefined).finally(() => { refreshInFlight = null; });
551
- try {
552
- return await job;
553
- } catch (error) {
554
- return { ok: false, reason: error instanceof Error ? error.message : String(error) };
555
- }
573
+ const settled = job.catch((error): RefreshOutcome => ({
574
+ ok: false,
575
+ reason: error instanceof Error ? error.message : String(error),
576
+ }));
577
+ return waitForRefresh(settled, options.waitMs);
556
578
  }
557
579
 
558
580
  /**
559
- * Kick a background refresh when the snapshot is missing or stale. Called from the ladder read
560
- * path so both the long-lived proxy and short-lived ocx sync self-heal without a new CLI
561
- * surface. One refresh per process at a time; failures are ignored on purpose.
581
+ * Optional background refresh for callers that do not wait for a snapshot. Catalog sync uses
582
+ * refreshReasoningMetadata with a bounded wait; an expired ladder read can request this refresh.
583
+ * A classified toggle/budget model can have a fallback ladder without any snapshot, so this
584
+ * path must never bootstrap a missing snapshot. One refresh per process; failures are ignored.
562
585
  */
563
586
  export function ensureReasoningMetadataSnapshot(): void {
564
587
  const snapshot = loadSnapshot();
565
- if (snapshot && Date.now() - snapshot.fetchedAt <= CACHE_TTL_MS) return;
588
+ if (!snapshot || Date.now() - snapshot.fetchedAt <= CACHE_TTL_MS) return;
566
589
  if (refreshInFlight) return;
567
590
  void refreshReasoningMetadata().catch(() => undefined);
568
591
  }
@@ -14,6 +14,7 @@ import { cursorFastCapableBases } from "../../adapters/cursor/catalog";
14
14
  import { COMMAND_CODE_MODEL_REASONING_EFFORTS } from "../command-code-efforts";
15
15
  import { isCanonicalOpenRouterTarget } from "../openrouter-routing";
16
16
  import type { ProviderRegistryEntry } from "./types";
17
+ import { ANTHROPIC_FAST_MODE_BETA } from "../anthropic-fast";
17
18
  import {
18
19
  ANTHROPIC_MODELS,
19
20
  ANTHROPIC_MODEL_CONTEXT_WINDOWS,
@@ -52,6 +53,7 @@ import {
52
53
  DEEPSEEK_NATIVE_THINKING_MODELS,
53
54
  DEEPSEEK_GATEWAY_THINKING_MODELS,
54
55
  DEEPSEEK_VISION_PREVIEW_MODEL,
56
+ COMMAND_CODE_MIMO_CONTEXT_WINDOWS,
55
57
  COMMAND_CODE_MODEL_INPUT_MODALITIES,
56
58
  deepseekThinkingEffortsFor,
57
59
  deepseekReasoningMapFor,
@@ -85,6 +87,27 @@ import {
85
87
  CLINE_PASS_MODEL_INPUT_MODALITIES,
86
88
  } from "./model-seeds";
87
89
 
90
+ /**
91
+ * Claude fast mode (`speed: "fast"` + beta), shared by the OAuth and API-key Anthropic entries.
92
+ * Only the models Anthropic documents for the lane are classified; Opus 4.6 silently runs
93
+ * standard and Opus 4.7, Sonnet, Haiku and Fable reject `speed`, so they and future ids stay
94
+ * unclassified. Source: https://platform.claude.com/docs/en/build-with-claude/fast-mode
95
+ * (2026-09-23) and the live probe in devlog/_plan/260923_anthropic_fast_speed.
96
+ */
97
+ const ANTHROPIC_FAST_WIRE = Object.freeze({
98
+ kind: "anthropic-speed" as const,
99
+ canonicalToWire: Object.freeze({ priority: "fast" }),
100
+ foreignCallerTiers: "drop" as const,
101
+ betas: Object.freeze([ANTHROPIC_FAST_MODE_BETA]),
102
+ });
103
+ const ANTHROPIC_FAST_MODELS: Readonly<Record<string, boolean>> = Object.freeze({
104
+ "claude-opus-5-5": true,
105
+ "claude-opus-5": true,
106
+ "claude-opus-4-8": true,
107
+ });
108
+ const ANTHROPIC_FAST_TIER_DESCRIPTION =
109
+ "Claude fast mode: faster output at 2x price; needs usage credits (subscription) or fast-mode access (API)";
110
+
88
111
  export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
89
112
  {
90
113
  id: "openai",
@@ -167,7 +190,7 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
167
190
  // (it is the current catalog, so its default ordering wins), then the ids
168
191
  // only the old devin entry carried. Degraded-mode seed only either way —
169
192
  // `liveModels` discovers the account's real roster.
170
- models: ["swe-2", "swe-1-7", "gpt-5-6-sol", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", "claude-opus-5-5", "claude-opus-5", "claude-fable-5-1", "claude-sonnet-5", "glm-5-3", "kimi-k3", "gemini-3-8-flash", "grok-4-6", "swe-1-7-lightning", "gpt-5-6-luna", "gpt-5-6-terra", "claude-opus-4-8", "glm-5-2", "kimi-k2-7", "grok-4-5"],
193
+ models: ["swe-2", "swe-1-7", "gpt-5-6-sol", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", "claude-opus-5-5", "claude-opus-5", "claude-fable-5-1", "claude-sonnet-5", "glm-5-3", "kimi-k3", "gemini-3-8-flash", "grok-4-6", "grok-4-7", "swe-1-7-lightning", "gpt-5-6-luna", "gpt-5-6-terra", "claude-opus-4-8", "glm-5-2", "kimi-k2-7", "grok-4-5"],
171
194
  liveModels: true,
172
195
  defaultModel: "swe-2",
173
196
  modelContextWindows: DEVIN_MODEL_CONTEXT_WINDOWS,
@@ -198,7 +221,10 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
198
221
  // the OAuth lane. grok-4.20-multi-agent-0309 is deliberately absent: the gateway accepts
199
222
  // the field but answers service_tier "default" — a live downgrade, not a fast tier.
200
223
  // Unlisted and future-discovered ids stay unclassified.
224
+ // grok-4.7 applied and confirmed priority on OAuth Responses in the 2026-09-23
225
+ // live probe: devlog/_plan/260923_grok47_parity/010_probe-evidence.md.
201
226
  modelSupportsServiceTier: {
227
+ "grok-4.7": true,
202
228
  "grok-4.6": true,
203
229
  "grok-4.5": true,
204
230
  "grok-4.3": true,
@@ -253,14 +279,19 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
253
279
  // than the seeded ones do.
254
280
  supportsVerbosity: false,
255
281
  defaultModel: "grok-4.5",
256
- // Grok 4.6/4.5 subscription Responses callers use the native wire with the existing
282
+ // Grok 4.7/4.6/4.5 subscription Responses callers use the native wire with the existing
257
283
  // namespace/web-search/replay normalization. Chat remains an explicit modelAdapters
258
284
  // opt-in. Multi-agent has no Chat wire and uses Responses under both auth modes.
259
- // grok-4.6/4.5 are classified OAuth fast-tier models (modelSupportsServiceTier above),
285
+ // grok-4.7/4.6/4.5 are classified OAuth fast-tier models (modelSupportsServiceTier above),
260
286
  // so a caller-sent service_tier:"priority" forwards on this lane — the Codex fast-toggle
261
287
  // path. Multi-agent keeps its pin: probed 2026-09-13, the gateway downgrades its tier to
262
288
  // "default", so forwarding a caller tier would advertise a tier it does not get.
263
289
  modelWireDefaults: {
290
+ "grok-4.7": {
291
+ wire: "openai-responses",
292
+ inbound: ["responses"],
293
+ authModes: ["oauth"],
294
+ },
264
295
  "grok-4.6": {
265
296
  wire: "openai-responses",
266
297
  inbound: ["responses"],
@@ -303,6 +334,7 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
303
334
  // the app blocks attachments client-side. grok-build-0.1 / grok-composer-2.5-fast stay out
304
335
  // (they are already listed in noVisionModels below).
305
336
  modelInputModalities: {
337
+ "grok-4.7": ["text", "image"],
306
338
  "grok-4.6": ["text", "image"],
307
339
  "grok-4.5": ["text", "image"],
308
340
  "grok-4.3": ["text", "image"],
@@ -315,18 +347,24 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
315
347
  // reasoning_content as the top cause of prompt-cache misses on multi-turn conversations
316
348
  // (docs.x.ai prompt-caching/multi-turn, verified 2026-07-13 — devlog/_plan/260713_grok_caching).
317
349
  // Models that never emit reasoning simply have no thinking parts to replay (no-op).
318
- preserveReasoningContentModels: ["grok-4.6", "grok-4.5", "grok-4.3", "grok-4.20-0309-reasoning"],
350
+ preserveReasoningContentModels: ["grok-4.7", "grok-4.6", "grok-4.5", "grok-4.3", "grok-4.20-0309-reasoning"],
319
351
  // grok-4.5 reasoning is always-on with low/medium/high (no off tier, no xhigh).
320
352
  // grok-4.6 adds xhigh per docs.x.ai/developers/model-capabilities/text/reasoning;
321
353
  // multi-agent accepts the same four wire values to select 4 or 16 collaborators. xAI
322
354
  // documents high as the 4.6 default but no multi-agent default, so do not invent one.
323
355
  modelReasoningEfforts: {
356
+ // 2026-09-23 live probe accepted low..xhigh and rejected max on both wires;
357
+ // devlog/_plan/260923_grok47_parity/010_probe-evidence.md.
358
+ "grok-4.7": ["low", "medium", "high", "xhigh"],
324
359
  "grok-4.6": ["low", "medium", "high", "xhigh"],
325
360
  "grok-4.5": ["low", "medium", "high"],
326
361
  "grok-4.20-multi-agent-0309": ["low", "medium", "high", "xhigh"],
327
362
  },
328
- modelDefaultReasoningEfforts: { "grok-4.6": "high" },
363
+ modelDefaultReasoningEfforts: { "grok-4.7": "high", "grok-4.6": "high" },
329
364
  modelContextWindows: {
365
+ // 500k confirmed by context_length_exceeded:
366
+ // devlog/_plan/260923_grok47_parity/010_probe-evidence.md.
367
+ "grok-4.7": 500_000,
330
368
  "grok-4.6": 500_000,
331
369
  "grok-4.5": 500_000,
332
370
  "grok-4.3": 1_000_000,
@@ -363,6 +401,7 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
363
401
  // merge into deepseek-v4-flash later.
364
402
  modelContextWindows: {
365
403
  [`deepseek/${DEEPSEEK_VISION_PREVIEW_MODEL}`]: 1_048_576,
404
+ ...COMMAND_CODE_MIMO_CONTEXT_WINDOWS,
366
405
  },
367
406
  modelInputModalities: COMMAND_CODE_MODEL_INPUT_MODALITIES,
368
407
  defaultMaxOutputTokens: 64_000,
@@ -404,6 +443,12 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
404
443
  // falls back to 8192, which truncates long answers with stop_reason=max_tokens.
405
444
  defaultMaxOutputTokens: ANTHROPIC_DEFAULT_MAX_OUTPUT_TOKENS,
406
445
  defaultModel: "claude-sonnet-5",
446
+ // Claude fast mode on the subscription lane (Claude Code `/fast`): the OAuth route accepts
447
+ // `speed` and gates it on account entitlement (usage credits / org enablement), probed live
448
+ // 2026-09-23 (devlog/_plan/260923_anthropic_fast_speed/020_probe-evidence.md).
449
+ fastWire: ANTHROPIC_FAST_WIRE,
450
+ modelSupportsServiceTier: { ...ANTHROPIC_FAST_MODELS },
451
+ fastTierDescription: ANTHROPIC_FAST_TIER_DESCRIPTION,
407
452
  },
408
453
  {
409
454
  id: "anthropic-apikey",
@@ -423,6 +468,9 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
423
468
  modelReasoningEfforts: { ...ANTHROPIC_MODEL_REASONING_EFFORTS },
424
469
  defaultMaxOutputTokens: ANTHROPIC_DEFAULT_MAX_OUTPUT_TOKENS,
425
470
  defaultModel: "claude-sonnet-5",
471
+ fastWire: ANTHROPIC_FAST_WIRE,
472
+ modelSupportsServiceTier: { ...ANTHROPIC_FAST_MODELS },
473
+ fastTierDescription: ANTHROPIC_FAST_TIER_DESCRIPTION,
426
474
  },
427
475
  {
428
476
  id: "kimi",
@@ -466,6 +514,41 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
466
514
  autoToolChoiceOnlyModels: KIMI_AUTO_TOOL_CHOICE_ONLY_MODELS,
467
515
  preserveReasoningContentModels: KIMI_THINKING_MODELS,
468
516
  },
517
+ {
518
+ id: "kimi-responses",
519
+ label: "Kimi (Responses)",
520
+ adapter: "openai-responses",
521
+ baseUrl: "https://api.kimi.com/coding/v1",
522
+ authKind: "oauth",
523
+ modelSuffixBracketStrip: true,
524
+ // Same wire-capability defaults as the Chat preset. promptCacheKey is copied here
525
+ // deliberately even though only the Chat adapter reads it today: the field is a
526
+ // stable session/task key Kimi documents for cache affinity, and the Responses
527
+ // endpoint already accepts it (live probe 260921: prompt_cache_key round-trips 200).
528
+ promptCacheKey: true,
529
+ // Kimi's Responses endpoint rejects hook-provided context between a tool call and
530
+ // its matching result (#4726); the flag is live on this wire.
531
+ requiresAdjacentResponsesToolResults: true,
532
+ featured: false,
533
+ // Shares the kimi OAuth account: the login flow and credential store are keyed by
534
+ // oauthId, so adding this preset after logging into kimi needs no second login.
535
+ oauthId: "kimi",
536
+ jawcodeBundle: "moonshot",
537
+ note: "Same Kimi account login, routed over the OpenAI Responses wire. Thinking content stays encrypted server-side; tool calls and results stay visible. Chat wire remains the default preset for transparency.",
538
+ models: KIMI_CODING_LIVE_MODELS,
539
+ defaultModel: "kimi-for-coding",
540
+ modelContextWindows: KIMI_CODING_MODEL_CONTEXT_WINDOWS,
541
+ modelInputModalities: KIMI_CODING_MODEL_INPUT_MODALITIES,
542
+ noReasoningModels: KIMI_CODING_NO_REASONING_MODELS,
543
+ modelReasoningEfforts: KIMI_CODING_REASONING_EFFORTS,
544
+ modelDefaultReasoningEfforts: KIMI_CODING_DEFAULT_REASONING_EFFORTS,
545
+ modelReasoningEffortMap: KIMI_CODING_REASONING_EFFORT_MAPS,
546
+ noTemperatureModels: KIMI_LOCKED_PARAMETER_MODELS,
547
+ noTopPModels: KIMI_LOCKED_PARAMETER_MODELS,
548
+ noPenaltyModels: KIMI_LOCKED_PARAMETER_MODELS,
549
+ autoToolChoiceOnlyModels: KIMI_AUTO_TOOL_CHOICE_ONLY_MODELS,
550
+ preserveReasoningContentModels: KIMI_THINKING_MODELS,
551
+ },
469
552
  {
470
553
  id: "kiro",
471
554
  label: "Kiro (AWS CodeWhisperer)",
@@ -680,7 +763,7 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
680
763
  // Use explicit replay history and the existing stateless Responses policy.
681
764
  statelessResponses: true,
682
765
  /* [Decision Log]
683
- - 목적과 의도: Route the exact models OpenCode Go documents on the Responses endpoint — GPT 5.6 Luna, Grok 4.6, and Muse Spark Contributor (#2617).
766
+ - 목적과 의도: Route the exact models OpenCode Go documents on the Responses endpoint — GPT 5.6 Luna, Grok 4.6/4.7, and Muse Spark Contributor (#2617; opencode.ai/docs/go).
684
767
  - 기존 구현 및 제약 조건: The provider is mixed-wire but its provider-wide `openai-chat` adapter sent Luna to `/chat/completions`; explicit user `modelAdapters` entries must remain authoritative.
685
768
  - 검토한 주요 대안: Change the whole provider to Responses; infer the wire from model-family names; add one registry-only exact-model default.
686
769
  - 선택한 방식: Declare only the named models as `openai-responses` through the existing registry default mechanism; the map stays an exact-model allowlist rather than a family or provider-wide rule.
@@ -690,6 +773,7 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
690
773
  modelWireDefaults: {
691
774
  "gpt-5.6-luna": "openai-responses",
692
775
  "grok-4.6": "openai-responses",
776
+ "grok-4.7": "openai-responses",
693
777
  "muse-spark-1.3-contributor": "openai-responses",
694
778
  "muse-spark-1.2-contributor": "openai-responses",
695
779
  },
@@ -750,6 +834,7 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
750
834
  modelReasoningEfforts: {
751
835
  "gpt-5.6-luna": OPENAI_API_GPT56_REASONING_EFFORTS,
752
836
  "grok-4.6": ["low", "medium", "high", "xhigh"],
837
+ "grok-4.7": ["low", "medium", "high", "xhigh"],
753
838
  "glm-5.3": ZAI_GLM_53_REASONING_EFFORTS,
754
839
  "glm-5.3-flash": ZAI_GLM_53_REASONING_EFFORTS,
755
840
  "glm-5.2": ZAI_GLM_52_REASONING_EFFORTS,
@@ -761,7 +846,7 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
761
846
  ...Object.fromEntries(OPENCODE_GO_THINKING_BUDGET_MODELS.map(id => [id, THINKING_BUDGET_EFFORTS])),
762
847
  ...Object.fromEntries(DEEPSEEK_GATEWAY_THINKING_MODELS.map(id => [id, deepseekThinkingEffortsFor(id)])),
763
848
  },
764
- modelDefaultReasoningEfforts: { "grok-4.6": "high", "kimi-k3": "max" },
849
+ modelDefaultReasoningEfforts: { "grok-4.6": "high", "grok-4.7": "high", "kimi-k3": "max" },
765
850
  // glm-5.2 uses identity labels now that `max` is a native Codex level (no alias map);
766
851
  // the thinking-toggle map is a REAL wire alias (effort -> enabled/disabled) and stays.
767
852
  modelReasoningEffortMap: {
@@ -797,6 +882,9 @@ export const PROVIDER_REGISTRY_CORE: readonly ProviderRegistryEntry[] = [
797
882
  // deepseek-v4-flash stays listed — that route rejects image_url upstream.
798
883
  "deepseek-v4-flash",
799
884
  "mimo-v2-pro", "mimo-v2.5-pro",
885
+ // V2.6 is multimodal first-party, but image forwarding on this gateway is unprobed:
886
+ // the sidecar describes images until a route probe proves native input.
887
+ "mimo-v2.6-pro", "mimo-v2.6-flash",
800
888
  "minimax-m2.5", "minimax-m2.7",
801
889
  "qwen3.7-max",
802
890
  ],
@@ -47,6 +47,7 @@ import {
47
47
  DEEPSEEK_V4_LEGACY_MODELS,
48
48
  DEEPSEEK_GATEWAY_THINKING_MODELS,
49
49
  DEEPSEEK_VISION_PREVIEW_MODEL,
50
+ COMMAND_CODE_MIMO_CONTEXT_WINDOWS,
50
51
  COMMAND_CODE_MODEL_INPUT_MODALITIES,
51
52
  OPENCODE_FREE_DEEPSEEK_MODELS,
52
53
  OPENCODE_ZEN_TEXT_ONLY_MODELS,
@@ -170,6 +171,7 @@ export const PROVIDER_REGISTRY_EXTENDED: readonly ProviderRegistryEntry[] = [
170
171
  // (merges into v4-flash later).
171
172
  modelContextWindows: {
172
173
  [`deepseek/${DEEPSEEK_VISION_PREVIEW_MODEL}`]: 1_048_576,
174
+ ...COMMAND_CODE_MIMO_CONTEXT_WINDOWS,
173
175
  },
174
176
  modelInputModalities: COMMAND_CODE_MODEL_INPUT_MODALITIES,
175
177
  modelDiscovery: {
@@ -1139,7 +1141,11 @@ export const PROVIDER_REGISTRY_EXTENDED: readonly ProviderRegistryEntry[] = [
1139
1141
  // narrower table that silently falls behind whenever the keyed one is updated.
1140
1142
  noJsonSchemaModels: [...DEEPSEEK_GATEWAY_THINKING_MODELS, ...OPENCODE_FREE_DEEPSEEK_MODELS],
1141
1143
  },
1142
- { id: "xiaomi", label: "Xiaomi MiMo", baseUrl: "https://api.xiaomimimo.com/anthropic", adapter: "anthropic", authKind: "key", dashboardUrl: "https://xiaomimimo.com", defaultModel: "mimo-v2.5-pro" },
1144
+ // Xiaomi retires mimo-v2.5 and mimo-v2.5-pro on 2026-10-21 with no redirect
1145
+ // (https://mimo.mi.com/docs/en-US/updates/deprecate), so the first-party presets default to V2.6.
1146
+ // Saved defaults are not rewritten; V2.5 stays listed until it stops answering.
1147
+ // Both first-party presets read the xiaomi metadata bundle for window, output, modalities and price.
1148
+ { id: "xiaomi", label: "Xiaomi MiMo", baseUrl: "https://api.xiaomimimo.com/anthropic", adapter: "anthropic", authKind: "key", dashboardUrl: "https://xiaomimimo.com", defaultModel: "mimo-v2.6-pro", models: ["mimo-v2.6-pro", "mimo-v2.6-flash", "mimo-v2.6-pro-ultraspeed", "mimo-v2.5-pro", "mimo-v2.5"], jawcodeBundle: "xiaomi" },
1143
1149
  // Xiaomi's public OpenAI-compatible endpoint is a distinct transport from both the Anthropic
1144
1150
  // preset above and the paid token-plan host below. Keep a separate fixed-destination contract
1145
1151
  // so existing custom providers are never retargeted while the official route receives the
@@ -1151,8 +1157,9 @@ export const PROVIDER_REGISTRY_EXTENDED: readonly ProviderRegistryEntry[] = [
1151
1157
  adapter: "openai-chat",
1152
1158
  authKind: "key",
1153
1159
  dashboardUrl: "https://platform.xiaomimimo.com/console/balance",
1154
- defaultModel: "mimo-v2.5",
1155
- models: ["mimo-v2.5"],
1160
+ defaultModel: "mimo-v2.6-flash",
1161
+ models: ["mimo-v2.6-flash", "mimo-v2.6-pro", "mimo-v2.6-pro-ultraspeed", "mimo-v2.5"],
1162
+ jawcodeBundle: "xiaomi",
1156
1163
  reasoningEfforts: ["low", "medium", "high"],
1157
1164
  reasoningEffortMap: { xhigh: "high", max: "high", ultra: "high" },
1158
1165
  preserveCustomDestination: true,
@@ -1192,8 +1199,11 @@ export const PROVIDER_REGISTRY_EXTENDED: readonly ProviderRegistryEntry[] = [
1192
1199
  adapter: "openai-chat",
1193
1200
  authKind: "key",
1194
1201
  dashboardUrl: "https://xiaomimimo.com",
1195
- defaultModel: "mimo-v2.5-pro",
1196
- models: ["mimo-v2.5-pro", "mimo-v2.5"],
1202
+ // Token-plan roster per Xiaomi's token-plan model list (V2.6 Pro and Flash). No jawcodeBundle,
1203
+ // so no plan-specific facts are claimed; usage estimates still come from the model-level vendor
1204
+ // price fallback (the pay-as-you-go equivalent), exactly as they did for V2.5.
1205
+ defaultModel: "mimo-v2.6-pro",
1206
+ models: ["mimo-v2.6-pro", "mimo-v2.6-flash", "mimo-v2.5-pro", "mimo-v2.5"],
1197
1207
  // The gateway validates the ladder strictly and rejects anything above `high`.
1198
1208
  reasoningEfforts: ["low", "medium", "high"],
1199
1209
  reasoningEffortMap: { xhigh: "high", max: "high", ultra: "high" },
@@ -1324,9 +1334,10 @@ export const PROVIDER_REGISTRY_EXTENDED: readonly ProviderRegistryEntry[] = [
1324
1334
  // private console endpoint — the approach closed in #687 and left in draft in #2244.
1325
1335
  // baseUrl is the canonical region identity: the adapter fails closed if it is overridden, so a
1326
1336
  // global key is never sent to the CN environment (that is the separate `codebuddy-cn` entry).
1327
- // v1 runs tools-disabled so Codex keeps tool ownership; this provider is text/reasoning only
1328
- // until the control-protocol tool bridge lands (see docs). Free/trial/promotional/subscription
1329
- // credits draw from the same official API-key pool. Requires the CLI: `npm i -g @tencent-ai/codebuddy-code`.
1337
+ // The CLI always runs tools-disabled; a capture-only MCP bridge advertises the request's
1338
+ // Codex tool catalog, so approval, sandboxing, and execution stay with the client.
1339
+ // Free/trial/promotional/subscription credits draw from the same official API-key pool.
1340
+ // Requires the CLI: `npm i -g @tencent-ai/codebuddy-code`.
1330
1341
  // GOVERNANCE: whether routing this vendor automation surface behind a proxy for a third-party
1331
1342
  // agent satisfies CodeBuddy's AUP is an open question flagged for maintainer security review.
1332
1343
  id: "codebuddy",
@@ -1346,7 +1357,7 @@ export const PROVIDER_REGISTRY_EXTENDED: readonly ProviderRegistryEntry[] = [
1346
1357
  reasoningEfforts: CODEBUDDY_REASONING_EFFORTS,
1347
1358
  modelReasoningEfforts: CODEBUDDY_GLOBAL_MODEL_REASONING_EFFORTS,
1348
1359
  modelDefaultReasoningEfforts: CODEBUDDY_GLOBAL_MODEL_DEFAULT_REASONING_EFFORTS,
1349
- note: "Official CodeBuddy Code CLI (Tencent Cloud), global/public environment. Uses the documented CODEBUDDY_API_KEY + headless CLI surface; never reads desktop sessions or private console endpoints. Region-isolated from codebuddy-cn. v1 disables CLI tools (--tools \"\") so Codex retains tool ownership: text/reasoning only for now. Requires `npm i -g @tencent-ai/codebuddy-code`. AUP/routing authorization flagged for maintainer security review.",
1360
+ note: "Official CodeBuddy Code CLI (Tencent Cloud), global/public environment. Uses the documented CODEBUDDY_API_KEY + headless CLI surface; never reads desktop sessions or private console endpoints. Region-isolated from codebuddy-cn. The CLI always runs tools-disabled (--tools \"\"); a capture-only MCP bridge surfaces the request's Codex tool catalog as capturable calls, with approval and execution kept by the client. Requires `npm i -g @tencent-ai/codebuddy-code`. AUP/routing authorization flagged for maintainer security review.",
1350
1361
  },
1351
1362
  {
1352
1363
  // Official CodeBuddy Code CLI provider, CHINA / `internal` environment. Identical adapter and
@@ -1371,7 +1382,7 @@ export const PROVIDER_REGISTRY_EXTENDED: readonly ProviderRegistryEntry[] = [
1371
1382
  modelReasoningEfforts: CODEBUDDY_CN_MODEL_REASONING_EFFORTS,
1372
1383
  modelDefaultReasoningEfforts: CODEBUDDY_CN_MODEL_DEFAULT_REASONING_EFFORTS,
1373
1384
  noVisionModels: CODEBUDDY_CN_NO_VISION_MODELS,
1374
- note: "Official CodeBuddy Code CLI (Tencent Cloud), China/internal environment. Uses the documented CODEBUDDY_API_KEY + headless CLI surface; never reads desktop sessions or private console endpoints. Region-isolated from codebuddy (Global); credentials are never exchanged across regions. v1 disables CLI tools (--tools \"\"): text/reasoning only for now. Requires `npm i -g @tencent-ai/codebuddy-code`. AUP/routing authorization flagged for maintainer security review.",
1385
+ note: "Official CodeBuddy Code CLI (Tencent Cloud), China/internal environment. Uses the documented CODEBUDDY_API_KEY + headless CLI surface; never reads desktop sessions or private console endpoints. Region-isolated from codebuddy (Global); credentials are never exchanged across regions. The CLI always runs tools-disabled (--tools \"\"); a capture-only MCP bridge surfaces the request's Codex tool catalog as capturable calls, with approval and execution kept by the client. Requires `npm i -g @tencent-ai/codebuddy-code`. AUP/routing authorization flagged for maintainer security review.",
1375
1386
  },
1376
1387
  {
1377
1388
  id: "stepfun",
@@ -118,6 +118,7 @@ export const REGISTRY_FIELD_MODEL_ID_ROLES = {
118
118
  requiresReasoningPlaceholderModels: NONE,
119
119
  showThinkingSummary: NONE,
120
120
  reasoningSplitModels: NONE,
121
+ inlineThinkTagModels: NONE,
121
122
  reasoningDetailsModels: NONE,
122
123
  thinkingToggleModels: NONE,
123
124
  thinkingBudgetModels: NONE,
@@ -231,6 +231,7 @@ export const OPENAI_DAYBREAK_REASONING_EFFORTS: Record<string, string[]> = Objec
231
231
  );
232
232
  export const OPENROUTER_GPT56_MODELS = OPENAI_GPT56_MODELS.map(id => `openai/${id}`);
233
233
  export const XAI_MODELS = [
234
+ "grok-4.7",
234
235
  "grok-4.6",
235
236
  "grok-4.5",
236
237
  "grok-4.3",
@@ -270,6 +271,8 @@ export const THINKING_TOGGLE_MAP: Record<string, string> = {
270
271
  };
271
272
  export const OPENCODE_GO_THINKING_TOGGLE_MODELS = [
272
273
  "mimo-v2.5", "mimo-v2.5-pro", "glm-5", "glm-5.1",
274
+ // V2.6 keeps the vendor's thinking toggle; listed ahead of a Go probe (preemptive, 2026-09-23).
275
+ "mimo-v2.6-pro", "mimo-v2.6-flash",
273
276
  ];
274
277
  /**
275
278
  * Zhipu's domestic BigModel platform. Text families first, then the vision member: modalities are
@@ -329,7 +332,7 @@ export const DEEPSEEK_VISION_PREVIEW_MODEL = "deepseek-v4-flash-vision-exp";
329
332
  * CommandCode routes verified to accept image input end-to-end (#2406).
330
333
  *
331
334
  * Verified-negative and therefore deliberately ABSENT: deepseek/deepseek-v4-flash,
332
- * zai-org/GLM-5.2, zai-org/GLM-5.3, xai/grok-4.6. Those
335
+ * zai-org/GLM-5.2, zai-org/GLM-5.3. Those
333
336
  * routes accept the request and drop the image, which is worse than declining it — the
334
337
  * model answers about an image it never saw. Do not add an id here on family resemblance;
335
338
  * capability intersection trusts this map.
@@ -351,10 +354,16 @@ export const COMMAND_CODE_IMAGE_MODELS = [
351
354
  "meta/muse-spark-1.3-contributor",
352
355
  "meta/muse-spark-1.2",
353
356
  "meta/muse-spark-1.2-contributor",
357
+ // Live 2026-09-23 3x3 random-color grid (180x180) via ocx 2.62.0:
358
+ // 4.7 read 9/9 in user messages and tool results; 4.6 read 9/9 and 8/9.
359
+ // Neither route requested a vision sidecar. Evidence:
360
+ // devlog/_plan/260923_grok47_parity/010_probe-evidence.md.
361
+ "xai/grok-4.6",
362
+ "xai/grok-4.7",
354
363
  // Native Z.AI VLM (docs.z.ai/guides/vlm/glm-5.3-flash). This exact id is already
355
364
  // classified as natively vision-capable in NVIDIA_NIM_VISION_MODELS in this file;
356
365
  // it is not one of the verified-negative ids the header names (those are
357
- // deepseek/deepseek-v4-flash, zai-org/GLM-5.2, zai-org/GLM-5.3, xai/grok-4.6 —
366
+ // deepseek/deepseek-v4-flash, zai-org/GLM-5.2, zai-org/GLM-5.3 —
358
367
  // different ids). Adding it on the shared GLM-5.3 prefix would be the family-
359
368
  // resemblance mistake the header forbids; the VLM docs are the evidence (#4505).
360
369
  "z-ai/glm-5.3-flash",
@@ -374,6 +383,19 @@ export const COMMAND_CODE_IMAGE_MODELS = [
374
383
  * the user-message and tool-result paths (see the note at that entry). The
375
384
  * mechanism stays for the next route that measures text-only.
376
385
  */
386
+ /**
387
+ * Command Code MiMo context windows from the live /provider/v1/models catalog (2026-09-23 fixture,
388
+ * tests/fixtures/commandcode-models.json). Model-keyed registry facts double as the router's native
389
+ * decode ids, so a cold start or failed discovery still turns `command-code/xiaomi-mimo-v2.6-pro`
390
+ * into `xiaomi/mimo-v2.6-pro` instead of sending the flattened slug upstream. They are not a roster.
391
+ */
392
+ export const COMMAND_CODE_MIMO_CONTEXT_WINDOWS: Record<string, number> = {
393
+ "xiaomi/mimo-v2.6-pro": 1_048_576,
394
+ "xiaomi/mimo-v2.6-pro-ultraspeed": 1_048_576,
395
+ "xiaomi/mimo-v2.6-flash": 1_048_576,
396
+ "xiaomi/mimo-v2.5-pro": 1_000_000,
397
+ "xiaomi/mimo-v2.5": 1_000_000,
398
+ };
377
399
  export const COMMAND_CODE_TEXT_ONLY_MODELS = [] as const;
378
400
  export const COMMAND_CODE_MODEL_INPUT_MODALITIES: Record<string, ["text"] | ["text", "image"]> = {
379
401
  ...Object.fromEntries(COMMAND_CODE_IMAGE_MODELS.map(id => [id, ["text", "image"] as ["text", "image"]])),
@@ -649,11 +671,13 @@ export const ALIBABA_TOKEN_PLAN_PRESERVE_REASONING = [
649
671
  // entitlement tiers. Bare `k3` advertises the Moderato 256K ceiling; the local `[1m]`
650
672
  // alias advertises Allegretto's 1M ceiling and is stripped before the upstream request.
651
673
  // The separately billed Moonshot API uses `kimi-k3`.
674
+ // 260921: `k3-256k` is the same K3 served under the explicit ceiling id (verified live
675
+ // 260921: same 988-token scaffold and identity answer as bare `k3` on the same input).
652
676
  // Evidence: https://www.kimi.com/code/docs/en/kimi-code/models.html
653
677
  // https://www.kimi.com/code/docs/en/kimi-code/error-reference.html
654
678
  export const KIMI_K3_STANDARD_CONTEXT_WINDOW = 262_144;
655
679
  export const KIMI_K3_1M_CONTEXT_WINDOW = 1_048_576;
656
- export const KIMI_CODING_K3_MODELS = ["k3", "k3[1m]"];
680
+ export const KIMI_CODING_K3_MODELS = ["k3", "k3[1m]", "k3-256k"];
657
681
  // 260921 Kimi K2.8: `kimi-for-coding` is the stable subscription alias Moonshot re-points
658
682
  // at each coding release. Live GET /coding/v1/models lists only kimi-for-coding[-highspeed],
659
683
  // k3, k3-256k — the k2.x ids are retired from the subscription endpoint. Since K2.8 Preview
@@ -940,6 +964,8 @@ export const CLINE_PASS_MODELS = [
940
964
  "cline-pass/kimi-k2.7-code",
941
965
  "cline-pass/kimi-k2.6",
942
966
  "cline-pass/deepseek-v4-flash",
967
+ "cline-pass/mimo-v2.6-pro",
968
+ "cline-pass/mimo-v2.6-flash",
943
969
  "cline-pass/mimo-v2.5",
944
970
  "cline-pass/mimo-v2.5-pro",
945
971
  "cline-pass/minimax-m3",
@@ -988,6 +1014,8 @@ export const CLINE_PASS_MODEL_CONTEXT_WINDOWS: Record<string, number> = {
988
1014
  "cline-pass/kimi-k2.7-code": 262_144,
989
1015
  "cline-pass/kimi-k2.6": 262_144,
990
1016
  "cline-pass/deepseek-v4-flash": 1_048_576,
1017
+ "cline-pass/mimo-v2.6-pro": 1_048_576,
1018
+ "cline-pass/mimo-v2.6-flash": 1_048_576,
991
1019
  "cline-pass/mimo-v2.5": 1_050_000,
992
1020
  "cline-pass/mimo-v2.5-pro": 1_050_000,
993
1021
  "cline-pass/minimax-m3": 1_048_576,
@@ -335,6 +335,8 @@ export interface ProviderRegistryEntry {
335
335
  */
336
336
  showThinkingSummary?: boolean;
337
337
  reasoningSplitModels?: string[];
338
+ /** See OcxProviderConfig.inlineThinkTagModels. */
339
+ inlineThinkTagModels?: string[];
338
340
  reasoningDetailsModels?: string[];
339
341
  thinkingToggleModels?: string[];
340
342
  thinkingBudgetModels?: string[];
@@ -358,6 +360,6 @@ export type ProviderConfigSeed = Pick<
358
360
  | "modelMaxInputTokens" | "defaultMaxOutputTokens" | "modelMaxOutputTokens"
359
361
  | "reasoningEfforts" | "modelReasoningEfforts" | "modelDefaultReasoningEfforts" | "reasoningEffortMap" | "modelReasoningEffortMap" | "reasoningWireFormat"
360
362
  | "noVisionModels" | "noReasoningModels" | "noTemperatureModels" | "noTopPModels" | "noPenaltyModels"
361
- | "autoToolChoiceOnlyModels" | "preserveReasoningContentModels" | "requiresReasoningPlaceholderModels" | "reasoningSplitModels" | "reasoningDetailsModels" | "thinkingToggleModels" | "thinkingBudgetModels" | "escapeBuiltinToolNames" | "openaiChatEofTolerance" | "showThinkingSummary"
363
+ | "autoToolChoiceOnlyModels" | "preserveReasoningContentModels" | "requiresReasoningPlaceholderModels" | "reasoningSplitModels" | "inlineThinkTagModels" | "reasoningDetailsModels" | "thinkingToggleModels" | "thinkingBudgetModels" | "escapeBuiltinToolNames" | "openaiChatEofTolerance" | "showThinkingSummary"
362
364
  | "googleMode" | "project" | "location" | "headers"
363
365
  >;
@@ -32,7 +32,15 @@ export function mapFill<T>(
32
32
  operator: Readonly<Record<string, T>> | undefined,
33
33
  ): [Record<string, T> | undefined, StaticPolicySource] {
34
34
  if (!registry && !operator) return [undefined, "unknown"];
35
- return [detachedClone({ ...(registry ?? {}), ...(operator ?? {}) }), operator ? "operator" : "registry"];
35
+ // Per-model lookups fold case (legacyModelValue), so a case-varied operator key must claim the
36
+ // registry row here; leaving both keys lets the earlier registry entry shadow the override.
37
+ const claimed = new Set(Object.keys(operator ?? {}).map(key => key.toLowerCase()));
38
+ const merged: Record<string, T> = {};
39
+ for (const [key, value] of Object.entries(registry ?? {})) {
40
+ if (!claimed.has(key.toLowerCase())) merged[key] = value;
41
+ }
42
+ for (const [key, value] of Object.entries(operator ?? {})) merged[key] = value;
43
+ return [detachedClone(merged), operator ? "operator" : "registry"];
36
44
  }
37
45
 
38
46
  export function nestedMapFill(
@@ -40,10 +48,19 @@ export function nestedMapFill(
40
48
  operator: Readonly<Record<string, Record<string, string>>> | undefined,
41
49
  ): [Record<string, Record<string, string>> | undefined, StaticPolicySource] {
42
50
  if (!registry && !operator) return [undefined, "unknown"];
51
+ // The outer model key folds case like mapFill: a case-varied operator key claims the registry
52
+ // row instead of shadowing behind it, while the claimed row's inner entries still fill
53
+ // underneath the operator's inner map.
54
+ const claimed = new Set(Object.keys(operator ?? {}).map(key => key.toLowerCase()));
43
55
  const merged: Record<string, Record<string, string>> = {};
44
- for (const [key, value] of Object.entries(registry ?? {})) merged[key] = { ...value };
56
+ const claimedInner: Record<string, Record<string, string>> = {};
57
+ for (const [key, value] of Object.entries(registry ?? {})) {
58
+ const folded = key.toLowerCase();
59
+ if (claimed.has(folded)) claimedInner[folded] = { ...(claimedInner[folded] ?? {}), ...value };
60
+ else merged[key] = { ...value };
61
+ }
45
62
  for (const [key, value] of Object.entries(operator ?? {})) {
46
- merged[key] = { ...(merged[key] ?? {}), ...value };
63
+ merged[key] = { ...(claimedInner[key.toLowerCase()] ?? merged[key] ?? {}), ...value };
47
64
  }
48
65
  return [merged, operator ? "operator" : "registry"];
49
66
  }
@@ -52,12 +69,19 @@ export function positiveCapMap(
52
69
  registry: Readonly<Record<string, number>> | undefined,
53
70
  operator: Readonly<Record<string, number>> | undefined,
54
71
  ): [Record<string, number> | undefined, StaticPolicySource] {
55
- if (!registry && !operator) return [undefined, "unknown"];
56
- const merged = { ...(registry ?? {}) };
72
+ const [merged, source] = mapFill(registry, operator);
73
+ if (!merged) return [undefined, source];
74
+ // The operator owns a case-equal row, as in mapFill, but cannot widen its registry cap.
75
+ const registryCaps = new Map<string, number>();
76
+ for (const [key, value] of Object.entries(registry ?? {})) {
77
+ const folded = key.toLowerCase();
78
+ registryCaps.set(folded, Math.min(registryCaps.get(folded) ?? value, value));
79
+ }
57
80
  for (const [key, value] of Object.entries(operator ?? {})) {
58
- merged[key] = typeof merged[key] === "number" ? Math.min(merged[key]!, value) : value;
81
+ const cap = registryCaps.get(key.toLowerCase());
82
+ merged[key] = cap === undefined ? value : Math.min(cap, value);
59
83
  }
60
- return [merged, operator ? "operator" : "registry"];
84
+ return [merged, source];
61
85
  }
62
86
 
63
87
  export function stableUnion(
@@ -118,7 +142,13 @@ export function legacyModelSource<T>(
118
142
  registry: Readonly<Record<string, T>> | undefined,
119
143
  modelId: string,
120
144
  ): StaticPolicySource {
121
- const merged = { ...(registry ?? {}), ...(operator ?? {}) };
145
+ // Match mapFill's case-folded ownership so provenance follows the value lookup.
146
+ const claimed = new Set(Object.keys(operator ?? {}).map(key => key.toLowerCase()));
147
+ const merged: Record<string, T> = {};
148
+ for (const [key, value] of Object.entries(registry ?? {})) {
149
+ if (!claimed.has(key.toLowerCase())) merged[key] = value;
150
+ }
151
+ for (const [key, value] of Object.entries(operator ?? {})) merged[key] = value;
122
152
  let winningKey: string | undefined;
123
153
  if (Object.hasOwn(merged, modelId)) winningKey = modelId;
124
154
  const colon = modelId.indexOf(":");