mixdog 0.7.18 → 0.8.1

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 (847) hide show
  1. package/README.md +37 -331
  2. package/package.json +67 -99
  3. package/scripts/boot-smoke.mjs +94 -0
  4. package/scripts/build-tui.mjs +52 -0
  5. package/scripts/compact-smoke.mjs +199 -0
  6. package/scripts/lead-workflow-smoke.mjs +598 -0
  7. package/scripts/live-worker-smoke.mjs +239 -0
  8. package/scripts/output-style-smoke.mjs +101 -0
  9. package/scripts/session-context-bench.mjs +172 -0
  10. package/scripts/smoke-loop-report.mjs +221 -0
  11. package/scripts/smoke-loop.mjs +201 -0
  12. package/scripts/smoke.mjs +113 -0
  13. package/scripts/tool-failures.mjs +143 -0
  14. package/scripts/tool-smoke.mjs +452 -0
  15. package/src/agents/debugger/AGENT.md +3 -0
  16. package/src/agents/debugger/agent.json +6 -0
  17. package/src/agents/explore/AGENT.md +4 -0
  18. package/src/agents/explore/agent.json +6 -0
  19. package/src/agents/heavy-worker/AGENT.md +3 -0
  20. package/src/agents/heavy-worker/agent.json +6 -0
  21. package/src/agents/maintainer/AGENT.md +3 -0
  22. package/src/agents/maintainer/agent.json +6 -0
  23. package/src/agents/reviewer/AGENT.md +3 -0
  24. package/src/agents/reviewer/agent.json +6 -0
  25. package/src/agents/scheduler-task.md +3 -0
  26. package/src/agents/web-researcher/AGENT.md +3 -0
  27. package/src/agents/web-researcher/agent.json +6 -0
  28. package/src/agents/webhook-handler.md +3 -0
  29. package/src/agents/worker/AGENT.md +3 -0
  30. package/src/agents/worker/agent.json +6 -0
  31. package/src/app.mjs +90 -0
  32. package/src/cli.mjs +11 -0
  33. package/src/defaults/hidden-roles.json +72 -0
  34. package/src/defaults/mixdog-config.template.json +15 -0
  35. package/src/hooks/lib/permission-evaluator.cjs +488 -0
  36. package/src/hooks/lib/settings-loader.cjs +112 -0
  37. package/src/lib/keychain-cjs.cjs +332 -0
  38. package/src/lib/plugin-paths.cjs +28 -0
  39. package/src/lib/rules-builder.cjs +315 -0
  40. package/src/mixdog-session-runtime.mjs +3813 -0
  41. package/src/output-styles/default.md +38 -0
  42. package/src/output-styles/extreme-simple.md +17 -0
  43. package/src/output-styles/simple.md +17 -0
  44. package/src/repl.mjs +330 -0
  45. package/src/rules/bridge/00-common.md +5 -0
  46. package/src/rules/bridge/20-skip-protocol.md +11 -0
  47. package/src/rules/bridge/30-explorer.md +4 -0
  48. package/src/rules/bridge/40-cycle1-agent.md +28 -0
  49. package/src/rules/bridge/41-cycle2-agent.md +59 -0
  50. package/src/rules/lead/00-tool-lead.md +5 -0
  51. package/src/rules/lead/01-general.md +5 -0
  52. package/src/rules/lead/02-channels.md +3 -0
  53. package/src/rules/lead/04-workflow.md +12 -0
  54. package/src/rules/shared/00-language.md +3 -0
  55. package/src/rules/shared/01-tool.md +3 -0
  56. package/src/runtime/agent/orchestrator/bridge-trace.mjs +814 -0
  57. package/src/runtime/agent/orchestrator/cache-mtime.mjs +60 -0
  58. package/src/runtime/agent/orchestrator/config.mjs +446 -0
  59. package/src/runtime/agent/orchestrator/context/collect.mjs +796 -0
  60. package/src/runtime/agent/orchestrator/dispatch-persist.mjs +417 -0
  61. package/src/runtime/agent/orchestrator/internal-roles.mjs +188 -0
  62. package/src/runtime/agent/orchestrator/internal-tools.mjs +88 -0
  63. package/src/runtime/agent/orchestrator/mcp/client.mjs +345 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2104 -0
  65. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +784 -0
  66. package/src/runtime/agent/orchestrator/providers/api-usage.mjs +341 -0
  67. package/src/runtime/agent/orchestrator/providers/gemini.mjs +1679 -0
  68. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +959 -0
  69. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +213 -0
  70. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +38 -0
  71. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +471 -0
  72. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +615 -0
  73. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +808 -0
  74. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +1719 -0
  75. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +2587 -0
  76. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +1953 -0
  77. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +136 -0
  78. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +317 -0
  79. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +109 -0
  80. package/src/runtime/agent/orchestrator/providers/registry.mjs +247 -0
  81. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +332 -0
  82. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +11 -0
  83. package/src/runtime/agent/orchestrator/providers/trace-utils.mjs +50 -0
  84. package/src/runtime/agent/orchestrator/session/cache/post-edit-marks.mjs +42 -0
  85. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +142 -0
  86. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +318 -0
  87. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +367 -0
  88. package/src/runtime/agent/orchestrator/session/compact.mjs +882 -0
  89. package/src/runtime/agent/orchestrator/session/context-utils.mjs +233 -0
  90. package/src/runtime/agent/orchestrator/session/loop.mjs +2269 -0
  91. package/src/runtime/agent/orchestrator/session/manager.mjs +2972 -0
  92. package/src/runtime/agent/orchestrator/session/result-classification.mjs +65 -0
  93. package/src/runtime/agent/orchestrator/session/store.mjs +870 -0
  94. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +166 -0
  95. package/src/runtime/agent/orchestrator/smart-bridge/bridge-llm.mjs +339 -0
  96. package/src/runtime/agent/orchestrator/smart-bridge/cache-strategy.mjs +419 -0
  97. package/src/runtime/agent/orchestrator/stall-policy.mjs +227 -0
  98. package/src/runtime/agent/orchestrator/tool-loop-guard.mjs +235 -0
  99. package/src/runtime/agent/orchestrator/tools/bash-session.mjs +723 -0
  100. package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +171 -0
  101. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +389 -0
  102. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +637 -0
  103. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +165 -0
  104. package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +104 -0
  105. package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +194 -0
  106. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +596 -0
  107. package/src/runtime/agent/orchestrator/tools/builtin/native-edit-runner.mjs +110 -0
  108. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +153 -0
  109. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +118 -0
  110. package/src/runtime/agent/orchestrator/tools/builtin/read-open.mjs +189 -0
  111. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +731 -0
  112. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +168 -0
  113. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +602 -0
  114. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +465 -0
  115. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +160 -0
  116. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +982 -0
  117. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +1087 -0
  118. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +231 -0
  119. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-store.mjs +223 -0
  120. package/src/runtime/agent/orchestrator/tools/builtin.mjs +478 -0
  121. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +24 -0
  122. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4102 -0
  123. package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +323 -0
  124. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +154 -0
  125. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +26 -0
  126. package/src/runtime/agent/orchestrator/tools/patch-binary-fetcher.mjs +143 -0
  127. package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +18 -0
  128. package/src/runtime/agent/orchestrator/tools/patch.mjs +2772 -0
  129. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +114 -0
  130. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +880 -0
  131. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +312 -0
  132. package/src/runtime/channels/backends/discord.mjs +781 -0
  133. package/src/runtime/channels/data/voice-runtime-manifest.json +138 -0
  134. package/src/runtime/channels/index.mjs +3309 -0
  135. package/src/runtime/channels/lib/config.mjs +285 -0
  136. package/src/runtime/channels/lib/drop-trace.mjs +71 -0
  137. package/src/runtime/channels/lib/event-pipeline.mjs +81 -0
  138. package/src/runtime/channels/lib/holidays.mjs +138 -0
  139. package/src/runtime/channels/lib/hook-pipe-server.mjs +671 -0
  140. package/src/runtime/channels/lib/output-forwarder.mjs +765 -0
  141. package/src/runtime/channels/lib/runtime-paths.mjs +497 -0
  142. package/src/runtime/channels/lib/scheduler.mjs +710 -0
  143. package/src/runtime/channels/lib/session-discovery.mjs +102 -0
  144. package/src/runtime/channels/lib/state-file.mjs +68 -0
  145. package/src/runtime/channels/lib/status-snapshot.mjs +224 -0
  146. package/src/runtime/channels/lib/tool-format.mjs +122 -0
  147. package/src/runtime/channels/lib/transcript-discovery.mjs +195 -0
  148. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +734 -0
  149. package/src/runtime/channels/lib/webhook.mjs +1288 -0
  150. package/src/runtime/channels/tool-defs.mjs +177 -0
  151. package/src/runtime/lib/keychain-cjs.cjs +289 -0
  152. package/src/runtime/memory/data/runtime-manifest.json +40 -0
  153. package/src/runtime/memory/index.mjs +3706 -0
  154. package/src/runtime/memory/lib/core-memory-store.mjs +336 -0
  155. package/src/runtime/memory/lib/embedding-provider.mjs +275 -0
  156. package/src/runtime/memory/lib/embedding-worker.mjs +331 -0
  157. package/src/runtime/memory/lib/memory-cycle-requests.mjs +276 -0
  158. package/src/runtime/memory/lib/memory-cycle1.mjs +783 -0
  159. package/src/runtime/memory/lib/memory-cycle2.mjs +1389 -0
  160. package/src/runtime/memory/lib/memory-cycle3.mjs +646 -0
  161. package/src/runtime/memory/lib/memory-embed.mjs +300 -0
  162. package/src/runtime/memory/lib/memory-ops-policy.mjs +149 -0
  163. package/src/runtime/memory/lib/memory-recall-store.mjs +644 -0
  164. package/src/runtime/memory/lib/memory.mjs +418 -0
  165. package/src/runtime/memory/lib/pg/adapter.mjs +328 -0
  166. package/src/runtime/memory/lib/pg/process.mjs +366 -0
  167. package/src/runtime/memory/lib/pg/supervisor.mjs +495 -0
  168. package/src/runtime/memory/lib/runtime-fetcher.mjs +464 -0
  169. package/src/runtime/memory/lib/trace-store.mjs +734 -0
  170. package/src/runtime/memory/tool-defs.mjs +79 -0
  171. package/src/runtime/search/index.mjs +925 -0
  172. package/src/runtime/search/lib/config.mjs +61 -0
  173. package/src/runtime/search/lib/web-tools.mjs +1278 -0
  174. package/src/runtime/search/tool-defs.mjs +64 -0
  175. package/src/runtime/shared/atomic-file.mjs +435 -0
  176. package/src/runtime/shared/background-tasks.mjs +376 -0
  177. package/src/runtime/shared/child-guardian.mjs +98 -0
  178. package/src/runtime/shared/config.mjs +393 -0
  179. package/src/runtime/shared/err-text.mjs +121 -0
  180. package/src/runtime/shared/launcher-control.mjs +259 -0
  181. package/src/runtime/shared/llm/http-agent.mjs +129 -0
  182. package/src/runtime/shared/open-url.mjs +37 -0
  183. package/src/runtime/shared/plugin-paths.mjs +25 -0
  184. package/src/runtime/shared/process-shutdown.mjs +147 -0
  185. package/src/runtime/shared/schedules-store.mjs +70 -0
  186. package/src/runtime/shared/tool-execution-contract.mjs +104 -0
  187. package/src/runtime/shared/tool-surface.mjs +947 -0
  188. package/src/runtime/shared/user-cwd.mjs +221 -0
  189. package/src/runtime/shared/user-data-guard.mjs +232 -0
  190. package/src/runtime/shared/workspace-router.mjs +259 -0
  191. package/src/standalone/bridge-tool.mjs +1414 -0
  192. package/src/standalone/channel-admin.mjs +366 -0
  193. package/src/standalone/channel-worker-preload.cjs +3 -0
  194. package/src/standalone/channel-worker.mjs +353 -0
  195. package/src/standalone/explore-tool.mjs +233 -0
  196. package/src/standalone/hook-bus.mjs +246 -0
  197. package/src/standalone/plugin-admin.mjs +247 -0
  198. package/src/standalone/provider-admin.mjs +338 -0
  199. package/src/standalone/seeds.mjs +94 -0
  200. package/src/standalone/usage-dashboard.mjs +510 -0
  201. package/src/tui/App.jsx +5446 -0
  202. package/src/tui/components/AnsiText.jsx +199 -0
  203. package/src/tui/components/ContextPanel.jsx +265 -0
  204. package/src/tui/components/Markdown.jsx +205 -0
  205. package/src/tui/components/MarkdownTable.jsx +204 -0
  206. package/src/tui/components/Message.jsx +103 -0
  207. package/src/tui/components/Picker.jsx +317 -0
  208. package/src/tui/components/PromptInput.jsx +584 -0
  209. package/src/tui/components/QueuedCommands.jsx +47 -0
  210. package/src/tui/components/SlashCommandPalette.jsx +114 -0
  211. package/src/tui/components/Spinner.jsx +317 -0
  212. package/src/tui/components/StatusLine.jsx +87 -0
  213. package/src/tui/components/TextEntryPanel.jsx +323 -0
  214. package/src/tui/components/ToolExecution.jsx +791 -0
  215. package/src/tui/components/TurnDone.jsx +78 -0
  216. package/src/tui/components/UsagePanel.jsx +331 -0
  217. package/src/tui/dist/index.mjs +12420 -0
  218. package/src/tui/engine.mjs +2410 -0
  219. package/src/tui/figures.mjs +50 -0
  220. package/src/tui/hooks/useEngine.mjs +16 -0
  221. package/src/tui/index.jsx +254 -0
  222. package/src/tui/input-editing.mjs +242 -0
  223. package/src/tui/markdown/format-token.mjs +194 -0
  224. package/src/tui/paste-attachments.mjs +198 -0
  225. package/src/tui/runtime/shared/process-shutdown.mjs +1 -0
  226. package/src/tui/spinner-verbs.mjs +45 -0
  227. package/src/tui/theme.mjs +67 -0
  228. package/src/tui/time-format.mjs +53 -0
  229. package/src/ui/ansi.mjs +115 -0
  230. package/src/ui/markdown.mjs +195 -0
  231. package/src/ui/statusline.mjs +730 -0
  232. package/src/ui/tool-card.mjs +99 -0
  233. package/src/vendor/statusline/bin/statusline-lib.mjs +805 -0
  234. package/src/vendor/statusline/bin/statusline-route.mjs +596 -0
  235. package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +285 -0
  236. package/src/vendor/statusline/src/gateway/claude-current.mjs +320 -0
  237. package/src/vendor/statusline/src/gateway/route-meta.mjs +753 -0
  238. package/src/vendor/statusline/src/gateway/session-routes.mjs +244 -0
  239. package/src/workflows/default/WORKFLOW.md +7 -0
  240. package/src/workflows/default/workflow.json +14 -0
  241. package/vendor/ink/build/ansi-tokenizer.d.ts +38 -0
  242. package/vendor/ink/build/ansi-tokenizer.js +316 -0
  243. package/vendor/ink/build/ansi-tokenizer.js.map +1 -0
  244. package/vendor/ink/build/colorize.d.ts +3 -0
  245. package/vendor/ink/build/colorize.js +48 -0
  246. package/vendor/ink/build/colorize.js.map +1 -0
  247. package/vendor/ink/build/components/AccessibilityContext.d.ts +3 -0
  248. package/vendor/ink/build/components/AccessibilityContext.js +5 -0
  249. package/vendor/ink/build/components/AccessibilityContext.js.map +1 -0
  250. package/vendor/ink/build/components/AnimationContext.d.ts +9 -0
  251. package/vendor/ink/build/components/AnimationContext.js +13 -0
  252. package/vendor/ink/build/components/AnimationContext.js.map +1 -0
  253. package/vendor/ink/build/components/App.d.ts +24 -0
  254. package/vendor/ink/build/components/App.js +554 -0
  255. package/vendor/ink/build/components/App.js.map +1 -0
  256. package/vendor/ink/build/components/AppContext.d.ts +80 -0
  257. package/vendor/ink/build/components/AppContext.js +25 -0
  258. package/vendor/ink/build/components/AppContext.js.map +1 -0
  259. package/vendor/ink/build/components/BackgroundContext.d.ts +4 -0
  260. package/vendor/ink/build/components/BackgroundContext.js +3 -0
  261. package/vendor/ink/build/components/BackgroundContext.js.map +1 -0
  262. package/vendor/ink/build/components/Box.d.ts +130 -0
  263. package/vendor/ink/build/components/Box.js +34 -0
  264. package/vendor/ink/build/components/Box.js.map +1 -0
  265. package/vendor/ink/build/components/CursorContext.d.ts +11 -0
  266. package/vendor/ink/build/components/CursorContext.js +8 -0
  267. package/vendor/ink/build/components/CursorContext.js.map +1 -0
  268. package/vendor/ink/build/components/ErrorBoundary.d.ts +18 -0
  269. package/vendor/ink/build/components/ErrorBoundary.js +23 -0
  270. package/vendor/ink/build/components/ErrorBoundary.js.map +1 -0
  271. package/vendor/ink/build/components/ErrorOverview.d.ts +6 -0
  272. package/vendor/ink/build/components/ErrorOverview.js +90 -0
  273. package/vendor/ink/build/components/ErrorOverview.js.map +1 -0
  274. package/vendor/ink/build/components/FocusContext.d.ts +16 -0
  275. package/vendor/ink/build/components/FocusContext.js +17 -0
  276. package/vendor/ink/build/components/FocusContext.js.map +1 -0
  277. package/vendor/ink/build/components/Newline.d.ts +13 -0
  278. package/vendor/ink/build/components/Newline.js +8 -0
  279. package/vendor/ink/build/components/Newline.js.map +1 -0
  280. package/vendor/ink/build/components/Spacer.d.ts +7 -0
  281. package/vendor/ink/build/components/Spacer.js +11 -0
  282. package/vendor/ink/build/components/Spacer.js.map +1 -0
  283. package/vendor/ink/build/components/Static.d.ts +24 -0
  284. package/vendor/ink/build/components/Static.js +28 -0
  285. package/vendor/ink/build/components/Static.js.map +1 -0
  286. package/vendor/ink/build/components/StderrContext.d.ts +15 -0
  287. package/vendor/ink/build/components/StderrContext.js +13 -0
  288. package/vendor/ink/build/components/StderrContext.js.map +1 -0
  289. package/vendor/ink/build/components/StdinContext.d.ts +28 -0
  290. package/vendor/ink/build/components/StdinContext.js +20 -0
  291. package/vendor/ink/build/components/StdinContext.js.map +1 -0
  292. package/vendor/ink/build/components/StdoutContext.d.ts +15 -0
  293. package/vendor/ink/build/components/StdoutContext.js +13 -0
  294. package/vendor/ink/build/components/StdoutContext.js.map +1 -0
  295. package/vendor/ink/build/components/Text.d.ts +55 -0
  296. package/vendor/ink/build/components/Text.js +50 -0
  297. package/vendor/ink/build/components/Text.js.map +1 -0
  298. package/vendor/ink/build/components/Transform.d.ts +16 -0
  299. package/vendor/ink/build/components/Transform.js +15 -0
  300. package/vendor/ink/build/components/Transform.js.map +1 -0
  301. package/vendor/ink/build/cursor-helpers.d.ts +39 -0
  302. package/vendor/ink/build/cursor-helpers.js +62 -0
  303. package/vendor/ink/build/cursor-helpers.js.map +1 -0
  304. package/vendor/ink/build/devtools-window-polyfill.d.ts +1 -0
  305. package/vendor/ink/build/devtools-window-polyfill.js +68 -0
  306. package/vendor/ink/build/devtools-window-polyfill.js.map +1 -0
  307. package/vendor/ink/build/devtools.d.ts +1 -0
  308. package/vendor/ink/build/devtools.js +36 -0
  309. package/vendor/ink/build/devtools.js.map +1 -0
  310. package/vendor/ink/build/dom.d.ts +62 -0
  311. package/vendor/ink/build/dom.js +143 -0
  312. package/vendor/ink/build/dom.js.map +1 -0
  313. package/vendor/ink/build/get-max-width.d.ts +3 -0
  314. package/vendor/ink/build/get-max-width.js +10 -0
  315. package/vendor/ink/build/get-max-width.js.map +1 -0
  316. package/vendor/ink/build/hooks/use-animation.d.ts +49 -0
  317. package/vendor/ink/build/hooks/use-animation.js +87 -0
  318. package/vendor/ink/build/hooks/use-animation.js.map +1 -0
  319. package/vendor/ink/build/hooks/use-app.d.ts +5 -0
  320. package/vendor/ink/build/hooks/use-app.js +8 -0
  321. package/vendor/ink/build/hooks/use-app.js.map +1 -0
  322. package/vendor/ink/build/hooks/use-box-metrics.d.ts +59 -0
  323. package/vendor/ink/build/hooks/use-box-metrics.js +81 -0
  324. package/vendor/ink/build/hooks/use-box-metrics.js.map +1 -0
  325. package/vendor/ink/build/hooks/use-cursor.d.ts +12 -0
  326. package/vendor/ink/build/hooks/use-cursor.js +29 -0
  327. package/vendor/ink/build/hooks/use-cursor.js.map +1 -0
  328. package/vendor/ink/build/hooks/use-focus-manager.d.ts +43 -0
  329. package/vendor/ink/build/hooks/use-focus-manager.js +18 -0
  330. package/vendor/ink/build/hooks/use-focus-manager.js.map +1 -0
  331. package/vendor/ink/build/hooks/use-focus.d.ts +30 -0
  332. package/vendor/ink/build/hooks/use-focus.js +43 -0
  333. package/vendor/ink/build/hooks/use-focus.js.map +1 -0
  334. package/vendor/ink/build/hooks/use-input.d.ts +132 -0
  335. package/vendor/ink/build/hooks/use-input.js +126 -0
  336. package/vendor/ink/build/hooks/use-input.js.map +1 -0
  337. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.d.ts +6 -0
  338. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js +12 -0
  339. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js.map +1 -0
  340. package/vendor/ink/build/hooks/use-paste.d.ts +35 -0
  341. package/vendor/ink/build/hooks/use-paste.js +62 -0
  342. package/vendor/ink/build/hooks/use-paste.js.map +1 -0
  343. package/vendor/ink/build/hooks/use-stderr.d.ts +5 -0
  344. package/vendor/ink/build/hooks/use-stderr.js +8 -0
  345. package/vendor/ink/build/hooks/use-stderr.js.map +1 -0
  346. package/vendor/ink/build/hooks/use-stdin.d.ts +7 -0
  347. package/vendor/ink/build/hooks/use-stdin.js +9 -0
  348. package/vendor/ink/build/hooks/use-stdin.js.map +1 -0
  349. package/vendor/ink/build/hooks/use-stdout.d.ts +5 -0
  350. package/vendor/ink/build/hooks/use-stdout.js +8 -0
  351. package/vendor/ink/build/hooks/use-stdout.js.map +1 -0
  352. package/vendor/ink/build/hooks/use-window-size.d.ts +18 -0
  353. package/vendor/ink/build/hooks/use-window-size.js +22 -0
  354. package/vendor/ink/build/hooks/use-window-size.js.map +1 -0
  355. package/vendor/ink/build/index.d.ts +42 -0
  356. package/vendor/ink/build/index.js +24 -0
  357. package/vendor/ink/build/index.js.map +1 -0
  358. package/vendor/ink/build/ink.d.ts +146 -0
  359. package/vendor/ink/build/ink.js +1022 -0
  360. package/vendor/ink/build/ink.js.map +1 -0
  361. package/vendor/ink/build/input-parser.d.ts +10 -0
  362. package/vendor/ink/build/input-parser.js +194 -0
  363. package/vendor/ink/build/input-parser.js.map +1 -0
  364. package/vendor/ink/build/instances.d.ts +3 -0
  365. package/vendor/ink/build/instances.js +8 -0
  366. package/vendor/ink/build/instances.js.map +1 -0
  367. package/vendor/ink/build/kitty-keyboard.d.ts +23 -0
  368. package/vendor/ink/build/kitty-keyboard.js +32 -0
  369. package/vendor/ink/build/kitty-keyboard.js.map +1 -0
  370. package/vendor/ink/build/log-update.d.ts +20 -0
  371. package/vendor/ink/build/log-update.js +261 -0
  372. package/vendor/ink/build/log-update.js.map +1 -0
  373. package/vendor/ink/build/measure-element.d.ts +20 -0
  374. package/vendor/ink/build/measure-element.js +13 -0
  375. package/vendor/ink/build/measure-element.js.map +1 -0
  376. package/vendor/ink/build/measure-text.d.ts +6 -0
  377. package/vendor/ink/build/measure-text.js +21 -0
  378. package/vendor/ink/build/measure-text.js.map +1 -0
  379. package/vendor/ink/build/output.d.ts +35 -0
  380. package/vendor/ink/build/output.js +328 -0
  381. package/vendor/ink/build/output.js.map +1 -0
  382. package/vendor/ink/build/parse-keypress.d.ts +20 -0
  383. package/vendor/ink/build/parse-keypress.js +495 -0
  384. package/vendor/ink/build/parse-keypress.js.map +1 -0
  385. package/vendor/ink/build/reconciler.d.ts +4 -0
  386. package/vendor/ink/build/reconciler.js +306 -0
  387. package/vendor/ink/build/reconciler.js.map +1 -0
  388. package/vendor/ink/build/render-background.d.ts +4 -0
  389. package/vendor/ink/build/render-background.js +25 -0
  390. package/vendor/ink/build/render-background.js.map +1 -0
  391. package/vendor/ink/build/render-border.d.ts +4 -0
  392. package/vendor/ink/build/render-border.js +84 -0
  393. package/vendor/ink/build/render-border.js.map +1 -0
  394. package/vendor/ink/build/render-node-to-output.d.ts +14 -0
  395. package/vendor/ink/build/render-node-to-output.js +162 -0
  396. package/vendor/ink/build/render-node-to-output.js.map +1 -0
  397. package/vendor/ink/build/render-to-string.d.ts +38 -0
  398. package/vendor/ink/build/render-to-string.js +116 -0
  399. package/vendor/ink/build/render-to-string.js.map +1 -0
  400. package/vendor/ink/build/render.d.ts +176 -0
  401. package/vendor/ink/build/render.js +71 -0
  402. package/vendor/ink/build/render.js.map +1 -0
  403. package/vendor/ink/build/renderer.d.ts +8 -0
  404. package/vendor/ink/build/renderer.js +64 -0
  405. package/vendor/ink/build/renderer.js.map +1 -0
  406. package/vendor/ink/build/sanitize-ansi.d.ts +2 -0
  407. package/vendor/ink/build/sanitize-ansi.js +27 -0
  408. package/vendor/ink/build/sanitize-ansi.js.map +1 -0
  409. package/vendor/ink/build/squash-text-nodes.d.ts +3 -0
  410. package/vendor/ink/build/squash-text-nodes.js +36 -0
  411. package/vendor/ink/build/squash-text-nodes.js.map +1 -0
  412. package/vendor/ink/build/styles.d.ts +302 -0
  413. package/vendor/ink/build/styles.js +303 -0
  414. package/vendor/ink/build/styles.js.map +1 -0
  415. package/vendor/ink/build/utils.d.ts +9 -0
  416. package/vendor/ink/build/utils.js +19 -0
  417. package/vendor/ink/build/utils.js.map +1 -0
  418. package/vendor/ink/build/wrap-text.d.ts +3 -0
  419. package/vendor/ink/build/wrap-text.js +38 -0
  420. package/vendor/ink/build/wrap-text.js.map +1 -0
  421. package/vendor/ink/build/write-synchronized.d.ts +4 -0
  422. package/vendor/ink/build/write-synchronized.js +9 -0
  423. package/vendor/ink/build/write-synchronized.js.map +1 -0
  424. package/vendor/ink/license +10 -0
  425. package/vendor/ink/package.json +137 -0
  426. package/.claude-plugin/marketplace.json +0 -34
  427. package/.claude-plugin/plugin.json +0 -20
  428. package/.gitattributes +0 -34
  429. package/.mcp.json +0 -14
  430. package/ARCHITECTURE.md +0 -77
  431. package/CHANGELOG.md +0 -30
  432. package/CONTRIBUTING.md +0 -45
  433. package/DATA-FLOW.md +0 -79
  434. package/LICENSE +0 -21
  435. package/SECURITY.md +0 -138
  436. package/UNINSTALL.md +0 -115
  437. package/agents/maintenance.md +0 -5
  438. package/agents/memory-classification.md +0 -30
  439. package/agents/scheduler-task.md +0 -18
  440. package/agents/webhook-handler.md +0 -27
  441. package/agents/worker.md +0 -24
  442. package/bin/bridge +0 -133
  443. package/bin/statusline-launcher.mjs +0 -82
  444. package/bin/statusline-lib.mjs +0 -581
  445. package/bin/statusline-route.mjs +0 -273
  446. package/bin/statusline.mjs +0 -638
  447. package/bun.lock +0 -927
  448. package/commands/config.md +0 -16
  449. package/commands/doctor.md +0 -13
  450. package/commands/model.md +0 -61
  451. package/commands/setup.md +0 -17
  452. package/defaults/hidden-roles.json +0 -68
  453. package/defaults/memory-chunk-prompt.md +0 -63
  454. package/defaults/mixdog-config.template.json +0 -27
  455. package/defaults/user-workflow.json +0 -8
  456. package/defaults/user-workflow.md +0 -17
  457. package/hooks/hooks.json +0 -73
  458. package/hooks/lib/active-instance.cjs +0 -77
  459. package/hooks/lib/permission-evaluator.cjs +0 -411
  460. package/hooks/lib/permission-route.cjs +0 -63
  461. package/hooks/lib/settings-loader.cjs +0 -117
  462. package/hooks/post-tool-use.cjs +0 -84
  463. package/hooks/pre-mcp-sandbox.cjs +0 -158
  464. package/hooks/pre-tool-subagent.cjs +0 -258
  465. package/hooks/session-start.cjs +0 -1493
  466. package/hooks/shim-launcher.cjs +0 -65
  467. package/hooks/turn-timer.cjs +0 -82
  468. package/lib/claude-md-writer.cjs +0 -386
  469. package/lib/keychain-cjs.cjs +0 -290
  470. package/lib/plugin-paths.cjs +0 -69
  471. package/lib/rules-builder.cjs +0 -241
  472. package/native/README.md +0 -117
  473. package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
  474. package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
  475. package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
  476. package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
  477. package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
  478. package/prompts/code-review.txt +0 -16
  479. package/prompts/security-audit.txt +0 -17
  480. package/rules/bridge/00-common.md +0 -39
  481. package/rules/bridge/20-skip-protocol.md +0 -18
  482. package/rules/bridge/30-explorer.md +0 -33
  483. package/rules/bridge/40-cycle1-agent.md +0 -52
  484. package/rules/bridge/41-cycle2-agent.md +0 -62
  485. package/rules/lead/00-tool-lead.md +0 -61
  486. package/rules/lead/01-general.md +0 -26
  487. package/rules/lead/02-channels.md +0 -49
  488. package/rules/lead/03-team.md +0 -27
  489. package/rules/lead/04-workflow.md +0 -20
  490. package/rules/shared/00-language.md +0 -14
  491. package/rules/shared/01-tool.md +0 -138
  492. package/scripts/bootstrap.mjs +0 -130
  493. package/scripts/bridge-unify-smoke.mjs +0 -308
  494. package/scripts/build-runtime-linux.sh +0 -348
  495. package/scripts/build-runtime-macos.sh +0 -217
  496. package/scripts/build-runtime-windows.ps1 +0 -242
  497. package/scripts/builtin-utils-smoke.mjs +0 -398
  498. package/scripts/bump.mjs +0 -80
  499. package/scripts/check-json.mjs +0 -45
  500. package/scripts/check-syntax-changed.mjs +0 -102
  501. package/scripts/check-syntax.mjs +0 -58
  502. package/scripts/code-graph-batch.test.mjs +0 -33
  503. package/scripts/config-preserve-smoke.mjs +0 -180
  504. package/scripts/doctor.mjs +0 -489
  505. package/scripts/edit-normalize-fuzz.mjs +0 -130
  506. package/scripts/edit-normalize-smoke.mjs +0 -401
  507. package/scripts/edit-operation-smoke.mjs +0 -369
  508. package/scripts/edit2-smoke.mjs +0 -63
  509. package/scripts/ensure-deps.mjs +0 -259
  510. package/scripts/fuzzy-e2e.mjs +0 -28
  511. package/scripts/fuzzy-smoke.mjs +0 -26
  512. package/scripts/gateway-model.mjs +0 -596
  513. package/scripts/generate-runtime-manifest.mjs +0 -166
  514. package/scripts/guard-smoke.mjs +0 -66
  515. package/scripts/hidden-role-schema-smoke.mjs +0 -162
  516. package/scripts/hook-routing-smoke.mjs +0 -29
  517. package/scripts/inject-input.ps1 +0 -204
  518. package/scripts/io-complex-smoke.mjs +0 -667
  519. package/scripts/io-explore-bench.mjs +0 -424
  520. package/scripts/io-guardrails-smoke.mjs +0 -205
  521. package/scripts/io-mini-bench-baseline.json +0 -11
  522. package/scripts/io-mini-bench.mjs +0 -216
  523. package/scripts/io-route-harness.mjs +0 -933
  524. package/scripts/io-telemetry-report.mjs +0 -691
  525. package/scripts/lib/gateway-inventory.mjs +0 -178
  526. package/scripts/lib/gateway-settings.mjs +0 -78
  527. package/scripts/mutation-bench.mjs +0 -564
  528. package/scripts/mutation-io-smoke.mjs +0 -1097
  529. package/scripts/native-patch-bridge-smoke.mjs +0 -288
  530. package/scripts/native-patch-smoke.mjs +0 -304
  531. package/scripts/openai-oauth-catalog-smoke.mjs +0 -53
  532. package/scripts/patch-interior-context-smoke.mjs +0 -49
  533. package/scripts/patch-newline-utf8-smoke.mjs +0 -157
  534. package/scripts/perf-hook-smoke.mjs +0 -71
  535. package/scripts/permission-eval-smoke.mjs +0 -443
  536. package/scripts/prep-patch.mjs +0 -53
  537. package/scripts/prep-shim.mjs +0 -96
  538. package/scripts/provider-cache-smoke.mjs +0 -687
  539. package/scripts/report-runtime-health.mjs +0 -132
  540. package/scripts/resolve-bun.mjs +0 -60
  541. package/scripts/run-mcp.mjs +0 -1473
  542. package/scripts/salvage-v4a-shatter.test.mjs +0 -58
  543. package/scripts/scoped-cache-io-smoke.mjs +0 -103
  544. package/scripts/shell-policy-round3-smoke.mjs +0 -46
  545. package/scripts/smoke-runtime-negative.ps1 +0 -100
  546. package/scripts/smoke-runtime-negative.sh +0 -95
  547. package/scripts/stall-policy-smoke.mjs +0 -50
  548. package/scripts/start-memory-worker.mjs +0 -23
  549. package/scripts/statusline-launcher-smoke.mjs +0 -235
  550. package/scripts/stress-atomic-write.mjs +0 -1028
  551. package/scripts/test-fault-inject.mjs +0 -164
  552. package/scripts/test-large-file.mjs +0 -174
  553. package/scripts/tool-edge-smoke.mjs +0 -209
  554. package/scripts/uninstall.mjs +0 -238
  555. package/scripts/webhook-selfheal-smoke.mjs +0 -27
  556. package/scripts/write-overwrite-guard-smoke.mjs +0 -56
  557. package/server-main.mjs +0 -3350
  558. package/server.mjs +0 -468
  559. package/setup/config-merge.mjs +0 -246
  560. package/setup/install.mjs +0 -574
  561. package/setup/launch-core.mjs +0 -617
  562. package/setup/launch.mjs +0 -101
  563. package/setup/locate-claude.mjs +0 -56
  564. package/setup/mixdog-cli.mjs +0 -122
  565. package/setup/setup-server.mjs +0 -3305
  566. package/setup/setup.html +0 -3740
  567. package/setup/tui.mjs +0 -325
  568. package/skills/retro-skill-proposer/SKILL.md +0 -92
  569. package/skills/schedule-add/SKILL.md +0 -77
  570. package/skills/setup/SKILL.md +0 -356
  571. package/skills/webhook-add/SKILL.md +0 -81
  572. package/src/agent/bridge-stall-watchdog.mjs +0 -337
  573. package/src/agent/index.mjs +0 -2229
  574. package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +0 -1010
  575. package/src/agent/orchestrator/bridge-retry.mjs +0 -220
  576. package/src/agent/orchestrator/bridge-trace.mjs +0 -601
  577. package/src/agent/orchestrator/cache-mtime.mjs +0 -58
  578. package/src/agent/orchestrator/config.mjs +0 -405
  579. package/src/agent/orchestrator/context/collect.mjs +0 -651
  580. package/src/agent/orchestrator/dispatch-persist.mjs +0 -549
  581. package/src/agent/orchestrator/drain-registry.mjs +0 -50
  582. package/src/agent/orchestrator/explore-validator.mjs +0 -8
  583. package/src/agent/orchestrator/internal-roles.mjs +0 -118
  584. package/src/agent/orchestrator/internal-tools.mjs +0 -88
  585. package/src/agent/orchestrator/jobs.mjs +0 -116
  586. package/src/agent/orchestrator/mcp/client.mjs +0 -364
  587. package/src/agent/orchestrator/providers/anthropic-oauth.mjs +0 -1884
  588. package/src/agent/orchestrator/providers/anthropic.mjs +0 -598
  589. package/src/agent/orchestrator/providers/gemini.mjs +0 -1530
  590. package/src/agent/orchestrator/providers/grok-oauth.mjs +0 -779
  591. package/src/agent/orchestrator/providers/model-catalog.mjs +0 -374
  592. package/src/agent/orchestrator/providers/openai-compat-stream.mjs +0 -366
  593. package/src/agent/orchestrator/providers/openai-compat.mjs +0 -1511
  594. package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +0 -1891
  595. package/src/agent/orchestrator/providers/openai-oauth.mjs +0 -1456
  596. package/src/agent/orchestrator/providers/openai-ws.mjs +0 -127
  597. package/src/agent/orchestrator/providers/registry.mjs +0 -192
  598. package/src/agent/orchestrator/providers/retry-classifier.mjs +0 -325
  599. package/src/agent/orchestrator/session/cache/post-edit-marks.mjs +0 -42
  600. package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +0 -142
  601. package/src/agent/orchestrator/session/cache/read-cache.mjs +0 -319
  602. package/src/agent/orchestrator/session/cache/scoped-cache.mjs +0 -361
  603. package/src/agent/orchestrator/session/loop.mjs +0 -1619
  604. package/src/agent/orchestrator/session/manager.mjs +0 -1991
  605. package/src/agent/orchestrator/session/result-classification.mjs +0 -65
  606. package/src/agent/orchestrator/session/store.mjs +0 -632
  607. package/src/agent/orchestrator/session/stream-watchdog.mjs +0 -130
  608. package/src/agent/orchestrator/session/tool-result-offload.mjs +0 -166
  609. package/src/agent/orchestrator/session/trim.mjs +0 -491
  610. package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +0 -115
  611. package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +0 -331
  612. package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +0 -150
  613. package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +0 -228
  614. package/src/agent/orchestrator/smart-bridge/index.mjs +0 -215
  615. package/src/agent/orchestrator/smart-bridge/profiles.mjs +0 -37
  616. package/src/agent/orchestrator/smart-bridge/registry.mjs +0 -348
  617. package/src/agent/orchestrator/stall-policy.mjs +0 -201
  618. package/src/agent/orchestrator/tool-loop-guard.mjs +0 -75
  619. package/src/agent/orchestrator/tools/bash-session.mjs +0 -722
  620. package/src/agent/orchestrator/tools/builtin/advisory-lock.mjs +0 -171
  621. package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +0 -511
  622. package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -480
  623. package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +0 -256
  624. package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +0 -58
  625. package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +0 -240
  626. package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +0 -113
  627. package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +0 -74
  628. package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +0 -242
  629. package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +0 -211
  630. package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +0 -1364
  631. package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +0 -126
  632. package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +0 -141
  633. package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +0 -194
  634. package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +0 -60
  635. package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +0 -168
  636. package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +0 -173
  637. package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +0 -48
  638. package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +0 -99
  639. package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +0 -193
  640. package/src/agent/orchestrator/tools/builtin/list-tool.mjs +0 -597
  641. package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +0 -110
  642. package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +0 -300
  643. package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +0 -152
  644. package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +0 -118
  645. package/src/agent/orchestrator/tools/builtin/read-open.mjs +0 -190
  646. package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +0 -728
  647. package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +0 -173
  648. package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +0 -602
  649. package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +0 -196
  650. package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +0 -422
  651. package/src/agent/orchestrator/tools/builtin/search-builders.mjs +0 -158
  652. package/src/agent/orchestrator/tools/builtin/search-tool.mjs +0 -869
  653. package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +0 -962
  654. package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +0 -223
  655. package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +0 -206
  656. package/src/agent/orchestrator/tools/builtin/write-tool.mjs +0 -401
  657. package/src/agent/orchestrator/tools/builtin.mjs +0 -503
  658. package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +0 -24
  659. package/src/agent/orchestrator/tools/code-graph.mjs +0 -4095
  660. package/src/agent/orchestrator/tools/cwd-tool.mjs +0 -298
  661. package/src/agent/orchestrator/tools/destructive-warning.mjs +0 -323
  662. package/src/agent/orchestrator/tools/edit-normalize.mjs +0 -603
  663. package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +0 -154
  664. package/src/agent/orchestrator/tools/graph-manifest.json +0 -26
  665. package/src/agent/orchestrator/tools/host-input.mjs +0 -204
  666. package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +0 -143
  667. package/src/agent/orchestrator/tools/patch-manifest.json +0 -26
  668. package/src/agent/orchestrator/tools/patch-tool-defs.mjs +0 -20
  669. package/src/agent/orchestrator/tools/patch.mjs +0 -2754
  670. package/src/agent/orchestrator/tools/progress-message.mjs +0 -118
  671. package/src/agent/orchestrator/tools/shell-command.mjs +0 -865
  672. package/src/agent/orchestrator/tools/shell-policy-imports.mjs +0 -7
  673. package/src/agent/orchestrator/tools/shell-snapshot.mjs +0 -313
  674. package/src/agent/orchestrator/workflow-store.mjs +0 -93
  675. package/src/agent/tool-defs.mjs +0 -110
  676. package/src/channels/backends/discord.mjs +0 -784
  677. package/src/channels/data/voice-runtime-manifest.json +0 -138
  678. package/src/channels/index.mjs +0 -3268
  679. package/src/channels/lib/config.mjs +0 -292
  680. package/src/channels/lib/drop-trace.mjs +0 -71
  681. package/src/channels/lib/event-pipeline.mjs +0 -81
  682. package/src/channels/lib/holidays.mjs +0 -138
  683. package/src/channels/lib/hook-pipe-server.mjs +0 -822
  684. package/src/channels/lib/output-forwarder.mjs +0 -765
  685. package/src/channels/lib/runtime-paths.mjs +0 -552
  686. package/src/channels/lib/scheduler.mjs +0 -723
  687. package/src/channels/lib/session-discovery.mjs +0 -103
  688. package/src/channels/lib/state-file.mjs +0 -68
  689. package/src/channels/lib/status-snapshot.mjs +0 -219
  690. package/src/channels/lib/tool-format.mjs +0 -140
  691. package/src/channels/lib/transcript-discovery.mjs +0 -195
  692. package/src/channels/lib/voice-runtime-fetcher.mjs +0 -734
  693. package/src/channels/lib/webhook.mjs +0 -1318
  694. package/src/channels/tool-defs.mjs +0 -170
  695. package/src/daemon/host.mjs +0 -118
  696. package/src/daemon/mcp-transport.mjs +0 -47
  697. package/src/daemon/session.mjs +0 -100
  698. package/src/daemon/thin-client.mjs +0 -71
  699. package/src/daemon/transport.mjs +0 -163
  700. package/src/gateway/claude-current.mjs +0 -255
  701. package/src/gateway/oauth-usage.mjs +0 -598
  702. package/src/gateway/route-meta.mjs +0 -629
  703. package/src/gateway/server.mjs +0 -713
  704. package/src/memory/data/runtime-manifest.json +0 -40
  705. package/src/memory/index.mjs +0 -3332
  706. package/src/memory/lib/core-memory-store.mjs +0 -330
  707. package/src/memory/lib/embedding-provider.mjs +0 -269
  708. package/src/memory/lib/embedding-worker.mjs +0 -323
  709. package/src/memory/lib/memory-cycle1.mjs +0 -645
  710. package/src/memory/lib/memory-cycle2.mjs +0 -1284
  711. package/src/memory/lib/memory-cycle3.mjs +0 -540
  712. package/src/memory/lib/memory-embed.mjs +0 -299
  713. package/src/memory/lib/memory-ops-policy.mjs +0 -190
  714. package/src/memory/lib/memory-recall-store.mjs +0 -638
  715. package/src/memory/lib/memory.mjs +0 -412
  716. package/src/memory/lib/pg/adapter.mjs +0 -308
  717. package/src/memory/lib/pg/process.mjs +0 -360
  718. package/src/memory/lib/pg/supervisor.mjs +0 -396
  719. package/src/memory/lib/runtime-fetcher.mjs +0 -458
  720. package/src/memory/lib/trace-store.mjs +0 -728
  721. package/src/memory/tool-defs.mjs +0 -79
  722. package/src/search/index.mjs +0 -1173
  723. package/src/search/lib/backends/anthropic-oauth.mjs +0 -98
  724. package/src/search/lib/backends/exa.mjs +0 -50
  725. package/src/search/lib/backends/firecrawl.mjs +0 -61
  726. package/src/search/lib/backends/gemini-api.mjs +0 -83
  727. package/src/search/lib/backends/grok-oauth.mjs +0 -86
  728. package/src/search/lib/backends/index.mjs +0 -150
  729. package/src/search/lib/backends/openai-api.mjs +0 -144
  730. package/src/search/lib/backends/openai-oauth.mjs +0 -102
  731. package/src/search/lib/backends/openai-web-search.mjs +0 -76
  732. package/src/search/lib/backends/tavily.mjs +0 -55
  733. package/src/search/lib/backends/xai-api.mjs +0 -113
  734. package/src/search/lib/config.mjs +0 -192
  735. package/src/search/lib/provider-usage.mjs +0 -67
  736. package/src/search/lib/providers.mjs +0 -47
  737. package/src/search/lib/search-intent.mjs +0 -109
  738. package/src/search/lib/setup-handler.mjs +0 -261
  739. package/src/search/lib/web-tools.mjs +0 -1219
  740. package/src/search/tool-defs.mjs +0 -83
  741. package/src/setup/defender-exclusion.mjs +0 -183
  742. package/src/shared/atomic-file.mjs +0 -436
  743. package/src/shared/config.mjs +0 -372
  744. package/src/shared/daemon-recycle.mjs +0 -108
  745. package/src/shared/disable-claude-builtins.mjs +0 -91
  746. package/src/shared/err-text.mjs +0 -12
  747. package/src/shared/llm/http-agent.mjs +0 -123
  748. package/src/shared/open-url.mjs +0 -62
  749. package/src/shared/plugin-paths.mjs +0 -58
  750. package/src/shared/schedules-store.mjs +0 -70
  751. package/src/shared/seed.mjs +0 -161
  752. package/src/shared/user-cwd.mjs +0 -225
  753. package/src/shared/user-data-guard.mjs +0 -244
  754. package/src/status/aggregator.mjs +0 -584
  755. package/src/status/server.mjs +0 -413
  756. package/tools.json +0 -1671
  757. /package/{defaults → src/defaults}/cycle3-review-prompt.md +0 -0
  758. /package/{defaults → src/defaults}/memory-promote-prompt.md +0 -0
  759. /package/{hooks → src/hooks}/lib/permission-rules.cjs +0 -0
  760. /package/{lib → src/lib}/config-cjs.cjs +0 -0
  761. /package/{lib → src/lib}/hook-pipe-path.cjs +0 -0
  762. /package/{lib → src/lib}/mixdog-debug.cjs +0 -0
  763. /package/{lib → src/lib}/text-utils.cjs +0 -0
  764. /package/{rules → src/rules}/bridge/42-cycle3-agent.md +0 -0
  765. /package/src/{agent → runtime/agent}/orchestrator/activity-bus.mjs +0 -0
  766. /package/src/{agent → runtime/agent}/orchestrator/providers/anthropic-betas.mjs +0 -0
  767. /package/src/{agent → runtime/agent}/orchestrator/session/abort-lookup.mjs +0 -0
  768. /package/src/{agent → runtime/agent}/orchestrator/session/cache/scoped-cache-outcome.mjs +0 -0
  769. /package/src/{agent → runtime/agent}/orchestrator/session/cache/util.mjs +0 -0
  770. /package/src/{agent → runtime/agent}/orchestrator/session/read-dedup.mjs +0 -0
  771. /package/src/{agent → runtime/agent}/orchestrator/session/save-session-worker.mjs +0 -0
  772. /package/src/{agent → runtime/agent}/orchestrator/smart-bridge/session-builder.mjs +0 -0
  773. /package/src/{agent → runtime/agent}/orchestrator/tools/bash-policy-scan.mjs +0 -0
  774. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/atomic-write.mjs +0 -0
  775. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/binary-file.mjs +0 -0
  776. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/cache-layers.mjs +0 -0
  777. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/cwd-utils.mjs +0 -0
  778. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/device-paths.mjs +0 -0
  779. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -0
  780. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/diff-utils.mjs +0 -0
  781. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/fs-reachability.mjs +0 -0
  782. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/grep-formatting.mjs +0 -0
  783. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/hash-utils.mjs +0 -0
  784. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/list-formatting.mjs +0 -0
  785. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/open-config-tool.mjs +0 -0
  786. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/path-locks.mjs +0 -0
  787. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/path-utils.mjs +0 -0
  788. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-args.mjs +0 -0
  789. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-batch.mjs +0 -0
  790. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-constants.mjs +0 -0
  791. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-image-resize.mjs +0 -0
  792. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-image.mjs +0 -0
  793. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-lines.mjs +0 -0
  794. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-mode-tool.mjs +0 -0
  795. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-range-index.mjs +0 -0
  796. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-ranges.mjs +0 -0
  797. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-special-files.mjs +0 -0
  798. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-tool.mjs +0 -0
  799. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-windows.mjs +0 -0
  800. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/shell-analysis.mjs +0 -0
  801. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/shell-output.mjs +0 -0
  802. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/snapshot-helpers.mjs +0 -0
  803. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/snapshot-validation.mjs +0 -0
  804. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/text-stats.mjs +0 -0
  805. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/windows-roots.mjs +0 -0
  806. /package/src/{agent → runtime/agent}/orchestrator/tools/code-graph-prewarm-worker.mjs +0 -0
  807. /package/src/{agent → runtime/agent}/orchestrator/tools/env-scrub.mjs +0 -0
  808. /package/src/{agent → runtime/agent}/orchestrator/tools/mutation-content-cache.mjs +0 -0
  809. /package/src/{agent → runtime/agent}/orchestrator/tools/mutation-planner.mjs +0 -0
  810. /package/src/{agent → runtime/agent}/orchestrator/tools/next-call-utils.mjs +0 -0
  811. /package/src/{agent → runtime/agent}/orchestrator/tools/result-compression.mjs +0 -0
  812. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-exec-policy.mjs +0 -0
  813. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-policy-danger-target.mjs +0 -0
  814. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-policy.mjs +0 -0
  815. /package/src/{channels → runtime/channels}/lib/cli-worker-host.mjs +0 -0
  816. /package/src/{channels → runtime/channels}/lib/config-lock.mjs +0 -0
  817. /package/src/{channels → runtime/channels}/lib/event-queue.mjs +0 -0
  818. /package/src/{channels → runtime/channels}/lib/executor.mjs +0 -0
  819. /package/src/{channels → runtime/channels}/lib/format.mjs +0 -0
  820. /package/src/{channels → runtime/channels}/lib/interaction-workflows.mjs +0 -0
  821. /package/src/{channels → runtime/channels}/lib/memory-client.mjs +0 -0
  822. /package/src/{channels → runtime/channels}/lib/session-control.mjs +0 -0
  823. /package/src/{channels → runtime/channels}/lib/settings.mjs +0 -0
  824. /package/src/{channels → runtime/channels}/lib/whisper-server.mjs +0 -0
  825. /package/src/{memory → runtime/memory}/lib/agent-ipc.mjs +0 -0
  826. /package/src/{memory → runtime/memory}/lib/bridge-trace-queries.mjs +0 -0
  827. /package/src/{memory → runtime/memory}/lib/llm-worker-host.mjs +0 -0
  828. /package/src/{memory → runtime/memory}/lib/memory-cycle.mjs +0 -0
  829. /package/src/{memory → runtime/memory}/lib/memory-extraction.mjs +0 -0
  830. /package/src/{memory → runtime/memory}/lib/memory-maintenance-store.mjs +0 -0
  831. /package/src/{memory → runtime/memory}/lib/memory-recall-id-patch.mjs +0 -0
  832. /package/src/{memory → runtime/memory}/lib/memory-recall-read-query.mjs +0 -0
  833. /package/src/{memory → runtime/memory}/lib/memory-recall-scope-filter.mjs +0 -0
  834. /package/src/{memory → runtime/memory}/lib/memory-retrievers.mjs +0 -0
  835. /package/src/{memory → runtime/memory}/lib/memory-score.mjs +0 -0
  836. /package/src/{memory → runtime/memory}/lib/memory-text-utils.mjs +0 -0
  837. /package/src/{memory → runtime/memory}/lib/model-profile.mjs +0 -0
  838. /package/src/{memory → runtime/memory}/lib/project-id-resolver.mjs +0 -0
  839. /package/src/{search → runtime/search}/lib/cache.mjs +0 -0
  840. /package/src/{search → runtime/search}/lib/formatter.mjs +0 -0
  841. /package/src/{search → runtime/search}/lib/state.mjs +0 -0
  842. /package/src/{shared → runtime/shared}/abort-controller.mjs +0 -0
  843. /package/src/{shared → runtime/shared}/llm/cost.mjs +0 -0
  844. /package/src/{shared → runtime/shared}/llm/index.mjs +0 -0
  845. /package/src/{shared → runtime/shared}/llm/pid-cleanup.mjs +0 -0
  846. /package/src/{shared → runtime/shared}/llm/usage-log.mjs +0 -0
  847. /package/src/{shared → runtime/shared}/wsl.mjs +0 -0
