@iislee/opencodex 2.11.0 → 2.31.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 (675) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +114 -19
  3. package/bin/ocx.mjs +164 -36
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-BF38heuV.js +104 -0
  6. package/gui/dist/assets/index-DMiI18Kv.css +1 -0
  7. package/gui/dist/index.html +2 -2
  8. package/gui/dist/provider-icons/alibaba-color.svg +1 -1
  9. package/gui/dist/provider-icons/antigravity-color.svg +1 -1
  10. package/gui/dist/provider-icons/claude-color.svg +1 -1
  11. package/gui/dist/provider-icons/cline-color.svg +16 -0
  12. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
  13. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  14. package/gui/dist/provider-icons/copilot-color.svg +1 -1
  15. package/gui/dist/provider-icons/cursor-color.svg +1 -1
  16. package/gui/dist/provider-icons/deepseek-color.svg +1 -1
  17. package/gui/dist/provider-icons/firepass-color.svg +1 -1
  18. package/gui/dist/provider-icons/fireworks-color.svg +1 -1
  19. package/gui/dist/provider-icons/gemini-color.svg +1 -1
  20. package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
  21. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
  22. package/gui/dist/provider-icons/grok.svg +1 -1
  23. package/gui/dist/provider-icons/groq-color.svg +1 -1
  24. package/gui/dist/provider-icons/huggingface-color.svg +1 -1
  25. package/gui/dist/provider-icons/kimi-color.svg +1 -1
  26. package/gui/dist/provider-icons/kiro-color.svg +2 -2
  27. package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
  28. package/gui/dist/provider-icons/mistral-color.svg +1 -1
  29. package/gui/dist/provider-icons/moonshot-color.svg +1 -1
  30. package/gui/dist/provider-icons/nvidia-color.svg +1 -1
  31. package/gui/dist/provider-icons/ollama-color.svg +1 -1
  32. package/gui/dist/provider-icons/openai.svg +1 -1
  33. package/gui/dist/provider-icons/opencode.svg +2 -1
  34. package/gui/dist/provider-icons/openrouter-color.svg +1 -1
  35. package/gui/dist/provider-icons/pi.svg +2 -2
  36. package/gui/dist/provider-icons/qianfan-color.svg +1 -1
  37. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
  38. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
  39. package/gui/dist/provider-icons/vllm-color.svg +1 -1
  40. package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
  41. package/package.json +19 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +376 -52
  44. package/src/adapters/base.ts +54 -7
  45. package/src/adapters/client-fingerprint.ts +18 -12
  46. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  47. package/src/adapters/command-code.ts +601 -0
  48. package/src/adapters/cursor/checkpoint-store.ts +303 -0
  49. package/src/adapters/cursor/cursor-errors.ts +129 -6
  50. package/src/adapters/cursor/discovery.ts +61 -4
  51. package/src/adapters/cursor/effort-map.ts +27 -3
  52. package/src/adapters/cursor/framing.ts +39 -0
  53. package/src/adapters/cursor/h2-pool.ts +123 -0
  54. package/src/adapters/cursor/http1-bidi.ts +361 -0
  55. package/src/adapters/cursor/images.ts +704 -0
  56. package/src/adapters/cursor/live-models.ts +174 -58
  57. package/src/adapters/cursor/live-transport.ts +609 -170
  58. package/src/adapters/cursor/native-exec-common.ts +23 -2
  59. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  60. package/src/adapters/cursor/native-exec-network.ts +1 -1
  61. package/src/adapters/cursor/native-exec-shell.ts +0 -1
  62. package/src/adapters/cursor/native-exec.ts +101 -14
  63. package/src/adapters/cursor/protobuf-events.ts +829 -11
  64. package/src/adapters/cursor/protobuf-request.ts +383 -65
  65. package/src/adapters/cursor/request-builder.ts +237 -31
  66. package/src/adapters/cursor/tool-definitions.ts +242 -12
  67. package/src/adapters/cursor/tool-result-normalize.ts +92 -0
  68. package/src/adapters/cursor/transport.ts +22 -0
  69. package/src/adapters/cursor/types.ts +28 -1
  70. package/src/adapters/cursor.ts +133 -7
  71. package/src/adapters/google-antigravity-replay.ts +558 -34
  72. package/src/adapters/google-antigravity-wire.ts +43 -10
  73. package/src/adapters/google-http.ts +38 -10
  74. package/src/adapters/google-tool-schema.ts +80 -15
  75. package/src/adapters/google-truncation.ts +11 -0
  76. package/src/adapters/google.ts +618 -74
  77. package/src/adapters/identity.ts +39 -6
  78. package/src/adapters/kiro-errors.ts +11 -0
  79. package/src/adapters/kiro-events.ts +19 -1
  80. package/src/adapters/kiro-thinking.ts +18 -2
  81. package/src/adapters/kiro-tools.ts +10 -1
  82. package/src/adapters/kiro.ts +92 -54
  83. package/src/adapters/mimo-free.ts +17 -0
  84. package/src/adapters/openai-chat-url.ts +11 -0
  85. package/src/adapters/openai-chat.ts +1311 -336
  86. package/src/adapters/openai-responses-url.ts +16 -0
  87. package/src/adapters/openai-responses.ts +830 -56
  88. package/src/adapters/registry.ts +175 -0
  89. package/src/adapters/responses-tool-schema.ts +67 -0
  90. package/src/adapters/tool-call-id.ts +119 -0
  91. package/src/adapters/tool-catalog-nudge.ts +104 -21
  92. package/src/adapters/xai-web-search.ts +185 -0
  93. package/src/bridge.ts +428 -61
  94. package/src/chat/inbound.ts +43 -19
  95. package/src/chat/outbound.ts +82 -26
  96. package/src/claude/agents-inject.ts +32 -9
  97. package/src/claude/context-windows.ts +21 -5
  98. package/src/claude/desktop-3p.ts +243 -9
  99. package/src/claude/gateway-cache.ts +41 -4
  100. package/src/claude/inbound.ts +72 -3
  101. package/src/claude/model-info.ts +38 -15
  102. package/src/claude/outbound.ts +70 -16
  103. package/src/cli/account-api.ts +35 -1
  104. package/src/cli/account-auth.ts +33 -6
  105. package/src/cli/account-catalog-refresh.ts +14 -0
  106. package/src/cli/account-extended.ts +389 -2
  107. package/src/cli/account-main.ts +317 -0
  108. package/src/cli/account.ts +30 -6
  109. package/src/cli/agent.ts +45 -1
  110. package/src/cli/claude-agent-startup-sync.ts +73 -0
  111. package/src/cli/claude-desktop.ts +29 -4
  112. package/src/cli/claude.ts +103 -34
  113. package/src/cli/codex-log-guard-doctor.ts +103 -0
  114. package/src/cli/codex-shim-autorestore.ts +2 -0
  115. package/src/cli/codex-shim-readiness.ts +76 -0
  116. package/src/cli/combo.ts +8 -0
  117. package/src/cli/config-command.ts +74 -10
  118. package/src/cli/dispatch.ts +593 -0
  119. package/src/cli/doctor.ts +315 -43
  120. package/src/cli/ensure-desired-integrations.ts +152 -0
  121. package/src/cli/export-command.ts +46 -20
  122. package/src/cli/help.ts +20 -271
  123. package/src/cli/index.ts +378 -519
  124. package/src/cli/init.ts +4 -17
  125. package/src/cli/integrations.ts +120 -2
  126. package/src/cli/lab.ts +607 -0
  127. package/src/cli/launcher-context.ts +77 -0
  128. package/src/cli/minimax.ts +497 -0
  129. package/src/cli/models-runtime.ts +35 -2
  130. package/src/cli/models.ts +100 -14
  131. package/src/cli/observe.ts +92 -3
  132. package/src/cli/opencode.ts +4 -2
  133. package/src/cli/provider-runtime.ts +18 -1
  134. package/src/cli/provider.ts +24 -3
  135. package/src/cli/ready.ts +301 -0
  136. package/src/cli/registry.ts +437 -0
  137. package/src/cli/root.ts +86 -0
  138. package/src/cli/route-policy.ts +92 -0
  139. package/src/cli/runtime-api.ts +6 -3
  140. package/src/cli/star-prompt.ts +71 -15
  141. package/src/cli/status.ts +10 -3
  142. package/src/cli/system-restart-client.ts +146 -0
  143. package/src/cli/tray-proxy.ts +153 -6
  144. package/src/cli/v2.ts +105 -10
  145. package/src/cli.ts +1 -1
  146. package/src/clients/config-export.ts +1358 -21
  147. package/src/codex/account-label.ts +14 -1
  148. package/src/codex/account-lifecycle.ts +130 -13
  149. package/src/codex/account-namespaces.ts +49 -3
  150. package/src/codex/account-priority.ts +83 -0
  151. package/src/codex/account-store.ts +29 -2
  152. package/src/codex/account-usability.ts +25 -2
  153. package/src/codex/admission.ts +256 -0
  154. package/src/codex/affinity-debug.ts +162 -0
  155. package/src/codex/app-server-processes.ts +493 -106
  156. package/src/codex/app-server-restart-service.ts +232 -0
  157. package/src/codex/auth-api.ts +849 -242
  158. package/src/codex/auth-collision.ts +5 -3
  159. package/src/codex/auth-context.ts +345 -32
  160. package/src/codex/autostart-health.ts +8 -1
  161. package/src/codex/catalog/account-models.ts +67 -0
  162. package/src/codex/catalog/aggregation.ts +68 -10
  163. package/src/codex/catalog/bundled.ts +331 -33
  164. package/src/codex/catalog/effort.ts +121 -30
  165. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  166. package/src/codex/catalog/kinds.ts +2 -0
  167. package/src/codex/catalog/metadata.ts +529 -45
  168. package/src/codex/catalog/native-models.ts +72 -0
  169. package/src/codex/catalog/parsing.ts +224 -30
  170. package/src/codex/catalog/provider-fetch.ts +1460 -134
  171. package/src/codex/catalog/sync.ts +1449 -186
  172. package/src/codex/catalog-admission.ts +199 -0
  173. package/src/codex/catalog-refresh-status.ts +105 -0
  174. package/src/codex/catalog-write-serialization.ts +242 -0
  175. package/src/codex/catalog.ts +6 -3
  176. package/src/codex/codex-write-lock.ts +384 -0
  177. package/src/codex/convergence-types.ts +614 -0
  178. package/src/codex/convergence.ts +651 -0
  179. package/src/codex/coordinator-doctor.ts +332 -0
  180. package/src/codex/custom-model-catalog-migration.ts +176 -0
  181. package/src/codex/desired-state.ts +230 -0
  182. package/src/codex/features.ts +636 -39
  183. package/src/codex/generation.ts +202 -0
  184. package/src/codex/history-job.ts +407 -0
  185. package/src/codex/history-lock.ts +242 -0
  186. package/src/codex/history-migration-guardian.ts +26 -20
  187. package/src/codex/history-provider.ts +231 -28
  188. package/src/codex/history-transition.ts +105 -0
  189. package/src/codex/history-worker.ts +220 -0
  190. package/src/codex/inject-coordination.ts +290 -0
  191. package/src/codex/inject.ts +1073 -152
  192. package/src/codex/injected-marker.ts +37 -3
  193. package/src/codex/integration-record.ts +266 -0
  194. package/src/codex/internal/catalog-writer.ts +203 -0
  195. package/src/codex/internal/history-writer.ts +80 -0
  196. package/src/codex/journal.ts +66 -4
  197. package/src/codex/log-guard/inspect.ts +506 -0
  198. package/src/codex/log-guard/lock.ts +150 -0
  199. package/src/codex/log-guard/maintenance.ts +403 -0
  200. package/src/codex/log-guard/path-safety.ts +88 -0
  201. package/src/codex/log-guard/policy.ts +44 -0
  202. package/src/codex/log-guard/processes.ts +205 -0
  203. package/src/codex/log-guard/protection.ts +489 -0
  204. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  205. package/src/codex/main-account-cache.ts +24 -0
  206. package/src/codex/main-account.ts +29 -1
  207. package/src/codex/management-convergence.ts +167 -0
  208. package/src/codex/model-cache.ts +56 -10
  209. package/src/codex/model-entitlements.ts +353 -0
  210. package/src/codex/native-main-admission.ts +47 -0
  211. package/src/codex/native-main-auth-temp.ts +187 -0
  212. package/src/codex/native-main-claim.ts +178 -0
  213. package/src/codex/native-main-lock-file.ts +162 -0
  214. package/src/codex/native-main-owner.ts +329 -0
  215. package/src/codex/native-profile-api.ts +247 -0
  216. package/src/codex/native-profile-manager.ts +1531 -0
  217. package/src/codex/native-profile-processes.ts +121 -0
  218. package/src/codex/native-profile-recovery.ts +99 -0
  219. package/src/codex/native-profile-stage-store.ts +387 -0
  220. package/src/codex/native-profile-startup.ts +492 -0
  221. package/src/codex/native-profile-store.ts +855 -0
  222. package/src/codex/native-profile-types.ts +120 -0
  223. package/src/codex/native-residue.ts +682 -0
  224. package/src/codex/paths.ts +80 -1
  225. package/src/codex/plan-from-token.ts +140 -0
  226. package/src/codex/plan.ts +40 -0
  227. package/src/codex/plugins-doctor.ts +1 -1
  228. package/src/codex/pool-rotation.ts +74 -4
  229. package/src/codex/project-config-warnings.ts +20 -6
  230. package/src/codex/prompt-journal.ts +352 -0
  231. package/src/codex/prompt-layers.ts +967 -0
  232. package/src/codex/prompt-lock.ts +143 -0
  233. package/src/codex/quota-rejection.ts +298 -0
  234. package/src/codex/quota.ts +175 -13
  235. package/src/codex/refresh.ts +11 -2
  236. package/src/codex/reset-credit-recovery.ts +1044 -0
  237. package/src/codex/routing.ts +505 -94
  238. package/src/codex/runtime.ts +159 -38
  239. package/src/codex/shim.ts +1009 -28
  240. package/src/codex/subagent-model-fallback.ts +350 -35
  241. package/src/codex/sync.ts +191 -2
  242. package/src/codex/transition-state.ts +612 -0
  243. package/src/codex/upstream-host-health.ts +368 -0
  244. package/src/codex/user-identity.ts +557 -0
  245. package/src/codex/warmup.ts +187 -81
  246. package/src/codex/write-coordination.ts +114 -0
  247. package/src/combos/failover.ts +20 -0
  248. package/src/combos/index.ts +4 -0
  249. package/src/combos/request.ts +32 -0
  250. package/src/combos/types.ts +81 -9
  251. package/src/config/provider-name.ts +24 -0
  252. package/src/config.ts +1762 -140
  253. package/src/generated/compatibility-version.json +3164 -0
  254. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  255. package/src/grok/inject.ts +16 -5
  256. package/src/grok/inspect.ts +45 -0
  257. package/src/grok/sync.ts +2 -2
  258. package/src/images/loop.ts +152 -29
  259. package/src/images/plan.ts +23 -13
  260. package/src/integrations/config-io.ts +269 -0
  261. package/src/integrations/journal.ts +315 -0
  262. package/src/integrations/merge.ts +135 -0
  263. package/src/integrations/mutation-flight.ts +71 -0
  264. package/src/integrations/native/ownership-preflight.ts +202 -0
  265. package/src/integrations/omp-yaml-source.ts +358 -0
  266. package/src/integrations/owned-refresh.ts +74 -0
  267. package/src/integrations/ownership.ts +111 -0
  268. package/src/integrations/registry.ts +159 -0
  269. package/src/integrations/serialize.ts +314 -0
  270. package/src/integrations/state.ts +361 -0
  271. package/src/integrations/store.ts +103 -0
  272. package/src/integrations/writer-lock.ts +98 -0
  273. package/src/integrations/writer.ts +691 -0
  274. package/src/lab/artifacts/sanitize.ts +586 -0
  275. package/src/lab/artifacts/secure-fs.ts +475 -0
  276. package/src/lab/artifacts/store.ts +310 -0
  277. package/src/lab/automation/budgets.ts +78 -0
  278. package/src/lab/automation/config-persistence.ts +256 -0
  279. package/src/lab/automation/constants.ts +39 -0
  280. package/src/lab/automation/cooldown.ts +103 -0
  281. package/src/lab/automation/dispatch.ts +211 -0
  282. package/src/lab/automation/index.ts +13 -0
  283. package/src/lab/automation/orchestrator.ts +499 -0
  284. package/src/lab/automation/persistence.ts +512 -0
  285. package/src/lab/automation/planner.ts +371 -0
  286. package/src/lab/automation/policy.ts +136 -0
  287. package/src/lab/automation/queue.ts +191 -0
  288. package/src/lab/automation/recovery.ts +24 -0
  289. package/src/lab/automation/route-context.ts +21 -0
  290. package/src/lab/automation/run-key.ts +44 -0
  291. package/src/lab/automation/runs-query.ts +34 -0
  292. package/src/lab/automation/types.ts +160 -0
  293. package/src/lab/conformance/assertion.ts +325 -0
  294. package/src/lab/conformance/digest.ts +22 -0
  295. package/src/lab/conformance/executor.ts +741 -0
  296. package/src/lab/conformance/fixture-provider.ts +27 -0
  297. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  298. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  299. package/src/lab/conformance/harness-budget.ts +47 -0
  300. package/src/lab/conformance/index.ts +5 -0
  301. package/src/lab/conformance/jcs.ts +64 -0
  302. package/src/lab/conformance/json-pointer.ts +39 -0
  303. package/src/lab/conformance/manifest.ts +180 -0
  304. package/src/lab/conformance/mcp-stub.ts +179 -0
  305. package/src/lab/conformance/negative-controls.ts +164 -0
  306. package/src/lab/conformance/observation.ts +355 -0
  307. package/src/lab/conformance/runner.ts +68 -0
  308. package/src/lab/conformance/sse-normalize.ts +59 -0
  309. package/src/lab/conformance/suite-manifest.ts +78 -0
  310. package/src/lab/conformance/types.ts +214 -0
  311. package/src/lab/constants.ts +126 -0
  312. package/src/lab/digest.ts +64 -0
  313. package/src/lab/events/errors.ts +9 -0
  314. package/src/lab/events/limits.ts +117 -0
  315. package/src/lab/events/types.ts +229 -0
  316. package/src/lab/events/validate.ts +781 -0
  317. package/src/lab/fabric/constants.ts +40 -0
  318. package/src/lab/fabric/executor.ts +492 -0
  319. package/src/lab/fabric/index.ts +80 -0
  320. package/src/lab/fabric/manifest.ts +222 -0
  321. package/src/lab/fabric/observe.ts +489 -0
  322. package/src/lab/fabric/patch.ts +79 -0
  323. package/src/lab/fabric/producer-child.ts +139 -0
  324. package/src/lab/fabric/producer-isolate.ts +276 -0
  325. package/src/lab/fabric/producer-protocol.ts +61 -0
  326. package/src/lab/fabric/scratch.ts +439 -0
  327. package/src/lab/fabric/subject.ts +106 -0
  328. package/src/lab/fabric/types.ts +134 -0
  329. package/src/lab/fabric/verifier.ts +98 -0
  330. package/src/lab/index.ts +54 -0
  331. package/src/lab/ledger/artifact-refs.ts +127 -0
  332. package/src/lab/ledger/invalidation.ts +136 -0
  333. package/src/lab/ledger/purge.ts +310 -0
  334. package/src/lab/ledger/store.ts +532 -0
  335. package/src/lab/live/credential-lease.ts +53 -0
  336. package/src/lab/live/destination.ts +155 -0
  337. package/src/lab/live/executor.ts +336 -0
  338. package/src/lab/live/inert-tools.ts +56 -0
  339. package/src/lab/live/manifest.ts +85 -0
  340. package/src/lab/live/mcp-loopback.ts +57 -0
  341. package/src/lab/live/runner.ts +19 -0
  342. package/src/lab/live/sandbox.ts +61 -0
  343. package/src/lab/live/suite-manifest.ts +41 -0
  344. package/src/lab/live/transport.ts +118 -0
  345. package/src/lab/live/types.ts +197 -0
  346. package/src/lab/observe/from-conformance.ts +301 -0
  347. package/src/lab/observe/from-live.ts +117 -0
  348. package/src/lab/paths.ts +153 -0
  349. package/src/lab/projection/rebuild.ts +495 -0
  350. package/src/lab/projection/schema.ts +135 -0
  351. package/src/lab/projection/verdicts.ts +474 -0
  352. package/src/lab/projection/verification.ts +412 -0
  353. package/src/lab/public/bundle.ts +217 -0
  354. package/src/lab/public/community-authority.ts +175 -0
  355. package/src/lab/public/community-files.ts +29 -0
  356. package/src/lab/public/community.ts +479 -0
  357. package/src/lab/public/file-safety.ts +155 -0
  358. package/src/lab/public/ids.ts +26 -0
  359. package/src/lab/public/index.ts +16 -0
  360. package/src/lab/public/mutation-lock.ts +424 -0
  361. package/src/lab/public/operator.ts +353 -0
  362. package/src/lab/public/origin-purge.ts +79 -0
  363. package/src/lab/public/origin.ts +203 -0
  364. package/src/lab/public/privacy.ts +143 -0
  365. package/src/lab/public/private-file.ts +261 -0
  366. package/src/lab/public/project.ts +124 -0
  367. package/src/lab/public/purge-test-fault.ts +21 -0
  368. package/src/lab/public/purge.ts +223 -0
  369. package/src/lab/public/registry.ts +44 -0
  370. package/src/lab/public/revocation.ts +252 -0
  371. package/src/lab/public/signature.ts +243 -0
  372. package/src/lab/public/storage.ts +105 -0
  373. package/src/lab/public/strict-json.ts +206 -0
  374. package/src/lab/public/time.ts +26 -0
  375. package/src/lab/public/types.ts +172 -0
  376. package/src/lab/public/validate.ts +391 -0
  377. package/src/lab/query/catalog.ts +101 -0
  378. package/src/lab/query/connection.ts +107 -0
  379. package/src/lab/query/constants.ts +4 -0
  380. package/src/lab/query/cursor.ts +132 -0
  381. package/src/lab/query/dto-map.ts +277 -0
  382. package/src/lab/query/errors.ts +22 -0
  383. package/src/lab/query/freshness.ts +53 -0
  384. package/src/lab/query/index.ts +45 -0
  385. package/src/lab/query/latest-observation.ts +59 -0
  386. package/src/lab/query/passive-production.ts +159 -0
  387. package/src/lab/query/queries.ts +444 -0
  388. package/src/lab/query/types.ts +266 -0
  389. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  390. package/src/lab/subject/installation-salt.ts +112 -0
  391. package/src/lab/subject/protocol-subject.ts +80 -0
  392. package/src/lab/subject/route-subject.ts +74 -0
  393. package/src/lib/app-owned-memory-stores.ts +22 -0
  394. package/src/lib/bounded-body.ts +153 -9
  395. package/src/lib/bun-runtime.ts +125 -12
  396. package/src/lib/bun-stream-caps.ts +13 -9
  397. package/src/lib/codex-restart-contract.ts +120 -0
  398. package/src/lib/config-ownership.ts +6 -2
  399. package/src/lib/destination-policy.ts +65 -1
  400. package/src/lib/errors.ts +44 -2
  401. package/src/lib/fabric-task-execution-authority.ts +7 -0
  402. package/src/lib/fabric-task-host.ts +29 -0
  403. package/src/lib/lab-activation.ts +223 -0
  404. package/src/lib/lab-live-execution-authority.ts +13 -0
  405. package/src/lib/lab-live-host.ts +30 -0
  406. package/src/lib/lab-live-pinned-sender.ts +56 -0
  407. package/src/lib/lab-live-route-production.ts +130 -0
  408. package/src/lib/lab-passive-linker-registration.ts +26 -0
  409. package/src/lib/local-management-attestation.ts +51 -0
  410. package/src/lib/local-management-capability.ts +100 -0
  411. package/src/lib/local-provider-reload-contract.ts +100 -0
  412. package/src/lib/optional-shutdown-hooks.ts +57 -0
  413. package/src/lib/pinned-http.ts +145 -26
  414. package/src/lib/process-control.ts +4 -1
  415. package/src/lib/provider-outbound.ts +49 -9
  416. package/src/lib/redact.ts +419 -3
  417. package/src/lib/self-launch-argv.ts +15 -0
  418. package/src/lib/server-resource-ownership.ts +71 -0
  419. package/src/lib/shadow-call.ts +35 -4
  420. package/src/lib/sse-decoder.ts +41 -0
  421. package/src/lib/state-store-registrations.ts +10 -2
  422. package/src/lib/system-restart-contract.ts +73 -0
  423. package/src/lib/token-estimate.ts +19 -2
  424. package/src/lib/tool-argument-integers.ts +202 -0
  425. package/src/lib/translator-budget.ts +44 -0
  426. package/src/lib/upstream-http-version.ts +57 -0
  427. package/src/lib/upstream-reachability.ts +95 -0
  428. package/src/lib/upstream-retry.ts +156 -3
  429. package/src/lib/windows-atomic-replace.ts +155 -0
  430. package/src/lib/windows-elevation.ts +70 -2
  431. package/src/lib/windows-secret-acl.ts +409 -69
  432. package/src/lib/windows-service-wrappers.ts +72 -0
  433. package/src/lib/windows-text.ts +106 -0
  434. package/src/lib/windows-user-principal.ts +341 -0
  435. package/src/lib/winsw.ts +33 -5
  436. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  437. package/src/oauth/account-import/index.ts +15 -0
  438. package/src/oauth/account-import/parser.ts +83 -0
  439. package/src/oauth/account-import/registry.ts +18 -0
  440. package/src/oauth/account-import/service.ts +75 -0
  441. package/src/oauth/account-import/types.ts +91 -0
  442. package/src/oauth/anthropic.ts +12 -1
  443. package/src/oauth/callback-server.ts +8 -2
  444. package/src/oauth/chatgpt.ts +12 -1
  445. package/src/oauth/command-code.ts +239 -0
  446. package/src/oauth/cursor.ts +46 -5
  447. package/src/oauth/google-antigravity.ts +35 -3
  448. package/src/oauth/health.ts +20 -12
  449. package/src/oauth/index.ts +398 -66
  450. package/src/oauth/key-providers.ts +16 -0
  451. package/src/oauth/kimi.ts +16 -2
  452. package/src/oauth/kiro.ts +50 -6
  453. package/src/oauth/local-token-detect.ts +11 -2
  454. package/src/oauth/log.ts +3 -1
  455. package/src/oauth/login-cli.ts +88 -28
  456. package/src/oauth/nous.ts +798 -0
  457. package/src/oauth/store.ts +119 -21
  458. package/src/oauth/token-guardian.ts +9 -3
  459. package/src/pi/models.ts +2 -2
  460. package/src/providers/alibaba-region-migration.ts +1 -1
  461. package/src/providers/antigravity-models.ts +521 -31
  462. package/src/providers/base-url-choices.ts +10 -0
  463. package/src/providers/codex-capacity.ts +292 -0
  464. package/src/providers/command-code-efforts.ts +144 -0
  465. package/src/providers/context-cap.ts +22 -5
  466. package/src/providers/cursor-pool.ts +72 -0
  467. package/src/providers/derive.ts +253 -6
  468. package/src/providers/fastwire.ts +501 -0
  469. package/src/providers/free-directory.ts +10 -7
  470. package/src/providers/google-vertex-location.ts +14 -0
  471. package/src/providers/key-failover.ts +71 -3
  472. package/src/providers/label.ts +1 -1
  473. package/src/providers/model-discovery-limits.ts +16 -0
  474. package/src/providers/model-discovery.ts +115 -22
  475. package/src/providers/model-rename-migration.ts +255 -0
  476. package/src/providers/model-rename-startup.ts +28 -0
  477. package/src/providers/openai-sidecar.ts +72 -4
  478. package/src/providers/openai-tier-startup.ts +31 -2
  479. package/src/providers/openai-tiers.ts +119 -4
  480. package/src/providers/openai-virtual-models.ts +1 -0
  481. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  482. package/src/providers/provider-id-rewrite.ts +29 -0
  483. package/src/providers/quota.ts +1319 -38
  484. package/src/providers/registry.ts +1429 -111
  485. package/src/providers/request-pacing.ts +310 -0
  486. package/src/providers/service-tier.ts +277 -0
  487. package/src/providers/slug-codec.ts +42 -6
  488. package/src/providers/static-model-discovery.ts +86 -0
  489. package/src/providers/xai-responses-opt-in.ts +15 -0
  490. package/src/providers/xai-transport.ts +11 -4
  491. package/src/reasoning-effort.ts +49 -1
  492. package/src/responses/compaction.ts +26 -1
  493. package/src/responses/custom-tool-compat.ts +266 -0
  494. package/src/responses/hosted-tool-policy.ts +9 -0
  495. package/src/responses/namespace-tool-compat.ts +355 -0
  496. package/src/responses/parser.ts +220 -38
  497. package/src/responses/provider-continuation.ts +98 -0
  498. package/src/responses/provider-opaque-metadata.ts +73 -0
  499. package/src/responses/reasoning-envelope.ts +9 -1
  500. package/src/responses/reasoning-replay-cache.ts +426 -0
  501. package/src/responses/schema.ts +7 -1
  502. package/src/responses/spill-store.ts +75 -10
  503. package/src/responses/state.ts +565 -27
  504. package/src/responses/thought-signature-replay.ts +347 -0
  505. package/src/responses/tool-search-compat.ts +301 -0
  506. package/src/responses/truncated-stop-reason.ts +60 -0
  507. package/src/router.ts +366 -30
  508. package/src/routing/analytics.ts +378 -0
  509. package/src/routing/capability.ts +244 -0
  510. package/src/routing/compatibility/assemble.ts +73 -0
  511. package/src/routing/compatibility/behavior.ts +278 -0
  512. package/src/routing/compatibility/catalog.ts +99 -0
  513. package/src/routing/compatibility/endpoint.ts +52 -0
  514. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  515. package/src/routing/compatibility/policy.ts +181 -0
  516. package/src/routing/compatibility/provider-slot.ts +56 -0
  517. package/src/routing/compatibility/reader.ts +110 -0
  518. package/src/routing/compatibility/subject.ts +191 -0
  519. package/src/routing/compatibility/types.ts +64 -0
  520. package/src/routing/compatibility/version.ts +104 -0
  521. package/src/routing/cost.ts +77 -0
  522. package/src/routing/evaluator.ts +495 -0
  523. package/src/routing/health.ts +412 -0
  524. package/src/routing/history/cursor.ts +43 -0
  525. package/src/routing/history/indexer.ts +605 -0
  526. package/src/routing/history/schema.ts +72 -0
  527. package/src/routing/profile-namespace.ts +15 -0
  528. package/src/routing/profile.ts +547 -0
  529. package/src/routing/quota.ts +145 -0
  530. package/src/routing/request-evidence.ts +45 -0
  531. package/src/routing/trace.ts +776 -0
  532. package/src/server/adapter-resolve.ts +2 -29
  533. package/src/server/auth-cors.ts +267 -46
  534. package/src/server/background-lifecycle.ts +182 -0
  535. package/src/server/chat-completions.ts +130 -56
  536. package/src/server/chat-native-sse.ts +331 -0
  537. package/src/server/chat-native.ts +426 -0
  538. package/src/server/claude-messages.ts +159 -43
  539. package/src/server/direct-local-http.ts +347 -0
  540. package/src/server/effort-policy.ts +18 -0
  541. package/src/server/github-copilot-responses-repair.ts +338 -0
  542. package/src/server/gui-static.ts +39 -10
  543. package/src/server/images.ts +94 -12
  544. package/src/server/index.ts +865 -181
  545. package/src/server/lifecycle.ts +284 -13
  546. package/src/server/live.ts +136 -17
  547. package/src/server/local-management-read-client.ts +90 -0
  548. package/src/server/local-provider-reload-client.ts +137 -0
  549. package/src/server/management/agent-settings-routes.ts +398 -103
  550. package/src/server/management/api-key-usage.ts +31 -5
  551. package/src/server/management/body.ts +6 -0
  552. package/src/server/management/combo-routes.ts +62 -24
  553. package/src/server/management/config-routes.ts +464 -51
  554. package/src/server/management/context.ts +80 -2
  555. package/src/server/management/integration-routes.ts +498 -0
  556. package/src/server/management/lab-automation-routes.ts +206 -0
  557. package/src/server/management/lab-routes.ts +563 -0
  558. package/src/server/management/logs-usage-routes.ts +101 -32
  559. package/src/server/management/model-routes.ts +189 -131
  560. package/src/server/management/model-rows.ts +163 -0
  561. package/src/server/management/native-integration-routes.ts +769 -0
  562. package/src/server/management/oauth-account-routes.ts +80 -4
  563. package/src/server/management/provider-capability-config.ts +48 -0
  564. package/src/server/management/provider-routes.ts +764 -157
  565. package/src/server/management/request-history-routes.ts +191 -0
  566. package/src/server/management/routing-analytics-routes.ts +74 -0
  567. package/src/server/management/routing-profile-routes.ts +380 -0
  568. package/src/server/management/shared.ts +27 -11
  569. package/src/server/management/sidebar-routes.ts +47 -31
  570. package/src/server/management/storage-log-guard-routes.ts +186 -0
  571. package/src/server/management/sync-response.ts +69 -0
  572. package/src/server/management/system-restart.ts +288 -32
  573. package/src/server/management/system-routes.ts +77 -0
  574. package/src/server/management/usage-summary-cache.ts +9 -1
  575. package/src/server/management/vision-sidecar-options.ts +167 -0
  576. package/src/server/management/web-search-sidecar-options.ts +120 -0
  577. package/src/server/management-api.ts +115 -14
  578. package/src/server/management-auth.ts +220 -5
  579. package/src/server/passive-route-linker.ts +66 -0
  580. package/src/server/ports.ts +41 -1
  581. package/src/server/proxy-liveness.ts +132 -5
  582. package/src/server/readiness.ts +99 -0
  583. package/src/server/relay-eager.ts +82 -42
  584. package/src/server/relay.ts +236 -76
  585. package/src/server/request-decompress.ts +113 -6
  586. package/src/server/request-log.ts +235 -22
  587. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  588. package/src/server/responses/agent-task-recovery.ts +465 -0
  589. package/src/server/responses/collaboration.ts +204 -35
  590. package/src/server/responses/compact.ts +442 -55
  591. package/src/server/responses/core.ts +2872 -331
  592. package/src/server/responses/empty-completion-guard.ts +276 -0
  593. package/src/server/responses/encrypted-payload.ts +62 -39
  594. package/src/server/responses/fetch-helpers.ts +79 -4
  595. package/src/server/responses/input-admission.ts +185 -0
  596. package/src/server/responses/pacing-overload.ts +13 -0
  597. package/src/server/responses/policy-fallback.ts +178 -0
  598. package/src/server/responses/responses-field-backfill.ts +251 -0
  599. package/src/server/responses/terminal-guard.ts +26 -5
  600. package/src/server/responses/upstream-error.ts +5 -0
  601. package/src/server/responses/ws-upstream.ts +308 -0
  602. package/src/server/responses-custom-tool-repair.ts +282 -0
  603. package/src/server/responses-item-id-repair.ts +54 -6
  604. package/src/server/responses-json-events.ts +90 -0
  605. package/src/server/responses-model-rewrite.ts +29 -0
  606. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  607. package/src/server/responses-snapshot-repair.ts +621 -0
  608. package/src/server/responses-terminal-repair.ts +342 -0
  609. package/src/server/responses-tool-search-repair.ts +267 -0
  610. package/src/server/responses-undeclared-tool-guard.ts +153 -0
  611. package/src/server/responses.ts +18 -2
  612. package/src/server/search.ts +78 -13
  613. package/src/server/sse-frame-buffer.ts +292 -0
  614. package/src/server/sse-payload-rewrite.ts +110 -22
  615. package/src/server/startup-action-control.ts +8 -1
  616. package/src/server/startup-health-cache.ts +19 -1
  617. package/src/server/system-env.ts +80 -9
  618. package/src/server/ws-bridge.ts +39 -38
  619. package/src/service-manager-probe.ts +892 -0
  620. package/src/service.ts +1111 -90
  621. package/src/sidecar/auth.ts +92 -0
  622. package/src/sidecar/candidates.ts +83 -0
  623. package/src/storage/cleanup.ts +2 -2
  624. package/src/storage/scanner.ts +1 -1
  625. package/src/storage/worker-lifecycle.ts +14 -14
  626. package/src/tray/windows-tray.ps1 +83 -9
  627. package/src/tray/windows.ts +43 -16
  628. package/src/types/accounts.ts +37 -0
  629. package/src/types/config.ts +845 -0
  630. package/src/types/provider.ts +545 -0
  631. package/src/types/request.ts +384 -0
  632. package/src/types/tools.ts +131 -0
  633. package/src/types/wire.ts +80 -0
  634. package/src/types.ts +104 -1236
  635. package/src/update/index.ts +32 -19
  636. package/src/update/job.ts +442 -67
  637. package/src/update/notify.ts +12 -6
  638. package/src/update/npm-cache-preflight.d.mts +47 -0
  639. package/src/update/npm-cache-preflight.mjs +201 -0
  640. package/src/update/transactional-install.d.mts +22 -0
  641. package/src/update/transactional-install.mjs +259 -0
  642. package/src/usage/cost.ts +0 -0
  643. package/src/usage/expected-prices.ts +268 -16
  644. package/src/usage/log.ts +606 -41
  645. package/src/usage/summary.ts +177 -9
  646. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  647. package/src/usage/user-cost-overlays.ts +314 -0
  648. package/src/vision/anthropic-describe.ts +10 -6
  649. package/src/vision/backends.ts +97 -0
  650. package/src/vision/describe.ts +9 -3
  651. package/src/vision/eligibility.ts +250 -0
  652. package/src/vision/index.ts +238 -24
  653. package/src/vision/reasoning.ts +55 -0
  654. package/src/vision/routed-describe.ts +175 -0
  655. package/src/vision/timeout-bounds.ts +9 -0
  656. package/src/web-search/anthropic-executor.ts +13 -7
  657. package/src/web-search/backends.ts +108 -0
  658. package/src/web-search/exa-executor.ts +88 -0
  659. package/src/web-search/executor.ts +11 -3
  660. package/src/web-search/gemini-executor.ts +141 -0
  661. package/src/web-search/index.ts +150 -15
  662. package/src/web-search/loop.ts +279 -50
  663. package/src/web-search/parse.ts +125 -30
  664. package/src/web-search/sources.ts +60 -0
  665. package/src/web-search/xai-executor.ts +219 -0
  666. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  667. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  668. package/gui/dist/provider-icons/antigravity.svg +0 -1
  669. package/gui/dist/provider-icons/claude.svg +0 -1
  670. package/gui/dist/provider-icons/copilot.svg +0 -1
  671. package/gui/dist/provider-icons/cursor.svg +0 -2
  672. package/gui/dist/provider-icons/gemini.svg +0 -1
  673. package/gui/dist/provider-icons/grok-color.svg +0 -1
  674. package/gui/dist/provider-icons/kiro.svg +0 -14
  675. package/src/cli/internal-dispatch.ts +0 -20
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Central identity neutralization.
2
+ * Central routed-model identity repair.
3
3
  *
