@iislee/opencodex 2.11.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 (476) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +225 -0
  3. package/assets/architecture.png +0 -0
  4. package/assets/banner.png +0 -0
  5. package/assets/claude-code-models.gif +0 -0
  6. package/assets/codex-app-picker.png +0 -0
  7. package/bin/ocx.mjs +451 -0
  8. package/bin/package-main.mjs +9 -0
  9. package/gui/dist/assets/index-DTpMHS4F.js +67 -0
  10. package/gui/dist/assets/index-ZNVDE3C7.css +1 -0
  11. package/gui/dist/favicon.png +0 -0
  12. package/gui/dist/icons.svg +24 -0
  13. package/gui/dist/index.html +25 -0
  14. package/gui/dist/logo.png +0 -0
  15. package/gui/dist/provider-icons/alibaba-color.svg +1 -0
  16. package/gui/dist/provider-icons/antigravity-color.svg +1 -0
  17. package/gui/dist/provider-icons/antigravity.svg +1 -0
  18. package/gui/dist/provider-icons/claude-color.svg +1 -0
  19. package/gui/dist/provider-icons/claude.svg +1 -0
  20. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
  21. package/gui/dist/provider-icons/copilot-color.svg +1 -0
  22. package/gui/dist/provider-icons/copilot.svg +1 -0
  23. package/gui/dist/provider-icons/cursor-color.svg +2 -0
  24. package/gui/dist/provider-icons/cursor.svg +2 -0
  25. package/gui/dist/provider-icons/deepseek-color.svg +1 -0
  26. package/gui/dist/provider-icons/discord.svg +1 -0
  27. package/gui/dist/provider-icons/firepass-color.svg +1 -0
  28. package/gui/dist/provider-icons/fireworks-color.svg +1 -0
  29. package/gui/dist/provider-icons/gemini-color.svg +1 -0
  30. package/gui/dist/provider-icons/gemini.svg +1 -0
  31. package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
  32. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
  33. package/gui/dist/provider-icons/grok-color.svg +1 -0
  34. package/gui/dist/provider-icons/grok.svg +1 -0
  35. package/gui/dist/provider-icons/groq-color.svg +1 -0
  36. package/gui/dist/provider-icons/huggingface-color.svg +1 -0
  37. package/gui/dist/provider-icons/kimi-color.svg +1 -0
  38. package/gui/dist/provider-icons/kiro-color.svg +15 -0
  39. package/gui/dist/provider-icons/kiro.svg +14 -0
  40. package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
  41. package/gui/dist/provider-icons/mistral-color.svg +1 -0
  42. package/gui/dist/provider-icons/moonshot-color.svg +1 -0
  43. package/gui/dist/provider-icons/nvidia-color.svg +1 -0
  44. package/gui/dist/provider-icons/ollama-color.svg +1 -0
  45. package/gui/dist/provider-icons/openai.svg +1 -0
  46. package/gui/dist/provider-icons/opencode.svg +1 -0
  47. package/gui/dist/provider-icons/openrouter-color.svg +1 -0
  48. package/gui/dist/provider-icons/pi.svg +21 -0
  49. package/gui/dist/provider-icons/qianfan-color.svg +1 -0
  50. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
  51. package/gui/dist/provider-icons/telegram.svg +1 -0
  52. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
  53. package/gui/dist/provider-icons/vllm-color.svg +1 -0
  54. package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
  55. package/package.json +102 -0
  56. package/src/AGENTS.md +28 -0
  57. package/src/adapters/anthropic-image-guard.ts +251 -0
  58. package/src/adapters/anthropic-image-normalize.ts +518 -0
  59. package/src/adapters/anthropic.ts +1003 -0
  60. package/src/adapters/azure.ts +36 -0
  61. package/src/adapters/base.ts +72 -0
  62. package/src/adapters/client-fingerprint.ts +59 -0
  63. package/src/adapters/cursor/arg-codec.ts +38 -0
  64. package/src/adapters/cursor/arg-normalize.ts +104 -0
  65. package/src/adapters/cursor/cursor-errors.ts +165 -0
  66. package/src/adapters/cursor/discovery.ts +276 -0
  67. package/src/adapters/cursor/effort-map.ts +127 -0
  68. package/src/adapters/cursor/exec-policy.ts +88 -0
  69. package/src/adapters/cursor/framing.ts +211 -0
  70. package/src/adapters/cursor/gen/agent_pb.ts +15274 -0
  71. package/src/adapters/cursor/kv-store.ts +52 -0
  72. package/src/adapters/cursor/live-models.ts +153 -0
  73. package/src/adapters/cursor/live-smoke-gate.ts +41 -0
  74. package/src/adapters/cursor/live-transport.ts +1214 -0
  75. package/src/adapters/cursor/mcp-config.ts +42 -0
  76. package/src/adapters/cursor/mcp-manager.ts +333 -0
  77. package/src/adapters/cursor/message-mapper.ts +49 -0
  78. package/src/adapters/cursor/native-exec-common.ts +55 -0
  79. package/src/adapters/cursor/native-exec-desktop.ts +184 -0
  80. package/src/adapters/cursor/native-exec-fs.ts +329 -0
  81. package/src/adapters/cursor/native-exec-mcp.ts +153 -0
  82. package/src/adapters/cursor/native-exec-network.ts +43 -0
  83. package/src/adapters/cursor/native-exec-shell.ts +548 -0
  84. package/src/adapters/cursor/native-exec-tools.ts +118 -0
  85. package/src/adapters/cursor/native-exec.ts +576 -0
  86. package/src/adapters/cursor/protobuf-events.ts +563 -0
  87. package/src/adapters/cursor/protobuf-request.ts +714 -0
  88. package/src/adapters/cursor/request-builder.ts +255 -0
  89. package/src/adapters/cursor/thread-continuity.ts +67 -0
  90. package/src/adapters/cursor/tool-definitions.ts +505 -0
  91. package/src/adapters/cursor/transport-retry.ts +132 -0
  92. package/src/adapters/cursor/transport.ts +57 -0
  93. package/src/adapters/cursor/types.ts +52 -0
  94. package/src/adapters/cursor.ts +196 -0
  95. package/src/adapters/google-antigravity-replay.ts +303 -0
  96. package/src/adapters/google-antigravity-wire.ts +108 -0
  97. package/src/adapters/google-errors.ts +85 -0
  98. package/src/adapters/google-http.ts +100 -0
  99. package/src/adapters/google-tool-schema.ts +173 -0
  100. package/src/adapters/google-truncation.ts +13 -0
  101. package/src/adapters/google-wire-compiler.ts +232 -0
  102. package/src/adapters/google.ts +758 -0
  103. package/src/adapters/identity.ts +44 -0
  104. package/src/adapters/image.ts +23 -0
  105. package/src/adapters/kiro-constants.ts +16 -0
  106. package/src/adapters/kiro-errors.ts +197 -0
  107. package/src/adapters/kiro-events.ts +179 -0
  108. package/src/adapters/kiro-images.ts +129 -0
  109. package/src/adapters/kiro-retry.ts +312 -0
  110. package/src/adapters/kiro-thinking.ts +96 -0
  111. package/src/adapters/kiro-tool-fallback.ts +36 -0
  112. package/src/adapters/kiro-tools.ts +215 -0
  113. package/src/adapters/kiro-truncation.ts +33 -0
  114. package/src/adapters/kiro-wire.ts +129 -0
  115. package/src/adapters/kiro.ts +1898 -0
  116. package/src/adapters/mimo-free.ts +263 -0
  117. package/src/adapters/openai-chat.ts +1005 -0
  118. package/src/adapters/openai-responses.ts +1137 -0
  119. package/src/adapters/run-turn-queue.ts +114 -0
  120. package/src/adapters/tool-catalog-nudge.ts +71 -0
  121. package/src/adapters/upstream-http-error.ts +48 -0
  122. package/src/bridge.ts +1619 -0
  123. package/src/chat/inbound.ts +295 -0
  124. package/src/chat/outbound.ts +765 -0
  125. package/src/claude/agents-inject.ts +243 -0
  126. package/src/claude/alias.ts +149 -0
  127. package/src/claude/auth-detect.ts +229 -0
  128. package/src/claude/auth-mode-migration.ts +32 -0
  129. package/src/claude/auth-mode.ts +62 -0
  130. package/src/claude/context-windows.ts +189 -0
  131. package/src/claude/desktop-3p-guard.ts +35 -0
  132. package/src/claude/desktop-3p-paths.ts +84 -0
  133. package/src/claude/desktop-3p.ts +381 -0
  134. package/src/claude/desktop-health.ts +26 -0
  135. package/src/claude/desktop-profile.ts +263 -0
  136. package/src/claude/gateway-cache.ts +70 -0
  137. package/src/claude/inbound-debug.ts +163 -0
  138. package/src/claude/inbound.ts +509 -0
  139. package/src/claude/model-info.ts +151 -0
  140. package/src/claude/outbound.ts +872 -0
  141. package/src/cli/access.ts +108 -0
  142. package/src/cli/account-api.ts +268 -0
  143. package/src/cli/account-auth.ts +223 -0
  144. package/src/cli/account-extended.ts +350 -0
  145. package/src/cli/account.ts +275 -0
  146. package/src/cli/agent-driven.ts +70 -0
  147. package/src/cli/agent.ts +184 -0
  148. package/src/cli/catalog-prewarm.ts +27 -0
  149. package/src/cli/claude-desktop.ts +188 -0
  150. package/src/cli/claude.ts +286 -0
  151. package/src/cli/codex-shim-autorestore.ts +45 -0
  152. package/src/cli/combo.ts +119 -0
  153. package/src/cli/config-command.ts +145 -0
  154. package/src/cli/debug.ts +228 -0
  155. package/src/cli/doctor.ts +930 -0
  156. package/src/cli/export-command.ts +187 -0
  157. package/src/cli/help.ts +354 -0
  158. package/src/cli/index.ts +1113 -0
  159. package/src/cli/init.ts +224 -0
  160. package/src/cli/integrations.ts +142 -0
  161. package/src/cli/interactive-confirm.ts +133 -0
  162. package/src/cli/internal-dispatch.ts +20 -0
  163. package/src/cli/models-runtime.ts +212 -0
  164. package/src/cli/models.ts +336 -0
  165. package/src/cli/observe.ts +117 -0
  166. package/src/cli/opencode.ts +586 -0
  167. package/src/cli/pi.ts +188 -0
  168. package/src/cli/provider-runtime.ts +162 -0
  169. package/src/cli/provider.ts +463 -0
  170. package/src/cli/runtime-api.ts +325 -0
  171. package/src/cli/star-prompt.ts +155 -0
  172. package/src/cli/status-oauth.ts +78 -0
  173. package/src/cli/status.ts +321 -0
  174. package/src/cli/sync-cloud.ts +283 -0
  175. package/src/cli/system-command.ts +112 -0
  176. package/src/cli/tray-proxy.ts +52 -0
  177. package/src/cli/v2.ts +173 -0
  178. package/src/cli.ts +10 -0
  179. package/src/clients/config-export.ts +377 -0
  180. package/src/clients/effective-status.ts +385 -0
  181. package/src/clients/probes/agy.ts +55 -0
  182. package/src/clients/probes/cc-switch.ts +110 -0
  183. package/src/clients/probes/claude.ts +90 -0
  184. package/src/clients/probes/codex.ts +125 -0
  185. package/src/clients/probes/grok.ts +29 -0
  186. package/src/clients/probes/opencode.ts +109 -0
  187. package/src/clients/probes/paseo.ts +55 -0
  188. package/src/clients/probes/pi.ts +55 -0
  189. package/src/cloud/onedrive-auth.ts +666 -0
  190. package/src/cloud/onedrive-graph.ts +108 -0
  191. package/src/cloud/settings.ts +75 -0
  192. package/src/cloud/sync.ts +212 -0
  193. package/src/cloud/types.ts +56 -0
  194. package/src/cloud/vault.ts +89 -0
  195. package/src/codex/account-id.ts +34 -0
  196. package/src/codex/account-label.ts +34 -0
  197. package/src/codex/account-lifecycle.ts +55 -0
  198. package/src/codex/account-namespace-match.ts +63 -0
  199. package/src/codex/account-namespaces.ts +149 -0
  200. package/src/codex/account-pause.ts +20 -0
  201. package/src/codex/account-runtime-state.ts +31 -0
  202. package/src/codex/account-store.ts +517 -0
  203. package/src/codex/account-usability.ts +20 -0
  204. package/src/codex/app-server-processes.ts +756 -0
  205. package/src/codex/auth-api.ts +1540 -0
  206. package/src/codex/auth-collision.ts +107 -0
  207. package/src/codex/auth-context.ts +352 -0
  208. package/src/codex/autostart-health.ts +149 -0
  209. package/src/codex/catalog/aggregation.ts +378 -0
  210. package/src/codex/catalog/bundled.ts +251 -0
  211. package/src/codex/catalog/effort.ts +355 -0
  212. package/src/codex/catalog/metadata.ts +180 -0
  213. package/src/codex/catalog/parsing.ts +456 -0
  214. package/src/codex/catalog/provider-fetch.ts +902 -0
  215. package/src/codex/catalog/sync.ts +620 -0
  216. package/src/codex/catalog.ts +12 -0
  217. package/src/codex/data/upstream-models.json +830 -0
  218. package/src/codex/exec-invocation.ts +22 -0
  219. package/src/codex/features.ts +969 -0
  220. package/src/codex/history-migration-guardian.ts +102 -0
  221. package/src/codex/history-provider.ts +776 -0
  222. package/src/codex/home.ts +206 -0
  223. package/src/codex/inject.ts +799 -0
  224. package/src/codex/injected-marker.ts +72 -0
  225. package/src/codex/journal.ts +163 -0
  226. package/src/codex/main-account-cache.ts +32 -0
  227. package/src/codex/main-account.ts +40 -0
  228. package/src/codex/model-cache.ts +227 -0
  229. package/src/codex/paths.ts +65 -0
  230. package/src/codex/plugins-doctor.ts +242 -0
  231. package/src/codex/pool-rotation.ts +225 -0
  232. package/src/codex/project-config-warnings.ts +411 -0
  233. package/src/codex/quota.ts +411 -0
  234. package/src/codex/refresh.ts +53 -0
  235. package/src/codex/routing.ts +1477 -0
  236. package/src/codex/runtime.ts +538 -0
  237. package/src/codex/shim.ts +1189 -0
  238. package/src/codex/subagent-defaults.ts +550 -0
  239. package/src/codex/subagent-model-fallback.ts +469 -0
  240. package/src/codex/sync.ts +130 -0
  241. package/src/codex/warmup.ts +192 -0
  242. package/src/codex/websocket-registry.ts +100 -0
  243. package/src/combos/failover.ts +140 -0
  244. package/src/combos/index.ts +41 -0
  245. package/src/combos/request.ts +62 -0
  246. package/src/combos/resolve.ts +232 -0
  247. package/src/combos/types.ts +326 -0
  248. package/src/config.ts +2356 -0
  249. package/src/generated/jawcode-model-metadata.ts +104 -0
  250. package/src/github/star-state.ts +203 -0
  251. package/src/grok/inject.ts +545 -0
  252. package/src/grok/status.ts +121 -0
  253. package/src/grok/sync.ts +103 -0
  254. package/src/grok/usage-hook/report.mjs +348 -0
  255. package/src/grok/usage-hook.ts +278 -0
  256. package/src/images/artifacts.ts +516 -0
  257. package/src/images/fulfill-video.ts +163 -0
  258. package/src/images/fulfill.ts +149 -0
  259. package/src/images/index.ts +4 -0
  260. package/src/images/loop.ts +829 -0
  261. package/src/images/plan.ts +133 -0
  262. package/src/images/synthetic-tool.ts +133 -0
  263. package/src/images/types.ts +41 -0
  264. package/src/images/xai-client.ts +141 -0
  265. package/src/images/xai-video-client.ts +163 -0
  266. package/src/index.ts +22 -0
  267. package/src/lib/abort.ts +146 -0
  268. package/src/lib/admin-secrets.ts +25 -0
  269. package/src/lib/admission.ts +83 -0
  270. package/src/lib/app-owned-memory-stores.ts +173 -0
  271. package/src/lib/app-owned-memory.ts +265 -0
  272. package/src/lib/bounded-body.ts +202 -0
  273. package/src/lib/bun-binary-validator.d.mts +3 -0
  274. package/src/lib/bun-binary-validator.mjs +18 -0
  275. package/src/lib/bun-runtime.ts +71 -0
  276. package/src/lib/bun-stream-caps.ts +126 -0
  277. package/src/lib/config-ownership.ts +360 -0
  278. package/src/lib/crash-guard.ts +344 -0
  279. package/src/lib/debug-log-buffer.ts +83 -0
  280. package/src/lib/debug-settings.ts +108 -0
  281. package/src/lib/debug.ts +31 -0
  282. package/src/lib/destination-policy.ts +316 -0
  283. package/src/lib/errors.ts +364 -0
  284. package/src/lib/eventstream-decoder.ts +253 -0
  285. package/src/lib/gcp-adc.ts +341 -0
  286. package/src/lib/injection-debug-log.ts +58 -0
  287. package/src/lib/open-url.ts +25 -0
  288. package/src/lib/pinned-http.ts +151 -0
  289. package/src/lib/privacy.ts +20 -0
  290. package/src/lib/process-control.ts +165 -0
  291. package/src/lib/provider-outbound.ts +170 -0
  292. package/src/lib/provider-url.ts +14 -0
  293. package/src/lib/proxy-env.ts +18 -0
  294. package/src/lib/redact.ts +105 -0
  295. package/src/lib/retry-after.ts +55 -0
  296. package/src/lib/service-secrets.ts +25 -0
  297. package/src/lib/shadow-call.ts +30 -0
  298. package/src/lib/sidecar-tracker.ts +52 -0
  299. package/src/lib/sse-decoder.ts +323 -0
  300. package/src/lib/state-store-registrations.ts +109 -0
  301. package/src/lib/state-store-sweeper.ts +184 -0
  302. package/src/lib/test-home-guard.ts +90 -0
  303. package/src/lib/token-estimate.ts +69 -0
  304. package/src/lib/translator-budget.ts +356 -0
  305. package/src/lib/upstream-retry.ts +239 -0
  306. package/src/lib/win-exec.ts +115 -0
  307. package/src/lib/win-paths.ts +68 -0
  308. package/src/lib/windows-elevation.ts +705 -0
  309. package/src/lib/windows-secret-acl.ts +514 -0
  310. package/src/lib/winsw.ts +375 -0
  311. package/src/oauth/anthropic-routing.ts +594 -0
  312. package/src/oauth/anthropic.ts +177 -0
  313. package/src/oauth/callback-server.ts +294 -0
  314. package/src/oauth/chatgpt.ts +150 -0
  315. package/src/oauth/cursor.ts +211 -0
  316. package/src/oauth/github-copilot.ts +428 -0
  317. package/src/oauth/google-antigravity.ts +230 -0
  318. package/src/oauth/health.ts +399 -0
  319. package/src/oauth/index.ts +1174 -0
  320. package/src/oauth/key-providers.ts +108 -0
  321. package/src/oauth/kimi.ts +213 -0
  322. package/src/oauth/kiro-credentials.ts +726 -0
  323. package/src/oauth/kiro.ts +577 -0
  324. package/src/oauth/local-token-detect.ts +121 -0
  325. package/src/oauth/log.ts +48 -0
  326. package/src/oauth/login-cli.ts +163 -0
  327. package/src/oauth/pkce.ts +15 -0
  328. package/src/oauth/store.ts +630 -0
  329. package/src/oauth/token-guardian.ts +303 -0
  330. package/src/oauth/types.ts +62 -0
  331. package/src/oauth/xai.ts +241 -0
  332. package/src/pi/extensions.ts +72 -0
  333. package/src/pi/home.ts +42 -0
  334. package/src/pi/index.ts +40 -0
  335. package/src/pi/models.ts +278 -0
  336. package/src/pi/packages.ts +219 -0
  337. package/src/pi/settings.ts +365 -0
  338. package/src/pi/status.ts +68 -0
  339. package/src/pi/sync.ts +75 -0
  340. package/src/providers/alibaba-region-backup.ts +75 -0
  341. package/src/providers/alibaba-region-migration.ts +156 -0
  342. package/src/providers/alibaba-region-startup.ts +36 -0
  343. package/src/providers/antigravity-models.ts +205 -0
  344. package/src/providers/api-keys.ts +140 -0
  345. package/src/providers/base-url-choices.ts +64 -0
  346. package/src/providers/context-cap.ts +65 -0
  347. package/src/providers/derive.ts +339 -0
  348. package/src/providers/free-directory.ts +184 -0
  349. package/src/providers/github-copilot-transport.ts +56 -0
  350. package/src/providers/key-failover.ts +203 -0
  351. package/src/providers/kiro-models.ts +67 -0
  352. package/src/providers/label.ts +19 -0
  353. package/src/providers/model-discovery.ts +356 -0
  354. package/src/providers/openai-sidecar.ts +175 -0
  355. package/src/providers/openai-tier-startup.ts +27 -0
  356. package/src/providers/openai-tiers.ts +301 -0
  357. package/src/providers/openai-virtual-models.ts +82 -0
  358. package/src/providers/openrouter-routing.ts +102 -0
  359. package/src/providers/provider-id-rewrite.ts +150 -0
  360. package/src/providers/quota.ts +1260 -0
  361. package/src/providers/registry.ts +1600 -0
  362. package/src/providers/slug-codec.ts +67 -0
  363. package/src/providers/xai-transport.ts +141 -0
  364. package/src/reasoning-effort.ts +135 -0
  365. package/src/responses/compaction.ts +117 -0
  366. package/src/responses/parser.ts +656 -0
  367. package/src/responses/reasoning-envelope.ts +52 -0
  368. package/src/responses/schema.ts +159 -0
  369. package/src/responses/spill-store.ts +394 -0
  370. package/src/responses/state.ts +895 -0
  371. package/src/responses/tool-groups.ts +19 -0
  372. package/src/router.ts +425 -0
  373. package/src/server/adapter-resolve.ts +80 -0
  374. package/src/server/auth-cors.ts +530 -0
  375. package/src/server/chat-completions.ts +368 -0
  376. package/src/server/claude-messages.ts +914 -0
  377. package/src/server/effort-policy.ts +172 -0
  378. package/src/server/gui-static.ts +123 -0
  379. package/src/server/image-retry.ts +42 -0
  380. package/src/server/images.ts +476 -0
  381. package/src/server/index.ts +1126 -0
  382. package/src/server/lifecycle.ts +227 -0
  383. package/src/server/live.ts +598 -0
  384. package/src/server/management/agent-settings-routes.ts +1169 -0
  385. package/src/server/management/api-access.ts +141 -0
  386. package/src/server/management/api-key-usage.ts +167 -0
  387. package/src/server/management/body.ts +35 -0
  388. package/src/server/management/clients-routes.ts +63 -0
  389. package/src/server/management/cloud-sync-routes.ts +266 -0
  390. package/src/server/management/combo-routes.ts +220 -0
  391. package/src/server/management/config-routes.ts +422 -0
  392. package/src/server/management/context.ts +31 -0
  393. package/src/server/management/logs-usage-routes.ts +707 -0
  394. package/src/server/management/model-routes.ts +525 -0
  395. package/src/server/management/oauth-account-routes.ts +563 -0
  396. package/src/server/management/provider-routes.ts +556 -0
  397. package/src/server/management/shared.ts +277 -0
  398. package/src/server/management/sidebar-routes.ts +90 -0
  399. package/src/server/management/system-restart.ts +179 -0
  400. package/src/server/management/system-routes.ts +117 -0
  401. package/src/server/management/usage-summary-cache.ts +86 -0
  402. package/src/server/management-api.ts +215 -0
  403. package/src/server/management-auth.ts +267 -0
  404. package/src/server/memory-watchdog.ts +156 -0
  405. package/src/server/port-reclaim.ts +307 -0
  406. package/src/server/ports.ts +116 -0
  407. package/src/server/proxy-liveness.ts +201 -0
  408. package/src/server/relay-eager.ts +313 -0
  409. package/src/server/relay.ts +1049 -0
  410. package/src/server/request-decompress.ts +132 -0
  411. package/src/server/request-log-conversation.ts +168 -0
  412. package/src/server/request-log.ts +1046 -0
  413. package/src/server/responses/collaboration.ts +354 -0
  414. package/src/server/responses/compact.ts +384 -0
  415. package/src/server/responses/core.ts +2758 -0
  416. package/src/server/responses/encrypted-payload.ts +308 -0
  417. package/src/server/responses/fetch-helpers.ts +157 -0
  418. package/src/server/responses/passthrough-error.ts +78 -0
  419. package/src/server/responses/terminal-guard.ts +230 -0
  420. package/src/server/responses/upstream-error.ts +48 -0
  421. package/src/server/responses-image-gen-repair.ts +132 -0
  422. package/src/server/responses-item-id-repair.ts +224 -0
  423. package/src/server/responses.ts +9 -0
  424. package/src/server/search.ts +136 -0
  425. package/src/server/sse-payload-rewrite.ts +175 -0
  426. package/src/server/startup-action-control.ts +308 -0
  427. package/src/server/startup-health-cache.ts +113 -0
  428. package/src/server/system-env.ts +413 -0
  429. package/src/server/windows-tcp-drop.ts +184 -0
  430. package/src/server/windows-tray-control.ts +41 -0
  431. package/src/server/ws-bridge.ts +471 -0
  432. package/src/service.ts +2554 -0
  433. package/src/stall-timeout.ts +20 -0
  434. package/src/storage/cleanup-job.ts +57 -0
  435. package/src/storage/cleanup.ts +3085 -0
  436. package/src/storage/policy-job.ts +457 -0
  437. package/src/storage/policy-scheduler.ts +40 -0
  438. package/src/storage/policy-worker.ts +59 -0
  439. package/src/storage/policy.ts +527 -0
  440. package/src/storage/restore-job.ts +299 -0
  441. package/src/storage/restore-worker.ts +58 -0
  442. package/src/storage/scanner.ts +238 -0
  443. package/src/storage/storage-mutation-coordinator.ts +139 -0
  444. package/src/storage/worker-lifecycle.ts +215 -0
  445. package/src/tray/assets/opencodex-tray-offline.ico +0 -0
  446. package/src/tray/assets/opencodex-tray-online.ico +0 -0
  447. package/src/tray/assets/opencodex-tray-warning.ico +0 -0
  448. package/src/tray/assets/opencodex-tray.png +0 -0
  449. package/src/tray/windows-tray.ps1 +290 -0
  450. package/src/tray/windows.ts +730 -0
  451. package/src/types.ts +1237 -0
  452. package/src/update/badge.ts +72 -0
  453. package/src/update/index.ts +407 -0
  454. package/src/update/job.ts +1520 -0
  455. package/src/update/notify.ts +257 -0
  456. package/src/update/npm-invocation.d.mts +23 -0
  457. package/src/update/npm-invocation.mjs +94 -0
  458. package/src/update/tray-update-plan.d.mts +18 -0
  459. package/src/update/tray-update-plan.mjs +38 -0
  460. package/src/usage/cost.ts +0 -0
  461. package/src/usage/debug.ts +97 -0
  462. package/src/usage/expected-prices.ts +164 -0
  463. package/src/usage/log.ts +658 -0
  464. package/src/usage/summary.ts +585 -0
  465. package/src/usage/totals.ts +14 -0
  466. package/src/vision/anthropic-describe.ts +185 -0
  467. package/src/vision/describe.ts +125 -0
  468. package/src/vision/index.ts +467 -0
  469. package/src/web-search/anthropic-executor.ts +189 -0
  470. package/src/web-search/executor.ts +105 -0
  471. package/src/web-search/format-result.ts +89 -0
  472. package/src/web-search/index.ts +196 -0
  473. package/src/web-search/loop.ts +664 -0
  474. package/src/web-search/parse.ts +220 -0
  475. package/src/web-search/progress-stream.ts +342 -0
  476. package/src/web-search/synthetic-tool.ts +47 -0