@@ -1,1511 +0,0 @@
1
- import OpenAI from 'openai';
2
- import { createHash } from 'crypto';
3
- import { loadConfig } from '../config.mjs';
4
- import { withRetry } from './retry-classifier.mjs';
5
- import { sendViaWebSocket } from './openai-oauth-ws.mjs';
6
- import {
7
- consumeCompatChatCompletionStream,
8
- consumeCompatResponsesStream,
9
- parseCompletedToolCallArgumentsJson,
10
- } from './openai-compat-stream.mjs';
11
- import { appendBridgeTrace, traceBridgeUsage } from '../bridge-trace.mjs';
12
- import { resolveProviderCacheKey } from '../smart-bridge/cache-strategy.mjs';
13
- import {
14
- PROVIDER_FIRST_BYTE_TIMEOUT_MS,
15
- PROVIDER_NONSTREAM_TOTAL_TIMEOUT_MS,
16
- PROVIDER_GENERATE_TOTAL_TIMEOUT_MS,
17
- createTimeoutSignal,
18
- resolveTimeoutMs,
19
- } from '../stall-policy.mjs';
20
- // OPENAI_COMPAT_PRESETS — self-declaring list of compat provider names and
21
- // their base URLs / defaults. registry.mjs imports this export so there is no
22
- // parallel OPENAI_COMPAT_PROVIDERS list to maintain separately.
23
- export const OPENAI_COMPAT_PRESETS = {
24
- deepseek: {
25
- baseURL: 'https://api.deepseek.com',
26
- defaultModel: 'deepseek-v4-pro',
27
- },
28
- xai: {
29
- baseURL: 'https://api.x.ai/v1',
30
- defaultModel: 'grok-4.3',
31
- },
32
- // OpenCode Go — low-cost coding-model subscription gateway. The Go
33
- // gateway exposes a unified OpenAI-compatible /chat/completions surface
34
- // that transparently fronts every Go model (GLM / Kimi / DeepSeek / MiMo
35
- // and the anthropic-native MiniMax / Qwen), including tool-calling and
36
- // server-side prefix caching (cached_tokens), so no separate Anthropic
37
- // transport is needed. Auth is a single OPENCODE_API_KEY (Bearer).
38
- // listModels() pulls the live roster from {baseURL}/models.
39
- 'opencode-go': {
40
- baseURL: 'https://opencode.ai/zen/go/v1',
41
- defaultModel: 'glm-5.2',
42
- },
43
- ollama: {
44
- baseURL: 'http://localhost:11434/v1',
45
- defaultModel: 'llama3.3:latest',
46
- },
47
- lmstudio: {
48
- baseURL: 'http://localhost:1234/v1',
49
- defaultModel: 'default',
50
- },
51
- };
52
- const PRESETS = OPENAI_COMPAT_PRESETS;
53
- const MODEL_LIST_TIMEOUT_MS = resolveTimeoutMs(
54
- 'MIXDOG_COMPAT_MODEL_LIST_TIMEOUT_MS',
55
- 10_000,
56
- { minMs: 1_000, maxMs: PROVIDER_GENERATE_TOTAL_TIMEOUT_MS },
57
- );
58
-
59
- // SSRF guard for provider baseURL. config.baseURL comes from user JSON;
60
- // reject non-http(s) schemes (file:/data:/ftp:/etc.) and require https for
61
- // any non-localhost host. Localhost-only presets (ollama, lmstudio) and
62
- // loopback hosts may use http. Throws a clear config error — no silent
63
- // fallback — so misconfig surfaces immediately instead of leaking apiKey.
64
- function assertSafeBaseURL(rawURL, providerName) {
65
- let parsed;
66
- try {
67
- parsed = new URL(String(rawURL));
68
- } catch {
69
- throw new Error(`[provider:${providerName}] invalid baseURL: ${rawURL}`);
70
- }
71
- const scheme = parsed.protocol.toLowerCase();
72
- if (scheme !== 'https:' && scheme !== 'http:') {
73
- throw new Error(`[provider:${providerName}] baseURL scheme not allowed: ${parsed.protocol} (only http/https)`);
74
- }
75
- if (scheme === 'http:') {
76
- const host = parsed.hostname.toLowerCase();
77
- const isLocal = host === 'localhost' || host === '127.0.0.1' || host === '::1';
78
- if (!isLocal) {
79
- throw new Error(`[provider:${providerName}] baseURL must use https for non-localhost host (got ${parsed.protocol}//${parsed.hostname})`);
80
- }
81
- }
82
- return rawURL;
83
- }
84
-
85
- function traceHash(value) {
86
- return createHash('sha256')
87
- .update(String(value ?? ''))
88
- .digest('hex')
89
- .slice(0, 16);
90
- }
91
-
92
- function stableTraceStringify(value, seen = new WeakSet()) {
93
- if (value === null || typeof value !== 'object') {
94
- if (typeof value === 'bigint') return JSON.stringify(String(value));
95
- if (typeof value === 'undefined' || typeof value === 'function') return 'null';
96
- return JSON.stringify(value);
97
- }
98
- if (seen.has(value)) return JSON.stringify('[Circular]');
99
- seen.add(value);
100
- if (Array.isArray(value)) {
101
- const serialized = '[' + value.map(v => stableTraceStringify(v, seen)).join(',') + ']';
102
- seen.delete(value);
103
- return serialized;
104
- }
105
- const parts = [];
106
- for (const key of Object.keys(value).sort()) {
107
- const v = value[key];
108
- if (typeof v === 'undefined' || typeof v === 'function') continue;
109
- parts.push(JSON.stringify(key) + ':' + stableTraceStringify(v, seen));
110
- }
111
- seen.delete(value);
112
- return '{' + parts.join(',') + '}';
113
- }
114
-
115
- function traceTextShape(text) {
116
- const value = String(text ?? '');
117
- return { chars: value.length, hash: traceHash(value) };
118
- }
119
-
120
- function summarizeTraceMessages(messages) {
121
- const summaries = (messages || []).map((m, index) => {
122
- const content = typeof m?.content === 'string'
123
- ? { type: 'text', ...traceTextShape(m.content) }
124
- : { type: m?.content == null ? 'null' : typeof m.content, hash: traceHash(stableTraceStringify(m?.content ?? null)) };
125
- const toolCalls = Array.isArray(m?.tool_calls)
126
- ? m.tool_calls.map(tc => ({
127
- name: tc?.function?.name || null,
128
- argsHash: traceHash(tc?.function?.arguments || ''),
129
- }))
130
- : [];
131
- return {
132
- index,
133
- role: m?.role || null,
134
- content,
135
- ...(typeof m?.reasoning_content === 'string'
136
- ? { reasoningContent: traceTextShape(m.reasoning_content) }
137
- : {}),
138
- toolCallCount: toolCalls.length,
139
- ...(toolCalls.length ? { toolCalls } : {}),
140
- };
141
- });
142
- if (summaries.length <= 12) return summaries;
143
- return [
144
- ...summaries.slice(0, 8),
145
- { omittedTurns: summaries.length - 12 },
146
- ...summaries.slice(-4),
147
- ];
148
- }
149
-
150
- function summarizeTraceTools(tools) {
151
- return (tools || []).map(t => ({
152
- name: t?.name || null,
153
- description: t?.description || '',
154
- inputSchema: t?.inputSchema || null,
155
- }));
156
- }
157
-
158
- function extractCompatCachedTokens(usage) {
159
- const candidates = [
160
- usage?.prompt_tokens_details?.cached_tokens,
161
- usage?.input_tokens_details?.cached_tokens,
162
- usage?.prompt_cache_hit_tokens,
163
- usage?.cached_prompt_text_tokens,
164
- ];
165
- for (const v of candidates) {
166
- const n = Number(v);
167
- if (Number.isFinite(n) && n > 0) return n;
168
- }
169
- for (const v of candidates) {
170
- const n = Number(v);
171
- if (Number.isFinite(n)) return n;
172
- }
173
- return 0;
174
- }
175
-
176
- function xaiPrefixSeed({ opts, params, rawTools, model }) {
177
- const providerKey = resolveProviderCacheKey(opts, 'xai');
178
- const systemMessages = (params?.messages || [])
179
- .filter(m => m?.role === 'system')
180
- .map(m => String(m?.content ?? ''));
181
- return stableTraceStringify({
182
- scope: 'xai-prefix-model-system-tools',
183
- providerKey: String(providerKey),
184
- model: model || null,
185
- systemMessages,
186
- tools: summarizeTraceTools(rawTools),
187
- });
188
- }
189
-
190
- function xaiCacheRouting(opts, params, rawTools, model) {
191
- const sessionId = String(opts?.sessionId || opts?.session?.id || '').trim();
192
- const providerKey = resolveProviderCacheKey(opts, 'xai');
193
- const prefixSeed = xaiPrefixSeed({ opts, params, rawTools, model });
194
- const prefixHash = traceHash(prefixSeed);
195
- const routingSeed = stableTraceStringify({
196
- scope: 'xai-chat-session-v1',
197
- providerKey: String(providerKey),
198
- model: model || null,
199
- sessionId: sessionId || `ephemeral:${process.pid}`,
200
- });
201
- return {
202
- key: deterministicUuidFromKey(routingSeed),
203
- mode: sessionId ? 'session' : 'ephemeral',
204
- seedHash: traceHash(routingSeed),
205
- prefixHash,
206
- ownerSessionHash: sessionId ? traceHash(sessionId) : null,
207
- };
208
- }
209
-
210
- function xaiResponsesCacheRouting(opts, params, rawTools, model) {
211
- // Default to 'prefix' so parallel workers sharing the same model + system
212
- // + tools land on a common prompt_cache_key, letting xAI's server-side
213
- // prefix cache hit across sessions instead of cold-starting per worker.
214
- // Override with 'session' (env or opts) for legacy session-isolated lanes.
215
- const scope = String(opts?.xaiResponsesCacheScope || process.env.MIXDOG_XAI_RESPONSES_CACHE_SCOPE || 'prefix')
216
- .trim()
217
- .toLowerCase();
218
- if (scope !== 'prefix') {
219
- return xaiCacheRouting(opts, params, rawTools, model);
220
- }
221
- const sessionId = String(opts?.sessionId || opts?.session?.id || '').trim();
222
- const providerKey = resolveProviderCacheKey(opts, 'xai');
223
- const prefixSeed = xaiPrefixSeed({ opts, params, rawTools, model });
224
- const prefixHash = traceHash(prefixSeed);
225
- const routingSeed = stableTraceStringify({
226
- scope: 'xai-responses-prefix-v1',
227
- providerKey: String(providerKey),
228
- model: model || null,
229
- prefixHash,
230
- });
231
- return {
232
- key: deterministicUuidFromKey(routingSeed),
233
- mode: 'prefix',
234
- seedHash: traceHash(routingSeed),
235
- prefixHash,
236
- ownerSessionHash: sessionId ? traceHash(sessionId) : null,
237
- };
238
- }
239
-
240
- function normalizeXaiReasoningEffort(value) {
241
- const effort = String(value || '').trim().toLowerCase();
242
- return ['none', 'low', 'medium', 'high'].includes(effort) ? effort : null;
243
- }
244
-
245
- function useXaiResponsesApi(opts, config) {
246
- const raw = opts?.xaiApiMode
247
- ?? config?.apiMode
248
- ?? config?.xaiApiMode
249
- ?? process.env.MIXDOG_XAI_API_MODE
250
- ?? process.env.MIXDOG_XAI_RESPONSES;
251
- if (raw == null || raw === '') return true;
252
- const mode = String(raw).trim().toLowerCase();
253
- return !['0', 'false', 'off', 'chat', 'chat-completions', 'chat_completions'].includes(mode);
254
- }
255
-
256
- function useXaiResponsesWebSocket(opts, config) {
257
- const raw = opts?.xaiResponsesTransport
258
- ?? opts?.xaiTransport
259
- ?? config?.responsesTransport
260
- ?? config?.transport
261
- ?? process.env.MIXDOG_XAI_RESPONSES_TRANSPORT
262
- ?? process.env.MIXDOG_XAI_TRANSPORT;
263
- if (raw == null || raw === '') return true;
264
- const transport = String(raw).trim().toLowerCase();
265
- return !['0', 'false', 'off', 'http', 'https', 'responses-http', 'sdk'].includes(transport);
266
- }
267
-
268
- function useXaiResponsesWebSocketWarmup(opts, config, { previousResponseId, instructions, rawTools }) {
269
- if (previousResponseId) return false;
270
- const raw = opts?.xaiResponsesWarmup
271
- ?? opts?.xaiWsWarmup
272
- ?? config?.responsesWarmup
273
- ?? config?.wsWarmup
274
- ?? process.env.MIXDOG_XAI_RESPONSES_WARMUP
275
- ?? process.env.MIXDOG_XAI_WS_WARMUP;
276
- if (raw != null && raw !== '') {
277
- const mode = String(raw).trim().toLowerCase();
278
- if (['0', 'false', 'off', 'none', 'disabled'].includes(mode)) return false;
279
- if (['1', 'true', 'on', 'always', 'force'].includes(mode)) return true;
280
- }
281
- return String(instructions || '').length >= 2048 || (Array.isArray(rawTools) && rawTools.length >= 10);
282
- }
283
-
284
- const XAI_RESPONSES_CACHE_LANE_DEFAULT_MAX_IN_FLIGHT = 2;
285
- const xaiResponsesCacheLanes = new Map();
286
-
287
- function parseXaiPositiveInt(value, fallback) {
288
- if (value == null || value === '') return fallback;
289
- const text = String(value).trim().toLowerCase();
290
- if (['0', 'false', 'off', 'none', 'disabled', 'unlimited'].includes(text)) return 0;
291
- const n = Number(text);
292
- if (!Number.isFinite(n)) return fallback;
293
- return Math.max(0, Math.floor(n));
294
- }
295
-
296
- function xaiResponsesCacheLaneMaxInFlight(opts, config) {
297
- return parseXaiPositiveInt(
298
- opts?.xaiCacheMaxInFlight
299
- ?? opts?.xaiResponsesCacheMaxInFlight
300
- ?? config?.xaiCacheMaxInFlight
301
- ?? config?.xaiResponsesCacheMaxInFlight
302
- ?? process.env.MIXDOG_XAI_CACHE_MAX_INFLIGHT
303
- ?? process.env.MIXDOG_XAI_RESPONSES_CACHE_MAX_INFLIGHT,
304
- XAI_RESPONSES_CACHE_LANE_DEFAULT_MAX_IN_FLIGHT,
305
- );
306
- }
307
-
308
- function xaiResponsesCacheLaneQueueTimeoutMs(opts, config) {
309
- return parseXaiPositiveInt(
310
- opts?.xaiCacheQueueTimeoutMs
311
- ?? opts?.xaiResponsesCacheQueueTimeoutMs
312
- ?? config?.xaiCacheQueueTimeoutMs
313
- ?? config?.xaiResponsesCacheQueueTimeoutMs
314
- ?? process.env.MIXDOG_XAI_CACHE_QUEUE_TIMEOUT_MS
315
- ?? process.env.MIXDOG_XAI_RESPONSES_CACHE_QUEUE_TIMEOUT_MS,
316
- 0,
317
- );
318
- }
319
-
320
- function xaiResponsesCacheLaneShard(opts, cacheRouting) {
321
- const shardCount = parseXaiPositiveInt(
322
- opts?.xaiCacheLaneShards
323
- ?? opts?.xaiResponsesCacheLaneShards
324
- ?? process.env.MIXDOG_XAI_CACHE_LANE_SHARDS
325
- ?? process.env.MIXDOG_XAI_RESPONSES_CACHE_LANE_SHARDS,
326
- 1,
327
- );
328
- if (shardCount <= 1) return 0;
329
- const seed = String(opts?.sessionId || opts?.session?.id || cacheRouting?.ownerSessionHash || cacheRouting?.key || '');
330
- const hex = traceHash(seed || 'xai-cache-lane');
331
- return Number.parseInt(hex.slice(0, 8), 16) % shardCount;
332
- }
333
-
334
- function xaiResponsesCacheLaneKey({ model, cacheRouting, opts }) {
335
- const prefix = cacheRouting?.prefixHash || cacheRouting?.seedHash || cacheRouting?.key || 'unknown-prefix';
336
- const shard = xaiResponsesCacheLaneShard(opts, cacheRouting);
337
- return {
338
- key: `xai-responses:${model || 'default'}:${prefix}:shard-${shard}`,
339
- shard,
340
- };
341
- }
342
-
343
- function getXaiResponsesCacheLaneState(key, maxInFlight) {
344
- let state = xaiResponsesCacheLanes.get(key);
345
- if (!state) {
346
- state = { key, active: 0, queue: [], maxInFlight, nextId: 0 };
347
- xaiResponsesCacheLanes.set(key, state);
348
- }
349
- state.maxInFlight = maxInFlight;
350
- return state;
351
- }
352
-
353
- function cleanupXaiResponsesCacheLane(state) {
354
- if (state.active === 0 && state.queue.length === 0) {
355
- xaiResponsesCacheLanes.delete(state.key);
356
- }
357
- }
358
-
359
- function removeQueuedXaiCacheLaneRequest(state, request) {
360
- const index = state.queue.indexOf(request);
361
- if (index >= 0) state.queue.splice(index, 1);
362
- cleanupXaiResponsesCacheLane(state);
363
- }
364
-
365
- function makeXaiCacheLaneHandle(state, requestId, enqueuedAt) {
366
- let released = false;
367
- return {
368
- requestId,
369
- waitedMs: Date.now() - enqueuedAt,
370
- activeCount: state.active,
371
- queueDepth: state.queue.length,
372
- release() {
373
- if (released) return;
374
- released = true;
375
- releaseXaiResponsesCacheLane(state);
376
- },
377
- };
378
- }
379
-
380
- function releaseXaiResponsesCacheLane(state) {
381
- state.active = Math.max(0, state.active - 1);
382
- while (state.queue.length > 0 && state.active < state.maxInFlight) {
383
- const next = state.queue.shift();
384
- next.cleanup?.();
385
- state.active += 1;
386
- next.resolve(makeXaiCacheLaneHandle(state, next.requestId, next.enqueuedAt));
387
- }
388
- cleanupXaiResponsesCacheLane(state);
389
- }
390
-
391
- function acquireXaiResponsesCacheLane({ key, maxInFlight, signal, timeoutMs }) {
392
- const state = getXaiResponsesCacheLaneState(key, maxInFlight);
393
- const requestId = ++state.nextId;
394
- const enqueuedAt = Date.now();
395
- if (state.active < state.maxInFlight) {
396
- state.active += 1;
397
- return Promise.resolve(makeXaiCacheLaneHandle(state, requestId, enqueuedAt));
398
- }
399
- return new Promise((resolve, reject) => {
400
- const request = {
401
- requestId,
402
- enqueuedAt,
403
- resolve,
404
- reject,
405
- cleanup: null,
406
- };
407
- const cleanup = () => {
408
- if (request.timer) clearTimeout(request.timer);
409
- if (signal && request.abortListener) signal.removeEventListener('abort', request.abortListener);
410
- };
411
- request.cleanup = cleanup;
412
- request.abortListener = () => {
413
- cleanup();
414
- removeQueuedXaiCacheLaneRequest(state, request);
415
- const reason = signal?.reason;
416
- reject(reason instanceof Error ? reason : new Error('xAI cache lane wait aborted'));
417
- };
418
- if (signal?.aborted) {
419
- request.abortListener();
420
- return;
421
- }
422
- if (signal) signal.addEventListener('abort', request.abortListener, { once: true });
423
- if (timeoutMs > 0) {
424
- request.timer = setTimeout(() => {
425
- cleanup();
426
- removeQueuedXaiCacheLaneRequest(state, request);
427
- reject(new Error(`xAI cache lane wait timed out after ${timeoutMs}ms`));
428
- }, timeoutMs);
429
- }
430
- state.queue.push(request);
431
- });
432
- }
433
-
434
- function traceXaiCacheLane(opts, payload) {
435
- if (!compatCacheTraceEnabled('xai')) return;
436
- try {
437
- appendBridgeTrace({
438
- sessionId: opts?.sessionId || opts?.session?.id || null,
439
- iteration: Number.isFinite(Number(opts?.iteration)) ? Number(opts.iteration) : null,
440
- kind: 'cache_lane',
441
- ...payload,
442
- payload,
443
- });
444
- } catch {}
445
- }
446
-
447
- async function withXaiResponsesCacheLane({ opts, config, cacheRouting, model, transport, previousResponseId, inputCount, signal }, fn) {
448
- const maxInFlight = xaiResponsesCacheLaneMaxInFlight(opts, config);
449
- if (maxInFlight <= 0) {
450
- const laneMeta = { enabled: false, maxInFlight: 0 };
451
- return { value: await fn(laneMeta), laneMeta };
452
- }
453
- const { key: laneKey, shard } = xaiResponsesCacheLaneKey({ model, cacheRouting, opts });
454
- const timeoutMs = xaiResponsesCacheLaneQueueTimeoutMs(opts, config);
455
- const state = getXaiResponsesCacheLaneState(laneKey, maxInFlight);
456
- const queued = state.active >= state.maxInFlight;
457
- if (queued) {
458
- traceXaiCacheLane(opts, {
459
- provider: 'xai',
460
- api: 'responses',
461
- transport,
462
- event: 'queued',
463
- lane_key_hash: traceHash(laneKey),
464
- lane_shard: shard,
465
- max_in_flight: maxInFlight,
466
- active: state.active,
467
- queue_depth: state.queue.length,
468
- previous_response_used: !!previousResponseId,
469
- input_count: inputCount,
470
- });
471
- }
472
- const handle = await acquireXaiResponsesCacheLane({ key: laneKey, maxInFlight, signal, timeoutMs });
473
- const laneMeta = {
474
- enabled: true,
475
- laneKeyHash: traceHash(laneKey),
476
- shard,
477
- maxInFlight,
478
- queued,
479
- waitMs: handle.waitedMs,
480
- activeAfterAcquire: handle.activeCount,
481
- queueDepthAfterAcquire: handle.queueDepth,
482
- };
483
- traceXaiCacheLane(opts, {
484
- provider: 'xai',
485
- api: 'responses',
486
- transport,
487
- event: 'acquired',
488
- lane_key_hash: laneMeta.laneKeyHash,
489
- lane_shard: shard,
490
- max_in_flight: maxInFlight,
491
- wait_ms: laneMeta.waitMs,
492
- active: laneMeta.activeAfterAcquire,
493
- queue_depth: laneMeta.queueDepthAfterAcquire,
494
- previous_response_used: !!previousResponseId,
495
- input_count: inputCount,
496
- });
497
- const startedAt = Date.now();
498
- try {
499
- return { value: await fn(laneMeta), laneMeta };
500
- } finally {
501
- handle.release();
502
- traceXaiCacheLane(opts, {
503
- provider: 'xai',
504
- api: 'responses',
505
- transport,
506
- event: 'released',
507
- lane_key_hash: laneMeta.laneKeyHash,
508
- lane_shard: shard,
509
- max_in_flight: maxInFlight,
510
- held_ms: Date.now() - startedAt,
511
- previous_response_used: !!previousResponseId,
512
- input_count: inputCount,
513
- });
514
- }
515
- }
516
-
517
- function deterministicUuidFromKey(key) {
518
- const hex = createHash('sha256').update(String(key ?? '')).digest('hex');
519
- const variant = ((Number.parseInt(hex[16], 16) & 0x3) | 0x8).toString(16);
520
- return [
521
- hex.slice(0, 8),
522
- hex.slice(8, 12),
523
- '4' + hex.slice(13, 16),
524
- variant + hex.slice(17, 20),
525
- hex.slice(20, 32),
526
- ].join('-');
527
- }
528
-
529
- function compatCacheTraceEnabled(provider) {
530
- return process.env.MIXDOG_COMPAT_CACHE_TRACE === '1'
531
- || process.env.MIXDOG_PROVIDER_CACHE_TRACE === '1'
532
- || (provider === 'xai' && process.env.MIXDOG_XAI_CACHE_TRACE === '1');
533
- }
534
-
535
- function writeCompatCacheTrace({ provider, model, opts, params, rawTools, response, cacheRoutingKey, cacheRouting }) {
536
- if (!compatCacheTraceEnabled(provider)) return;
537
- try {
538
- const usage = response?.usage || {};
539
- const inputTokens = Number(usage.prompt_tokens ?? usage.input_tokens ?? 0);
540
- const cachedTokens = extractCompatCachedTokens(usage);
541
- const toolShape = summarizeTraceTools(rawTools);
542
- const traceMessages = Array.isArray(params?.messages) ? params.messages : [];
543
- const trace = {
544
- event: 'chat.completions',
545
- provider,
546
- model,
547
- responseModel: response?.model || null,
548
- owner: opts?.session?.owner || null,
549
- role: opts?.session?.role || opts?.role || null,
550
- permission: opts?.session?.permission || null,
551
- toolPermission: opts?.session?.toolPermission || null,
552
- profileId: opts?.session?.profileId || null,
553
- sourceType: opts?.session?.sourceType || null,
554
- sourceName: opts?.session?.sourceName || null,
555
- sessionIdHash: opts?.sessionId ? traceHash(opts.sessionId) : null,
556
- providerCacheKeyHash: opts?.providerCacheKey ? traceHash(opts.providerCacheKey) : null,
557
- promptCacheKeyHash: opts?.promptCacheKey ? traceHash(opts.promptCacheKey) : null,
558
- xGrokConvIdHash: provider === 'xai' && cacheRoutingKey ? traceHash(cacheRoutingKey) : null,
559
- xGrokConvIdSeedHash: provider === 'xai' ? cacheRouting?.seedHash || null : null,
560
- xGrokPromptPrefixHash: provider === 'xai' ? cacheRouting?.prefixHash || null : null,
561
- xGrokConvIdMode: provider === 'xai' ? cacheRouting?.mode || null : null,
562
- xGrokConvIdLaneIndex: provider === 'xai' ? cacheRouting?.laneIndex ?? null : null,
563
- xGrokConvIdActiveLanes: provider === 'xai' ? cacheRouting?.activeLanes ?? null : null,
564
- xGrokConvIdIdleLanes: provider === 'xai' ? cacheRouting?.idleLanes ?? null : null,
565
- xGrokConvIdOwnerSessionHash: provider === 'xai' ? cacheRouting?.ownerSessionHash || null : null,
566
- xaiReasoningEffort: provider === 'xai' ? params?.reasoning_effort || null : null,
567
- messageCount: traceMessages.length,
568
- messageFullHash: traceHash(stableTraceStringify(traceMessages)),
569
- messagePrefixHash: traceHash(stableTraceStringify(traceMessages.slice(0, -1))),
570
- lastMessageHash: traceMessages.length ? traceHash(stableTraceStringify(traceMessages.at(-1))) : null,
571
- messages: summarizeTraceMessages(traceMessages),
572
- toolCount: Array.isArray(rawTools) ? rawTools.length : 0,
573
- toolSchemaHash: traceHash(stableTraceStringify(toolShape)),
574
- usageKeys: Object.keys(usage || {}).sort(),
575
- promptTokenDetailsKeys: Object.keys(usage?.prompt_tokens_details || {}).sort(),
576
- inputTokenDetailsKeys: Object.keys(usage?.input_tokens_details || {}).sort(),
577
- choiceMessageKeys: Object.keys(response?.choices?.[0]?.message || {}).sort(),
578
- responseReasoningContent: typeof response?.choices?.[0]?.message?.reasoning_content === 'string'
579
- ? traceTextShape(response.choices[0].message.reasoning_content)
580
- : null,
581
- responseReasoningTokens: Number(usage?.completion_tokens_details?.reasoning_tokens ?? 0),
582
- inputTokens,
583
- outputTokens: Number(usage.completion_tokens ?? usage.output_tokens ?? 0),
584
- cachedTokens,
585
- cacheHitRate: inputTokens > 0 ? Number((cachedTokens / inputTokens).toFixed(6)) : null,
586
- costInUsdTicks: typeof usage.cost_in_usd_ticks === 'number' ? usage.cost_in_usd_ticks : null,
587
- };
588
- process.stderr.write(`[compat-cache-trace] ${JSON.stringify(trace)}\n`);
589
- } catch (err) {
590
- process.stderr.write(`[compat-cache-trace] failed: ${err?.message || err}\n`);
591
- }
592
- }
593
-
594
- function summarizeResponsesInput(input) {
595
- return (input || []).map((item, index) => ({
596
- index,
597
- type: item?.type || null,
598
- role: item?.role || null,
599
- callIdHash: item?.call_id ? traceHash(item.call_id) : null,
600
- name: item?.name || null,
601
- content: typeof item?.content === 'string'
602
- ? { type: 'text', ...traceTextShape(item.content) }
603
- : { type: item?.content == null ? 'null' : typeof item.content, hash: traceHash(stableTraceStringify(item?.content ?? null)) },
604
- output: typeof item?.output === 'string' ? traceTextShape(item.output) : null,
605
- }));
606
- }
607
-
608
- function xaiUsageStats(usage) {
609
- const inputTokens = Number(usage?.input_tokens ?? usage?.prompt_tokens ?? 0);
610
- const outputTokens = Number(usage?.output_tokens ?? usage?.completion_tokens ?? 0);
611
- const cachedTokens = extractCompatCachedTokens(usage);
612
- const hitRate = inputTokens > 0 ? Number((cachedTokens / inputTokens).toFixed(6)) : null;
613
- return { inputTokens, outputTokens, cachedTokens, hitRate };
614
- }
615
-
616
- function xaiSanitizedRequestSansInput(params) {
617
- const { input: _input, ...rest } = params || {};
618
- const out = { ...rest };
619
- if (out.prompt_cache_key) out.prompt_cache_key = traceHash(out.prompt_cache_key);
620
- if (out.previous_response_id) out.previous_response_id = traceHash(out.previous_response_id);
621
- if (typeof out.instructions === 'string') out.instructions = traceHash(out.instructions);
622
- return out;
623
- }
624
-
625
- function xaiResponsesFingerprintPayload({ model, opts, params, rawTools, response, cacheRouting, previousResponseId, inputStartIndex, transport, cacheLane }) {
626
- const usage = response?.usage || {};
627
- const { inputTokens, outputTokens, cachedTokens, hitRate } = xaiUsageStats(usage);
628
- const toolShape = summarizeTraceTools(rawTools);
629
- const instructions = typeof params?.instructions === 'string' ? params.instructions : '';
630
- const requestSansInput = xaiSanitizedRequestSansInput(params);
631
- const contextShape = {
632
- provider: 'xai',
633
- api: 'responses',
634
- model: model || null,
635
- promptCacheKeyHash: params?.prompt_cache_key ? traceHash(params.prompt_cache_key) : null,
636
- instructions,
637
- tools: toolShape,
638
- reasoning: params?.reasoning || null,
639
- store: params?.store ?? null,
640
- };
641
- const previousResponseUsed = Boolean(previousResponseId);
642
- const midTurnCold = previousResponseUsed
643
- && inputTokens >= 1024
644
- && (cachedTokens <= 512 || (hitRate != null && hitRate < 0.1));
645
- return {
646
- provider: 'xai',
647
- api: 'responses',
648
- transport: transport || null,
649
- model: model || null,
650
- response_model: response?.model || null,
651
- session_id_hash: opts?.sessionId ? traceHash(opts.sessionId) : null,
652
- provider_cache_key_hash: opts?.providerCacheKey ? traceHash(opts.providerCacheKey) : null,
653
- prompt_cache_key_option_hash: opts?.promptCacheKey ? traceHash(opts.promptCacheKey) : null,
654
- prompt_cache_key_hash: params?.prompt_cache_key ? traceHash(params.prompt_cache_key) : null,
655
- xai_prompt_prefix_hash: cacheRouting?.prefixHash || null,
656
- xai_cache_mode: cacheRouting?.mode || null,
657
- xai_cache_seed_hash: cacheRouting?.seedHash || null,
658
- owner_session_hash: cacheRouting?.ownerSessionHash || null,
659
- response_id_hash: response?.id ? traceHash(response.id) : null,
660
- previous_response_id_hash: previousResponseId ? traceHash(previousResponseId) : null,
661
- previous_response_used: previousResponseUsed,
662
- input_start_index: inputStartIndex,
663
- input_count: Array.isArray(params?.input) ? params.input.length : 0,
664
- input_hash: traceHash(stableTraceStringify(params?.input || [])),
665
- request_sans_input_hash: traceHash(stableTraceStringify(requestSansInput)),
666
- context_prefix_hash: traceHash(stableTraceStringify(contextShape)),
667
- has_instructions: instructions.length > 0,
668
- instructions_chars: instructions.length,
669
- instructions_hash: instructions ? traceHash(instructions) : null,
670
- reasoning_effort: params?.reasoning?.effort || null,
671
- tool_count: Array.isArray(rawTools) ? rawTools.length : 0,
672
- tool_schema_hash: traceHash(stableTraceStringify(toolShape)),
673
- tool_names_hash: traceHash(stableTraceStringify(toolShape.map(t => t?.name || null))),
674
- xai_cache_lane_enabled: cacheLane?.enabled === true,
675
- xai_cache_lane_hash: cacheLane?.laneKeyHash || null,
676
- xai_cache_lane_shard: Number.isFinite(Number(cacheLane?.shard)) ? Number(cacheLane.shard) : null,
677
- xai_cache_lane_max_in_flight: Number.isFinite(Number(cacheLane?.maxInFlight)) ? Number(cacheLane.maxInFlight) : null,
678
- xai_cache_lane_wait_ms: Number.isFinite(Number(cacheLane?.waitMs)) ? Number(cacheLane.waitMs) : null,
679
- xai_cache_lane_queued: cacheLane?.queued === true,
680
- input_tokens: inputTokens,
681
- output_tokens: outputTokens,
682
- cached_tokens: cachedTokens,
683
- cache_hit_rate: hitRate,
684
- mid_turn_cold: midTurnCold,
685
- };
686
- }
687
-
688
- function traceXaiResponsesCacheContext(args) {
689
- if (!compatCacheTraceEnabled('xai')) return;
690
- try {
691
- const payload = xaiResponsesFingerprintPayload(args);
692
- const sessionId = args?.opts?.sessionId || args?.opts?.session?.id || null;
693
- const iteration = Number.isFinite(Number(args?.opts?.iteration)) ? Number(args.opts.iteration) : null;
694
- appendBridgeTrace({
695
- sessionId,
696
- iteration,
697
- kind: 'cache_context',
698
- ...payload,
699
- payload,
700
- });
701
- if (payload.mid_turn_cold) {
702
- const anomalyPayload = {
703
- ...payload,
704
- anomaly: 'xai_mid_turn_cold_cache',
705
- reason: 'previous_response_id_present_but_cached_tokens_low',
706
- };
707
- appendBridgeTrace({
708
- sessionId,
709
- iteration,
710
- kind: 'cache_anomaly',
711
- ...anomalyPayload,
712
- payload: anomalyPayload,
713
- });
714
- }
715
- } catch (err) {
716
- process.stderr.write(`[compat-cache-trace] xai context trace failed: ${err?.message || err}\n`);
717
- }
718
- }
719
-
720
- function writeXaiResponsesCacheTrace({ model, opts, params, rawTools, response, cacheRouting, previousResponseId, inputStartIndex, transport, cacheLane }) {
721
- if (!compatCacheTraceEnabled('xai')) return;
722
- try {
723
- const usage = response?.usage || {};
724
- const fingerprint = xaiResponsesFingerprintPayload({
725
- model,
726
- opts,
727
- params,
728
- rawTools,
729
- response,
730
- cacheRouting,
731
- previousResponseId,
732
- inputStartIndex,
733
- transport,
734
- cacheLane,
735
- });
736
- const inputTokens = fingerprint.input_tokens;
737
- const cachedTokens = fingerprint.cached_tokens;
738
- const toolShape = summarizeTraceTools(rawTools);
739
- const trace = {
740
- event: 'responses',
741
- provider: 'xai',
742
- transport: transport || null,
743
- model,
744
- responseModel: response?.model || null,
745
- responseIdHash: response?.id ? traceHash(response.id) : null,
746
- previousResponseIdHash: previousResponseId ? traceHash(previousResponseId) : null,
747
- owner: opts?.session?.owner || null,
748
- role: opts?.session?.role || opts?.role || null,
749
- permission: opts?.session?.permission || null,
750
- toolPermission: opts?.session?.toolPermission || null,
751
- profileId: opts?.session?.profileId || null,
752
- sourceType: opts?.session?.sourceType || null,
753
- sourceName: opts?.session?.sourceName || null,
754
- sessionIdHash: opts?.sessionId ? traceHash(opts.sessionId) : null,
755
- promptCacheKeyHash: params?.prompt_cache_key ? traceHash(params.prompt_cache_key) : null,
756
- xGrokPromptPrefixHash: cacheRouting?.prefixHash || null,
757
- xGrokConvIdMode: cacheRouting?.mode || null,
758
- xaiReasoningEffort: params?.reasoning?.effort || null,
759
- previousResponseUsed: Boolean(previousResponseId),
760
- inputStartIndex,
761
- inputCount: Array.isArray(params?.input) ? params.input.length : 0,
762
- cacheLaneEnabled: fingerprint.xai_cache_lane_enabled,
763
- cacheLaneHash: fingerprint.xai_cache_lane_hash,
764
- cacheLaneShard: fingerprint.xai_cache_lane_shard,
765
- cacheLaneMaxInFlight: fingerprint.xai_cache_lane_max_in_flight,
766
- cacheLaneWaitMs: fingerprint.xai_cache_lane_wait_ms,
767
- cacheLaneQueued: fingerprint.xai_cache_lane_queued,
768
- input: summarizeResponsesInput(params?.input || []),
769
- toolCount: Array.isArray(rawTools) ? rawTools.length : 0,
770
- toolSchemaHash: traceHash(stableTraceStringify(toolShape)),
771
- toolNamesHash: fingerprint.tool_names_hash,
772
- requestSansInputHash: fingerprint.request_sans_input_hash,
773
- contextPrefixHash: fingerprint.context_prefix_hash,
774
- instructionsHash: fingerprint.instructions_hash,
775
- instructionsChars: fingerprint.instructions_chars,
776
- usageKeys: Object.keys(usage || {}).sort(),
777
- inputTokenDetailsKeys: Object.keys(usage?.input_tokens_details || {}).sort(),
778
- outputTokenDetailsKeys: Object.keys(usage?.output_tokens_details || {}).sort(),
779
- outputTypes: (response?.output || []).map(item => item?.type || null),
780
- inputTokens,
781
- outputTokens: fingerprint.output_tokens,
782
- cachedTokens,
783
- cacheHitRate: fingerprint.cache_hit_rate,
784
- midTurnCold: fingerprint.mid_turn_cold,
785
- costInUsdTicks: typeof usage.cost_in_usd_ticks === 'number' ? usage.cost_in_usd_ticks : null,
786
- };
787
- process.stderr.write(`[compat-cache-trace] ${JSON.stringify(trace)}\n`);
788
- } catch (err) {
789
- process.stderr.write(`[compat-cache-trace] failed: ${err?.message || err}\n`);
790
- }
791
- }
792
-
793
- function toOpenAIMessages(messages, providerName) {
794
- // NOTE: chat.completions has no equivalent slot for replaying reasoning
795
- // encrypted_content the way the Responses API does (no `type:'reasoning'`
796
- // input item). Whatever reasoningItems may be attached to assistant
797
- // messages by the openai-oauth provider is intentionally dropped here —
798
- // strict providers (xai) reject unknown roles/types and would 400 the
799
- // request. Documented in v0.1.160 (GPT reasoning replay).
800
- //
801
- // DeepSeek thinking models require the prior turn's `reasoning_content`
802
- // string to be echoed back inside the assistant message, otherwise the API
803
- // returns 400. xAI reasoning models also preserve their official multi-turn
804
- // shape and cache prefix stability when prior assistant reasoning_content
805
- // is replayed; reasoning_effort itself remains caller/user-selected.
806
- const replaysReasoningContent = providerName === 'deepseek' || providerName === 'xai';
807
- const out = [];
808
- for (const m of messages) {
809
- if (m.role === 'tool') {
810
- out.push({
811
- role: 'tool',
812
- tool_call_id: m.toolCallId || '',
813
- content: m.content,
814
- });
815
- continue;
816
- }
817
- if (m.role === 'assistant' && m.toolCalls?.length) {
818
- const msg = {
819
- role: 'assistant',
820
- content: m.content || null,
821
- tool_calls: m.toolCalls.map((tc) => ({
822
- id: tc.id,
823
- type: 'function',
824
- function: { name: tc.name, arguments: JSON.stringify(tc.arguments) },
825
- })),
826
- };
827
- if (replaysReasoningContent && m.reasoningContent) msg.reasoning_content = m.reasoningContent;
828
- out.push(msg);
829
- continue;
830
- }
831
- if (m.role === 'assistant' && replaysReasoningContent && m.reasoningContent) {
832
- out.push({ role: m.role, content: m.content, reasoning_content: m.reasoningContent });
833
- continue;
834
- }
835
- out.push({ role: m.role, content: m.content });
836
- }
837
- return out;
838
- }
839
- function toOpenAITools(tools) {
840
- return tools.map((t) => ({
841
- type: 'function',
842
- function: {
843
- name: t.name,
844
- description: t.description,
845
- parameters: t.inputSchema,
846
- },
847
- }));
848
- }
849
- function toResponsesTools(tools) {
850
- return tools.map((t) => ({
851
- type: 'function',
852
- name: t.name,
853
- description: t.description,
854
- parameters: t.inputSchema,
855
- }));
856
- }
857
- function parseToolCalls(choice, label) {
858
- const calls = choice.message?.tool_calls;
859
- if (!calls?.length)
860
- return undefined;
861
- return calls
862
- .filter((tc) => tc.type === 'function')
863
- .map((tc) => ({
864
- id: tc.id,
865
- name: tc.function.name,
866
- arguments: parseCompletedToolCallArgumentsJson(tc.function.arguments, label),
867
- }));
868
- }
869
- function parseJsonObject(value) {
870
- try {
871
- const parsed = JSON.parse(value || '{}');
872
- return parsed && typeof parsed === 'object' ? parsed : {};
873
- } catch {
874
- return {};
875
- }
876
- }
877
- function parseResponsesToolCalls(response, label) {
878
- const out = [];
879
- for (const item of response?.output || []) {
880
- if (item?.type !== 'function_call') continue;
881
- out.push({
882
- id: item.call_id || item.id,
883
- name: item.name,
884
- arguments: parseCompletedToolCallArgumentsJson(item.arguments, label),
885
- });
886
- }
887
- return out.length ? out : undefined;
888
- }
889
- function responseOutputText(response) {
890
- if (typeof response?.output_text === 'string') return response.output_text;
891
- const chunks = [];
892
- for (const item of response?.output || []) {
893
- if (item?.type !== 'message' || !Array.isArray(item.content)) continue;
894
- for (const part of item.content) {
895
- if (part?.type === 'output_text' && typeof part.text === 'string') chunks.push(part.text);
896
- }
897
- }
898
- return chunks.join('');
899
- }
900
- function toResponsesInputMessage(m) {
901
- if (m.role === 'tool') {
902
- return {
903
- type: 'function_call_output',
904
- call_id: m.toolCallId || '',
905
- output: typeof m.content === 'string' ? m.content : JSON.stringify(m.content ?? ''),
906
- };
907
- }
908
- if (m.role === 'assistant' && Array.isArray(m.toolCalls) && m.toolCalls.length > 0) {
909
- const items = [];
910
- if (m.content) items.push({ role: 'assistant', content: m.content });
911
- for (const tc of m.toolCalls) {
912
- items.push({
913
- type: 'function_call',
914
- call_id: tc.id,
915
- name: tc.name,
916
- arguments: JSON.stringify(tc.arguments || {}),
917
- });
918
- }
919
- return items;
920
- }
921
- return { role: m.role, content: m.content || '' };
922
- }
923
- function xaiSystemInstructions(messages) {
924
- const instructions = (messages || [])
925
- .filter(m => m?.role === 'system')
926
- .map(m => String(m.content || ''))
927
- .filter(Boolean)
928
- .join('\n\n');
929
- return instructions || undefined;
930
- }
931
- function toXaiResponsesInput(messages, providerState, options = {}) {
932
- const includeSystem = options.includeSystem !== false;
933
- const state = providerState?.xaiResponses || null;
934
- let startIndex = 0;
935
- const previousResponseId = typeof state?.previousResponseId === 'string' ? state.previousResponseId : null;
936
- if (previousResponseId) {
937
- const seen = Number.isInteger(state?.seenMessageCount) ? state.seenMessageCount : messages.length;
938
- startIndex = Math.max(0, Math.min(seen, messages.length));
939
- if (messages[startIndex]?.role === 'assistant') startIndex += 1;
940
- }
941
- const input = [];
942
- for (const m of messages.slice(startIndex)) {
943
- if (!includeSystem && m.role === 'system') continue;
944
- const converted = toResponsesInputMessage(m);
945
- if (Array.isArray(converted)) input.push(...converted);
946
- else input.push(converted);
947
- }
948
- return { input, previousResponseId, startIndex };
949
- }
950
- export class OpenAICompatProvider {
951
- // Chat Completions prompt_tokens is already the total (includes cached).
952
- // Covers grok-oauth and all OPENAI_COMPAT_PRESETS. See registry.mjs.
953
- static inputExcludesCache = false;
954
- name;
955
- client;
956
- defaultModel;
957
- config;
958
- baseURL;
959
- apiKey;
960
- defaultHeaders;
961
- constructor(name, config) {
962
- const preset = PRESETS[name];
963
- const baseURL = assertSafeBaseURL(config.baseURL || preset?.baseURL || 'http://localhost:8080/v1', name);
964
- const apiKey = config.apiKey || 'no-key';
965
- this.name = name;
966
- this.config = config;
967
- this.baseURL = baseURL;
968
- this.apiKey = apiKey;
969
- // Merge caller-supplied headers (config.extraHeaders) over the preset's.
970
- // Used e.g. by grok-oauth to inject the Grok CLI client headers for the
971
- // grok-build proxy. Backward-compatible: providers that pass no
972
- // extraHeaders behave exactly as before.
973
- this.defaultHeaders = { ...(preset?.extraHeaders || {}), ...(config.extraHeaders || {}) };
974
- this.defaultModel = preset?.defaultModel || 'default';
975
- this.client = new OpenAI({
976
- baseURL,
977
- apiKey,
978
- defaultHeaders: this.defaultHeaders,
979
- });
980
- }
981
- reloadApiKey() {
982
- try {
983
- const freshConfig = loadConfig();
984
- const cfg = freshConfig.providers?.[this.name];
985
- const preset = PRESETS[this.name];
986
- const newKey = cfg?.apiKey || this.config.apiKey;
987
- const baseURL = assertSafeBaseURL(cfg?.baseURL || this.config.baseURL || preset?.baseURL || 'http://localhost:8080/v1', this.name);
988
- if (newKey) {
989
- this.config = { ...(this.config || {}), ...(cfg || {}), apiKey: newKey, baseURL };
990
- this.baseURL = baseURL;
991
- this.apiKey = newKey;
992
- this.defaultHeaders = { ...(preset?.extraHeaders || {}), ...(this.config.extraHeaders || {}) };
993
- this.client = new OpenAI({
994
- baseURL,
995
- apiKey: newKey,
996
- defaultHeaders: this.defaultHeaders,
997
- });
998
- }
999
- } catch { /* best effort */ }
1000
- }
1001
- async send(messages, model, tools, sendOpts) {
1002
- try {
1003
- return await this._doSend(messages, model, tools, sendOpts);
1004
- } catch (err) {
1005
- if (err.message && (err.message.includes('401') || err.message.includes('403'))) {
1006
- process.stderr.write(`[provider] Auth error, re-reading config...\n`);
1007
- this.reloadApiKey();
1008
- return await this._doSend(messages, model, tools, sendOpts);
1009
- }
1010
- throw err;
1011
- }
1012
- }
1013
- async _doSend(messages, model, tools, sendOpts) {
1014
- const useModel = model || this.defaultModel;
1015
- const opts = sendOpts || {};
1016
- if (this.name === 'xai' && useXaiResponsesApi(opts, this.config)) {
1017
- if (useXaiResponsesWebSocket(opts, this.config)) {
1018
- return await this._doSendXaiResponsesWebSocket(messages, useModel, tools, opts);
1019
- }
1020
- return await this._doSendXaiResponses(messages, useModel, tools, opts);
1021
- }
1022
- const signal = opts.signal || null;
1023
- if (signal?.aborted) {
1024
- const reason = signal.reason;
1025
- throw reason instanceof Error ? reason : new Error('OpenAI-compat request aborted by session close');
1026
- }
1027
- const params = {
1028
- model: useModel,
1029
- messages: toOpenAIMessages(messages, this.name),
1030
- };
1031
- if (tools?.length) {
1032
- params.tools = toOpenAITools(tools);
1033
- }
1034
- if (this.name === 'xai') {
1035
- const reasoningEffort = normalizeXaiReasoningEffort(opts.xaiReasoningEffort
1036
- ?? opts.effort
1037
- ?? this.config?.reasoningEffort
1038
- ?? process.env.MIXDOG_XAI_REASONING_EFFORT);
1039
- if (reasoningEffort) params.reasoning_effort = reasoningEffort;
1040
- }
1041
- const totalSignal = createTimeoutSignal(signal, PROVIDER_NONSTREAM_TOTAL_TIMEOUT_MS, `${this.name} total`);
1042
- const cacheRouting = this.name === 'xai'
1043
- ? xaiCacheRouting(opts, params, tools || [], useModel)
1044
- : null;
1045
- const cacheRoutingKey = cacheRouting?.key || null;
1046
- // Note: x-grok-conv-id is documented as a routing hint, but in our
1047
- // measured parallel-worker traffic it caused alternating cold caches
1048
- // (server-side per-conv shard isolation). Vercel ai-sdk and other
1049
- // reference clients omit it entirely and rely on xAI's automatic
1050
- // prompt-prefix caching, which holds up to 95%+ hit even across
1051
- // parallel workers. Keep the header off by default.
1052
- // Shared retry: deepseek / xai / other compat backends all sit behind
1053
- // their own load balancers and emit 5xx / "overloaded" under burst
1054
- // traffic. The withRetry wrapper preserves abort behavior via
1055
- // mergedSignal and only retries when classifyError() says transient.
1056
- params.stream = true;
1057
- params.stream_options = { include_usage: true };
1058
- let assembled;
1059
- try {
1060
- assembled = await withRetry(
1061
- async ({ signal: attemptSignal }) => {
1062
- try { opts.onStageChange?.('requesting'); } catch { /* heartbeat best-effort */ }
1063
- const stream = await withRetry(
1064
- ({ signal: openSignal }) => this.client.chat.completions.create(params, { signal: openSignal }),
1065
- {
1066
- signal: attemptSignal,
1067
- perAttemptTimeoutMs: PROVIDER_FIRST_BYTE_TIMEOUT_MS,
1068
- perAttemptLabel: `${this.name} first byte`,
1069
- },
1070
- );
1071
- try { opts.onStageChange?.('streaming'); } catch { /* heartbeat best-effort */ }
1072
- return consumeCompatChatCompletionStream(stream, {
1073
- signal: attemptSignal,
1074
- label: this.name,
1075
- onStreamDelta: opts.onStreamDelta,
1076
- parseToolCalls,
1077
- });
1078
- },
1079
- {
1080
- signal: totalSignal.signal,
1081
- onRetry: ({ attempt, lastErr, delayMs, delayReason }) => {
1082
- const delayLabel = Number.isFinite(Number(delayMs)) ? `, delay ${delayMs}ms${delayReason ? ` (${delayReason})` : ''}` : '';
1083
- process.stderr.write(`[${this.name}] retry attempt ${attempt + 1} after ${lastErr?.message || lastErr?.code || 'transient error'}${delayLabel}\n`);
1084
- },
1085
- },
1086
- );
1087
- } finally {
1088
- totalSignal.cleanup();
1089
- }
1090
- const response = assembled.response;
1091
- const choice = response.choices[0];
1092
- const toolCalls = assembled.toolCalls;
1093
- // Capture finish_reason early so we can refuse to return an
1094
- // incomplete completion as final content. OpenAI-compat backends use
1095
- // `length` (max_tokens / model context overflow) and `content_filter`
1096
- // (moderation cutoff) to flag responses that were terminated before
1097
- // the model finished its turn — treating those as success silently
1098
- // surfaces truncated text and lets the loop accept a partial answer.
1099
- const stopReason = choice?.finish_reason || null;
1100
- if (stopReason === 'length' || stopReason === 'content_filter') {
1101
- const err = Object.assign(
1102
- new Error(`${this.name} response incomplete: finish_reason=${stopReason}`),
1103
- {
1104
- name: 'ProviderIncompleteError',
1105
- code: 'PROVIDER_INCOMPLETE',
1106
- providerIncomplete: true,
1107
- finishReason: stopReason,
1108
- partialContent: choice?.message?.content || '',
1109
- partialToolCalls: toolCalls,
1110
- model: response.model || useModel,
1111
- responseId: response.id || null,
1112
- rawUsage: response.usage || null,
1113
- },
1114
- );
1115
- throw err;
1116
- }
1117
- writeCompatCacheTrace({
1118
- provider: this.name,
1119
- model: useModel,
1120
- opts,
1121
- params,
1122
- rawTools: tools || [],
1123
- response,
1124
- cacheRoutingKey,
1125
- cacheRouting,
1126
- });
1127
- if (response.usage) {
1128
- const inputTokens = Number(response.usage.prompt_tokens ?? response.usage.input_tokens ?? 0);
1129
- const cachedTokens = extractCompatCachedTokens(response.usage);
1130
- traceBridgeUsage({
1131
- sessionId: opts.sessionId || opts.session?.id || null,
1132
- iteration: Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null,
1133
- inputTokens,
1134
- outputTokens: Number(response.usage.completion_tokens ?? response.usage.output_tokens ?? 0),
1135
- cachedTokens,
1136
- cacheWriteTokens: 0,
1137
- promptTokens: inputTokens,
1138
- model: response.model || useModel,
1139
- modelDisplay: response.model || useModel,
1140
- responseId: response.id || null,
1141
- rawUsage: response.usage,
1142
- provider: this.name,
1143
- });
1144
- }
1145
- // Capture provider reasoning_content so loop.mjs can attach it to the
1146
- // assistant message and echo it back next turn for providers that
1147
- // require or benefit from that official multi-turn shape.
1148
- const capturesReasoningContent = this.name === 'deepseek' || this.name === 'xai';
1149
- const reasoningContent = (capturesReasoningContent && typeof assembled.reasoningContent === 'string')
1150
- ? assembled.reasoningContent
1151
- : null;
1152
- return {
1153
- content: assembled.content || '',
1154
- model: response.model,
1155
- toolCalls,
1156
- stopReason,
1157
- ...(reasoningContent ? { reasoningContent } : {}),
1158
- usage: response.usage ? (() => {
1159
- const input = response.usage.prompt_tokens ?? response.usage.input_tokens ?? 0;
1160
- const cached = extractCompatCachedTokens(response.usage);
1161
- // xAI Grok returns the actual billed amount in `cost_in_usd_ticks`
1162
- // (1 tick = $1e-10, per docs.x.ai). Surface it as costUsd so the
1163
- // session manager skips the catalog-rate fallback and records the
1164
- // provider-billed value verbatim.
1165
- const ticks = response.usage.cost_in_usd_ticks;
1166
- const costUsd = typeof ticks === 'number' && ticks >= 0
1167
- ? Number((ticks * 1e-10).toFixed(8))
1168
- : undefined;
1169
- return {
1170
- inputTokens: input,
1171
- outputTokens: response.usage.completion_tokens ?? response.usage.output_tokens ?? 0,
1172
- cachedTokens: cached,
1173
- // Chat Completions prompt_tokens is already the total prompt
1174
- // the model ingested (cached is a subset) — alias directly.
1175
- promptTokens: input,
1176
- raw: { ...response.usage },
1177
- ...(costUsd != null ? { costUsd } : {}),
1178
- };
1179
- })() : undefined,
1180
- };
1181
- }
1182
- async _doSendXaiResponses(messages, useModel, tools, opts) {
1183
- const signal = opts.signal || null;
1184
- if (signal?.aborted) {
1185
- const reason = signal.reason;
1186
- throw reason instanceof Error ? reason : new Error('xAI Responses request aborted by session close');
1187
- }
1188
- const chatMessagesForTrace = toOpenAIMessages(messages, this.name);
1189
- const cacheRouting = xaiResponsesCacheRouting(opts, { messages: chatMessagesForTrace }, tools || [], useModel);
1190
- const { input, previousResponseId, startIndex } = toXaiResponsesInput(messages, opts.providerState);
1191
- const params = {
1192
- model: useModel,
1193
- input,
1194
- store: true,
1195
- prompt_cache_key: cacheRouting.key,
1196
- };
1197
- if (previousResponseId) params.previous_response_id = previousResponseId;
1198
- if (tools?.length) params.tools = toResponsesTools(tools);
1199
- // SSE transport: report 'requesting' until the stream opens, then
1200
- // per-chunk onStreamDelta feeds the bridge stall watchdog.
1201
- try { opts.onStageChange?.('requesting'); } catch { /* heartbeat best-effort */ }
1202
- const reasoningEffort = normalizeXaiReasoningEffort(opts.xaiReasoningEffort
1203
- ?? opts.effort
1204
- ?? this.config?.reasoningEffort
1205
- ?? process.env.MIXDOG_XAI_REASONING_EFFORT);
1206
- if (reasoningEffort) params.reasoning = { effort: reasoningEffort };
1207
- params.stream = true;
1208
- let response;
1209
- let cacheLane = null;
1210
- const scheduled = await withXaiResponsesCacheLane({
1211
- opts,
1212
- config: this.config,
1213
- cacheRouting,
1214
- model: useModel,
1215
- transport: 'http',
1216
- previousResponseId,
1217
- inputCount: Array.isArray(input) ? input.length : 0,
1218
- signal,
1219
- }, async (laneMeta) => {
1220
- cacheLane = laneMeta;
1221
- const totalSignal = createTimeoutSignal(signal, PROVIDER_NONSTREAM_TOTAL_TIMEOUT_MS, 'xai responses total');
1222
- try {
1223
- return await withRetry(
1224
- async ({ signal: attemptSignal }) => {
1225
- const stream = await withRetry(
1226
- ({ signal: openSignal }) => this.client.responses.create(params, { signal: openSignal }),
1227
- {
1228
- signal: attemptSignal,
1229
- perAttemptTimeoutMs: PROVIDER_FIRST_BYTE_TIMEOUT_MS,
1230
- perAttemptLabel: 'xai responses first byte',
1231
- },
1232
- );
1233
- try { opts.onStageChange?.('streaming'); } catch { /* heartbeat best-effort */ }
1234
- return consumeCompatResponsesStream(stream, {
1235
- signal: attemptSignal,
1236
- label: 'xai:responses',
1237
- onStreamDelta: opts.onStreamDelta,
1238
- parseResponsesToolCalls,
1239
- responseOutputText,
1240
- });
1241
- },
1242
- {
1243
- signal: totalSignal.signal,
1244
- onRetry: ({ attempt, lastErr, delayMs, delayReason }) => {
1245
- const delayLabel = Number.isFinite(Number(delayMs)) ? `, delay ${delayMs}ms${delayReason ? ` (${delayReason})` : ''}` : '';
1246
- process.stderr.write(`[xai:responses] retry attempt ${attempt + 1} after ${lastErr?.message || lastErr?.code || 'transient error'}${delayLabel}\n`);
1247
- },
1248
- },
1249
- );
1250
- } finally {
1251
- totalSignal.cleanup();
1252
- }
1253
- });
1254
- const streamed = scheduled.value;
1255
- response = streamed.response;
1256
- cacheLane = cacheLane || scheduled.laneMeta;
1257
- const toolCalls = streamed.toolCalls;
1258
- writeXaiResponsesCacheTrace({
1259
- model: useModel,
1260
- opts,
1261
- params,
1262
- rawTools: tools || [],
1263
- response,
1264
- cacheRouting,
1265
- previousResponseId,
1266
- inputStartIndex: startIndex,
1267
- transport: 'http',
1268
- cacheLane,
1269
- });
1270
- traceXaiResponsesCacheContext({
1271
- model: useModel,
1272
- opts,
1273
- params,
1274
- rawTools: tools || [],
1275
- response,
1276
- cacheRouting,
1277
- previousResponseId,
1278
- inputStartIndex: startIndex,
1279
- transport: 'http',
1280
- cacheLane,
1281
- });
1282
- if (response.usage) {
1283
- const inputTokens = Number(response.usage.input_tokens ?? response.usage.prompt_tokens ?? 0);
1284
- const cachedTokens = extractCompatCachedTokens(response.usage);
1285
- traceBridgeUsage({
1286
- sessionId: opts.sessionId || opts.session?.id || null,
1287
- iteration: Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null,
1288
- inputTokens,
1289
- outputTokens: Number(response.usage.output_tokens ?? response.usage.completion_tokens ?? 0),
1290
- cachedTokens,
1291
- cacheWriteTokens: 0,
1292
- promptTokens: inputTokens,
1293
- model: response.model || useModel,
1294
- modelDisplay: response.model || useModel,
1295
- responseId: response.id || null,
1296
- rawUsage: response.usage,
1297
- provider: 'xai',
1298
- });
1299
- }
1300
- return {
1301
- content: streamed.content,
1302
- model: response.model || useModel,
1303
- toolCalls,
1304
- providerState: {
1305
- ...(opts.providerState || {}),
1306
- xaiResponses: {
1307
- previousResponseId: response.id,
1308
- seenMessageCount: Array.isArray(messages) ? messages.length : 0,
1309
- model: response.model || useModel,
1310
- updatedAt: Date.now(),
1311
- },
1312
- },
1313
- usage: response.usage ? (() => {
1314
- const inputTokens = response.usage.input_tokens ?? response.usage.prompt_tokens ?? 0;
1315
- const ticks = response.usage.cost_in_usd_ticks;
1316
- const costUsd = typeof ticks === 'number' && ticks >= 0
1317
- ? Number((ticks * 1e-10).toFixed(8))
1318
- : undefined;
1319
- return {
1320
- inputTokens,
1321
- outputTokens: response.usage.output_tokens ?? response.usage.completion_tokens ?? 0,
1322
- cachedTokens: extractCompatCachedTokens(response.usage),
1323
- promptTokens: inputTokens,
1324
- raw: { ...response.usage },
1325
- ...(costUsd != null ? { costUsd } : {}),
1326
- };
1327
- })() : undefined,
1328
- };
1329
- }
1330
- async _doSendXaiResponsesWebSocket(messages, useModel, tools, opts) {
1331
- const signal = opts.signal || null;
1332
- if (signal?.aborted) {
1333
- const reason = signal.reason;
1334
- throw reason instanceof Error ? reason : new Error('xAI Responses WebSocket request aborted by session close');
1335
- }
1336
- const apiKey = this.config?.apiKey || process.env.XAI_API_KEY;
1337
- if (!apiKey) throw new Error('xAI API key not configured');
1338
- const chatMessagesForTrace = toOpenAIMessages(messages, this.name);
1339
- const cacheRouting = xaiResponsesCacheRouting(opts, { messages: chatMessagesForTrace }, tools || [], useModel);
1340
- const { input, previousResponseId, startIndex } = toXaiResponsesInput(messages, opts.providerState, { includeSystem: false });
1341
- const params = {
1342
- model: useModel,
1343
- input,
1344
- // xAI's WebSocket continuation is documented for store=false, but
1345
- // the public endpoint currently returns previous_response_not_found
1346
- // in our live probes unless the chain is stored.
1347
- store: true,
1348
- prompt_cache_key: cacheRouting.key,
1349
- };
1350
- const instructions = xaiSystemInstructions(messages);
1351
- if (previousResponseId) params.previous_response_id = previousResponseId;
1352
- // xAI rejects instructions together with previous_response_id; the
1353
- // first response already anchors instructions for the continuation.
1354
- else if (instructions) params.instructions = instructions;
1355
- if (tools?.length) params.tools = toResponsesTools(tools);
1356
- const reasoningEffort = normalizeXaiReasoningEffort(opts.xaiReasoningEffort
1357
- ?? opts.effort
1358
- ?? this.config?.reasoningEffort
1359
- ?? process.env.MIXDOG_XAI_REASONING_EFFORT);
1360
- if (reasoningEffort) params.reasoning = { effort: reasoningEffort };
1361
- const warmupBody = useXaiResponsesWebSocketWarmup(opts, this.config, {
1362
- previousResponseId,
1363
- instructions,
1364
- rawTools: tools || [],
1365
- })
1366
- ? { ...params, generate: false, input: [] }
1367
- : null;
1368
- const iteration = Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null;
1369
- let cacheLane = null;
1370
- const scheduled = await withXaiResponsesCacheLane({
1371
- opts,
1372
- config: this.config,
1373
- cacheRouting,
1374
- model: useModel,
1375
- transport: 'websocket',
1376
- previousResponseId,
1377
- inputCount: Array.isArray(input) ? input.length : 0,
1378
- signal,
1379
- }, async (laneMeta) => {
1380
- cacheLane = laneMeta;
1381
- return await sendViaWebSocket({
1382
- auth: { type: 'xai', apiKey },
1383
- body: params,
1384
- sendOpts: opts,
1385
- onStreamDelta: typeof opts.onStreamDelta === 'function' ? opts.onStreamDelta : null,
1386
- onToolCall: typeof opts.onToolCall === 'function' ? opts.onToolCall : null,
1387
- onStageChange: typeof opts.onStageChange === 'function' ? opts.onStageChange : null,
1388
- externalSignal: signal,
1389
- poolKey: opts.sessionId || opts.session?.id || null,
1390
- cacheKey: cacheRouting.key,
1391
- iteration,
1392
- useModel,
1393
- displayModel: (id) => id,
1394
- includeResponseId: true,
1395
- traceProvider: 'xai',
1396
- logSuppressedReasoningDeltas: false,
1397
- warmupBody,
1398
- });
1399
- });
1400
- const result = scheduled.value;
1401
- cacheLane = cacheLane || scheduled.laneMeta;
1402
- const responseId = result.responseId || previousResponseId || null;
1403
- const rawUsage = result.usage?.raw || result.usage || null;
1404
- const traceParams = result.__warmup?.requestBody || params;
1405
- writeXaiResponsesCacheTrace({
1406
- model: useModel,
1407
- opts,
1408
- params: traceParams,
1409
- rawTools: tools || [],
1410
- response: {
1411
- id: responseId,
1412
- model: result.model || useModel,
1413
- output: [],
1414
- usage: rawUsage,
1415
- },
1416
- cacheRouting,
1417
- previousResponseId,
1418
- inputStartIndex: startIndex,
1419
- transport: 'websocket',
1420
- cacheLane,
1421
- });
1422
- traceXaiResponsesCacheContext({
1423
- model: useModel,
1424
- opts,
1425
- params: traceParams,
1426
- rawTools: tools || [],
1427
- response: {
1428
- id: responseId,
1429
- model: result.model || useModel,
1430
- output: [],
1431
- usage: rawUsage,
1432
- },
1433
- cacheRouting,
1434
- previousResponseId,
1435
- inputStartIndex: startIndex,
1436
- transport: 'websocket',
1437
- cacheLane,
1438
- });
1439
- const ticks = rawUsage?.cost_in_usd_ticks;
1440
- const costUsd = typeof ticks === 'number' && ticks >= 0
1441
- ? Number((ticks * 1e-10).toFixed(8))
1442
- : undefined;
1443
- return {
1444
- content: result.content || '',
1445
- model: result.model || useModel,
1446
- toolCalls: result.toolCalls,
1447
- providerState: {
1448
- ...(opts.providerState || {}),
1449
- xaiResponses: {
1450
- previousResponseId: responseId,
1451
- seenMessageCount: Array.isArray(messages) ? messages.length : 0,
1452
- model: result.model || useModel,
1453
- updatedAt: Date.now(),
1454
- transport: 'websocket',
1455
- },
1456
- },
1457
- usage: result.usage ? {
1458
- ...result.usage,
1459
- ...(costUsd != null ? { costUsd } : {}),
1460
- } : undefined,
1461
- };
1462
- }
1463
- async _fetchModelItems() {
1464
- const timeout = createTimeoutSignal(null, MODEL_LIST_TIMEOUT_MS, `${this.name} model list`);
1465
- try {
1466
- const res = await fetch(`${String(this.baseURL || '').replace(/\/+$/, '')}/models`, {
1467
- method: 'GET',
1468
- headers: {
1469
- Authorization: `Bearer ${this.apiKey || 'no-key'}`,
1470
- ...(this.defaultHeaders || {}),
1471
- },
1472
- signal: timeout.signal,
1473
- });
1474
- if (!res.ok) throw new Error(`${this.name} models ${res.status}`);
1475
- const data = await res.json();
1476
- if (Array.isArray(data?.data)) return data.data;
1477
- if (Array.isArray(data)) return data;
1478
- return [];
1479
- } finally {
1480
- timeout.cleanup();
1481
- }
1482
- }
1483
- async listModels() {
1484
- try {
1485
- const list = await this._fetchModelItems();
1486
- const models = [];
1487
- for (const m of list) {
1488
- models.push({
1489
- id: m?.id,
1490
- name: m?.id,
1491
- provider: this.name,
1492
- contextWindow: 0,
1493
- created: typeof m?.created === 'number' ? m.created : null,
1494
- });
1495
- }
1496
- return models.filter(m => m.id);
1497
- }
1498
- catch {
1499
- return [];
1500
- }
1501
- }
1502
- async isAvailable() {
1503
- try {
1504
- await this._fetchModelItems();
1505
- return true;
1506
- }
1507
- catch {
1508
- return false;
1509
- }
1510
- }
1511
- }