4
4
  * Codex sends the SAME GPT-5 identity line to EVERY model at request time (the per-model catalog
5
5
  * `base_instructions` is ignored on the wire). For routed, non-OpenAI providers that line is both
@@ -8,10 +8,11 @@
8
8
  * into the upstream payload — a signature no first-party client (Claude Code, Gemini CLI, Kiro) ever
9
9
  * sends, and a likely ToS trigger.
10
10
  *
11
- * The neutral replacement keeps ONLY the necessary instruction (don't misreport as GPT-5/OpenAI)
12
- * and names no proxy. Provider-native identity blocks (e.g. the anthropic OAuth "You are a Claude
13
- * agent..." prefix) are layered on TOP of this by the individual adapters; this module never claims
14
- * to be a specific first-party client.
11
+ * The replacement keeps the necessary instruction (don't misreport as GPT-5/OpenAI), names the
12
+ * model id that is actually sent on the wire when it is safe to interpolate, and names no proxy.
13
+ * Provider-native identity blocks (e.g. the anthropic OAuth "You are a Claude agent..." prefix)
14
+ * are layered on TOP of this by the individual adapters; this module never claims to be a specific
15
+ * first-party client.
15
16
  */
16
17
 
17
18
  /** Historical exact identity line Codex injected for every model. */
@@ -37,7 +38,39 @@ export const NEUTRAL_IDENTITY_LINE = "You are a coding agent. Do not claim to be
37
38
  * the leak can't reappear in one adapter while being fixed in another.
38
39
  */
39
40
  export function neutralizeIdentity(systemText: string): string {
40
- return systemText.replace(CODEX_GPT5_IDENTITY_RE, NEUTRAL_IDENTITY_LINE);
41
+ // A callback avoids `$&`, `$'`, and other replacement-string substitutions if this constant ever
42
+ // becomes configurable. Keep the same safe form in identifyRoutedModel below.
43
+ return systemText.replace(CODEX_GPT5_IDENTITY_RE, () => NEUTRAL_IDENTITY_LINE);
44
+ }
45
+
46
+ function safeRoutedModelIdentity(modelName: string): string | null {
47
+ // Callers pass the model id after adapter-specific wire normalization. Brackets remain valid for
48
+ // providers that intentionally send a suffix such as `[1m]`; the OpenAI-chat adapter strips that
49
+ // suffix before calling us only when modelSuffixBracketStrip is enabled.
50
+ const trimmed = modelName.trim();
51
+ if (trimmed.length === 0 || trimmed.length > 128) return null;
52
+ const allowedPunctuation = "._/@:+-[]~";
53
+ for (const char of trimmed) {
54
+ const code = char.charCodeAt(0);
55
+ const isAsciiAlphaNumeric = (code >= 48 && code <= 57)
56
+ || (code >= 65 && code <= 90)
57
+ || (code >= 97 && code <= 122);
58
+ if (!isAsciiAlphaNumeric && !allowedPunctuation.includes(char)) return null;
59
+ }
60
+ return trimmed;
61
+ }
62
+
63
+ /**
64
+ * Identity for a routed model. Callers pass the concrete model id that will be sent upstream, so
65
+ * identity questions can name it instead of falling back to Codex/GPT identity inherited from the
66
+ * native template.
67
+ */
68
+ export function identifyRoutedModel(systemText: string, modelName: string): string {
69
+ const identity = safeRoutedModelIdentity(modelName);
70
+ const replacement = identity
71
+ ? `You are a coding agent powered by the ${identity}. If asked which model you are, identify as ${identity}. Do not claim to be a different model or to have a different creator.`
72
+ : "You are a coding agent powered by the configured model. If asked which model you are, identify as configured model. Do not claim to be GPT-5 or made by OpenAI.";
73
+ return systemText.replace(CODEX_GPT5_IDENTITY_RE, () => replacement);
41
74
  }
42
75
 
43
76
  /** The catalog (static, on-disk) replacement for `base_instructions`. Same neutral wording. */
@@ -109,6 +109,17 @@ function classifyKiroFailure(
109
109
  retryable: false,
110
110
  };
111
111
  }
112
+ // #993: a gated model demanding a profileArn gets a stable, actionable code
113
+ // instead of the generic validation bucket. Non-retryable by definition.
114
+ if (evidence.includes("profilearn") && evidence.includes("required")) {
115
+ return {
116
+ message: "kiro_profile_required: Kiro requires a CodeWhisperer profileArn for this account and model. Re-login or re-import the matching Kiro account (ocx account login kiro --reauth) so the profile is captured, then retry.",
117
+ status: 400,
118
+ errorType: "invalid_request_error",
119
+ code: "kiro_profile_required",
120
+ retryable: false,
121
+ };
122
+ }
112
123
  if (
113
124
  evidence.includes("insufficient_quota")
114
125
  || evidence.includes("quota exhausted")
@@ -3,7 +3,8 @@ import { kiroTruncationReason } from "./kiro-truncation";
3
3
 
4
4
  export type ParsedKiroEvent =
5
5
  | { type: "content"; data?: string; modelId?: string }
6
- | { type: "reasoning"; data?: string }
6
+ | { type: "reasoning"; data?: string; redactedContent?: string }
7
+ | { type: "context_usage"; contextUsagePercentage: number }
7
8
  | { type: "tool"; name?: string; toolUseId?: string; input?: string; stop?: boolean }
8
9
  | { type: "truncation"; data: string }
9
10
  | { type: "metadata"; usage?: OcxUsage; contextUsagePercentage?: number; stopReason?: string }
@@ -17,6 +18,10 @@ const KNOWN_EVENT_TYPES = new Set([
17
18
  "toolUseEvent",
18
19
  "messageMetadataEvent",
19
20
  "metadataEvent",
21
+ // Authoritative context pressure. Every capture (kiro-cli 2.14.1 and 2.16.0) put the percentage
22
+ // HERE and left `metadataEvent` carrying only `stopReason`; metadataEvent's own
23
+ // contextUsagePercentage stays supported as a fallback rather than being dropped.
24
+ "contextUsageEvent",
20
25
  "invalidStateEvent",
21
26
  "error",
22
27
  ]);
@@ -114,11 +119,17 @@ export function parseKiroEvent(eventType: string, payload: Uint8Array): ParsedKi
114
119
  : {}),
115
120
  };
116
121
  case "reasoningContentEvent":
122
+ // `text` is plaintext reasoning; `redactedContent` is the encrypted blob the GPT-5.6 family
123
+ // (sol/terra/luna) actually returns — they never send `text`. Keyed off the wire field, not
124
+ // the model id. Both may be absent on a bare event.
117
125
  return {
118
126
  type: "reasoning",
119
127
  ...(optionalString(eventType, parsed, "text") !== undefined
120
128
  ? { data: optionalString(eventType, parsed, "text") }
121
129
  : {}),
130
+ ...(optionalString(eventType, parsed, "redactedContent") !== undefined
131
+ ? { redactedContent: optionalString(eventType, parsed, "redactedContent") }
132
+ : {}),
122
133
  };
123
134
  case "toolUseEvent":
124
135
  return {
@@ -161,6 +172,13 @@ export function parseKiroEvent(eventType: string, payload: Uint8Array): ParsedKi
161
172
  ...(stopReason !== undefined ? { stopReason } : {}),
162
173
  };
163
174
  }