@@ -0,0 +1,368 @@
1
+ /**
2
+ * OpenAI Chat Completions inbound (/v1/chat/completions) for GitHub Copilot App
3
+ * and other OpenAI-compatible clients.
4
+ *
5
+ * Translate-and-replay: Chat Completions body -> /v1/responses via handleResponses,
6
+ * then bridge the Responses output back to Chat Completions SSE/JSON.
7
+ */
8
+ import { FORWARD_HEADERS } from "../adapters/openai-responses";
9
+ import { ChatCompletionsRequestError, chatCompletionsToResponsesBody } from "../chat/inbound";
10
+ import {
11
+ chatCompletionsErrorResponse,
12
+ collectChatCompletion,
13
+ isChatCompletionsStreamError,
14
+ responsesJsonToChatCompletion,
15
+ responsesSseToChatCompletionsSse,
16
+ } from "../chat/outbound";
17
+ import { classifyError, CYBER_POLICY_ERROR_CODE, isCyberPolicyCode } from "../lib/errors";
18
+ import { redactSecretString } from "../lib/redact";
19
+ import { resolveClientRetryAfter } from "../lib/retry-after";
20
+ import { estimateTokens } from "../lib/token-estimate";
21
+ import { routeModel } from "../router";
22
+ import { resolveWireProtocolOverride } from "./adapter-resolve";
23
+ import type { OcxConfig } from "../types";
24
+ import { readJsonRequestBody } from "./request-decompress";
25
+ import {
26
+ addFinalRequestLog,
27
+ httpStatusForTerminalStatus,
28
+ recordFirstOutput,
29
+ type RequestLogContext,
30
+ type RequestLogEntry,
31
+ } from "./request-log";
32
+ import { responseWithDeferredRequestLog } from "./relay";
33
+ import { handleResponses } from "./responses";
34
+ import type { AdmissionLease } from "../lib/admission";
35
+ import {
36
+ createTranslatorBudget,
37
+ finalizeTranslatorBudgetResponse,
38
+ isTranslatorBudgetExceededError,
39
+ type TranslatorBudget,
40
+ } from "../lib/translator-budget";
41
+
42
+ type Rec = Record<string, unknown>;
43
+
44
+ function isRec(v: unknown): v is Rec {
45
+ return !!v && typeof v === "object" && !Array.isArray(v);
46
+ }
47
+ async function readChatBody(req: Request, budget: TranslatorBudget): Promise<unknown> {
48
+ try {
49
+ return await readJsonRequestBody(req, budget);
50
+ } catch (err) {
51
+ if (isTranslatorBudgetExceededError(err)) throw err;
52
+ throw new ChatCompletionsRequestError(err instanceof Error && err.message ? err.message : "Invalid JSON body");
53
+ }
54
+ }
55
+
56
+ export async function handleChatCompletions(
57
+ req: Request,
58
+ config: OcxConfig,
59
+ logCtx: RequestLogContext,
60
+ logIds?: { requestId: string; start: number; turnAdmissionLease?: AdmissionLease },
61
+ ): Promise<Response> {
62
+ const translatorBudget = createTranslatorBudget();
63
+ try {
64
+ return finalizeTranslatorBudgetResponse(
65
+ await handleChatCompletionsWithBudget(req, config, logCtx, translatorBudget, logIds),
66
+ translatorBudget,
67
+ );
68
+ } catch (error) {
69
+ translatorBudget.dispose();
70
+ throw error;
71
+ }
72
+ }
73
+
74
+ async function handleChatCompletionsWithBudget(
75
+ req: Request,
76
+ config: OcxConfig,
77
+ logCtx: RequestLogContext,
78
+ translatorBudget: TranslatorBudget,
79
+ logIds?: { requestId: string; start: number; turnAdmissionLease?: AdmissionLease },
80
+ ): Promise<Response> {
81
+ let chatBody: unknown;
82
+ let internalBody: Rec;
83
+ try {
84
+ chatBody = await readChatBody(req, translatorBudget);
85
+ internalBody = chatCompletionsToResponsesBody(chatBody);
86
+ translatorBudget.chargeRetained(new TextEncoder().encode(JSON.stringify(internalBody)).byteLength, { kind: "request_copies" });
87
+ } catch (err) {
88
+ const overflow = isTranslatorBudgetExceededError(err);
89
+ const status = overflow ? 413 : err instanceof ChatCompletionsRequestError ? 400 : 500;
90
+ if (logIds) addFinalRequestLog(logIds.requestId, logIds.start, logCtx, status, { closeReason: "non_stream" });
91
+ return chatCompletionsErrorResponse(
92
+ status,
93
+ overflow ? "request translation buffer exceeded the safe limit" : err instanceof Error ? err.message : String(err),
94
+ overflow ? "request_too_large" : undefined,
95
+ overflow ? "translation_buffer_limit" : undefined,
96
+ );
97
+ }
98
+
99
+ const requestedModel = (chatBody as Rec).model as string;
100
+ const stream = internalBody.stream === true;
101
+ // Best-effort Grok attribution: the managed fence stamps this header on every model
102
+ // it registers (extra_headers, sent verbatim by upstream Grok). Dashboard usage
103
+ // bucketing only — never an auth or billing signal.
104
+ if (req.headers.get("x-opencodex-grok") === "1") logCtx.surface = "grok";
105
+ // Routed adapters only support streamed turns; always stream internally and fold
106
+ // for non-streaming clients.
107
+ internalBody.stream = true;
108
+
109
+ let nativeRoute = false;
110
+ let directRoute = false;
111
+ try {
112
+ const route = routeModel(config, internalBody.model as string);
113
+ // Settle the wire once so every branch below reads the adapter this model will
114
+ // actually use, not the provider-wide default (#404).
115
+ route.provider = resolveWireProtocolOverride(route.providerName, route.modelId, route.provider, "chat");
116
+ logCtx.model = route.modelId;
117
+ logCtx.providerAdapter = route.provider.adapter;
118
+ logCtx.requestedModel = requestedModel;
119
+ logCtx.provider = route.providerName;
120
+ if (route.provider.adapter === "openai-responses") {
121
+ nativeRoute = true;
122
+ directRoute = route.codexAccountMode === "direct";
123
+ // ChatGPT backend rejects store:true and unsupported sampling knobs.
124
+ internalBody.store = false;
125
+ delete internalBody.max_output_tokens;
126
+ delete internalBody.temperature;
127
+ delete internalBody.top_p;
128
+ delete internalBody.stop;
129
+ delete internalBody.user;
130
+ } else if (internalBody.store === undefined) {
131
+ internalBody.store = false;
132
+ }
133
+ if (route.provider.adapter === "openai-chat" && internalBody.text !== undefined) {
134
+ if (logIds) addFinalRequestLog(logIds.requestId, logIds.start, logCtx, 400, { closeReason: "non_stream" });
135
+ return chatCompletionsErrorResponse(400, "response_format is not supported for routed openai-chat models");
136
+ }
137
+ if (route.provider.adapter === "cursor" || route.provider.adapter === "kiro") {
138
+ const raw = chatBody as Rec;
139
+ const parts: string[] = [];
140
+ if (raw.messages !== undefined) parts.push(JSON.stringify(raw.messages));
141
+ if (raw.tools !== undefined) parts.push(JSON.stringify(raw.tools));
142
+ logCtx.usageLogInputTokens = Math.max(1, estimateTokens(parts.join("\n"), requestedModel));
143
+ }
144
+ if (internalBody.reasoning !== undefined) {
145
+ const { supportedLadderFor } = await import("./effort-policy");
146
+ const ladder = supportedLadderFor({ provider: route.provider, modelId: route.modelId });
147
+ if (ladder !== undefined && ladder.length === 0) delete internalBody.reasoning;
148
+ }
149
+ } catch {
150
+ /* unknown model: let handleResponses shape the 404 */
151
+ }
152
+ void nativeRoute;
153
+
154
+ const headers = new Headers({ "content-type": "application/json" });
155
+ for (const name of FORWARD_HEADERS) {
156
+ if (name === "authorization" && !directRoute) continue;
157
+ const value = req.headers.get(name);
158
+ if (value) headers.set(name, value);
159
+ }
160
+ // Prefer main ChatGPT auth so OpenAI-backed sidecars remain reachable on routed turns.
161
+ if (!directRoute) try {
162
+ const { getMainAccountToken } = await import("../codex/main-account");
163
+ const token = getMainAccountToken();
164
+ if (token) {
165
+ headers.set("authorization", `Bearer ${token.accessToken}`);
166
+ headers.set("chatgpt-account-id", token.chatgptAccountId);
167
+ }
168
+ } catch {
169
+ /* optional */
170
+ }
171
+
172
+ const internalBodyJson = JSON.stringify(internalBody);
173
+ translatorBudget.chargeRetained(new TextEncoder().encode(internalBodyJson).byteLength, { kind: "request_copies" });
174
+ const internalReq = new Request("http://localhost/v1/responses", {
175
+ method: "POST",
176
+ headers,
177
+ body: internalBodyJson,
178
+ });
179
+
180
+ let nativeLogged = false;
181
+ const finalizeNativeLog = (status: number, meta: { terminalStatus?: RequestLogEntry["terminalStatus"]; closeReason: "terminal" | "client_cancel" }) => {
182
+ if (!logIds || nativeLogged) return;
183
+ nativeLogged = true;
184
+ addFinalRequestLog(logIds.requestId, logIds.start, logCtx, status, meta);
185
+ };
186
+ const upstream = await handleResponses(internalReq, config, logCtx, {
187
+ ...(logIds?.turnAdmissionLease ? { turnAdmissionLease: logIds.turnAdmissionLease } : {}),
188
+ abortSignal: req.signal,
189
+ // Body is Responses-shaped by now, but the client spoke Chat Completions.
190
+ inboundWire: "chat",
191
+ translatorBudget,
192
+ ...(logIds ? { onFirstOutput: () => recordFirstOutput(logCtx, logIds.start) } : {}),
193
+ onNativePassthroughTerminal: status => finalizeNativeLog(httpStatusForTerminalStatus(status), { terminalStatus: status, closeReason: "terminal" }),
194
+ onNativePassthroughCancel: () => finalizeNativeLog(499, { closeReason: "client_cancel" }),
195
+ });
196
+
197
+ // Rewrite non-2xx before deferred logging so /api/logs records the client-facing status
198
+ // (e.g. cyber_policy remapped from a passthrough 5xx to HTTP 400).
199
+ if (!upstream.ok) {
200
+ let message = `upstream error (${upstream.status})`;
201
+ let upstreamCode: string | null | undefined;
202
+ let upstreamType: string | undefined;
203
+ try {
204
+ const text = await upstream.text();
205
+ try {
206
+ const parsed = JSON.parse(text) as {
207
+ error?: { message?: string; type?: string; code?: string | null } | string;
208
+ message?: string;
209
+ };
210
+ const nested = typeof parsed?.error === "object" && parsed.error ? parsed.error : undefined;
211
+ const flat = typeof parsed?.error === "string" ? parsed.error : parsed?.message;
212
+ const rawFallback = text
213
+ ? `upstream error (${upstream.status}): ${redactSecretString(text).slice(0, 400)}`
214
+ : message;
215
+ message = nested?.message || flat || rawFallback;
216
+ if (nested) {
217
+ if (typeof nested.type === "string") upstreamType = nested.type;
218
+ if (nested.code === null || typeof nested.code === "string") upstreamCode = nested.code;
219
+ }
220
+ } catch {
221
+ if (text) message = `upstream error (${upstream.status}): ${redactSecretString(text).slice(0, 400)}`;
222
+ }
223
+ } catch { /* keep fallback */ }
224
+ const retryAfter = resolveClientRetryAfter({
225
+ status: upstream.status,
226
+ message,
227
+ upstreamRetryAfter: upstream.headers.get("retry-after"),
228
+ });
229
+ const classified = classifyError(
230
+ upstream.status,
231
+ upstreamType
232
+ ?? (upstream.status === 401 ? "authentication_error"
233
+ : upstream.status === 429 ? "rate_limit_error"
234
+ : upstream.status >= 500 ? "server_error"
235
+ : "invalid_request_error"),
236
+ message,
237
+ );
238
+ if (isCyberPolicyCode(upstreamCode)) {
239
+ classified.code = CYBER_POLICY_ERROR_CODE;
240
+ classified.type = "invalid_request_error";
241
+ } else if (upstreamCode === "model_not_found") {
242
+ // Structured model_not_found must win over classifyError's generic remaps.
243
+ classified.code = "model_not_found";
244
+ classified.type = "invalid_request_error";
245
+ } else if (upstreamCode !== undefined && upstreamCode !== null && classified.code == null) {
246
+ classified.code = upstreamCode;
247
+ }
248
+ const status = isCyberPolicyCode(classified.code) ? 400 : upstream.status;
249
+ const rewritten = new Response(JSON.stringify({
250
+ error: {
251
+ message: classified.message,
252
+ type: classified.type,
253
+ param: null,
254
+ code: classified.code,
255
+ },
256
+ }), {
257
+ status,
258
+ headers: {
259
+ "Content-Type": "application/json",
260
+ ...(retryAfter ? { "Retry-After": retryAfter } : {}),
261
+ },
262
+ });
263
+ return logIds
264
+ ? responseWithDeferredRequestLog(rewritten, logIds.requestId, logIds.start, logCtx)
265
+ : rewritten;
266
+ }
267
+
268
+ const response = logIds
269
+ ? responseWithDeferredRequestLog(upstream, logIds.requestId, logIds.start, logCtx)
270
+ : upstream;
271
+
272
+ const contentType = response.headers.get("content-type") ?? "";
273
+ if (contentType.includes("text/event-stream") && response.body) {
274
+ const chatSse = responsesSseToChatCompletionsSse(response.body, requestedModel, { translatorBudget });
275
+ if (stream) {
276
+ // Stream failures surface as an error SSE frame then abort the body — never a
277
+ // success completion that embeds `[error] ...` + clean [DONE].
278
+ return new Response(chatSse, {
279
+ status: 200,
280
+ headers: {
281
+ "Content-Type": "text/event-stream; charset=utf-8",
282
+ "Cache-Control": "no-cache",
283
+ Connection: "keep-alive",
284
+ },
285
+ });
286
+ }
287
+ try {
288
+ const completion = await collectChatCompletion(chatSse, requestedModel, translatorBudget);
289
+ return new Response(JSON.stringify(completion), {
290
+ status: 200,
291
+ headers: { "Content-Type": "application/json" },
292
+ });
293
+ } catch (err) {
294
+ if (isChatCompletionsStreamError(err)) {
295
+ return chatCompletionsErrorResponse(err.status, err.message, err.type, err.code);
296
+ }
297
+ return chatCompletionsErrorResponse(
298
+ 502,
299
+ err instanceof Error ? err.message : String(err),
300
+ "server_error",
301
+ );
302
+ }
303
+ }
304
+
305
+ // Defensive: JSON despite stream:true.
306
+ let json: unknown;
307
+ try {
308
+ json = await response.json();
309
+ } catch {
310
+ return chatCompletionsErrorResponse(502, "internal replay returned a non-JSON response", "server_error");
311
+ }
312
+ const status = (json as Rec)?.status;
313
+ if (status === "failed") {
314
+ const error = (json as { error?: { message?: string; type?: string; code?: string | null } }).error;
315
+ const message = error?.message ?? "upstream request failed";
316
+ const classified = classifyError(502, error?.type ?? "server_error", message);
317
+ if (error?.code === "translation_buffer_limit") {
318
+ classified.code = "translation_buffer_limit";
319
+ classified.type = "invalid_request_error";
320
+ } else if (isCyberPolicyCode(error?.code)) {
321
+ classified.code = CYBER_POLICY_ERROR_CODE;
322
+ classified.type = "invalid_request_error";
323
+ } else if (error?.code === "model_not_found") {
324
+ // Same deliberate preserve as the non-OK path: structured code beats generic classify.
325
+ classified.code = "model_not_found";
326
+ classified.type = "invalid_request_error";
327
+ }
328
+ return chatCompletionsErrorResponse(
329
+ classified.code === "translation_buffer_limit"
330
+ ? 413
331
+ : isCyberPolicyCode(classified.code) ? 400 : 502,
332
+ message,
333
+ classified.type,
334
+ classified.code,
335
+ );
336
+ }
337
+ const completion = responsesJsonToChatCompletion(json, requestedModel);
338
+ if (!stream) {
339
+ return new Response(JSON.stringify(completion), {
340
+ status: 200,
341
+ headers: { "Content-Type": "application/json" },
342
+ });
343
+ }
344
+
345
+ // Streaming client + JSON upstream: synthesize a minimal Chat Completions stream.
346
+ const encoder = new TextEncoder();
347
+ const id = typeof completion.id === "string" ? completion.id : `chatcmpl-${Date.now()}`;
348
+ const created = typeof completion.created === "number" ? completion.created : Math.floor(Date.now() / 1000);
349
+ const message = isRec((completion.choices as Rec[] | undefined)?.[0])
350
+ ? ((completion.choices as Rec[])[0] as Rec).message as Rec | undefined
351
+ : undefined;
352
+ const content = message && typeof message.content === "string" ? message.content : "";
353
+ const frames = [
354
+ `data: ${JSON.stringify({ id, object: "chat.completion.chunk", created, model: requestedModel, choices: [{ index: 0, delta: { role: "assistant", content: "" }, finish_reason: null }] })}\n\n`,
355
+ ...(content
356
+ ? [`data: ${JSON.stringify({ id, object: "chat.completion.chunk", created, model: requestedModel, choices: [{ index: 0, delta: { content }, finish_reason: null }] })}\n\n`]
357
+ : []),
358
+ `data: ${JSON.stringify({ id, object: "chat.completion.chunk", created, model: requestedModel, choices: [{ index: 0, delta: {}, finish_reason: "stop" }], usage: completion.usage })}\n\n`,
359
+ "data: [DONE]\n\n",
360
+ ];
361
+ return new Response(encoder.encode(frames.join("")), {
362
+ status: 200,
363
+ headers: {
364
+ "Content-Type": "text/event-stream; charset=utf-8",
365
+ "Cache-Control": "no-cache",
366
+ },
367
+ });
368
+ }