@yansigit/opencodex 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 (826) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/LICENSE +21 -0
  3. package/README.md +303 -0
  4. package/assets/architecture.png +0 -0
  5. package/assets/banner.png +0 -0
  6. package/assets/claude-code-models.gif +0 -0
  7. package/assets/codex-app-picker.png +0 -0
  8. package/bin/ocx.mjs +587 -0
  9. package/bin/package-main.mjs +9 -0
  10. package/gui/dist/assets/index-BNJ7r4Gd.js +102 -0
  11. package/gui/dist/assets/index-CGoDO3uO.css +1 -0
  12. package/gui/dist/favicon.png +0 -0
  13. package/gui/dist/icons.svg +24 -0
  14. package/gui/dist/index.html +25 -0
  15. package/gui/dist/logo.png +0 -0
  16. package/gui/dist/provider-icons/alibaba-color.svg +1 -0
  17. package/gui/dist/provider-icons/antigravity-color.svg +1 -0
  18. package/gui/dist/provider-icons/claude-color.svg +1 -0
  19. package/gui/dist/provider-icons/cline-color.svg +16 -0
  20. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
  21. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  22. package/gui/dist/provider-icons/copilot-color.svg +1 -0
  23. package/gui/dist/provider-icons/cursor-color.svg +2 -0
  24. package/gui/dist/provider-icons/deepseek-color.svg +1 -0
  25. package/gui/dist/provider-icons/discord.svg +1 -0
  26. package/gui/dist/provider-icons/firepass-color.svg +1 -0
  27. package/gui/dist/provider-icons/fireworks-color.svg +1 -0
  28. package/gui/dist/provider-icons/gemini-color.svg +1 -0
  29. package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
  30. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
  31. package/gui/dist/provider-icons/grok.svg +1 -0
  32. package/gui/dist/provider-icons/groq-color.svg +1 -0
  33. package/gui/dist/provider-icons/huggingface-color.svg +1 -0
  34. package/gui/dist/provider-icons/kimi-color.svg +1 -0
  35. package/gui/dist/provider-icons/kiro-color.svg +15 -0
  36. package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
  37. package/gui/dist/provider-icons/mistral-color.svg +1 -0
  38. package/gui/dist/provider-icons/moonshot-color.svg +1 -0
  39. package/gui/dist/provider-icons/nvidia-color.svg +1 -0
  40. package/gui/dist/provider-icons/ollama-color.svg +1 -0
  41. package/gui/dist/provider-icons/openai.svg +1 -0
  42. package/gui/dist/provider-icons/opencode.svg +2 -0
  43. package/gui/dist/provider-icons/openrouter-color.svg +1 -0
  44. package/gui/dist/provider-icons/pi.svg +21 -0
  45. package/gui/dist/provider-icons/qianfan-color.svg +1 -0
  46. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
  47. package/gui/dist/provider-icons/telegram.svg +1 -0
  48. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
  49. package/gui/dist/provider-icons/vllm-color.svg +1 -0
  50. package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
  51. package/package.json +108 -0
  52. package/src/AGENTS.md +28 -0
  53. package/src/adapters/anthropic-image-guard.ts +251 -0
  54. package/src/adapters/anthropic-image-normalize.ts +518 -0
  55. package/src/adapters/anthropic-output-schema.ts +137 -0
  56. package/src/adapters/anthropic.ts +1327 -0
  57. package/src/adapters/azure.ts +36 -0
  58. package/src/adapters/base.ts +121 -0
  59. package/src/adapters/client-fingerprint.ts +65 -0
  60. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  61. package/src/adapters/command-code.ts +601 -0
  62. package/src/adapters/cursor/arg-codec.ts +38 -0
  63. package/src/adapters/cursor/arg-normalize.ts +104 -0
  64. package/src/adapters/cursor/checkpoint-store.ts +303 -0
  65. package/src/adapters/cursor/cursor-errors.ts +288 -0
  66. package/src/adapters/cursor/discovery.ts +333 -0
  67. package/src/adapters/cursor/effort-map.ts +151 -0
  68. package/src/adapters/cursor/exec-policy.ts +88 -0
  69. package/src/adapters/cursor/framing.ts +250 -0
  70. package/src/adapters/cursor/gen/agent_pb.ts +15274 -0
  71. package/src/adapters/cursor/h2-pool.ts +123 -0
  72. package/src/adapters/cursor/http1-bidi.ts +361 -0
  73. package/src/adapters/cursor/images.ts +704 -0
  74. package/src/adapters/cursor/kv-store.ts +52 -0
  75. package/src/adapters/cursor/live-models.ts +269 -0
  76. package/src/adapters/cursor/live-smoke-gate.ts +41 -0
  77. package/src/adapters/cursor/live-transport.ts +1653 -0
  78. package/src/adapters/cursor/mcp-config.ts +42 -0
  79. package/src/adapters/cursor/mcp-manager.ts +333 -0
  80. package/src/adapters/cursor/message-mapper.ts +49 -0
  81. package/src/adapters/cursor/native-exec-common.ts +76 -0
  82. package/src/adapters/cursor/native-exec-desktop.ts +184 -0
  83. package/src/adapters/cursor/native-exec-fs.ts +332 -0
  84. package/src/adapters/cursor/native-exec-mcp.ts +153 -0
  85. package/src/adapters/cursor/native-exec-network.ts +43 -0
  86. package/src/adapters/cursor/native-exec-shell.ts +547 -0
  87. package/src/adapters/cursor/native-exec-tools.ts +118 -0
  88. package/src/adapters/cursor/native-exec.ts +663 -0
  89. package/src/adapters/cursor/protobuf-events.ts +1381 -0
  90. package/src/adapters/cursor/protobuf-request.ts +1032 -0
  91. package/src/adapters/cursor/request-builder.ts +461 -0
  92. package/src/adapters/cursor/thread-continuity.ts +67 -0
  93. package/src/adapters/cursor/tool-definitions.ts +735 -0
  94. package/src/adapters/cursor/tool-result-normalize.ts +92 -0
  95. package/src/adapters/cursor/transport-retry.ts +132 -0
  96. package/src/adapters/cursor/transport.ts +79 -0
  97. package/src/adapters/cursor/types.ts +79 -0
  98. package/src/adapters/cursor.ts +322 -0
  99. package/src/adapters/google-antigravity-hosts.ts +48 -0
  100. package/src/adapters/google-antigravity-replay.ts +827 -0
  101. package/src/adapters/google-antigravity-tools.ts +105 -0
  102. package/src/adapters/google-antigravity-wire.ts +141 -0
  103. package/src/adapters/google-errors.ts +92 -0
  104. package/src/adapters/google-http.ts +460 -0
  105. package/src/adapters/google-tool-schema.ts +238 -0
  106. package/src/adapters/google-truncation.ts +24 -0
  107. package/src/adapters/google-wire-compiler.ts +232 -0
  108. package/src/adapters/google.ts +1377 -0
  109. package/src/adapters/identity.ts +77 -0
  110. package/src/adapters/image.ts +23 -0
  111. package/src/adapters/kiro-constants.ts +16 -0
  112. package/src/adapters/kiro-errors.ts +208 -0
  113. package/src/adapters/kiro-events.ts +197 -0
  114. package/src/adapters/kiro-images.ts +129 -0
  115. package/src/adapters/kiro-retry.ts +312 -0
  116. package/src/adapters/kiro-thinking.ts +112 -0
  117. package/src/adapters/kiro-tool-fallback.ts +36 -0
  118. package/src/adapters/kiro-tools.ts +224 -0
  119. package/src/adapters/kiro-truncation.ts +33 -0
  120. package/src/adapters/kiro-wire.ts +129 -0
  121. package/src/adapters/kiro.ts +1936 -0
  122. package/src/adapters/mimo-free.ts +280 -0
  123. package/src/adapters/openai-chat-url.ts +11 -0
  124. package/src/adapters/openai-chat.ts +1980 -0
  125. package/src/adapters/openai-responses-url.ts +16 -0
  126. package/src/adapters/openai-responses.ts +1911 -0
  127. package/src/adapters/registry.ts +175 -0
  128. package/src/adapters/responses-tool-schema.ts +67 -0
  129. package/src/adapters/run-turn-queue.ts +114 -0
  130. package/src/adapters/tool-call-id.ts +119 -0
  131. package/src/adapters/tool-catalog-nudge.ts +154 -0
  132. package/src/adapters/upstream-http-error.ts +48 -0
  133. package/src/adapters/xai-web-search.ts +185 -0
  134. package/src/bridge.ts +1986 -0
  135. package/src/chat/inbound.ts +319 -0
  136. package/src/chat/outbound.ts +821 -0
  137. package/src/claude/agents-inject.ts +266 -0
  138. package/src/claude/alias.ts +149 -0
  139. package/src/claude/auth-detect.ts +229 -0
  140. package/src/claude/auth-mode-migration.ts +32 -0
  141. package/src/claude/auth-mode.ts +62 -0
  142. package/src/claude/context-windows.ts +205 -0
  143. package/src/claude/desktop-3p-guard.ts +35 -0
  144. package/src/claude/desktop-3p-paths.ts +84 -0
  145. package/src/claude/desktop-3p.ts +615 -0
  146. package/src/claude/desktop-health.ts +26 -0
  147. package/src/claude/desktop-profile.ts +263 -0
  148. package/src/claude/gateway-cache.ts +107 -0
  149. package/src/claude/inbound-debug.ts +163 -0
  150. package/src/claude/inbound.ts +578 -0
  151. package/src/claude/model-info.ts +174 -0
  152. package/src/claude/outbound.ts +926 -0
  153. package/src/cli/access.ts +108 -0
  154. package/src/cli/account-api.ts +302 -0
  155. package/src/cli/account-auth.ts +250 -0
  156. package/src/cli/account-catalog-refresh.ts +14 -0
  157. package/src/cli/account-extended.ts +737 -0
  158. package/src/cli/account-main.ts +317 -0
  159. package/src/cli/account.ts +299 -0
  160. package/src/cli/agent-driven.ts +70 -0
  161. package/src/cli/agent.ts +290 -0
  162. package/src/cli/catalog-prewarm.ts +27 -0
  163. package/src/cli/claude-agent-startup-sync.ts +73 -0
  164. package/src/cli/claude-desktop.ts +213 -0
  165. package/src/cli/claude.ts +355 -0
  166. package/src/cli/codex-log-guard-doctor.ts +103 -0
  167. package/src/cli/codex-shim-autorestore.ts +47 -0
  168. package/src/cli/codex-shim-readiness.ts +76 -0
  169. package/src/cli/combo.ts +127 -0
  170. package/src/cli/config-command.ts +209 -0
  171. package/src/cli/debug.ts +228 -0
  172. package/src/cli/dispatch.ts +585 -0
  173. package/src/cli/doctor.ts +1202 -0
  174. package/src/cli/ensure-desired-integrations.ts +152 -0
  175. package/src/cli/export-command.ts +213 -0
  176. package/src/cli/help.ts +101 -0
  177. package/src/cli/index.ts +973 -0
  178. package/src/cli/init.ts +211 -0
  179. package/src/cli/integrations.ts +260 -0
  180. package/src/cli/interactive-confirm.ts +133 -0
  181. package/src/cli/lab.ts +607 -0
  182. package/src/cli/launcher-context.ts +77 -0
  183. package/src/cli/minimax.ts +497 -0
  184. package/src/cli/models-runtime.ts +245 -0
  185. package/src/cli/models.ts +422 -0
  186. package/src/cli/observe.ts +206 -0
  187. package/src/cli/opencode.ts +588 -0
  188. package/src/cli/provider-replit.ts +232 -0
  189. package/src/cli/provider-runtime.ts +179 -0
  190. package/src/cli/provider.ts +492 -0
  191. package/src/cli/ready.ts +301 -0
  192. package/src/cli/registry.ts +422 -0
  193. package/src/cli/replit-gateway-key-input.ts +138 -0
  194. package/src/cli/root.ts +86 -0
  195. package/src/cli/route-policy.ts +92 -0
  196. package/src/cli/runtime-api.ts +328 -0
  197. package/src/cli/star-prompt.ts +211 -0
  198. package/src/cli/status-oauth.ts +78 -0
  199. package/src/cli/status.ts +328 -0
  200. package/src/cli/system-command.ts +112 -0
  201. package/src/cli/system-restart-client.ts +146 -0
  202. package/src/cli/tray-proxy.ts +199 -0
  203. package/src/cli/v2.ts +268 -0
  204. package/src/cli.ts +10 -0
  205. package/src/clients/config-export.ts +1704 -0
  206. package/src/codex/account-id.ts +34 -0
  207. package/src/codex/account-label.ts +47 -0
  208. package/src/codex/account-lifecycle.ts +172 -0
  209. package/src/codex/account-namespace-match.ts +63 -0
  210. package/src/codex/account-namespaces.ts +195 -0
  211. package/src/codex/account-pause.ts +20 -0
  212. package/src/codex/account-priority.ts +83 -0
  213. package/src/codex/account-runtime-state.ts +31 -0
  214. package/src/codex/account-store.ts +544 -0
  215. package/src/codex/account-usability.ts +43 -0
  216. package/src/codex/admission.ts +256 -0
  217. package/src/codex/affinity-debug.ts +162 -0
  218. package/src/codex/agent-roles-sync.ts +225 -0
  219. package/src/codex/agent-roles.ts +238 -0
  220. package/src/codex/app-server-processes.ts +1143 -0
  221. package/src/codex/app-server-restart-service.ts +232 -0
  222. package/src/codex/auth-api.ts +2147 -0
  223. package/src/codex/auth-collision.ts +109 -0
  224. package/src/codex/auth-context.ts +665 -0
  225. package/src/codex/autostart-health.ts +156 -0
  226. package/src/codex/catalog/account-models.ts +67 -0
  227. package/src/codex/catalog/aggregation.ts +436 -0
  228. package/src/codex/catalog/bundled.ts +549 -0
  229. package/src/codex/catalog/effort.ts +446 -0
  230. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  231. package/src/codex/catalog/kinds.ts +2 -0
  232. package/src/codex/catalog/metadata.ts +664 -0
  233. package/src/codex/catalog/native-models.ts +72 -0
  234. package/src/codex/catalog/parsing.ts +650 -0
  235. package/src/codex/catalog/provider-fetch.ts +2064 -0
  236. package/src/codex/catalog/sync.ts +1883 -0
  237. package/src/codex/catalog-admission.ts +199 -0
  238. package/src/codex/catalog-refresh-status.ts +105 -0
  239. package/src/codex/catalog-write-serialization.ts +242 -0
  240. package/src/codex/catalog.ts +14 -0
  241. package/src/codex/codex-write-lock.ts +384 -0
  242. package/src/codex/convergence-types.ts +614 -0
  243. package/src/codex/convergence.ts +651 -0
  244. package/src/codex/coordinator-doctor.ts +332 -0
  245. package/src/codex/custom-model-catalog-migration.ts +176 -0
  246. package/src/codex/data/upstream-models.json +830 -0
  247. package/src/codex/desired-state.ts +230 -0
  248. package/src/codex/exec-invocation.ts +22 -0
  249. package/src/codex/features.ts +1566 -0
  250. package/src/codex/generation.ts +202 -0
  251. package/src/codex/history-job.ts +407 -0
  252. package/src/codex/history-lock.ts +242 -0
  253. package/src/codex/history-migration-guardian.ts +108 -0
  254. package/src/codex/history-provider.ts +979 -0
  255. package/src/codex/history-transition.ts +105 -0
  256. package/src/codex/history-worker.ts +220 -0
  257. package/src/codex/home.ts +206 -0
  258. package/src/codex/inject-coordination.ts +290 -0
  259. package/src/codex/inject.ts +1733 -0
  260. package/src/codex/injected-marker.ts +106 -0
  261. package/src/codex/integration-record.ts +266 -0
  262. package/src/codex/internal/catalog-writer.ts +203 -0
  263. package/src/codex/internal/history-writer.ts +80 -0
  264. package/src/codex/journal.ts +225 -0
  265. package/src/codex/log-guard/inspect.ts +506 -0
  266. package/src/codex/log-guard/lock.ts +150 -0
  267. package/src/codex/log-guard/maintenance.ts +403 -0
  268. package/src/codex/log-guard/path-safety.ts +88 -0
  269. package/src/codex/log-guard/policy.ts +44 -0
  270. package/src/codex/log-guard/processes.ts +205 -0
  271. package/src/codex/log-guard/protection.ts +489 -0
  272. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  273. package/src/codex/main-account-cache.ts +56 -0
  274. package/src/codex/main-account.ts +68 -0
  275. package/src/codex/management-convergence.ts +167 -0
  276. package/src/codex/model-cache.ts +273 -0
  277. package/src/codex/model-entitlements.ts +353 -0
  278. package/src/codex/native-main-admission.ts +47 -0
  279. package/src/codex/native-main-auth-temp.ts +187 -0
  280. package/src/codex/native-main-claim.ts +178 -0
  281. package/src/codex/native-main-lock-file.ts +162 -0
  282. package/src/codex/native-main-owner.ts +329 -0
  283. package/src/codex/native-profile-api.ts +247 -0
  284. package/src/codex/native-profile-manager.ts +1531 -0
  285. package/src/codex/native-profile-processes.ts +121 -0
  286. package/src/codex/native-profile-recovery.ts +99 -0
  287. package/src/codex/native-profile-stage-store.ts +387 -0
  288. package/src/codex/native-profile-startup.ts +492 -0
  289. package/src/codex/native-profile-store.ts +855 -0
  290. package/src/codex/native-profile-types.ts +120 -0
  291. package/src/codex/native-residue.ts +682 -0
  292. package/src/codex/paths.ts +144 -0
  293. package/src/codex/plan-from-token.ts +140 -0
  294. package/src/codex/plan.ts +40 -0
  295. package/src/codex/plugins-doctor.ts +242 -0
  296. package/src/codex/pool-rotation.ts +295 -0
  297. package/src/codex/project-config-warnings.ts +425 -0
  298. package/src/codex/prompt-journal.ts +352 -0
  299. package/src/codex/prompt-layers.ts +967 -0
  300. package/src/codex/prompt-lock.ts +143 -0
  301. package/src/codex/quota-rejection.ts +298 -0
  302. package/src/codex/quota.ts +573 -0
  303. package/src/codex/refresh.ts +62 -0
  304. package/src/codex/reset-credit-recovery.ts +1044 -0
  305. package/src/codex/routing.ts +1888 -0
  306. package/src/codex/runtime.ts +659 -0
  307. package/src/codex/shim.ts +2170 -0
  308. package/src/codex/subagent-defaults.ts +550 -0
  309. package/src/codex/subagent-model-fallback.ts +784 -0
  310. package/src/codex/sync.ts +319 -0
  311. package/src/codex/transition-state.ts +612 -0
  312. package/src/codex/upstream-host-health.ts +368 -0
  313. package/src/codex/user-identity.ts +557 -0
  314. package/src/codex/warmup.ts +298 -0
  315. package/src/codex/websocket-registry.ts +100 -0
  316. package/src/codex/write-coordination.ts +114 -0
  317. package/src/combos/failover.ts +160 -0
  318. package/src/combos/index.ts +45 -0
  319. package/src/combos/request.ts +94 -0
  320. package/src/combos/resolve.ts +232 -0
  321. package/src/combos/types.ts +398 -0
  322. package/src/config/provider-name.ts +24 -0
  323. package/src/config.ts +4041 -0
  324. package/src/fork/register.ts +3 -0
  325. package/src/generated/compatibility-version.json +3116 -0
  326. package/src/generated/model-metadata.ts +106 -0
  327. package/src/github/star-state.ts +203 -0
  328. package/src/grok/inject.ts +530 -0
  329. package/src/grok/inspect.ts +45 -0
  330. package/src/grok/status.ts +121 -0
  331. package/src/grok/sync.ts +66 -0
  332. package/src/images/artifacts.ts +516 -0
  333. package/src/images/fulfill-video.ts +163 -0
  334. package/src/images/fulfill.ts +149 -0
  335. package/src/images/index.ts +4 -0
  336. package/src/images/loop.ts +955 -0
  337. package/src/images/plan.ts +143 -0
  338. package/src/images/synthetic-tool.ts +133 -0
  339. package/src/images/types.ts +41 -0
  340. package/src/images/xai-client.ts +141 -0
  341. package/src/images/xai-video-client.ts +163 -0
  342. package/src/index.ts +22 -0
  343. package/src/integrations/config-io.ts +269 -0
  344. package/src/integrations/journal.ts +315 -0
  345. package/src/integrations/merge.ts +135 -0
  346. package/src/integrations/mutation-flight.ts +71 -0
  347. package/src/integrations/native/ownership-preflight.ts +202 -0
  348. package/src/integrations/omp-yaml-source.ts +358 -0
  349. package/src/integrations/owned-refresh.ts +74 -0
  350. package/src/integrations/ownership.ts +111 -0
  351. package/src/integrations/registry.ts +159 -0
  352. package/src/integrations/serialize.ts +314 -0
  353. package/src/integrations/state.ts +361 -0
  354. package/src/integrations/store.ts +103 -0
  355. package/src/integrations/writer-lock.ts +98 -0
  356. package/src/integrations/writer.ts +691 -0
  357. package/src/lab/artifacts/sanitize.ts +586 -0
  358. package/src/lab/artifacts/secure-fs.ts +475 -0
  359. package/src/lab/artifacts/store.ts +310 -0
  360. package/src/lab/automation/budgets.ts +78 -0
  361. package/src/lab/automation/config-persistence.ts +256 -0
  362. package/src/lab/automation/constants.ts +39 -0
  363. package/src/lab/automation/cooldown.ts +103 -0
  364. package/src/lab/automation/dispatch.ts +211 -0
  365. package/src/lab/automation/index.ts +13 -0
  366. package/src/lab/automation/orchestrator.ts +499 -0
  367. package/src/lab/automation/persistence.ts +512 -0
  368. package/src/lab/automation/planner.ts +371 -0
  369. package/src/lab/automation/policy.ts +136 -0
  370. package/src/lab/automation/queue.ts +191 -0
  371. package/src/lab/automation/recovery.ts +24 -0
  372. package/src/lab/automation/route-context.ts +21 -0
  373. package/src/lab/automation/run-key.ts +44 -0
  374. package/src/lab/automation/runs-query.ts +34 -0
  375. package/src/lab/automation/types.ts +160 -0
  376. package/src/lab/conformance/assertion.ts +325 -0
  377. package/src/lab/conformance/digest.ts +22 -0
  378. package/src/lab/conformance/executor.ts +741 -0
  379. package/src/lab/conformance/fixture-provider.ts +27 -0
  380. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  381. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  382. package/src/lab/conformance/harness-budget.ts +47 -0
  383. package/src/lab/conformance/index.ts +5 -0
  384. package/src/lab/conformance/jcs.ts +64 -0
  385. package/src/lab/conformance/json-pointer.ts +39 -0
  386. package/src/lab/conformance/manifest.ts +180 -0
  387. package/src/lab/conformance/mcp-stub.ts +179 -0
  388. package/src/lab/conformance/negative-controls.ts +164 -0
  389. package/src/lab/conformance/observation.ts +355 -0
  390. package/src/lab/conformance/runner.ts +68 -0
  391. package/src/lab/conformance/sse-normalize.ts +59 -0
  392. package/src/lab/conformance/suite-manifest.ts +78 -0
  393. package/src/lab/conformance/types.ts +214 -0
  394. package/src/lab/constants.ts +126 -0
  395. package/src/lab/digest.ts +64 -0
  396. package/src/lab/events/errors.ts +9 -0
  397. package/src/lab/events/limits.ts +117 -0
  398. package/src/lab/events/types.ts +229 -0
  399. package/src/lab/events/validate.ts +781 -0
  400. package/src/lab/fabric/constants.ts +40 -0
  401. package/src/lab/fabric/executor.ts +492 -0
  402. package/src/lab/fabric/index.ts +80 -0
  403. package/src/lab/fabric/manifest.ts +222 -0
  404. package/src/lab/fabric/observe.ts +489 -0
  405. package/src/lab/fabric/patch.ts +79 -0
  406. package/src/lab/fabric/producer-child.ts +139 -0
  407. package/src/lab/fabric/producer-isolate.ts +276 -0
  408. package/src/lab/fabric/producer-protocol.ts +61 -0
  409. package/src/lab/fabric/scratch.ts +439 -0
  410. package/src/lab/fabric/subject.ts +106 -0
  411. package/src/lab/fabric/types.ts +134 -0
  412. package/src/lab/fabric/verifier.ts +98 -0
  413. package/src/lab/index.ts +54 -0
  414. package/src/lab/ledger/artifact-refs.ts +127 -0
  415. package/src/lab/ledger/invalidation.ts +136 -0
  416. package/src/lab/ledger/purge.ts +310 -0
  417. package/src/lab/ledger/store.ts +532 -0
  418. package/src/lab/live/credential-lease.ts +53 -0
  419. package/src/lab/live/destination.ts +155 -0
  420. package/src/lab/live/executor.ts +336 -0
  421. package/src/lab/live/inert-tools.ts +56 -0
  422. package/src/lab/live/manifest.ts +85 -0
  423. package/src/lab/live/mcp-loopback.ts +57 -0
  424. package/src/lab/live/runner.ts +19 -0
  425. package/src/lab/live/sandbox.ts +61 -0
  426. package/src/lab/live/suite-manifest.ts +41 -0
  427. package/src/lab/live/transport.ts +118 -0
  428. package/src/lab/live/types.ts +197 -0
  429. package/src/lab/observe/from-conformance.ts +301 -0
  430. package/src/lab/observe/from-live.ts +117 -0
  431. package/src/lab/paths.ts +153 -0
  432. package/src/lab/projection/rebuild.ts +495 -0
  433. package/src/lab/projection/schema.ts +135 -0
  434. package/src/lab/projection/verdicts.ts +474 -0
  435. package/src/lab/projection/verification.ts +412 -0
  436. package/src/lab/public/bundle.ts +217 -0
  437. package/src/lab/public/community-authority.ts +175 -0
  438. package/src/lab/public/community-files.ts +29 -0
  439. package/src/lab/public/community.ts +479 -0
  440. package/src/lab/public/file-safety.ts +155 -0
  441. package/src/lab/public/ids.ts +26 -0
  442. package/src/lab/public/index.ts +16 -0
  443. package/src/lab/public/mutation-lock.ts +424 -0
  444. package/src/lab/public/operator.ts +353 -0
  445. package/src/lab/public/origin-purge.ts +79 -0
  446. package/src/lab/public/origin.ts +203 -0
  447. package/src/lab/public/privacy.ts +143 -0
  448. package/src/lab/public/private-file.ts +261 -0
  449. package/src/lab/public/project.ts +124 -0
  450. package/src/lab/public/purge-test-fault.ts +21 -0
  451. package/src/lab/public/purge.ts +223 -0
  452. package/src/lab/public/registry.ts +44 -0
  453. package/src/lab/public/revocation.ts +252 -0
  454. package/src/lab/public/signature.ts +243 -0
  455. package/src/lab/public/storage.ts +105 -0
  456. package/src/lab/public/strict-json.ts +206 -0
  457. package/src/lab/public/time.ts +26 -0
  458. package/src/lab/public/types.ts +172 -0
  459. package/src/lab/public/validate.ts +391 -0
  460. package/src/lab/query/catalog.ts +101 -0
  461. package/src/lab/query/connection.ts +107 -0
  462. package/src/lab/query/constants.ts +4 -0
  463. package/src/lab/query/cursor.ts +132 -0
  464. package/src/lab/query/dto-map.ts +277 -0
  465. package/src/lab/query/errors.ts +22 -0
  466. package/src/lab/query/freshness.ts +53 -0
  467. package/src/lab/query/index.ts +45 -0
  468. package/src/lab/query/latest-observation.ts +59 -0
  469. package/src/lab/query/passive-production.ts +159 -0
  470. package/src/lab/query/queries.ts +444 -0
  471. package/src/lab/query/types.ts +266 -0
  472. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  473. package/src/lab/subject/installation-salt.ts +112 -0
  474. package/src/lab/subject/protocol-subject.ts +80 -0
  475. package/src/lab/subject/route-subject.ts +74 -0
  476. package/src/lib/abort.ts +146 -0
  477. package/src/lib/admin-secrets.ts +25 -0
  478. package/src/lib/admission.ts +83 -0
  479. package/src/lib/app-owned-memory-stores.ts +195 -0
  480. package/src/lib/app-owned-memory.ts +265 -0
  481. package/src/lib/bounded-body.ts +346 -0
  482. package/src/lib/bun-binary-validator.d.mts +3 -0
  483. package/src/lib/bun-binary-validator.mjs +18 -0
  484. package/src/lib/bun-runtime.ts +184 -0
  485. package/src/lib/bun-stream-caps.ts +130 -0
  486. package/src/lib/codex-restart-contract.ts +120 -0
  487. package/src/lib/config-ownership.ts +364 -0
  488. package/src/lib/crash-guard.ts +344 -0
  489. package/src/lib/debug-log-buffer.ts +83 -0
  490. package/src/lib/debug-settings.ts +108 -0
  491. package/src/lib/debug.ts +31 -0
  492. package/src/lib/destination-policy.ts +380 -0
  493. package/src/lib/errors.ts +406 -0
  494. package/src/lib/eventstream-decoder.ts +253 -0
  495. package/src/lib/fabric-task-execution-authority.ts +7 -0
  496. package/src/lib/fabric-task-host.ts +29 -0
  497. package/src/lib/gcp-adc.ts +341 -0
  498. package/src/lib/injection-debug-log.ts +58 -0
  499. package/src/lib/lab-activation.ts +223 -0
  500. package/src/lib/lab-live-execution-authority.ts +13 -0
  501. package/src/lib/lab-live-host.ts +30 -0
  502. package/src/lib/lab-live-pinned-sender.ts +56 -0
  503. package/src/lib/lab-live-route-production.ts +130 -0
  504. package/src/lib/lab-passive-linker-registration.ts +26 -0
  505. package/src/lib/local-management-attestation.ts +51 -0
  506. package/src/lib/local-management-capability.ts +100 -0
  507. package/src/lib/local-provider-reload-contract.ts +100 -0
  508. package/src/lib/open-url.ts +25 -0
  509. package/src/lib/optional-shutdown-hooks.ts +57 -0
  510. package/src/lib/pinned-http.ts +270 -0
  511. package/src/lib/privacy.ts +20 -0
  512. package/src/lib/process-control.ts +168 -0
  513. package/src/lib/provider-outbound.ts +210 -0
  514. package/src/lib/provider-url.ts +14 -0
  515. package/src/lib/proxy-env.ts +18 -0
  516. package/src/lib/redact.ts +521 -0
  517. package/src/lib/retry-after.ts +55 -0
  518. package/src/lib/self-launch-argv.ts +15 -0
  519. package/src/lib/server-resource-ownership.ts +71 -0
  520. package/src/lib/service-secrets.ts +25 -0
  521. package/src/lib/shadow-call.ts +61 -0
  522. package/src/lib/sidecar-tracker.ts +52 -0
  523. package/src/lib/sse-decoder.ts +364 -0
  524. package/src/lib/state-store-registrations.ts +119 -0
  525. package/src/lib/state-store-sweeper.ts +184 -0
  526. package/src/lib/system-restart-contract.ts +73 -0
  527. package/src/lib/test-home-guard.ts +90 -0
  528. package/src/lib/token-estimate.ts +86 -0
  529. package/src/lib/tool-argument-integers.ts +202 -0
  530. package/src/lib/translator-budget.ts +400 -0
  531. package/src/lib/upstream-http-version.ts +57 -0
  532. package/src/lib/upstream-reachability.ts +95 -0
  533. package/src/lib/upstream-retry.ts +392 -0
  534. package/src/lib/win-exec.ts +115 -0
  535. package/src/lib/win-paths.ts +68 -0
  536. package/src/lib/windows-atomic-replace.ts +156 -0
  537. package/src/lib/windows-elevation.ts +773 -0
  538. package/src/lib/windows-secret-acl.ts +854 -0
  539. package/src/lib/windows-service-wrappers.ts +72 -0
  540. package/src/lib/windows-text.ts +106 -0
  541. package/src/lib/windows-user-principal.ts +341 -0
  542. package/src/lib/winsw.ts +403 -0
  543. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  544. package/src/oauth/account-import/index.ts +15 -0
  545. package/src/oauth/account-import/parser.ts +83 -0
  546. package/src/oauth/account-import/registry.ts +18 -0
  547. package/src/oauth/account-import/service.ts +75 -0
  548. package/src/oauth/account-import/types.ts +91 -0
  549. package/src/oauth/anthropic-routing.ts +594 -0
  550. package/src/oauth/anthropic.ts +188 -0
  551. package/src/oauth/antigravity-routing.ts +151 -0
  552. package/src/oauth/callback-server.ts +300 -0
  553. package/src/oauth/chatgpt.ts +161 -0
  554. package/src/oauth/command-code.ts +239 -0
  555. package/src/oauth/cursor.ts +252 -0
  556. package/src/oauth/github-copilot.ts +428 -0
  557. package/src/oauth/google-antigravity.ts +262 -0
  558. package/src/oauth/health.ts +407 -0
  559. package/src/oauth/index.ts +1504 -0
  560. package/src/oauth/key-providers.ts +124 -0
  561. package/src/oauth/kimi.ts +227 -0
  562. package/src/oauth/kiro-credentials.ts +726 -0
  563. package/src/oauth/kiro.ts +621 -0
  564. package/src/oauth/local-token-detect.ts +130 -0
  565. package/src/oauth/log.ts +50 -0
  566. package/src/oauth/login-cli.ts +223 -0
  567. package/src/oauth/nous.ts +798 -0
  568. package/src/oauth/pkce.ts +15 -0
  569. package/src/oauth/store.ts +728 -0
  570. package/src/oauth/token-guardian.ts +309 -0
  571. package/src/oauth/types.ts +62 -0
  572. package/src/oauth/xai.ts +241 -0
  573. package/src/providers/alibaba-region-backup.ts +75 -0
  574. package/src/providers/alibaba-region-migration.ts +156 -0
  575. package/src/providers/alibaba-region-startup.ts +36 -0
  576. package/src/providers/antigravity-models.ts +695 -0
  577. package/src/providers/antigravity-quota.ts +216 -0
  578. package/src/providers/api-keys.ts +140 -0
  579. package/src/providers/base-url-choices.ts +74 -0
  580. package/src/providers/codex-capacity.ts +292 -0
  581. package/src/providers/command-code-efforts.ts +144 -0
  582. package/src/providers/context-cap.ts +82 -0
  583. package/src/providers/cursor-pool.ts +72 -0
  584. package/src/providers/derive.ts +586 -0
  585. package/src/providers/fastwire.ts +501 -0
  586. package/src/providers/free-directory.ts +187 -0
  587. package/src/providers/github-copilot-transport.ts +56 -0
  588. package/src/providers/google-vertex-location.ts +14 -0
  589. package/src/providers/key-failover.ts +271 -0
  590. package/src/providers/kiro-models.ts +67 -0
  591. package/src/providers/label.ts +19 -0
  592. package/src/providers/model-discovery-limits.ts +16 -0
  593. package/src/providers/model-discovery.ts +449 -0
  594. package/src/providers/model-rename-migration.ts +255 -0
  595. package/src/providers/model-rename-startup.ts +28 -0
  596. package/src/providers/openai-sidecar.ts +243 -0
  597. package/src/providers/openai-tier-startup.ts +56 -0
  598. package/src/providers/openai-tiers.ts +423 -0
  599. package/src/providers/openai-virtual-models.ts +83 -0
  600. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  601. package/src/providers/openrouter-routing.ts +102 -0
  602. package/src/providers/provider-id-rewrite.ts +185 -0
  603. package/src/providers/quota.ts +2345 -0
  604. package/src/providers/registry.ts +2918 -0
  605. package/src/providers/replit/constants.ts +27 -0
  606. package/src/providers/replit/derive.ts +85 -0
  607. package/src/providers/replit/headers.ts +28 -0
  608. package/src/providers/replit/origin.ts +55 -0
  609. package/src/providers/replit/pair-install-response.ts +72 -0
  610. package/src/providers/replit/probe.ts +199 -0
  611. package/src/providers/replit/setup.ts +350 -0
  612. package/src/providers/request-pacing.ts +310 -0
  613. package/src/providers/service-tier.ts +277 -0
  614. package/src/providers/slug-codec.ts +103 -0
  615. package/src/providers/static-model-discovery.ts +86 -0
  616. package/src/providers/xai-responses-opt-in.ts +15 -0
  617. package/src/providers/xai-transport.ts +148 -0
  618. package/src/reasoning-effort.ts +183 -0
  619. package/src/responses/compaction.ts +142 -0
  620. package/src/responses/custom-tool-compat.ts +266 -0
  621. package/src/responses/hosted-tool-policy.ts +9 -0
  622. package/src/responses/namespace-tool-compat.ts +355 -0
  623. package/src/responses/parser.ts +838 -0
  624. package/src/responses/provider-continuation.ts +98 -0
  625. package/src/responses/provider-opaque-metadata.ts +73 -0
  626. package/src/responses/reasoning-envelope.ts +60 -0
  627. package/src/responses/reasoning-replay-cache.ts +426 -0
  628. package/src/responses/schema.ts +165 -0
  629. package/src/responses/spill-store.ts +459 -0
  630. package/src/responses/state.ts +1433 -0
  631. package/src/responses/thought-signature-replay.ts +347 -0
  632. package/src/responses/tool-groups.ts +19 -0
  633. package/src/responses/tool-search-compat.ts +301 -0
  634. package/src/responses/truncated-stop-reason.ts +60 -0
  635. package/src/router.ts +761 -0
  636. package/src/routing/analytics.ts +378 -0
  637. package/src/routing/capability.ts +244 -0
  638. package/src/routing/compatibility/assemble.ts +73 -0
  639. package/src/routing/compatibility/behavior.ts +278 -0
  640. package/src/routing/compatibility/catalog.ts +99 -0
  641. package/src/routing/compatibility/endpoint.ts +52 -0
  642. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  643. package/src/routing/compatibility/policy.ts +181 -0
  644. package/src/routing/compatibility/provider-slot.ts +56 -0
  645. package/src/routing/compatibility/reader.ts +110 -0
  646. package/src/routing/compatibility/subject.ts +191 -0
  647. package/src/routing/compatibility/types.ts +64 -0
  648. package/src/routing/compatibility/version.ts +104 -0
  649. package/src/routing/cost.ts +77 -0
  650. package/src/routing/evaluator.ts +495 -0
  651. package/src/routing/health.ts +412 -0
  652. package/src/routing/history/cursor.ts +43 -0
  653. package/src/routing/history/indexer.ts +605 -0
  654. package/src/routing/history/schema.ts +72 -0
  655. package/src/routing/profile-namespace.ts +15 -0
  656. package/src/routing/profile.ts +547 -0
  657. package/src/routing/quota.ts +145 -0
  658. package/src/routing/request-evidence.ts +45 -0
  659. package/src/routing/trace.ts +776 -0
  660. package/src/server/adapter-resolve.ts +53 -0
  661. package/src/server/auth-cors.ts +751 -0
  662. package/src/server/background-lifecycle.ts +182 -0
  663. package/src/server/chat-completions.ts +442 -0
  664. package/src/server/chat-native-sse.ts +331 -0
  665. package/src/server/chat-native.ts +426 -0
  666. package/src/server/claude-messages.ts +1030 -0
  667. package/src/server/direct-local-http.ts +347 -0
  668. package/src/server/effort-policy.ts +190 -0
  669. package/src/server/github-copilot-responses-repair.ts +338 -0
  670. package/src/server/gui-static.ts +152 -0
  671. package/src/server/image-retry.ts +42 -0
  672. package/src/server/images.ts +568 -0
  673. package/src/server/index.ts +1813 -0
  674. package/src/server/lifecycle.ts +498 -0
  675. package/src/server/live.ts +717 -0
  676. package/src/server/local-management-read-client.ts +90 -0
  677. package/src/server/local-provider-reload-client.ts +137 -0
  678. package/src/server/management/agent-settings-routes.ts +1433 -0
  679. package/src/server/management/api-access.ts +141 -0
  680. package/src/server/management/api-key-usage.ts +193 -0
  681. package/src/server/management/body.ts +41 -0
  682. package/src/server/management/combo-routes.ts +263 -0
  683. package/src/server/management/config-routes.ts +835 -0
  684. package/src/server/management/context.ts +113 -0
  685. package/src/server/management/integration-routes.ts +498 -0
  686. package/src/server/management/lab-automation-routes.ts +206 -0
  687. package/src/server/management/lab-routes.ts +563 -0
  688. package/src/server/management/logs-usage-routes.ts +586 -0
  689. package/src/server/management/model-routes.ts +560 -0
  690. package/src/server/management/model-rows.ts +163 -0
  691. package/src/server/management/native-integration-routes.ts +769 -0
  692. package/src/server/management/oauth-account-routes.ts +637 -0
  693. package/src/server/management/provider-capability-config.ts +48 -0
  694. package/src/server/management/provider-routes.ts +1033 -0
  695. package/src/server/management/replit-provider-routes.ts +86 -0
  696. package/src/server/management/request-history-routes.ts +191 -0
  697. package/src/server/management/routing-analytics-routes.ts +74 -0
  698. package/src/server/management/routing-profile-routes.ts +385 -0
  699. package/src/server/management/shared.ts +286 -0
  700. package/src/server/management/sidebar-routes.ts +106 -0
  701. package/src/server/management/storage-log-guard-routes.ts +186 -0
  702. package/src/server/management/sync-response.ts +69 -0
  703. package/src/server/management/system-restart.ts +435 -0
  704. package/src/server/management/system-routes.ts +194 -0
  705. package/src/server/management/usage-summary-cache.ts +94 -0
  706. package/src/server/management/vision-sidecar-options.ts +167 -0
  707. package/src/server/management/web-search-sidecar-options.ts +120 -0
  708. package/src/server/management-api.ts +314 -0
  709. package/src/server/management-auth.ts +482 -0
  710. package/src/server/memory-watchdog.ts +156 -0
  711. package/src/server/passive-route-linker.ts +66 -0
  712. package/src/server/port-reclaim.ts +307 -0
  713. package/src/server/ports.ts +156 -0
  714. package/src/server/proxy-liveness.ts +328 -0
  715. package/src/server/readiness.ts +99 -0
  716. package/src/server/relay-eager.ts +353 -0
  717. package/src/server/relay.ts +1209 -0
  718. package/src/server/request-decompress.ts +239 -0
  719. package/src/server/request-log-conversation.ts +168 -0
  720. package/src/server/request-log.ts +1259 -0
  721. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  722. package/src/server/responses/agent-task-recovery.ts +465 -0
  723. package/src/server/responses/collaboration.ts +551 -0
  724. package/src/server/responses/compact.ts +771 -0
  725. package/src/server/responses/core.ts +5389 -0
  726. package/src/server/responses/empty-completion-guard.ts +276 -0
  727. package/src/server/responses/encrypted-payload.ts +331 -0
  728. package/src/server/responses/fetch-helpers.ts +232 -0
  729. package/src/server/responses/input-admission.ts +185 -0
  730. package/src/server/responses/pacing-overload.ts +13 -0
  731. package/src/server/responses/passthrough-error.ts +78 -0
  732. package/src/server/responses/policy-fallback.ts +178 -0
  733. package/src/server/responses/responses-field-backfill.ts +251 -0
  734. package/src/server/responses/terminal-guard.ts +251 -0
  735. package/src/server/responses/upstream-error.ts +53 -0
  736. package/src/server/responses/ws-upstream.ts +308 -0
  737. package/src/server/responses-custom-tool-repair.ts +282 -0
  738. package/src/server/responses-image-gen-repair.ts +132 -0
  739. package/src/server/responses-item-id-repair.ts +272 -0
  740. package/src/server/responses-json-events.ts +90 -0
  741. package/src/server/responses-model-rewrite.ts +29 -0
  742. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  743. package/src/server/responses-snapshot-repair.ts +621 -0
  744. package/src/server/responses-terminal-repair.ts +342 -0
  745. package/src/server/responses-tool-search-repair.ts +267 -0
  746. package/src/server/responses-undeclared-tool-guard.ts +153 -0
  747. package/src/server/responses.ts +25 -0
  748. package/src/server/search.ts +201 -0
  749. package/src/server/sse-frame-buffer.ts +292 -0
  750. package/src/server/sse-payload-rewrite.ts +263 -0
  751. package/src/server/startup-action-control.ts +315 -0
  752. package/src/server/startup-health-cache.ts +131 -0
  753. package/src/server/system-env.ts +484 -0
  754. package/src/server/windows-tcp-drop.ts +184 -0
  755. package/src/server/windows-tray-control.ts +41 -0
  756. package/src/server/ws-bridge.ts +472 -0
  757. package/src/service-manager-probe.ts +892 -0
  758. package/src/service.ts +3575 -0
  759. package/src/sidecar/auth.ts +92 -0
  760. package/src/sidecar/candidates.ts +83 -0
  761. package/src/stall-timeout.ts +20 -0
  762. package/src/storage/cleanup-job.ts +57 -0
  763. package/src/storage/cleanup.ts +3085 -0
  764. package/src/storage/policy-job.ts +457 -0
  765. package/src/storage/policy-scheduler.ts +40 -0
  766. package/src/storage/policy-worker.ts +59 -0
  767. package/src/storage/policy.ts +527 -0
  768. package/src/storage/restore-job.ts +299 -0
  769. package/src/storage/restore-worker.ts +58 -0
  770. package/src/storage/scanner.ts +238 -0
  771. package/src/storage/storage-mutation-coordinator.ts +139 -0
  772. package/src/storage/worker-lifecycle.ts +215 -0
  773. package/src/tray/assets/opencodex-tray-offline.ico +0 -0
  774. package/src/tray/assets/opencodex-tray-online.ico +0 -0
  775. package/src/tray/assets/opencodex-tray-warning.ico +0 -0
  776. package/src/tray/assets/opencodex-tray.png +0 -0
  777. package/src/tray/windows-tray.ps1 +364 -0
  778. package/src/tray/windows.ts +757 -0
  779. package/src/types/accounts.ts +37 -0
  780. package/src/types/config.ts +876 -0
  781. package/src/types/provider.ts +545 -0
  782. package/src/types/request.ts +384 -0
  783. package/src/types/tools.ts +131 -0
  784. package/src/types/wire.ts +80 -0
  785. package/src/types.ts +106 -0
  786. package/src/update/badge.ts +72 -0
  787. package/src/update/index.ts +415 -0
  788. package/src/update/job.ts +1887 -0
  789. package/src/update/notify.ts +263 -0
  790. package/src/update/npm-cache-preflight.d.mts +47 -0
  791. package/src/update/npm-cache-preflight.mjs +201 -0
  792. package/src/update/npm-invocation.d.mts +23 -0
  793. package/src/update/npm-invocation.mjs +94 -0
  794. package/src/update/transactional-install.d.mts +22 -0
  795. package/src/update/transactional-install.mjs +259 -0
  796. package/src/update/tray-update-plan.d.mts +18 -0
  797. package/src/update/tray-update-plan.mjs +38 -0
  798. package/src/usage/cost.ts +625 -0
  799. package/src/usage/debug.ts +97 -0
  800. package/src/usage/expected-prices.ts +416 -0
  801. package/src/usage/log.ts +1223 -0
  802. package/src/usage/summary.ts +753 -0
  803. package/src/usage/totals.ts +14 -0
  804. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  805. package/src/usage/user-cost-overlays.ts +314 -0
  806. package/src/vision/anthropic-describe.ts +189 -0
  807. package/src/vision/backends.ts +97 -0
  808. package/src/vision/describe.ts +131 -0
  809. package/src/vision/eligibility.ts +250 -0
  810. package/src/vision/index.ts +681 -0
  811. package/src/vision/reasoning.ts +55 -0
  812. package/src/vision/routed-describe.ts +175 -0
  813. package/src/vision/timeout-bounds.ts +9 -0
  814. package/src/web-search/anthropic-executor.ts +195 -0
  815. package/src/web-search/backends.ts +108 -0
  816. package/src/web-search/exa-executor.ts +88 -0
  817. package/src/web-search/executor.ts +113 -0
  818. package/src/web-search/format-result.ts +89 -0
  819. package/src/web-search/gemini-executor.ts +141 -0
  820. package/src/web-search/index.ts +331 -0
  821. package/src/web-search/loop.ts +896 -0
  822. package/src/web-search/parse.ts +315 -0
  823. package/src/web-search/progress-stream.ts +342 -0
  824. package/src/web-search/sources.ts +60 -0
  825. package/src/web-search/synthetic-tool.ts +47 -0
  826. package/src/web-search/xai-executor.ts +219 -0
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Stateless SSE block rewrite that backfills the `annotations` field on
3
+ * `output_text` content parts in Responses SSE events.
4
+ *
5
+ * The Responses API spec defines `annotations` as a required field on
6
+ * `OutputTextContent` (it is `Vec<Annotation>`, not `Option<Vec>`). Some
7
+ * upstream relays omit it when there are no annotations, which is technically
8
+ * spec-non-compliant. Strict deserializers — any client that follows the
9
+ * schema without `#[serde(default)]` on that field — fail with
10
+ * `missing field `annotations`` when the field is absent.
11
+ *
12
+ * This rewrite scans every SSE event for output_text content parts — whether
13
+ * they appear in item.content[], part, or response.output[].content[] — and
14
+ * adds annotations: [] if missing.
15
+ *
16
+ * Stateless: no retained buffers, no lifecycle tracking, no fail-closed.
17
+ * Existing values are always authoritative; only absent fields are added.
18
+ * The field is always valid on the wire, so adding it when absent is safe
19
+ * for all clients including Codex CLI/App.
20
+ */
21
+
22
+ import {
23
+ replaceSseDataPayload,
24
+ sseDataPayload,
25
+ type SseBlockRewrite,
26
+ } from "../sse-payload-rewrite";
27
+ import { isCompactionItemType } from "../../responses/compaction";
28
+
29
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
30
+ return !!value && typeof value === "object" && !Array.isArray(value);
31
+ }
32
+
33
+ /** Wire prefixes for Responses output item ids, matching OpenAI's id shapes. */
34
+ const ITEM_ID_PREFIXES: Readonly<Record<string, string>> = {
35
+ message: "msg_",
36
+ reasoning: "rs_",
37
+ function_call: "fc_",
38
+ custom_tool_call: "ctc_",
39
+ // A routed tool_search lowering is restored to `tool_search_call` without an id, so this
40
+ // backfill is what names it. The generic `item_` fallback is not merely cosmetic here:
41
+ // `stripInvalidItemIds` in the Responses adapter deletes any id whose prefix does not match
42
+ // the type, so an `item_`-named tool_search_call silently loses its id on the NEXT turn and
43
+ // the client sees an item it cannot correlate. The prefixes here must stay a superset of the
44
+ // ones that serializer enforces.
45
+ tool_search_call: "tsc_",
46
+ web_search_call: "ws_",
47
+ file_search_call: "fs_",
48
+ code_interpreter_call: "ci_",
49
+ computer_call: "cc_",
50
+ // The Responses wire type is `image_generation_call`; `image_gen_call` is kept only so a
51
+ // relay that emits the short spelling is not silently demoted to the generic `item_`.
52
+ image_generation_call: "ig_",
53
+ image_gen_call: "ig_",
54
+ };
55
+
56
+ /**
57
+ * Backfill a required id on an output item when absent. Strict Responses
58
+ * decoders (e.g. grok-build serde types) fail with "missing field id" when a
59
+ * message or reasoning item has no id, which some upstream relays omit. The
60
+ * generated id is deterministic per (type, output index) so it stays stable
61
+ * across streaming events that reference the same item.
62
+ */
63
+ function backfillItemId(item: Record<string, unknown>, slot: ItemIdSlot): Record<string, unknown> {
64
+ if (typeof item.id === "string" && item.id.length > 0) return item;
65
+ const type = typeof item.type === "string" ? item.type : "";
66
+ const prefix = Object.prototype.hasOwnProperty.call(ITEM_ID_PREFIXES, type) ? ITEM_ID_PREFIXES[type] : "item_";
67
+ return { ...item, id: prefix + "ocx_" + (slot.kind === "index" ? String(slot.index) : "fallback_" + slot.ordinal) };
68
+ }
69
+
70
+ /**
71
+ * Which namespace a synthesized id comes from.
72
+ *
73
+ * Keeping the fallback counter in the SAME numeric namespace as real output indexes only
74
+ * pushed the collision out of reach rather than removing it: a response whose real index
75
+ * happened to be 1_000_001 would produce the same id as the first malformed-index fallback,
76
+ * and a duplicate id is exactly what this backfill exists to prevent. The namespaces are now
77
+ * lexically disjoint, so no index value can ever collide with a fallback.
78
+ */
79
+ type ItemIdSlot = { kind: "index"; index: number } | { kind: "fallback"; ordinal: number };
80
+
81
+ /**
82
+ * Monotonic ordinal for an event whose `output_index` is absent or malformed.
83
+ *
84
+ * Process-global rather than per-response because this module is stateless by design and the
85
+ * value only has to be unique, not meaningful. It carries its own `fallback_` namespace, so
86
+ * uniqueness no longer depends on a real index never reaching some arbitrary ceiling.
87
+ */
88
+ let syntheticItemOrdinal = 0;
89
+ function nextSyntheticItemSlot(): ItemIdSlot {
90
+ syntheticItemOrdinal += 1;
91
+ return { kind: "fallback", ordinal: syntheticItemOrdinal };
92
+ }
93
+
94
+ /**
95
+ * Backfill annotations: [] on an output_text content part if missing.
96
+ * Returns the same object reference if no change is needed.
97
+ */
98
+ function backfillOutputTextPart(part: Record<string, unknown>): Record<string, unknown> {
99
+ if (part.type !== "output_text") return part;
100
+ // Only add annotations when the key is entirely absent — preserve any
101
+ // existing value (even null or a malformed type) so we never overwrite
102
+ // what the upstream actually sent.
103
+ if ("annotations" in part) return part;
104
+ return { ...part, annotations: [] };
105
+ }
106
+
107
+ /**
108
+ * Walk a content array and backfill output_text parts.
109
+ * Returns the same array reference if nothing changed.
110
+ */
111
+ function backfillContentArray(content: unknown): unknown {
112
+ if (!Array.isArray(content)) return content;
113
+ let changed = false;
114
+ const repaired = content.map((part) => {
115
+ if (!isPlainObject(part)) return part;
116
+ const next = backfillOutputTextPart(part);
117
+ if (next !== part) changed = true;
118
+ return next;
119
+ });
120
+ return changed ? repaired : content;
121
+ }
122
+
123
+ /**
124
+ * Walk an output item and backfill output_text parts in its content.
125
+ * Also backfills a missing required id on the item itself.
126
+ * Returns the same object reference if nothing changed.
127
+ */
128
+ function backfillOutputItem(item: unknown, slot: ItemIdSlot): unknown {
129
+ if (!isPlainObject(item)) return item;
130
+ // The compact wire family is the `/v1/responses/compact` format, not a Responses output item.
131
+ // Those items have no `id` in that contract, so synthesizing one changes a response body the
132
+ // client compares exactly — and the client replays the item on every later turn, where the
133
+ // minting backend rejects it as modified. The backfill exists to satisfy strict Responses
134
+ // decoders; a shape those decoders never see is outside its remit.
135
+ if (isCompactionItemType(item.type)) return item;
136
+ const content = item.content;
137
+ const repaired = backfillContentArray(content);
138
+ const withId = backfillItemId(item, slot);
139
+ if (repaired === content && withId === item) return item;
140
+ return { ...withId, ...(repaired === content ? {} : { content: repaired }) };
141
+ }
142
+
143
+ /**
144
+ * Walk a response object's output[] and backfill output_text parts.
145
+ * Returns the same object reference if nothing changed.
146
+ */
147
+ function backfillResponseOutput(response: unknown): unknown {
148
+ if (!isPlainObject(response)) return response;
149
+ const output = response.output;
150
+ if (!Array.isArray(output)) return response;
151
+ let changed = false;
152
+ const repaired = output.map((item, idx) => {
153
+ if (!isPlainObject(item)) return item;
154
+ const next = backfillOutputItem(item, { kind: "index", index: idx });
155
+ if (next !== item) changed = true;
156
+ return next;
157
+ });
158
+ return changed ? { ...response, output: repaired } : response;
159
+ }
160
+
161
+ /**
162
+ * Statelessly rewrite one SSE event: backfill annotations
163
+ * on any output_text content part found in the event payload.
164
+ */
165
+ function rewriteEvent(event: Record<string, unknown>): Record<string, unknown> {
166
+ const type = typeof event.type === "string" ? event.type : "";
167
+ let next = event;
168
+ let changed = false;
169
+
170
+ // output_item.added / output_item.done: item.content[] -> output_text parts
171
+ if ((type === "response.output_item.added" || type === "response.output_item.done")
172
+ && isPlainObject(event.item)) {
173
+ const rawIndex = event.output_index;
174
+ // A malformed or absent `output_index` must not collapse to 0: two such events would then
175
+ // both synthesize `msg_ocx_0`, and duplicate ids are the very thing this backfill exists to
176
+ // prevent. Fall back to a per-process counter so the synthesized id stays unique. Position
177
+ // is not recoverable in that case, but a unique id is what strict decoders require, and a
178
+ // well-formed stream still gets the stable index-derived id.
179
+ const item = typeof rawIndex === "number" && Number.isInteger(rawIndex) && rawIndex >= 0
180
+ ? backfillOutputItem(event.item, { kind: "index", index: rawIndex })
181
+ : backfillOutputItem(event.item, nextSyntheticItemSlot());
182
+ if (item !== event.item) {
183
+ next = { ...next, item };
184
+ changed = true;
185
+ }
186
+ }
187
+
188
+ // content_part.added / content_part.done: part -> output_text
189
+ if ((type === "response.content_part.added" || type === "response.content_part.done")
190
+ && isPlainObject(event.part)) {
191
+ const part = backfillOutputTextPart(event.part);
192
+ if (part !== event.part) {
193
+ next = { ...next, part };
194
+ changed = true;
195
+ }
196
+ }
197
+
198
+ // response.created / in_progress / completed / incomplete / failed:
199
+ // response.output[].content[] -> output_text parts
200
+ if (isPlainObject(event.response)) {
201
+ const response = backfillResponseOutput(event.response);
202
+ if (response !== event.response) {
203
+ next = { ...next, response };
204
+ changed = true;
205
+ }
206
+ }
207
+
208
+ return changed ? next : event;
209
+ }
210
+
211
+ /**
212
+ * Create a stateless SSE block rewrite that backfills annotations and
213
+ * on output_text content parts. Unconditional: the field is a required
214
+ * canonical Responses field, so adding it when absent is safe for all
215
+ * clients.
216
+ */
217
+ export function createResponsesFieldBackfillBlockRewrite(): SseBlockRewrite {
218
+ const rewrite: SseBlockRewrite = (block: string): readonly string[] => {
219
+ const payload = sseDataPayload(block);
220
+ if (payload === null) return [block];
221
+ let event: unknown;
222
+ try {
223
+ event = JSON.parse(payload);
224
+ } catch {
225
+ return [block];
226
+ }
227
+ if (!isPlainObject(event)) return [block];
228
+ const rewritten = rewriteEvent(event);
229
+ if (rewritten === event) return [block];
230
+ return [replaceSseDataPayload(block, JSON.stringify(rewritten))];
231
+ };
232
+ return rewrite;
233
+ }
234
+
235
+ /**
236
+ * Backfill annotations on a non-streaming Responses JSON
237
+ * object. Mirrors the SSE block rewrite for the bounded-JSON passthrough
238
+ * path. Returns the original string if no change is needed.
239
+ */
240
+ export function backfillResponsesFieldsJson(payload: string): string {
241
+ let response: unknown;
242
+ try {
243
+ response = JSON.parse(payload);
244
+ } catch {
245
+ return payload;
246
+ }
247
+ if (!isPlainObject(response)) return payload;
248
+ const repaired = backfillResponseOutput(response);
249
+ if (repaired === response) return payload;
250
+ return JSON.stringify(repaired);
251
+ }
@@ -0,0 +1,251 @@
1
+ import type {
2
+ AdapterEvent,
3
+ OcxAssistantContentPart,
4
+ OcxAssistantMessage,
5
+ OcxParsedRequest,
6
+ OcxUsage,
7
+ } from "../../types";
8
+
9
+ const ACTIONABLE_REQUEST_RE = /(?:\b(?:add|change|check|continue|create|debug|delete|deploy|edit|execute|fix|implement|inspect|keep going|modify|patch|proceed|refactor|remove|review|run|test|update|write)\b|继续|接着|往下|升级|修改|改(?:一下|下)?|修复|实现|添加|新增|删除|重构|更新|运行|执行|检查|查看|排查|调试|创建|写入|提交|推送|部署|看下|改成|修一下)/iu;
10
+ const PLAN_ONLY_REQUEST_RE = /(?:暂时不要(?:调用|使用)工具|不要调用工具|不用执行|只回复(?:计划|方案)|(?:只|先|给|说|写|出|来)(?:我)?(?:一个|个|一下|份)?[^。!?\n]{0,8}?(?:计划|方案|草案|提案|思路)|(?:计划|方案|草案|提案|思路)(?:就(?:行|好|可以)|即可)|\b(?:just give|provide)\s+(?:me\s+)?(?:a\s+)?plan\b|\b(?:do not|don't)\s+(?:use|call)\s+tools?\b|\b(?:write|draft|outline|propose|give|provide|create|make|share|suggest|sketch)\s+(?:me\s+)?(?:a\s+|an\s+|the\s+|your\s+)?(?:(?:brief|concise|short|detailed|high[-\s]?level|rough|quick|step[-\s]?by[-\s]?step|implementation|migration|refactor(?:ing)?|design|technical)\s+)*(?:plan|proposal|draft|outline|approach|strategy|design\s+doc)\b)/iu;
11
+ const PLAN_INTENT_RE = /(?:\b(?:i(?:'|’)m going to|i will|i(?:'|’)ll|let me|next i)\b|我(?:先|会|将|接下来)|下一步)/iu;
12
+ const PLAN_OR_COMPLETION_RE = /(?:\b(?:i(?:'|’)m going to|i will|i(?:'|’)ll|let me|next i|i(?:'|’)ve (?:already )?(?:added|applied|changed|completed|fixed|implemented|modified|updated))\b|\b(?:done|completed|fixed|implemented|updated|applied)\b|我(?:先|会|将|接下来)|下一步|已(?:经)?(?:修改|修复|完成|应用|更新|实现|处理)|完成了|已经好了)/iu;
13
+ const WAITING_FOR_USER_RE = /(?:[??]\s*$|需要我|请(?:确认|选择|提供)|是否|要不要|可以吗|\b(?:do you want|should i|which file|please confirm|please provide)\b)/iu;
14
+ const EXPLICIT_CONTINUE_RE = /^(?:继续|接着|往下|go on|continue|proceed|keep going)\s*[.!。!]?$/iu;
15
+ const MAX_ANNOUNCEMENT_CHARS = 280;
16
+
17
+ export const TERMINAL_GUARD_NUDGE =
18
+ "你刚才只描述了计划,没有执行任何工具。不要再次解释计划,现在立即调用必要工具执行用户任务。" +
19
+ "只有工具返回后才总结;如果确实无法执行,请明确说明阻塞原因。";
20
+
21
+ export type TerminalGuardDecision = "pass" | "continue" | "ambiguous";
22
+
23
+ export interface TerminalTurnAnalysis {
24
+ decision: TerminalGuardDecision;
25
+ reason: "normal" | "waiting_for_user" | "no_tools" | "no_actionable_request" | "no_execution_claim" | "recent_tool_activity" | "substantive_answer" | "suspicious_no_tool";
26
+ assistantText: string;
27
+ userText: string;
28
+ hasToolCall: boolean;
29
+ }
30
+
31
+ function messageText(value: unknown): string {
32
+ if (typeof value === "string") return value;
33
+ if (!Array.isArray(value)) return "";
34
+ return value
35
+ .filter((part): part is { type?: unknown; text?: unknown } => !!part && typeof part === "object")
36
+ .filter(part => part.type === "text" && typeof part.text === "string")
37
+ .map(part => part.text as string)
38
+ .join("");
39
+ }
40
+
41
+ function latestUserText(parsed: OcxParsedRequest): string {
42
+ for (let i = parsed.context.messages.length - 1; i >= 0; i -= 1) {
43
+ const message = parsed.context.messages[i];
44
+ if (message.role === "user") return messageText(message.content);
45
+ }
46
+ return "";
47
+ }
48
+
49
+ function recentTurnHasToolActivity(parsed: OcxParsedRequest): boolean {
50
+ let latestUserIndex = -1;
51
+ for (let i = parsed.context.messages.length - 1; i >= 0; i -= 1) {
52
+ if (parsed.context.messages[i]?.role === "user") {
53
+ latestUserIndex = i;
54
+ break;
55
+ }
56
+ }
57
+ if (latestUserIndex < 0) return false;
58
+ let lastAssistant: OcxAssistantMessage | undefined;
59
+ for (let i = latestUserIndex - 1; i >= 0; i -= 1) {
60
+ const message = parsed.context.messages[i];
61
+ if (message.role === "assistant") {
62
+ lastAssistant = message;
63
+ break;
64
+ }
65
+ }
66
+ if (lastAssistant?.role === "assistant") {
67
+ const hasToolCall = lastAssistant.content.some(part => part.type === "toolCall");
68
+ const text = lastAssistant.content
69
+ .filter(part => part.type === "text")
70
+ .map(part => part.text)
71
+ .join("");
72
+ if (!hasToolCall && PLAN_INTENT_RE.test(text)) return false;
73
+ }
74
+ for (let i = latestUserIndex - 1; i >= 0 && parsed.context.messages[i]?.role !== "user"; i -= 1) {
75
+ const message = parsed.context.messages[i];
76
+ if (message.role === "toolResult") return true;
77
+ if (message.role === "assistant" && message.content.some(part => part.type === "toolCall")) return true;
78
+ }
79
+ return false;
80
+ }
81
+
82
+ function assistantText(events: readonly AdapterEvent[]): string {
83
+ return events
84
+ .filter((event): event is Extract<AdapterEvent, { type: "text_delta" }> => event.type === "text_delta")
85
+ .map(event => event.text)
86
+ .join("");
87
+ }
88
+
89
+ export function analyzeTerminalTurn(parsed: OcxParsedRequest, events: readonly AdapterEvent[]): TerminalTurnAnalysis {
90
+ const userText = latestUserText(parsed);
91
+ const text = assistantText(events);
92
+ const hasToolCall = events.some(event => event.type === "tool_call_start");
93
+ if (hasToolCall) {
94
+ return { decision: "pass", reason: "normal", assistantText: text, userText, hasToolCall };
95
+ }
96
+ if (!parsed.context.tools || parsed.context.tools.length === 0 || parsed.options.toolChoice === "none") {
97
+ return { decision: "pass", reason: "no_tools", assistantText: text, userText, hasToolCall };
98
+ }
99
+ if (!ACTIONABLE_REQUEST_RE.test(userText)) {
100
+ return { decision: "pass", reason: "no_actionable_request", assistantText: text, userText, hasToolCall };
101
+ }
102
+ if (PLAN_ONLY_REQUEST_RE.test(userText)) {
103
+ return { decision: "pass", reason: "no_actionable_request", assistantText: text, userText, hasToolCall };
104
+ }
105
+ if (EXPLICIT_CONTINUE_RE.test(userText) && recentTurnHasToolActivity(parsed)) {
106
+ return { decision: "pass", reason: "recent_tool_activity", assistantText: text, userText, hasToolCall };
107
+ }
108
+ if (WAITING_FOR_USER_RE.test(text)) {
109
+ return { decision: "pass", reason: "waiting_for_user", assistantText: text, userText, hasToolCall };
110
+ }
111
+ if (text.trim().length > MAX_ANNOUNCEMENT_CHARS) {
112
+ return { decision: "pass", reason: "substantive_answer", assistantText: text, userText, hasToolCall };
113
+ }
114
+ if (!PLAN_OR_COMPLETION_RE.test(text)) {
115
+ return { decision: "ambiguous", reason: "no_execution_claim", assistantText: text, userText, hasToolCall };
116
+ }
117
+ return { decision: "continue", reason: "suspicious_no_tool", assistantText: text, userText, hasToolCall };
118
+ }
119
+
120
+ function assistantMessageFromEvents(events: readonly AdapterEvent[], timestamp: number): OcxAssistantMessage | undefined {
121
+ let text = "";
122
+ let thinking = "";
123
+ let signature: string | undefined;
124
+ const redacted: string[] = [];
125
+ for (const event of events) {
126
+ if (event.type === "text_delta") text += event.text;
127
+ else if (event.type === "thinking_delta") thinking += event.thinking;
128
+ else if (event.type === "thinking_signature") signature = event.signature;
129
+ else if (event.type === "redacted_thinking") redacted.push(event.data);
130
+ }
131
+ const content: OcxAssistantContentPart[] = [];
132
+ if (thinking || signature || redacted.length > 0) {
133
+ content.push({ type: "thinking", thinking, ...(signature ? { signature } : {}), ...(redacted.length > 0 ? { redacted } : {}) });
134
+ }
135
+ if (text) content.push({ type: "text", text });
136
+ if (content.length === 0) return undefined;
137
+ return { role: "assistant", content, timestamp };
138
+ }
139
+
140
+ export function buildContinuationRequest(parsed: OcxParsedRequest, events: readonly AdapterEvent[]): OcxParsedRequest {
141
+ const messages = [...parsed.context.messages];
142
+ // One clock read for the whole rebuild. Two Date.now() calls could straddle a millisecond
143
+ // boundary, which made the retained-heartbeat contract test fail intermittently in CI on a
144
+ // 1ms skew between the assistant message and the nudge that follows it.
145
+ const timestamp = Date.now();
146
+ const assistant = assistantMessageFromEvents(events, timestamp);
147
+ if (assistant) messages.push(assistant);
148
+ messages.push({ role: "developer", content: TERMINAL_GUARD_NUDGE, timestamp });
149
+ return { ...parsed, context: { ...parsed.context, messages } };
150
+ }
151
+
152
+ export interface GuardedEventStreamOptions {
153
+ parsed: OcxParsedRequest;
154
+ firstEvents: AsyncIterable<AdapterEvent>;
155
+ continuation: (parsed: OcxParsedRequest) => AsyncIterable<AdapterEvent> | Promise<AsyncIterable<AdapterEvent>>;
156
+ adapterName?: string;
157
+ maxAutoContinuations?: number;
158
+ }
159
+
160
+ /**
161
+ * Events that are useful to the downstream stream consumer but carry no state used by the
162
+ * terminal-continuation decision or its rebuilt request. Keep them out of the retained event
163
+ * list so adapter liveness markers and arbitrarily large tool-argument fragments cannot make
164
+ * the guard's per-turn memory grow without adding any continuation semantics.
165
+ */
166
+ export function isTerminalGuardPassthroughOnly(event: AdapterEvent): boolean {
167
+ return event.type === "heartbeat" || event.type === "tool_call_delta";
168
+ }
169
+
170
+ function mergeUsage(first: OcxUsage | undefined, second: OcxUsage | undefined): OcxUsage | undefined {
171
+ if (!first) return second;
172
+ if (!second) return first;
173
+ const sumOptional = (key: keyof OcxUsage): number | undefined => {
174
+ const left = first[key];
175
+ const right = second[key];
176
+ return typeof left === "number" || typeof right === "number"
177
+ ? (typeof left === "number" ? left : 0) + (typeof right === "number" ? right : 0)
178
+ : undefined;
179
+ };
180
+ const cachedInputTokens = sumOptional("cachedInputTokens");
181
+ const cacheReadInputTokens = sumOptional("cacheReadInputTokens");
182
+ const cacheCreationInputTokens = sumOptional("cacheCreationInputTokens");
183
+ const reasoningOutputTokens = sumOptional("reasoningOutputTokens");
184
+ const inputTokens = first.inputTokens + second.inputTokens;
185
+ const outputTokens = first.outputTokens + second.outputTokens;
186
+ return {
187
+ inputTokens,
188
+ outputTokens,
189
+ totalTokens: inputTokens + outputTokens,
190
+ ...(cachedInputTokens !== undefined ? { cachedInputTokens } : {}),
191
+ ...(cacheReadInputTokens !== undefined ? { cacheReadInputTokens } : {}),
192
+ ...(cacheCreationInputTokens !== undefined ? { cacheCreationInputTokens } : {}),
193
+ ...(reasoningOutputTokens !== undefined ? { reasoningOutputTokens } : {}),
194
+ ...(first.estimated || second.estimated ? { estimated: true } : {}),
195
+ };
196
+ }
197
+
198
+ /** Preserve normal terminals, but withhold one suspicious no-tool terminal for a bounded re-ask. */
199
+ export async function* guardTerminalEventStream(options: GuardedEventStreamOptions): AsyncGenerator<AdapterEvent> {
200
+ const maxContinuations = Math.max(0, Math.min(2, Math.floor(options.maxAutoContinuations ?? 1)));
201
+ let parsed = options.parsed;
202
+ let continuations = 0;
203
+ let accumulatedUsage: OcxUsage | undefined;
204
+ let source: AsyncIterable<AdapterEvent> = options.firstEvents;
205
+
206
+ while (true) {
207
+ const seen: AdapterEvent[] = [];
208
+ let terminalSeen = false;
209
+ for await (const event of source) {
210
+ // Liveness markers and tool argument fragments are passed through to the bridge, but
211
+ // neither analyzeTerminalTurn nor buildContinuationRequest consumes them. Retaining the
212
+ // fragments would duplicate arbitrarily large argument payloads in `seen` for no effect.
213
+ if (isTerminalGuardPassthroughOnly(event)) {
214
+ yield event;
215
+ continue;
216
+ }
217
+ if (event.type === "done") {
218
+ terminalSeen = true;
219
+ const analysis = (options.adapterName === "anthropic" || options.adapterName === "openai-chat")
220
+ ? analyzeTerminalTurn(parsed, seen)
221
+ : { decision: "pass" as const };
222
+ const normalStop = event.stopReason !== "max_tokens" && event.stopReason !== "content_filter";
223
+ if (normalStop && analysis.decision === "continue" && continuations < maxContinuations) {
224
+ accumulatedUsage = mergeUsage(accumulatedUsage, event.usage);
225
+ continuations += 1;
226
+ parsed = buildContinuationRequest(parsed, seen);
227
+ yield { type: "assistant_boundary" };
228
+ try {
229
+ source = await options.continuation(parsed);
230
+ } catch (error) {
231
+ yield { type: "error", message: error instanceof Error ? error.message : String(error) };
232
+ return;
233
+ }
234
+ break;
235
+ }
236
+ const usage = mergeUsage(accumulatedUsage, event.usage);
237
+ yield usage ? { ...event, usage } : event;
238
+ return;
239
+ }
240
+ if (event.type === "incomplete" || event.type === "error") {
241
+ terminalSeen = true;
242
+ const usage = mergeUsage(accumulatedUsage, event.usage);
243
+ yield usage ? { ...event, usage } : event;
244
+ return;
245
+ }
246
+ seen.push(event);
247
+ yield event;
248
+ }
249
+ if (!terminalSeen) return;
250
+ }
251
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Upstream connection failures share one message shape across the three catch sites in
3
+ * core.ts. A TLS certificate/hostname mismatch deserves its own wording: the generic
4
+ * "Provider unreachable" reads as if opencodex built a wrong endpoint, which sent issue
5
+ * #553 looking for an adapter URL bug that does not exist. Name the likely cause and the
6
+ * command that settles it.
7
+ */
8
+ import { RequestPacingQueueOverloadError } from "../../providers/request-pacing";
9
+
10
+ export function describeUpstreamConnectFailure(err: unknown, connectMs: number): string {
11
+ // Local pacing admission is not a transport failure. Let the outer response boundary
12
+ // preserve its retryable 429 identity instead of laundering it into a 502.
13
+ if (err instanceof RequestPacingQueueOverloadError) throw err;
14
+ if (err instanceof Error && err.name === "TimeoutError") {
15
+ return `Provider connect timeout after ${connectMs}ms`;
16
+ }
17
+ const detail = err instanceof Error ? err.message : String(err);
18
+ const code = err instanceof Error ? (err as { code?: unknown }).code : undefined;
19
+ // `code` is the reliable signal. The message fallback is anchored to the head because Bun
20
+ // renders this rejection as `ERR_TLS_CERT_ALTNAME_INVALID fetching "<url>"`; matching the
21
+ // bare substring anywhere would also fire on text that merely quotes the code back at us.
22
+ // Only transport failures reach these call sites, so that is defensive rather than load-bearing.
23
+ if (code === "ERR_TLS_CERT_ALTNAME_INVALID" || detail.startsWith("ERR_TLS_CERT_ALTNAME_INVALID")) {
24
+ const host = extractHostname(detail);
25
+ const target = host ?? "the provider host";
26
+ const probe = host ?? "<host>";
27
+ return `Provider TLS certificate does not match ${target}: ${redactUrlUserinfo(detail)}. `
28
+ + "opencodex did not rewrite this hostname — a certificate that does not cover it normally "
29
+ + "means TLS interception (corporate proxy, VPN, or local MITM tooling) or a poisoned DNS "
30
+ + `answer. Check with: openssl s_client -connect ${probe}:443 -servername ${probe} `
31
+ + "</dev/null | openssl x509 -noout -subject -ext subjectAltName";
32
+ }
33
+ return `Provider unreachable: ${redactUrlUserinfo(detail)}`;
34
+ }
35
+
36
+ /**
37
+ * A provider base URL may carry credentials as userinfo (`https://user:token@host/`), and the
38
+ * runtime error echoes the URL it was fetching. Strip it before the message reaches a client
39
+ * or a log line.
40
+ */
41
+ function redactUrlUserinfo(detail: string): string {
42
+ return detail.replace(/(https?:\/\/)[^/\s"'@]*@/g, "$1<redacted>@");
43
+ }
44
+
45
+ function extractHostname(detail: string): string | null {
46
+ const match = detail.match(/https?:\/\/([^/\s"']+)/);
47
+ if (!match?.[1]) return null;
48
+ try {
49
+ return new URL(`https://${match[1]}`).hostname || null;
50
+ } catch {
51
+ return null;
52
+ }
53
+ }