175
+ case "contextUsageEvent": {
176
+ const contextUsagePercentage = parsed.contextUsagePercentage;
177
+ if (typeof contextUsagePercentage !== "number" || !Number.isFinite(contextUsagePercentage)) {
178
+ return malformed(eventType, "contextUsagePercentage must be a finite number");
179
+ }
180
+ return { type: "context_usage", contextUsagePercentage };
181
+ }
164
182
  case "invalidStateEvent":
165
183
  return { type: "invalid_state", message: optionalString(eventType, parsed, "message") };
166
184
  case "error":
@@ -75,6 +75,14 @@ export class KiroThinkingParser {
75
75
  return [];
76
76
  }
77
77
 
78
+ /** Release any partial tag/content carry when the owning stream stops early. */
79
+ dispose(): void {
80
+ this.replaceCarry("preBuffer", "");
81
+ this.replaceCarry("thinkingBuffer", "");
82
+ this.closeTag = "";
83
+ this.state = "streaming";
84
+ }
85
+
78
86
  private drainThinking(): AdapterEvent[] {
79
87
  const close = this.closeTag;
80
88
  const idx = this.thinkingBuffer.indexOf(close);
@@ -89,8 +97,16 @@ export class KiroThinkingParser {
89
97
  return events;
90
98
  }
91
99
  if (this.thinkingBuffer.length <= MAX_CLOSE_TAG) return [];
92
- const send = this.thinkingBuffer.slice(0, -MAX_CLOSE_TAG);
93
- this.replaceCarry("thinkingBuffer", this.thinkingBuffer.slice(-MAX_CLOSE_TAG));
100
+ // Never split a surrogate pair at the send boundary: a lone high
101
+ // surrogate at the end of one delta encodes as U+FFFD. Move the cut one
102
+ // unit earlier so the whole pair stays in the carry.
103
+ let cut = this.thinkingBuffer.length - MAX_CLOSE_TAG;
104
+ if (cut > 0 && cut < this.thinkingBuffer.length) {
105
+ const atCut = this.thinkingBuffer.charCodeAt(cut - 1);
106
+ if (atCut >= 0xd800 && atCut <= 0xdbff) cut -= 1;
107
+ }
108
+ const send = this.thinkingBuffer.slice(0, cut);
109
+ this.replaceCarry("thinkingBuffer", this.thinkingBuffer.slice(cut));
94
110
  return send ? [{ type: "reasoning_raw_delta", text: send }] : [];
95
111
  }
96
112
  }
@@ -149,7 +149,16 @@ function toolDescriptionLimit(modelId: string): number {
149
149
  function truncateDescription(description: string, limit: number): string {
150
150
  if (description.length <= limit) return description;
151
151
  if (limit <= 1) return description.slice(0, limit);
152
- return `${description.slice(0, limit - 1)}…`;
152
+ let end = limit - 1;
153
+ // Never end the kept text on a lone high surrogate; one step back keeps
154
+ // the whole pair out instead of a U+FFFD-producing half.
155
+ if (description.charCodeAt(end - 1) >= 0xd800 && description.charCodeAt(end - 1) <= 0xdbff) end -= 1;
156
+ return `${description.slice(0, end)}…`;
157
+ }
158
+
159
+ /** Test-only: exercise the surrogate-safe description truncation directly. */
160
+ export function truncateDescriptionForTests(description: string, limit: number): string {
161
+ return truncateDescription(description, limit);
153
162
  }
154
163
 
155
164
  function serializedToolCatalogBytes(tools: readonly unknown[]): number {
@@ -19,6 +19,8 @@ import { createKiroToolNameRegistry, fallbackToolUseId, fingerprint, invocationI
19
19
  import { namespacedToolName } from "../types";
20
20
  import {
21
21
  isTranslatorBudgetExceededError,
22
+ releaseTranslatedEvent,
23
+ retainTranslatedEvent,
22
24
  type TranslatorBudget,
23
25
  } from "../lib/translator-budget";
24
26
  import type {
@@ -39,7 +41,7 @@ import { extractKiroImages, normalizeKiroImages, type KiroImage } from "./kiro-i
39
41
  import { sniffImageDimensions } from "./anthropic-image-guard";
40
42
  import { fetchKiroWithRetry, noteKiroTransientThrottle } from "./kiro-retry";
41
43
  import { convertKiroToolContext } from "./kiro-tools";
42
- import { neutralizeIdentity } from "./identity";
44
+ import { identifyRoutedModel } from "./identity";
43
45
  import { buildNonOpenAIToolCatalogNudgeFromNames } from "./tool-catalog-nudge";
44
46
  import {
45
47
  KIRO_COMPLETION_INSTRUCTIONS,
@@ -99,7 +101,11 @@ interface KiroUserInputMessage {
99
101
  }
100
102
  interface KiroHistoryEntry {
101
103
  userInputMessage?: KiroUserInputMessage;
102
- assistantResponseMessage?: { content: string; toolUses?: KiroToolUse[] };
104
+ assistantResponseMessage?: {
105
+ content: string;
106
+ toolUses?: KiroToolUse[];
107
+ reasoningContent?: { redactedContent: string };
108
+ };
103
109
  }
104
110
 
105
111
  function kiroToolWireNames(tools: readonly unknown[]): string[] {
@@ -326,7 +332,7 @@ function validateKiroCapabilities(parsed: OcxParsedRequest): void {
326
332
 
327
333
  type KiroTurn =
328
334
  | { kind: "user"; content: string; images: KiroImage[]; toolResults: KiroToolResult[] }
329
- | { kind: "assistant"; content: string; toolUses: KiroToolUse[] };
335
+ | { kind: "assistant"; content: string; toolUses: KiroToolUse[]; redactedReasoning?: string };
330
336
 
331
337
  function appendTurnText(target: string, next: string): string {
332
338
  if (!next) return target;
@@ -381,9 +387,21 @@ function validateKiroConversationState(history: KiroHistoryEntry[], currentMessa
381
387
  function boundedInjectedInstruction(text: string, used: { value: number }): string | undefined {
382
388
  const remaining = MAX_KIRO_INJECTED_INSTRUCTION_CHARS - used.value;
383
389
  if (remaining <= 0 || !text) return undefined;
384
- const result = text.length <= remaining ? text : text.slice(0, remaining);
390
+ let result = text.length <= remaining ? text : text.slice(0, remaining);
391
+ // Never end the slice on a lone high surrogate: encoding it substitutes
392
+ // U+FFFD into the injected instruction. One step back keeps a valid pair
393
+ // out instead of a broken half.
394
+ if (result.length > 0) {
395
+ const last = result.charCodeAt(result.length - 1);
396
+ if (last >= 0xd800 && last <= 0xdbff) result = result.slice(0, -1);
397
+ }
385
398
  used.value += result.length;
386
- return result;
399
+ return result.length > 0 ? result : undefined;
400
+ }
401
+
402
+ /** Test-only: exercise the surrogate-safe instruction bound directly. */
403
+ export function boundedInjectedInstructionForTests(text: string, used: { value: number }): string | undefined {
404
+ return boundedInjectedInstruction(text, used);
387
405
  }
388
406
 
389
407
  function kiroCompletionTool(): Record<string, unknown> {
@@ -431,14 +449,24 @@ export function buildKiroPayload(
431
449
  const nameMap = toolContext.nameMap;
432
450
  const systemParts: string[] = [];
433
451
  const injectedChars = { value: 0 };
434
- // Neutralize Codex's GPT-5 identity line so a routed Kiro model never misreports as GPT-5/OpenAI
435
- // and the proxy identity never leaks upstream.
436
- if (parsed.context.systemPrompt?.length) systemParts.push(neutralizeIdentity(parsed.context.systemPrompt.join("\n\n")));
452
+ // Name the Kiro model id actually sent on the wire without leaking the proxy identity upstream.
453
+ if (parsed.context.systemPrompt?.length) {
454
+ systemParts.push(identifyRoutedModel(parsed.context.systemPrompt.join("\n\n"), modelId));
455
+ }
437
456
  for (const addition of toolContext.systemAdditions) {
438
457
  const boundedAddition = boundedInjectedInstruction(addition, injectedChars);
439
458
  if (boundedAddition) systemParts.push(boundedAddition);
440
459
  }
441
- const toolCatalogNudge = buildNonOpenAIToolCatalogNudgeFromNames(kiroToolWireNames(kiroTools));
460
+ // Kiro renames tools to satisfy its wire constraints, so resolve neighbor names through the
461
+ // registry's existing aliases; a bare-name comparison would forbid tools this turn actually
462
+ // advertises. Read the recorded mapping instead of calling `alias()`, which would REGISTER a
463
+ // name for a tool that was never advertised and pollute the collision domain.
464
+ const advertisedAlias = new Map<string, string>();
465
+ for (const [alias, wireName] of registry.nameMap) advertisedAlias.set(wireName, alias);
466
+ const toolCatalogNudge = buildNonOpenAIToolCatalogNudgeFromNames(
467
+ kiroToolWireNames(kiroTools),
468
+ name => advertisedAlias.get(name) ?? name,
469
+ );
442
470
  const boundedNudge = toolCatalogNudge ? boundedInjectedInstruction(toolCatalogNudge, injectedChars) : undefined;
443
471
  if (boundedNudge) systemParts.push(boundedNudge);
444
472
  if (completionMode !== "disabled") {
@@ -458,13 +486,15 @@ export function buildKiroPayload(
458
486
  turns.push({ kind: "user", content, images: [...images], toolResults: [...toolResults] });
459
487
  }
460
488
  };
461
- const pushAssistant = (content: string, toolUses: KiroToolUse[]): void => {
489
+ const pushAssistant = (content: string, toolUses: KiroToolUse[], redactedReasoning?: string): void => {
462
490
  const last = turns.at(-1);
463
491
  if (last?.kind === "assistant") {
464
492
  last.content = appendTurnText(last.content, content);
465
493
  last.toolUses.push(...toolUses);
494
+ // Merged turns keep the newest blob: it covers the reasoning up to the merged turn's end.
495
+ if (redactedReasoning) last.redactedReasoning = redactedReasoning;
466
496
  } else {
467
- turns.push({ kind: "assistant", content, toolUses: [...toolUses] });
497
+ turns.push({ kind: "assistant", content, toolUses: [...toolUses], ...(redactedReasoning ? { redactedReasoning } : {}) });
468
498
  }
469
499
  };
470
500
 
@@ -494,7 +524,7 @@ export function buildKiroPayload(
494
524
  const hasReasoning = aMsg.content.some(part => part.type === "thinking" && part.thinking.trim());
495
525
  if (hasReasoning) continue;
496
526
  }
497
- pushAssistant(text, toolUses);
527
+ pushAssistant(text, toolUses, aMsg.kiroRedactedReasoning);
498
528
  } else if (msg.role === "toolResult") {
499
529
  const tr = msg as OcxToolResultMessage;
500
530
  if (tr.containsEncryptedContent) {
@@ -548,6 +578,7 @@ export function buildKiroPayload(
548
578
  assistantResponseMessage: {
549
579
  content: turn.content,
550
580
  ...(turn.toolUses.length > 0 ? { toolUses: turn.toolUses } : {}),
581
+ ...(turn.redactedReasoning ? { reasoningContent: { redactedContent: turn.redactedReasoning } } : {}),
551
582
  },
552
583
  }
553
584
  : {
@@ -607,8 +638,8 @@ export function buildKiroPayload(
607
638
 
608
639
  // Stream parsing (shared by parseStream + parseResponse)
609
640
  // CodeWhisperer GenerateAssistantResponse ALWAYS returns an AWS eventstream body (there is no
610
- // non-streaming mode), so both the streaming bridge and the non-streaming web-search sidecar loop
611
- // decode the same way — parseResponse just collects what parseStream yields.
641
+ // non-streaming wire mode), so the streaming bridge and non-streaming Responses path decode the
642
+ // same way — parseResponse just collects what parseStream yields.
612
643
  interface KiroAttemptParseResult {
613
644
  terminal?: AdapterEvent;
614
645
  needsFallback?: boolean;
@@ -830,16 +861,12 @@ async function* parseKiroAttempt(
830
861
  );
831
862
  let handedOff = false;
832
863
  try {
833
- let next = await attempt.next();
834
- while (!next.done) {
835
- yield next.value;
836
- next = await attempt.next();
837
- }
864
+ const result = yield* attempt;
838
865
  for (const event of deferred.splice(0)) {
839
866
  try { yield event; } finally { retention.releaseEvent(event); }
840
867
  }
841
868
  handedOff = true;
842
- return { ...next.value, releaseRetained: () => retention.releaseAll() };
869
+ return { ...result, releaseRetained: () => retention.releaseAll() };
843
870
  } finally {
844
871
  if (!handedOff) retention.releaseAll();
845
872
  }
@@ -868,6 +895,12 @@ async function* parseKiroAttemptEvents(
868
895
  }
869
896
 
870
897
  let open: { id: string; name: string; chunks: string[]; completion: boolean } | null = null;
898
+ let openCallId: string | undefined;
899
+ const closeOpenCall = () => {
900
+ if (!openCallId) return;
901
+ budget.closeCall(openCallId);
902
+ openCallId = undefined;
903
+ };
871
904
  let outputChars = "";
872
905
  let outputCharsBytes = 0;
873
906
  let contextUsagePercentage: number | undefined;
@@ -1080,7 +1113,7 @@ async function* parseKiroAttemptEvents(
1080
1113
  if (!open) return { events: [] };
1081
1114
  const tool = open;
1082
1115
  open = null;
1083
- budget.closeCall(tool.id);
1116
+ closeOpenCall();
1084
1117
  const input = tool.chunks.join("");
1085
1118
  if (!isCompleteKiroToolInput(input)) {
1086
1119
  return { events: [], terminal: protocolTerminal(kiroTruncationErrorMessage("incomplete tool input JSON"), tool.completion) };
@@ -1170,6 +1203,12 @@ async function* parseKiroAttemptEvents(
1170
1203
  if (ev.data) {
1171
1204
  yield* emitRetained(stage({ type: "reasoning_raw_delta", text: ev.data }));
1172
1205
  }
1206
+ if (ev.redactedContent) {
1207
+ yield* emitRetained(stage({ type: "kiro_redacted_reasoning", data: ev.redactedContent }));
1208
+ }
1209
+ break;
1210
+ case "context_usage":
1211
+ if (ev.contextUsagePercentage > 0) contextUsagePercentage = ev.contextUsagePercentage;
1173
1212
  break;
1174
1213
  case "tool": {
1175
1214
  for (const contentEvent of thinking.flush()) {
@@ -1186,11 +1225,12 @@ async function* parseKiroAttemptEvents(
1186
1225
  if (started.terminal) return { assistantText, sawReasoning, terminal: started.terminal };
1187
1226
  open = started.tool!;
1188
1227
  budget.openCall(open.id);
1228
+ openCallId = open.id;
1189
1229
  } else if (
1190
1230
  (ev.toolUseId && ev.toolUseId !== open.id)
1191
1231
  || (ev.name && open.name !== "unknown" && ev.name !== open.name)
1192
1232
  ) {
1193
- budget.closeCall(open.id);
1233
+ closeOpenCall();
1194
1234
  open = null;
1195
1235
  return { assistantText, sawReasoning, terminal: protocolTerminal(kiroTruncationErrorMessage("tool input changed identity before stop")) };
1196
1236
  }
@@ -1454,7 +1494,7 @@ async function* parseKiroAttemptEvents(
1454
1494
  };
1455
1495
  } catch (err) {
1456
1496
  if (isTranslatorBudgetExceededError(err)) {
1457
- if (open) budget.closeCall(open.id);
1497
+ closeOpenCall();
1458
1498
  return {
1459
1499
  assistantText,
1460
1500
  sawReasoning,
@@ -1496,6 +1536,9 @@ async function* parseKiroAttemptEvents(
1496
1536
  usage: usage(),
1497
1537
  },
1498
1538
  };
1539
+ } finally {
1540
+ thinking.dispose();
1541
+ closeOpenCall();
1499
1542
  }
1500
1543
  }
1501
1544
 
@@ -1512,7 +1555,7 @@ export async function* parseKiroStream(
1512
1555
  contextInputEstimate?: number,
1513
1556
  ): AsyncGenerator<AdapterEvent> {
1514
1557
  const contextWindowState: KiroContextWindowState = { value: contextWindow };
1515
- const first = parseKiroAttempt(
1558
+ const firstResult = yield* parseKiroAttempt(
1516
1559
  response,
1517
1560
  budget,
1518
1561
  completionMode,
@@ -1524,12 +1567,6 @@ export async function* parseKiroStream(
1524
1567
  contextInputEstimate,
1525
1568
  false,
1526
1569
  );
1527
- let firstNext = await first.next();
1528
- while (!firstNext.done) {
1529
- yield firstNext.value;
1530
- firstNext = await first.next();
1531
- }
1532
- const firstResult = firstNext.value;
1533
1570
  try {
1534
1571
  if (!firstResult.needsFallback) {
1535
1572
  if (firstResult.terminal) yield firstResult.terminal;
@@ -1607,7 +1644,7 @@ export async function* parseKiroStream(
1607
1644
  return;
1608
1645
  }
1609
1646
 
1610
- const second = parseKiroAttempt(
1647
+ const secondResult = yield* parseKiroAttempt(
1611
1648
  fallback.response,
1612
1649
  budget,
1613
1650
  "text_fallback",
@@ -1621,12 +1658,6 @@ export async function* parseKiroStream(
1621
1658
  // A zero-output transport failure here must stay non-retryable to avoid duplicating that text.
1622
1659
  priorEmittedOutput,
1623
1660
  );
1624
- let secondNext = await second.next();
1625
- while (!secondNext.done) {
1626
- yield secondNext.value;
1627
- secondNext = await second.next();
1628
- }
1629
- const secondResult = secondNext.value;
1630
1661
  try {
1631
1662
  if (!secondResult.terminal) {
1632
1663
  yield retryableKiroIncomplete(
@@ -1874,25 +1905,32 @@ export function createKiroAdapter(provider: OcxProviderConfig): ProviderAdapter
1874
1905
  return safeKiroHttpErrorMessage(status, headers, payloadText);
1875
1906
  },
1876
1907
 
1877
- // Non-streaming path used by the web-search sidecar loop (loop.ts runs each iteration
1878
- // non-streamed so it can inspect tool calls). CW only ever event-streams, so we drain the
1879
- // same decoder into an array. Without this, any Codex request that includes the web_search
1880
- // tool failed with "web-search sidecar requires a non-streaming adapter" (kiro-only).
1908
+ // Kiro always returns an event stream, including for non-streaming Responses requests. Drain
1909
+ // the decoder into a budget-owned batch so an upstream stream cannot grow this array without
1910
+ // bound while the caller waits for the complete JSON response.
1881
1911
  async parseResponse(response: Response, budget: TranslatorBudget): Promise<AdapterEvent[]> {
1882
1912
  const events: AdapterEvent[] = [];
1883
- for await (const e of parseKiroStream(
1884
- response,
1885
- budget,
1886
- modelId,
1887
- inputTokens,
1888
- contextWindow,
1889
- toolNameMap,
1890
- conversationId,
1891
- completionMode,
1892
- completionMode === "required" ? fallbackFactory : undefined,
1893
- contextInputEstimate,
1894
- )) events.push(e);
1895
- return events;
1913
+ try {
1914
+ for await (const e of parseKiroStream(
1915
+ response,
1916
+ budget,
1917
+ modelId,
1918
+ inputTokens,
1919
+ contextWindow,
1920
+ toolNameMap,
1921
+ conversationId,
1922
+ completionMode,
1923
+ completionMode === "required" ? fallbackFactory : undefined,
1924
+ contextInputEstimate,
1925
+ )) {
1926
+ retainTranslatedEvent(e, budget, events.at(-1));
1927
+ events.push(e);
1928
+ }
1929
+ return events;
1930
+ } catch (error) {
1931
+ for (const event of events) releaseTranslatedEvent(event, budget);
1932
+ throw error;
1933
+ }
1896
1934
  },
1897
1935
  };
1898
1936
  }
@@ -40,6 +40,18 @@ function randomUserAgent(): string {
40
40
  return USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)]!;
41
41
  }
42
42
 
43
+ function isCanonicalMimoFreeEndpoint(baseUrl: string): boolean {
44
+ try {
45
+ const actual = new URL(baseUrl.trim());
46
+ const expected = new URL(MIMO_CHAT_URL);
47
+ actual.pathname = actual.pathname.replace(/\/+$/, "") || "/";
48
+ expected.pathname = expected.pathname.replace(/\/+$/, "") || "/";
49
+ return actual.toString().replace(/\/$/, "") === expected.toString().replace(/\/$/, "");
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
54
+
43
55
  /**
44
56
  * Anonymous per-install client id for the bootstrap `client` field. A random UUID
45
57
  * persisted under the config dir (OPENCODEX_HOME-aware) — deliberately NOT derived
@@ -194,6 +206,11 @@ export function injectMimoSystemMarker(body: unknown): unknown {
194
206
  * On 401/403, flushes the JWT cache and retries once via fetchResponse.
195
207
  */
196
208
  export function createMimoFreeAdapter(provider: OcxProviderConfig): ProviderAdapter {
209
+ if (!isCanonicalMimoFreeEndpoint(provider.baseUrl)) {
210
+ throw new Error(
211
+ "The mimo-free adapter only supports the canonical Xiaomi MiMo Free endpoint. Use openai-chat for a custom endpoint.",
212
+ );
213
+ }
197
214
  const base = createOpenAIChatAdapter(provider);
198
215
  // Per-adapter session-affinity id (random, per process instance).
199
216
  const sessionId = `ses_${Math.random().toString(36).slice(2, 26)}`;
@@ -0,0 +1,11 @@
1
+ const TRAILING_SLASHES = /\/+$/;
2
+ const TRAILING_CHAT_COMPLETIONS = /\/chat\/completions\/?$/;
3
+
4
+ /** Build the openai-chat send URL from a configured baseUrl.
5
+ * Accepts /v1, /v1/, /v1/chat/completions, and /v1/chat/completions/.
6
+ */
7
+ export function openaiChatCompletionsUrl(baseUrl: string): string {
8
+ const trimmed = baseUrl.trim().replace(TRAILING_SLASHES, "");
9
+ const withoutEndpoint = trimmed.replace(TRAILING_CHAT_COMPLETIONS, "");
10
+ return `${withoutEndpoint}/chat/completions`;
11
+ }