mixdog 0.7.17 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (836) 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/smoke-loop-report.mjs +221 -0
  10. package/scripts/smoke-loop.mjs +201 -0
  11. package/scripts/smoke.mjs +113 -0
  12. package/scripts/tool-failures.mjs +143 -0
  13. package/scripts/tool-smoke.mjs +456 -0
  14. package/src/agents/debugger/AGENT.md +3 -0
  15. package/src/agents/debugger/agent.json +6 -0
  16. package/src/agents/explore/AGENT.md +4 -0
  17. package/src/agents/explore/agent.json +6 -0
  18. package/src/agents/heavy-worker/AGENT.md +3 -0
  19. package/src/agents/heavy-worker/agent.json +6 -0
  20. package/src/agents/maintainer/AGENT.md +3 -0
  21. package/src/agents/maintainer/agent.json +6 -0
  22. package/src/agents/reviewer/AGENT.md +3 -0
  23. package/src/agents/reviewer/agent.json +6 -0
  24. package/src/agents/scheduler-task.md +3 -0
  25. package/src/agents/web-researcher/AGENT.md +3 -0
  26. package/src/agents/web-researcher/agent.json +6 -0
  27. package/src/agents/webhook-handler.md +3 -0
  28. package/src/agents/worker/AGENT.md +3 -0
  29. package/src/agents/worker/agent.json +6 -0
  30. package/src/app.mjs +90 -0
  31. package/src/cli.mjs +11 -0
  32. package/src/defaults/hidden-roles.json +72 -0
  33. package/src/defaults/mixdog-config.template.json +15 -0
  34. package/src/hooks/lib/permission-evaluator.cjs +488 -0
  35. package/src/hooks/lib/settings-loader.cjs +112 -0
  36. package/src/lib/keychain-cjs.cjs +332 -0
  37. package/src/lib/plugin-paths.cjs +28 -0
  38. package/src/lib/rules-builder.cjs +315 -0
  39. package/src/mixdog-session-runtime.mjs +3704 -0
  40. package/src/output-styles/default.md +38 -0
  41. package/src/output-styles/extreme-simple.md +17 -0
  42. package/src/output-styles/simple.md +17 -0
  43. package/src/repl.mjs +322 -0
  44. package/src/rules/bridge/00-common.md +5 -0
  45. package/src/rules/bridge/20-skip-protocol.md +11 -0
  46. package/src/rules/bridge/30-explorer.md +4 -0
  47. package/src/rules/bridge/40-cycle1-agent.md +28 -0
  48. package/src/rules/bridge/41-cycle2-agent.md +59 -0
  49. package/src/rules/lead/00-tool-lead.md +5 -0
  50. package/src/rules/lead/01-general.md +5 -0
  51. package/src/rules/lead/02-channels.md +3 -0
  52. package/src/rules/lead/04-workflow.md +12 -0
  53. package/src/rules/shared/00-language.md +3 -0
  54. package/src/rules/shared/01-tool.md +3 -0
  55. package/src/runtime/agent/orchestrator/bridge-trace.mjs +814 -0
  56. package/src/runtime/agent/orchestrator/cache-mtime.mjs +60 -0
  57. package/src/runtime/agent/orchestrator/config.mjs +446 -0
  58. package/src/runtime/agent/orchestrator/context/collect.mjs +796 -0
  59. package/src/runtime/agent/orchestrator/dispatch-persist.mjs +417 -0
  60. package/src/runtime/agent/orchestrator/internal-roles.mjs +188 -0
  61. package/src/runtime/agent/orchestrator/internal-tools.mjs +88 -0
  62. package/src/runtime/agent/orchestrator/mcp/client.mjs +345 -0
  63. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2104 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +784 -0
  65. package/src/runtime/agent/orchestrator/providers/api-usage.mjs +341 -0
  66. package/src/runtime/agent/orchestrator/providers/gemini.mjs +1679 -0
  67. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +959 -0
  68. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +213 -0
  69. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +38 -0
  70. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +471 -0
  71. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +615 -0
  72. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +808 -0
  73. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +1719 -0
  74. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +2587 -0
  75. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +1953 -0
  76. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +136 -0
  77. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +317 -0
  78. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +109 -0
  79. package/src/runtime/agent/orchestrator/providers/registry.mjs +247 -0
  80. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +332 -0
  81. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +11 -0
  82. package/src/runtime/agent/orchestrator/providers/trace-utils.mjs +50 -0
  83. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +142 -0
  84. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +318 -0
  85. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +367 -0
  86. package/src/runtime/agent/orchestrator/session/compact.mjs +882 -0
  87. package/src/runtime/agent/orchestrator/session/context-utils.mjs +233 -0
  88. package/src/runtime/agent/orchestrator/session/loop.mjs +2320 -0
  89. package/src/runtime/agent/orchestrator/session/manager.mjs +2960 -0
  90. package/src/runtime/agent/orchestrator/session/result-classification.mjs +65 -0
  91. package/src/runtime/agent/orchestrator/session/store.mjs +663 -0
  92. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +166 -0
  93. package/src/runtime/agent/orchestrator/smart-bridge/bridge-llm.mjs +339 -0
  94. package/src/runtime/agent/orchestrator/smart-bridge/cache-strategy.mjs +419 -0
  95. package/src/runtime/agent/orchestrator/stall-policy.mjs +227 -0
  96. package/src/runtime/agent/orchestrator/tool-loop-guard.mjs +235 -0
  97. package/src/runtime/agent/orchestrator/tools/bash-session.mjs +723 -0
  98. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +389 -0
  99. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +637 -0
  100. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +165 -0
  101. package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +104 -0
  102. package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +194 -0
  103. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +596 -0
  104. package/src/runtime/agent/orchestrator/tools/builtin/native-edit-runner.mjs +110 -0
  105. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +153 -0
  106. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +118 -0
  107. package/src/runtime/agent/orchestrator/tools/builtin/read-open.mjs +189 -0
  108. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +731 -0
  109. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +168 -0
  110. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +602 -0
  111. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +465 -0
  112. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +160 -0
  113. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +982 -0
  114. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +1087 -0
  115. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +231 -0
  116. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-store.mjs +223 -0
  117. package/src/runtime/agent/orchestrator/tools/builtin.mjs +478 -0
  118. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +24 -0
  119. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4102 -0
  120. package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +323 -0
  121. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +154 -0
  122. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +26 -0
  123. package/src/runtime/agent/orchestrator/tools/patch-binary-fetcher.mjs +143 -0
  124. package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +18 -0
  125. package/src/runtime/agent/orchestrator/tools/patch.mjs +2772 -0
  126. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +114 -0
  127. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +880 -0
  128. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +312 -0
  129. package/src/runtime/channels/backends/discord.mjs +781 -0
  130. package/src/runtime/channels/data/voice-runtime-manifest.json +138 -0
  131. package/src/runtime/channels/index.mjs +3309 -0
  132. package/src/runtime/channels/lib/config.mjs +285 -0
  133. package/src/runtime/channels/lib/drop-trace.mjs +71 -0
  134. package/src/runtime/channels/lib/event-pipeline.mjs +81 -0
  135. package/src/runtime/channels/lib/holidays.mjs +138 -0
  136. package/src/runtime/channels/lib/hook-pipe-server.mjs +671 -0
  137. package/src/runtime/channels/lib/output-forwarder.mjs +765 -0
  138. package/src/runtime/channels/lib/runtime-paths.mjs +497 -0
  139. package/src/runtime/channels/lib/scheduler.mjs +710 -0
  140. package/src/runtime/channels/lib/session-discovery.mjs +102 -0
  141. package/src/runtime/channels/lib/state-file.mjs +68 -0
  142. package/src/runtime/channels/lib/status-snapshot.mjs +224 -0
  143. package/src/runtime/channels/lib/tool-format.mjs +124 -0
  144. package/src/runtime/channels/lib/transcript-discovery.mjs +195 -0
  145. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +734 -0
  146. package/src/runtime/channels/lib/webhook.mjs +1288 -0
  147. package/src/runtime/channels/tool-defs.mjs +177 -0
  148. package/src/runtime/lib/keychain-cjs.cjs +289 -0
  149. package/src/runtime/memory/data/runtime-manifest.json +40 -0
  150. package/src/runtime/memory/index.mjs +3600 -0
  151. package/src/runtime/memory/lib/core-memory-store.mjs +336 -0
  152. package/src/runtime/memory/lib/embedding-provider.mjs +275 -0
  153. package/src/runtime/memory/lib/embedding-worker.mjs +331 -0
  154. package/src/runtime/memory/lib/memory-cycle-requests.mjs +276 -0
  155. package/src/runtime/memory/lib/memory-cycle1.mjs +783 -0
  156. package/src/runtime/memory/lib/memory-cycle2.mjs +1389 -0
  157. package/src/runtime/memory/lib/memory-cycle3.mjs +646 -0
  158. package/src/runtime/memory/lib/memory-embed.mjs +300 -0
  159. package/src/runtime/memory/lib/memory-ops-policy.mjs +149 -0
  160. package/src/runtime/memory/lib/memory-recall-store.mjs +644 -0
  161. package/src/runtime/memory/lib/memory.mjs +418 -0
  162. package/src/runtime/memory/lib/pg/adapter.mjs +314 -0
  163. package/src/runtime/memory/lib/pg/process.mjs +366 -0
  164. package/src/runtime/memory/lib/pg/supervisor.mjs +495 -0
  165. package/src/runtime/memory/lib/runtime-fetcher.mjs +464 -0
  166. package/src/runtime/memory/lib/trace-store.mjs +734 -0
  167. package/src/runtime/memory/tool-defs.mjs +79 -0
  168. package/src/runtime/search/index.mjs +925 -0
  169. package/src/runtime/search/lib/config.mjs +61 -0
  170. package/src/runtime/search/lib/web-tools.mjs +1278 -0
  171. package/src/runtime/search/tool-defs.mjs +64 -0
  172. package/src/runtime/shared/atomic-file.mjs +435 -0
  173. package/src/runtime/shared/background-tasks.mjs +376 -0
  174. package/src/runtime/shared/child-guardian.mjs +98 -0
  175. package/src/runtime/shared/config.mjs +393 -0
  176. package/src/runtime/shared/err-text.mjs +121 -0
  177. package/src/runtime/shared/launcher-control.mjs +259 -0
  178. package/src/runtime/shared/llm/cost.mjs +66 -0
  179. package/src/runtime/shared/llm/http-agent.mjs +129 -0
  180. package/src/runtime/shared/open-url.mjs +37 -0
  181. package/src/runtime/shared/plugin-paths.mjs +25 -0
  182. package/src/runtime/shared/process-shutdown.mjs +147 -0
  183. package/src/runtime/shared/schedules-store.mjs +70 -0
  184. package/src/runtime/shared/tool-execution-contract.mjs +104 -0
  185. package/src/runtime/shared/tool-surface.mjs +950 -0
  186. package/src/runtime/shared/user-cwd.mjs +221 -0
  187. package/src/runtime/shared/user-data-guard.mjs +232 -0
  188. package/src/runtime/shared/workspace-router.mjs +259 -0
  189. package/src/standalone/bridge-tool.mjs +1414 -0
  190. package/src/standalone/channel-admin.mjs +366 -0
  191. package/src/standalone/channel-worker-preload.cjs +3 -0
  192. package/src/standalone/channel-worker.mjs +353 -0
  193. package/src/standalone/explore-tool.mjs +233 -0
  194. package/src/standalone/hook-bus.mjs +246 -0
  195. package/src/standalone/plugin-admin.mjs +247 -0
  196. package/src/standalone/provider-admin.mjs +338 -0
  197. package/src/standalone/seeds.mjs +94 -0
  198. package/src/standalone/usage-dashboard.mjs +510 -0
  199. package/src/tui/App.jsx +5438 -0
  200. package/src/tui/components/AnsiText.jsx +199 -0
  201. package/src/tui/components/ContextPanel.jsx +217 -0
  202. package/src/tui/components/Markdown.jsx +205 -0
  203. package/src/tui/components/MarkdownTable.jsx +204 -0
  204. package/src/tui/components/Message.jsx +103 -0
  205. package/src/tui/components/Picker.jsx +317 -0
  206. package/src/tui/components/PromptInput.jsx +584 -0
  207. package/src/tui/components/QueuedCommands.jsx +47 -0
  208. package/src/tui/components/SlashCommandPalette.jsx +114 -0
  209. package/src/tui/components/Spinner.jsx +317 -0
  210. package/src/tui/components/StatusLine.jsx +87 -0
  211. package/src/tui/components/TextEntryPanel.jsx +323 -0
  212. package/src/tui/components/ToolExecution.jsx +772 -0
  213. package/src/tui/components/TurnDone.jsx +78 -0
  214. package/src/tui/components/UsagePanel.jsx +331 -0
  215. package/src/tui/dist/index.mjs +12359 -0
  216. package/src/tui/engine.mjs +2410 -0
  217. package/src/tui/figures.mjs +50 -0
  218. package/src/tui/hooks/useEngine.mjs +16 -0
  219. package/src/tui/index.jsx +254 -0
  220. package/src/tui/input-editing.mjs +242 -0
  221. package/src/tui/markdown/format-token.mjs +194 -0
  222. package/src/tui/paste-attachments.mjs +198 -0
  223. package/src/tui/runtime/shared/process-shutdown.mjs +1 -0
  224. package/src/tui/spinner-verbs.mjs +45 -0
  225. package/src/tui/theme.mjs +67 -0
  226. package/src/tui/time-format.mjs +53 -0
  227. package/src/ui/ansi.mjs +115 -0
  228. package/src/ui/markdown.mjs +195 -0
  229. package/src/ui/statusline.mjs +730 -0
  230. package/src/ui/tool-card.mjs +101 -0
  231. package/src/vendor/statusline/bin/statusline-lib.mjs +805 -0
  232. package/src/vendor/statusline/bin/statusline-route.mjs +596 -0
  233. package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +285 -0
  234. package/src/vendor/statusline/src/gateway/claude-current.mjs +320 -0
  235. package/src/vendor/statusline/src/gateway/route-meta.mjs +753 -0
  236. package/src/vendor/statusline/src/gateway/session-routes.mjs +244 -0
  237. package/src/workflows/default/WORKFLOW.md +7 -0
  238. package/src/workflows/default/workflow.json +14 -0
  239. package/vendor/ink/build/ansi-tokenizer.d.ts +38 -0
  240. package/vendor/ink/build/ansi-tokenizer.js +316 -0
  241. package/vendor/ink/build/ansi-tokenizer.js.map +1 -0
  242. package/vendor/ink/build/colorize.d.ts +3 -0
  243. package/vendor/ink/build/colorize.js +48 -0
  244. package/vendor/ink/build/colorize.js.map +1 -0
  245. package/vendor/ink/build/components/AccessibilityContext.d.ts +3 -0
  246. package/vendor/ink/build/components/AccessibilityContext.js +5 -0
  247. package/vendor/ink/build/components/AccessibilityContext.js.map +1 -0
  248. package/vendor/ink/build/components/AnimationContext.d.ts +9 -0
  249. package/vendor/ink/build/components/AnimationContext.js +13 -0
  250. package/vendor/ink/build/components/AnimationContext.js.map +1 -0
  251. package/vendor/ink/build/components/App.d.ts +24 -0
  252. package/vendor/ink/build/components/App.js +554 -0
  253. package/vendor/ink/build/components/App.js.map +1 -0
  254. package/vendor/ink/build/components/AppContext.d.ts +80 -0
  255. package/vendor/ink/build/components/AppContext.js +25 -0
  256. package/vendor/ink/build/components/AppContext.js.map +1 -0
  257. package/vendor/ink/build/components/BackgroundContext.d.ts +4 -0
  258. package/vendor/ink/build/components/BackgroundContext.js +3 -0
  259. package/vendor/ink/build/components/BackgroundContext.js.map +1 -0
  260. package/vendor/ink/build/components/Box.d.ts +130 -0
  261. package/vendor/ink/build/components/Box.js +34 -0
  262. package/vendor/ink/build/components/Box.js.map +1 -0
  263. package/vendor/ink/build/components/CursorContext.d.ts +11 -0
  264. package/vendor/ink/build/components/CursorContext.js +8 -0
  265. package/vendor/ink/build/components/CursorContext.js.map +1 -0
  266. package/vendor/ink/build/components/ErrorBoundary.d.ts +18 -0
  267. package/vendor/ink/build/components/ErrorBoundary.js +23 -0
  268. package/vendor/ink/build/components/ErrorBoundary.js.map +1 -0
  269. package/vendor/ink/build/components/ErrorOverview.d.ts +6 -0
  270. package/vendor/ink/build/components/ErrorOverview.js +90 -0
  271. package/vendor/ink/build/components/ErrorOverview.js.map +1 -0
  272. package/vendor/ink/build/components/FocusContext.d.ts +16 -0
  273. package/vendor/ink/build/components/FocusContext.js +17 -0
  274. package/vendor/ink/build/components/FocusContext.js.map +1 -0
  275. package/vendor/ink/build/components/Newline.d.ts +13 -0
  276. package/vendor/ink/build/components/Newline.js +8 -0
  277. package/vendor/ink/build/components/Newline.js.map +1 -0
  278. package/vendor/ink/build/components/Spacer.d.ts +7 -0
  279. package/vendor/ink/build/components/Spacer.js +11 -0
  280. package/vendor/ink/build/components/Spacer.js.map +1 -0
  281. package/vendor/ink/build/components/Static.d.ts +24 -0
  282. package/vendor/ink/build/components/Static.js +28 -0
  283. package/vendor/ink/build/components/Static.js.map +1 -0
  284. package/vendor/ink/build/components/StderrContext.d.ts +15 -0
  285. package/vendor/ink/build/components/StderrContext.js +13 -0
  286. package/vendor/ink/build/components/StderrContext.js.map +1 -0
  287. package/vendor/ink/build/components/StdinContext.d.ts +28 -0
  288. package/vendor/ink/build/components/StdinContext.js +20 -0
  289. package/vendor/ink/build/components/StdinContext.js.map +1 -0
  290. package/vendor/ink/build/components/StdoutContext.d.ts +15 -0
  291. package/vendor/ink/build/components/StdoutContext.js +13 -0
  292. package/vendor/ink/build/components/StdoutContext.js.map +1 -0
  293. package/vendor/ink/build/components/Text.d.ts +55 -0
  294. package/vendor/ink/build/components/Text.js +50 -0
  295. package/vendor/ink/build/components/Text.js.map +1 -0
  296. package/vendor/ink/build/components/Transform.d.ts +16 -0
  297. package/vendor/ink/build/components/Transform.js +15 -0
  298. package/vendor/ink/build/components/Transform.js.map +1 -0
  299. package/vendor/ink/build/cursor-helpers.d.ts +39 -0
  300. package/vendor/ink/build/cursor-helpers.js +62 -0
  301. package/vendor/ink/build/cursor-helpers.js.map +1 -0
  302. package/vendor/ink/build/devtools-window-polyfill.d.ts +1 -0
  303. package/vendor/ink/build/devtools-window-polyfill.js +68 -0
  304. package/vendor/ink/build/devtools-window-polyfill.js.map +1 -0
  305. package/vendor/ink/build/devtools.d.ts +1 -0
  306. package/vendor/ink/build/devtools.js +36 -0
  307. package/vendor/ink/build/devtools.js.map +1 -0
  308. package/vendor/ink/build/dom.d.ts +62 -0
  309. package/vendor/ink/build/dom.js +143 -0
  310. package/vendor/ink/build/dom.js.map +1 -0
  311. package/vendor/ink/build/get-max-width.d.ts +3 -0
  312. package/vendor/ink/build/get-max-width.js +10 -0
  313. package/vendor/ink/build/get-max-width.js.map +1 -0
  314. package/vendor/ink/build/hooks/use-animation.d.ts +49 -0
  315. package/vendor/ink/build/hooks/use-animation.js +87 -0
  316. package/vendor/ink/build/hooks/use-animation.js.map +1 -0
  317. package/vendor/ink/build/hooks/use-app.d.ts +5 -0
  318. package/vendor/ink/build/hooks/use-app.js +8 -0
  319. package/vendor/ink/build/hooks/use-app.js.map +1 -0
  320. package/vendor/ink/build/hooks/use-box-metrics.d.ts +59 -0
  321. package/vendor/ink/build/hooks/use-box-metrics.js +81 -0
  322. package/vendor/ink/build/hooks/use-box-metrics.js.map +1 -0
  323. package/vendor/ink/build/hooks/use-cursor.d.ts +12 -0
  324. package/vendor/ink/build/hooks/use-cursor.js +29 -0
  325. package/vendor/ink/build/hooks/use-cursor.js.map +1 -0
  326. package/vendor/ink/build/hooks/use-focus-manager.d.ts +43 -0
  327. package/vendor/ink/build/hooks/use-focus-manager.js +18 -0
  328. package/vendor/ink/build/hooks/use-focus-manager.js.map +1 -0
  329. package/vendor/ink/build/hooks/use-focus.d.ts +30 -0
  330. package/vendor/ink/build/hooks/use-focus.js +43 -0
  331. package/vendor/ink/build/hooks/use-focus.js.map +1 -0
  332. package/vendor/ink/build/hooks/use-input.d.ts +132 -0
  333. package/vendor/ink/build/hooks/use-input.js +126 -0
  334. package/vendor/ink/build/hooks/use-input.js.map +1 -0
  335. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.d.ts +6 -0
  336. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js +12 -0
  337. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js.map +1 -0
  338. package/vendor/ink/build/hooks/use-paste.d.ts +35 -0
  339. package/vendor/ink/build/hooks/use-paste.js +62 -0
  340. package/vendor/ink/build/hooks/use-paste.js.map +1 -0
  341. package/vendor/ink/build/hooks/use-stderr.d.ts +5 -0
  342. package/vendor/ink/build/hooks/use-stderr.js +8 -0
  343. package/vendor/ink/build/hooks/use-stderr.js.map +1 -0
  344. package/vendor/ink/build/hooks/use-stdin.d.ts +7 -0
  345. package/vendor/ink/build/hooks/use-stdin.js +9 -0
  346. package/vendor/ink/build/hooks/use-stdin.js.map +1 -0
  347. package/vendor/ink/build/hooks/use-stdout.d.ts +5 -0
  348. package/vendor/ink/build/hooks/use-stdout.js +8 -0
  349. package/vendor/ink/build/hooks/use-stdout.js.map +1 -0
  350. package/vendor/ink/build/hooks/use-window-size.d.ts +18 -0
  351. package/vendor/ink/build/hooks/use-window-size.js +22 -0
  352. package/vendor/ink/build/hooks/use-window-size.js.map +1 -0
  353. package/vendor/ink/build/index.d.ts +42 -0
  354. package/vendor/ink/build/index.js +24 -0
  355. package/vendor/ink/build/index.js.map +1 -0
  356. package/vendor/ink/build/ink.d.ts +146 -0
  357. package/vendor/ink/build/ink.js +1022 -0
  358. package/vendor/ink/build/ink.js.map +1 -0
  359. package/vendor/ink/build/input-parser.d.ts +10 -0
  360. package/vendor/ink/build/input-parser.js +194 -0
  361. package/vendor/ink/build/input-parser.js.map +1 -0
  362. package/vendor/ink/build/instances.d.ts +3 -0
  363. package/vendor/ink/build/instances.js +8 -0
  364. package/vendor/ink/build/instances.js.map +1 -0
  365. package/vendor/ink/build/kitty-keyboard.d.ts +23 -0
  366. package/vendor/ink/build/kitty-keyboard.js +32 -0
  367. package/vendor/ink/build/kitty-keyboard.js.map +1 -0
  368. package/vendor/ink/build/log-update.d.ts +20 -0
  369. package/vendor/ink/build/log-update.js +261 -0
  370. package/vendor/ink/build/log-update.js.map +1 -0
  371. package/vendor/ink/build/measure-element.d.ts +20 -0
  372. package/vendor/ink/build/measure-element.js +13 -0
  373. package/vendor/ink/build/measure-element.js.map +1 -0
  374. package/vendor/ink/build/measure-text.d.ts +6 -0
  375. package/vendor/ink/build/measure-text.js +21 -0
  376. package/vendor/ink/build/measure-text.js.map +1 -0
  377. package/vendor/ink/build/output.d.ts +35 -0
  378. package/vendor/ink/build/output.js +328 -0
  379. package/vendor/ink/build/output.js.map +1 -0
  380. package/vendor/ink/build/parse-keypress.d.ts +20 -0
  381. package/vendor/ink/build/parse-keypress.js +495 -0
  382. package/vendor/ink/build/parse-keypress.js.map +1 -0
  383. package/vendor/ink/build/reconciler.d.ts +4 -0
  384. package/vendor/ink/build/reconciler.js +306 -0
  385. package/vendor/ink/build/reconciler.js.map +1 -0
  386. package/vendor/ink/build/render-background.d.ts +4 -0
  387. package/vendor/ink/build/render-background.js +25 -0
  388. package/vendor/ink/build/render-background.js.map +1 -0
  389. package/vendor/ink/build/render-border.d.ts +4 -0
  390. package/vendor/ink/build/render-border.js +84 -0
  391. package/vendor/ink/build/render-border.js.map +1 -0
  392. package/vendor/ink/build/render-node-to-output.d.ts +14 -0
  393. package/vendor/ink/build/render-node-to-output.js +162 -0
  394. package/vendor/ink/build/render-node-to-output.js.map +1 -0
  395. package/vendor/ink/build/render-to-string.d.ts +38 -0
  396. package/vendor/ink/build/render-to-string.js +116 -0
  397. package/vendor/ink/build/render-to-string.js.map +1 -0
  398. package/vendor/ink/build/render.d.ts +176 -0
  399. package/vendor/ink/build/render.js +71 -0
  400. package/vendor/ink/build/render.js.map +1 -0
  401. package/vendor/ink/build/renderer.d.ts +8 -0
  402. package/vendor/ink/build/renderer.js +64 -0
  403. package/vendor/ink/build/renderer.js.map +1 -0
  404. package/vendor/ink/build/sanitize-ansi.d.ts +2 -0
  405. package/vendor/ink/build/sanitize-ansi.js +27 -0
  406. package/vendor/ink/build/sanitize-ansi.js.map +1 -0
  407. package/vendor/ink/build/squash-text-nodes.d.ts +3 -0
  408. package/vendor/ink/build/squash-text-nodes.js +36 -0
  409. package/vendor/ink/build/squash-text-nodes.js.map +1 -0
  410. package/vendor/ink/build/styles.d.ts +302 -0
  411. package/vendor/ink/build/styles.js +303 -0
  412. package/vendor/ink/build/styles.js.map +1 -0
  413. package/vendor/ink/build/utils.d.ts +9 -0
  414. package/vendor/ink/build/utils.js +19 -0
  415. package/vendor/ink/build/utils.js.map +1 -0
  416. package/vendor/ink/build/wrap-text.d.ts +3 -0
  417. package/vendor/ink/build/wrap-text.js +38 -0
  418. package/vendor/ink/build/wrap-text.js.map +1 -0
  419. package/vendor/ink/build/write-synchronized.d.ts +4 -0
  420. package/vendor/ink/build/write-synchronized.js +9 -0
  421. package/vendor/ink/build/write-synchronized.js.map +1 -0
  422. package/vendor/ink/license +10 -0
  423. package/vendor/ink/package.json +137 -0
  424. package/.claude-plugin/marketplace.json +0 -34
  425. package/.claude-plugin/plugin.json +0 -20
  426. package/.gitattributes +0 -34
  427. package/.mcp.json +0 -14
  428. package/ARCHITECTURE.md +0 -77
  429. package/CHANGELOG.md +0 -30
  430. package/CONTRIBUTING.md +0 -45
  431. package/DATA-FLOW.md +0 -79
  432. package/LICENSE +0 -21
  433. package/SECURITY.md +0 -138
  434. package/UNINSTALL.md +0 -112
  435. package/agents/maintenance.md +0 -5
  436. package/agents/memory-classification.md +0 -30
  437. package/agents/scheduler-task.md +0 -18
  438. package/agents/webhook-handler.md +0 -27
  439. package/agents/worker.md +0 -24
  440. package/bin/bridge +0 -133
  441. package/bin/statusline-launcher.mjs +0 -82
  442. package/bin/statusline-lib.mjs +0 -558
  443. package/bin/statusline.mjs +0 -615
  444. package/bun.lock +0 -927
  445. package/commands/config.md +0 -16
  446. package/commands/doctor.md +0 -13
  447. package/commands/setup.md +0 -17
  448. package/defaults/hidden-roles.json +0 -68
  449. package/defaults/memory-chunk-prompt.md +0 -63
  450. package/defaults/mixdog-config.template.json +0 -27
  451. package/defaults/user-workflow.json +0 -8
  452. package/defaults/user-workflow.md +0 -17
  453. package/hooks/hooks.json +0 -73
  454. package/hooks/lib/active-instance.cjs +0 -77
  455. package/hooks/lib/permission-evaluator.cjs +0 -411
  456. package/hooks/lib/permission-route.cjs +0 -63
  457. package/hooks/lib/settings-loader.cjs +0 -117
  458. package/hooks/post-tool-use.cjs +0 -84
  459. package/hooks/pre-mcp-sandbox.cjs +0 -158
  460. package/hooks/pre-tool-subagent.cjs +0 -258
  461. package/hooks/session-start.cjs +0 -1479
  462. package/hooks/shim-launcher.cjs +0 -65
  463. package/hooks/turn-timer.cjs +0 -82
  464. package/lib/claude-md-writer.cjs +0 -386
  465. package/lib/keychain-cjs.cjs +0 -290
  466. package/lib/plugin-paths.cjs +0 -69
  467. package/lib/rules-builder.cjs +0 -241
  468. package/native/README.md +0 -117
  469. package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
  470. package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
  471. package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
  472. package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
  473. package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
  474. package/prompts/code-review.txt +0 -16
  475. package/prompts/security-audit.txt +0 -17
  476. package/rules/bridge/00-common.md +0 -39
  477. package/rules/bridge/20-skip-protocol.md +0 -18
  478. package/rules/bridge/30-explorer.md +0 -33
  479. package/rules/bridge/40-cycle1-agent.md +0 -52
  480. package/rules/bridge/41-cycle2-agent.md +0 -62
  481. package/rules/lead/00-tool-lead.md +0 -61
  482. package/rules/lead/01-general.md +0 -23
  483. package/rules/lead/02-channels.md +0 -49
  484. package/rules/lead/03-team.md +0 -27
  485. package/rules/lead/04-workflow.md +0 -20
  486. package/rules/shared/00-language.md +0 -14
  487. package/rules/shared/01-tool.md +0 -138
  488. package/scripts/bootstrap.mjs +0 -130
  489. package/scripts/bridge-unify-smoke.mjs +0 -308
  490. package/scripts/build-runtime-linux.sh +0 -348
  491. package/scripts/build-runtime-macos.sh +0 -217
  492. package/scripts/build-runtime-windows.ps1 +0 -242
  493. package/scripts/builtin-utils-smoke.mjs +0 -398
  494. package/scripts/bump.mjs +0 -80
  495. package/scripts/check-json.mjs +0 -45
  496. package/scripts/check-syntax-changed.mjs +0 -102
  497. package/scripts/check-syntax.mjs +0 -58
  498. package/scripts/code-graph-batch.test.mjs +0 -33
  499. package/scripts/config-preserve-smoke.mjs +0 -180
  500. package/scripts/doctor.mjs +0 -489
  501. package/scripts/edit-normalize-fuzz.mjs +0 -130
  502. package/scripts/edit-normalize-smoke.mjs +0 -401
  503. package/scripts/edit-operation-smoke.mjs +0 -369
  504. package/scripts/edit2-smoke.mjs +0 -63
  505. package/scripts/ensure-deps.mjs +0 -259
  506. package/scripts/fuzzy-e2e.mjs +0 -28
  507. package/scripts/fuzzy-smoke.mjs +0 -26
  508. package/scripts/generate-runtime-manifest.mjs +0 -166
  509. package/scripts/guard-smoke.mjs +0 -66
  510. package/scripts/hidden-role-schema-smoke.mjs +0 -162
  511. package/scripts/hook-routing-smoke.mjs +0 -29
  512. package/scripts/inject-input.ps1 +0 -204
  513. package/scripts/io-complex-smoke.mjs +0 -667
  514. package/scripts/io-explore-bench.mjs +0 -424
  515. package/scripts/io-guardrails-smoke.mjs +0 -205
  516. package/scripts/io-mini-bench-baseline.json +0 -11
  517. package/scripts/io-mini-bench.mjs +0 -216
  518. package/scripts/io-route-harness.mjs +0 -933
  519. package/scripts/io-telemetry-report.mjs +0 -691
  520. package/scripts/mutation-bench.mjs +0 -564
  521. package/scripts/mutation-io-smoke.mjs +0 -1097
  522. package/scripts/native-patch-bridge-smoke.mjs +0 -288
  523. package/scripts/native-patch-smoke.mjs +0 -304
  524. package/scripts/openai-oauth-catalog-smoke.mjs +0 -53
  525. package/scripts/patch-interior-context-smoke.mjs +0 -49
  526. package/scripts/patch-newline-utf8-smoke.mjs +0 -157
  527. package/scripts/perf-hook-smoke.mjs +0 -71
  528. package/scripts/permission-eval-smoke.mjs +0 -443
  529. package/scripts/prep-patch.mjs +0 -53
  530. package/scripts/prep-shim.mjs +0 -96
  531. package/scripts/provider-cache-smoke.mjs +0 -687
  532. package/scripts/report-runtime-health.mjs +0 -132
  533. package/scripts/resolve-bun.mjs +0 -60
  534. package/scripts/run-mcp.mjs +0 -1448
  535. package/scripts/salvage-v4a-shatter.test.mjs +0 -58
  536. package/scripts/scoped-cache-io-smoke.mjs +0 -103
  537. package/scripts/shell-policy-round3-smoke.mjs +0 -46
  538. package/scripts/smoke-runtime-negative.ps1 +0 -100
  539. package/scripts/smoke-runtime-negative.sh +0 -95
  540. package/scripts/stall-policy-smoke.mjs +0 -50
  541. package/scripts/start-memory-worker.mjs +0 -23
  542. package/scripts/statusline-launcher-smoke.mjs +0 -82
  543. package/scripts/stress-atomic-write.mjs +0 -1028
  544. package/scripts/test-fault-inject.mjs +0 -164
  545. package/scripts/test-large-file.mjs +0 -174
  546. package/scripts/tool-edge-smoke.mjs +0 -209
  547. package/scripts/uninstall.mjs +0 -201
  548. package/scripts/webhook-selfheal-smoke.mjs +0 -27
  549. package/scripts/write-overwrite-guard-smoke.mjs +0 -56
  550. package/server-main.mjs +0 -3109
  551. package/server.mjs +0 -468
  552. package/setup/config-merge.mjs +0 -246
  553. package/setup/install.mjs +0 -574
  554. package/setup/launch-core.mjs +0 -617
  555. package/setup/launch.mjs +0 -101
  556. package/setup/locate-claude.mjs +0 -56
  557. package/setup/mixdog-cli.mjs +0 -122
  558. package/setup/setup-server.mjs +0 -3305
  559. package/setup/setup.html +0 -3740
  560. package/setup/tui.mjs +0 -325
  561. package/skills/retro-skill-proposer/SKILL.md +0 -92
  562. package/skills/schedule-add/SKILL.md +0 -77
  563. package/skills/setup/SKILL.md +0 -356
  564. package/skills/webhook-add/SKILL.md +0 -81
  565. package/src/agent/bridge-stall-watchdog.mjs +0 -337
  566. package/src/agent/index.mjs +0 -2138
  567. package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +0 -1010
  568. package/src/agent/orchestrator/bridge-retry.mjs +0 -220
  569. package/src/agent/orchestrator/bridge-trace.mjs +0 -583
  570. package/src/agent/orchestrator/cache-mtime.mjs +0 -58
  571. package/src/agent/orchestrator/config.mjs +0 -405
  572. package/src/agent/orchestrator/context/collect.mjs +0 -651
  573. package/src/agent/orchestrator/dispatch-persist.mjs +0 -549
  574. package/src/agent/orchestrator/drain-registry.mjs +0 -50
  575. package/src/agent/orchestrator/explore-validator.mjs +0 -8
  576. package/src/agent/orchestrator/internal-roles.mjs +0 -118
  577. package/src/agent/orchestrator/internal-tools.mjs +0 -88
  578. package/src/agent/orchestrator/jobs.mjs +0 -116
  579. package/src/agent/orchestrator/mcp/client.mjs +0 -364
  580. package/src/agent/orchestrator/providers/anthropic-oauth.mjs +0 -1881
  581. package/src/agent/orchestrator/providers/anthropic.mjs +0 -594
  582. package/src/agent/orchestrator/providers/gemini.mjs +0 -1530
  583. package/src/agent/orchestrator/providers/grok-oauth.mjs +0 -779
  584. package/src/agent/orchestrator/providers/model-catalog.mjs +0 -374
  585. package/src/agent/orchestrator/providers/openai-compat-stream.mjs +0 -366
  586. package/src/agent/orchestrator/providers/openai-compat.mjs +0 -1511
  587. package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +0 -1891
  588. package/src/agent/orchestrator/providers/openai-oauth.mjs +0 -1456
  589. package/src/agent/orchestrator/providers/openai-ws.mjs +0 -127
  590. package/src/agent/orchestrator/providers/registry.mjs +0 -192
  591. package/src/agent/orchestrator/providers/retry-classifier.mjs +0 -325
  592. package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +0 -142
  593. package/src/agent/orchestrator/session/cache/read-cache.mjs +0 -319
  594. package/src/agent/orchestrator/session/cache/scoped-cache.mjs +0 -361
  595. package/src/agent/orchestrator/session/loop.mjs +0 -1478
  596. package/src/agent/orchestrator/session/manager.mjs +0 -1991
  597. package/src/agent/orchestrator/session/result-classification.mjs +0 -65
  598. package/src/agent/orchestrator/session/store.mjs +0 -632
  599. package/src/agent/orchestrator/session/stream-watchdog.mjs +0 -130
  600. package/src/agent/orchestrator/session/tool-result-offload.mjs +0 -166
  601. package/src/agent/orchestrator/session/trim.mjs +0 -491
  602. package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +0 -115
  603. package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +0 -331
  604. package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +0 -150
  605. package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +0 -228
  606. package/src/agent/orchestrator/smart-bridge/index.mjs +0 -215
  607. package/src/agent/orchestrator/smart-bridge/profiles.mjs +0 -37
  608. package/src/agent/orchestrator/smart-bridge/registry.mjs +0 -348
  609. package/src/agent/orchestrator/stall-policy.mjs +0 -201
  610. package/src/agent/orchestrator/tool-loop-guard.mjs +0 -75
  611. package/src/agent/orchestrator/tools/bash-session.mjs +0 -722
  612. package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +0 -455
  613. package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -480
  614. package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +0 -256
  615. package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +0 -58
  616. package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +0 -240
  617. package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +0 -113
  618. package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +0 -74
  619. package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +0 -242
  620. package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +0 -211
  621. package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +0 -1364
  622. package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +0 -126
  623. package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +0 -141
  624. package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +0 -194
  625. package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +0 -60
  626. package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +0 -168
  627. package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +0 -173
  628. package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +0 -48
  629. package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +0 -99
  630. package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +0 -193
  631. package/src/agent/orchestrator/tools/builtin/list-tool.mjs +0 -597
  632. package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +0 -110
  633. package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +0 -300
  634. package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +0 -152
  635. package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +0 -118
  636. package/src/agent/orchestrator/tools/builtin/read-open.mjs +0 -190
  637. package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +0 -728
  638. package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +0 -173
  639. package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +0 -602
  640. package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +0 -196
  641. package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +0 -422
  642. package/src/agent/orchestrator/tools/builtin/search-builders.mjs +0 -158
  643. package/src/agent/orchestrator/tools/builtin/search-tool.mjs +0 -869
  644. package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +0 -962
  645. package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +0 -223
  646. package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +0 -206
  647. package/src/agent/orchestrator/tools/builtin/write-tool.mjs +0 -401
  648. package/src/agent/orchestrator/tools/builtin.mjs +0 -503
  649. package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +0 -24
  650. package/src/agent/orchestrator/tools/code-graph.mjs +0 -4095
  651. package/src/agent/orchestrator/tools/cwd-tool.mjs +0 -298
  652. package/src/agent/orchestrator/tools/destructive-warning.mjs +0 -323
  653. package/src/agent/orchestrator/tools/edit-normalize.mjs +0 -603
  654. package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +0 -154
  655. package/src/agent/orchestrator/tools/graph-manifest.json +0 -26
  656. package/src/agent/orchestrator/tools/host-input.mjs +0 -204
  657. package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +0 -143
  658. package/src/agent/orchestrator/tools/patch-manifest.json +0 -26
  659. package/src/agent/orchestrator/tools/patch-tool-defs.mjs +0 -20
  660. package/src/agent/orchestrator/tools/patch.mjs +0 -2754
  661. package/src/agent/orchestrator/tools/progress-message.mjs +0 -118
  662. package/src/agent/orchestrator/tools/shell-command.mjs +0 -865
  663. package/src/agent/orchestrator/tools/shell-policy-imports.mjs +0 -7
  664. package/src/agent/orchestrator/tools/shell-snapshot.mjs +0 -313
  665. package/src/agent/orchestrator/workflow-store.mjs +0 -93
  666. package/src/agent/tool-defs.mjs +0 -103
  667. package/src/channels/backends/discord.mjs +0 -784
  668. package/src/channels/data/voice-runtime-manifest.json +0 -138
  669. package/src/channels/index.mjs +0 -3268
  670. package/src/channels/lib/config.mjs +0 -292
  671. package/src/channels/lib/drop-trace.mjs +0 -71
  672. package/src/channels/lib/event-pipeline.mjs +0 -81
  673. package/src/channels/lib/holidays.mjs +0 -138
  674. package/src/channels/lib/hook-pipe-server.mjs +0 -822
  675. package/src/channels/lib/output-forwarder.mjs +0 -765
  676. package/src/channels/lib/runtime-paths.mjs +0 -517
  677. package/src/channels/lib/scheduler.mjs +0 -723
  678. package/src/channels/lib/session-discovery.mjs +0 -103
  679. package/src/channels/lib/state-file.mjs +0 -68
  680. package/src/channels/lib/status-snapshot.mjs +0 -219
  681. package/src/channels/lib/tool-format.mjs +0 -140
  682. package/src/channels/lib/transcript-discovery.mjs +0 -195
  683. package/src/channels/lib/voice-runtime-fetcher.mjs +0 -734
  684. package/src/channels/lib/webhook.mjs +0 -1318
  685. package/src/channels/tool-defs.mjs +0 -170
  686. package/src/daemon/host.mjs +0 -118
  687. package/src/daemon/mcp-transport.mjs +0 -47
  688. package/src/daemon/session.mjs +0 -100
  689. package/src/daemon/thin-client.mjs +0 -71
  690. package/src/daemon/transport.mjs +0 -163
  691. package/src/memory/data/runtime-manifest.json +0 -40
  692. package/src/memory/index.mjs +0 -3332
  693. package/src/memory/lib/core-memory-store.mjs +0 -330
  694. package/src/memory/lib/embedding-provider.mjs +0 -269
  695. package/src/memory/lib/embedding-worker.mjs +0 -323
  696. package/src/memory/lib/memory-cycle1.mjs +0 -645
  697. package/src/memory/lib/memory-cycle2.mjs +0 -1284
  698. package/src/memory/lib/memory-cycle3.mjs +0 -540
  699. package/src/memory/lib/memory-embed.mjs +0 -299
  700. package/src/memory/lib/memory-ops-policy.mjs +0 -190
  701. package/src/memory/lib/memory-recall-store.mjs +0 -638
  702. package/src/memory/lib/memory.mjs +0 -412
  703. package/src/memory/lib/pg/adapter.mjs +0 -308
  704. package/src/memory/lib/pg/process.mjs +0 -360
  705. package/src/memory/lib/pg/supervisor.mjs +0 -396
  706. package/src/memory/lib/runtime-fetcher.mjs +0 -458
  707. package/src/memory/lib/trace-store.mjs +0 -728
  708. package/src/memory/tool-defs.mjs +0 -79
  709. package/src/search/index.mjs +0 -1173
  710. package/src/search/lib/backends/anthropic-oauth.mjs +0 -98
  711. package/src/search/lib/backends/exa.mjs +0 -50
  712. package/src/search/lib/backends/firecrawl.mjs +0 -61
  713. package/src/search/lib/backends/gemini-api.mjs +0 -83
  714. package/src/search/lib/backends/grok-oauth.mjs +0 -86
  715. package/src/search/lib/backends/index.mjs +0 -150
  716. package/src/search/lib/backends/openai-api.mjs +0 -144
  717. package/src/search/lib/backends/openai-oauth.mjs +0 -102
  718. package/src/search/lib/backends/openai-web-search.mjs +0 -76
  719. package/src/search/lib/backends/tavily.mjs +0 -55
  720. package/src/search/lib/backends/xai-api.mjs +0 -113
  721. package/src/search/lib/config.mjs +0 -192
  722. package/src/search/lib/provider-usage.mjs +0 -67
  723. package/src/search/lib/providers.mjs +0 -47
  724. package/src/search/lib/search-intent.mjs +0 -109
  725. package/src/search/lib/setup-handler.mjs +0 -261
  726. package/src/search/lib/web-tools.mjs +0 -1219
  727. package/src/search/tool-defs.mjs +0 -83
  728. package/src/setup/defender-exclusion.mjs +0 -183
  729. package/src/shared/atomic-file.mjs +0 -436
  730. package/src/shared/config.mjs +0 -372
  731. package/src/shared/daemon-recycle.mjs +0 -108
  732. package/src/shared/disable-claude-builtins.mjs +0 -91
  733. package/src/shared/err-text.mjs +0 -12
  734. package/src/shared/llm/cost.mjs +0 -66
  735. package/src/shared/llm/http-agent.mjs +0 -123
  736. package/src/shared/open-url.mjs +0 -62
  737. package/src/shared/plugin-paths.mjs +0 -58
  738. package/src/shared/schedules-store.mjs +0 -70
  739. package/src/shared/seed.mjs +0 -136
  740. package/src/shared/user-cwd.mjs +0 -225
  741. package/src/shared/user-data-guard.mjs +0 -244
  742. package/src/status/aggregator.mjs +0 -584
  743. package/src/status/server.mjs +0 -413
  744. package/tools.json +0 -1653
  745. /package/{defaults → src/defaults}/cycle3-review-prompt.md +0 -0
  746. /package/{defaults → src/defaults}/memory-promote-prompt.md +0 -0
  747. /package/{hooks → src/hooks}/lib/permission-rules.cjs +0 -0
  748. /package/{lib → src/lib}/config-cjs.cjs +0 -0
  749. /package/{lib → src/lib}/hook-pipe-path.cjs +0 -0
  750. /package/{lib → src/lib}/mixdog-debug.cjs +0 -0
  751. /package/{lib → src/lib}/text-utils.cjs +0 -0
  752. /package/{rules → src/rules}/bridge/42-cycle3-agent.md +0 -0
  753. /package/src/{agent → runtime/agent}/orchestrator/activity-bus.mjs +0 -0
  754. /package/src/{agent → runtime/agent}/orchestrator/providers/anthropic-betas.mjs +0 -0
  755. /package/src/{agent → runtime/agent}/orchestrator/session/abort-lookup.mjs +0 -0
  756. /package/src/{agent → runtime/agent}/orchestrator/session/cache/post-edit-marks.mjs +0 -0
  757. /package/src/{agent → runtime/agent}/orchestrator/session/cache/scoped-cache-outcome.mjs +0 -0
  758. /package/src/{agent → runtime/agent}/orchestrator/session/cache/util.mjs +0 -0
  759. /package/src/{agent → runtime/agent}/orchestrator/session/read-dedup.mjs +0 -0
  760. /package/src/{agent → runtime/agent}/orchestrator/session/save-session-worker.mjs +0 -0
  761. /package/src/{agent → runtime/agent}/orchestrator/smart-bridge/session-builder.mjs +0 -0
  762. /package/src/{agent → runtime/agent}/orchestrator/tools/bash-policy-scan.mjs +0 -0
  763. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/advisory-lock.mjs +0 -0
  764. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/atomic-write.mjs +0 -0
  765. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/binary-file.mjs +0 -0
  766. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/cache-layers.mjs +0 -0
  767. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/cwd-utils.mjs +0 -0
  768. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/device-paths.mjs +0 -0
  769. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -0
  770. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/diff-utils.mjs +0 -0
  771. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/fs-reachability.mjs +0 -0
  772. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/grep-formatting.mjs +0 -0
  773. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/hash-utils.mjs +0 -0
  774. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/list-formatting.mjs +0 -0
  775. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/open-config-tool.mjs +0 -0
  776. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/path-locks.mjs +0 -0
  777. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/path-utils.mjs +0 -0
  778. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-args.mjs +0 -0
  779. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-batch.mjs +0 -0
  780. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-constants.mjs +0 -0
  781. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-image-resize.mjs +0 -0
  782. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-image.mjs +0 -0
  783. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-lines.mjs +0 -0
  784. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-mode-tool.mjs +0 -0
  785. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-range-index.mjs +0 -0
  786. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-ranges.mjs +0 -0
  787. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-special-files.mjs +0 -0
  788. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-tool.mjs +0 -0
  789. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-windows.mjs +0 -0
  790. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/shell-analysis.mjs +0 -0
  791. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/shell-output.mjs +0 -0
  792. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/snapshot-helpers.mjs +0 -0
  793. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/snapshot-validation.mjs +0 -0
  794. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/text-stats.mjs +0 -0
  795. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/windows-roots.mjs +0 -0
  796. /package/src/{agent → runtime/agent}/orchestrator/tools/code-graph-prewarm-worker.mjs +0 -0
  797. /package/src/{agent → runtime/agent}/orchestrator/tools/env-scrub.mjs +0 -0
  798. /package/src/{agent → runtime/agent}/orchestrator/tools/mutation-content-cache.mjs +0 -0
  799. /package/src/{agent → runtime/agent}/orchestrator/tools/mutation-planner.mjs +0 -0
  800. /package/src/{agent → runtime/agent}/orchestrator/tools/next-call-utils.mjs +0 -0
  801. /package/src/{agent → runtime/agent}/orchestrator/tools/result-compression.mjs +0 -0
  802. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-exec-policy.mjs +0 -0
  803. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-policy-danger-target.mjs +0 -0
  804. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-policy.mjs +0 -0
  805. /package/src/{channels → runtime/channels}/lib/cli-worker-host.mjs +0 -0
  806. /package/src/{channels → runtime/channels}/lib/config-lock.mjs +0 -0
  807. /package/src/{channels → runtime/channels}/lib/event-queue.mjs +0 -0
  808. /package/src/{channels → runtime/channels}/lib/executor.mjs +0 -0
  809. /package/src/{channels → runtime/channels}/lib/format.mjs +0 -0
  810. /package/src/{channels → runtime/channels}/lib/interaction-workflows.mjs +0 -0
  811. /package/src/{channels → runtime/channels}/lib/memory-client.mjs +0 -0
  812. /package/src/{channels → runtime/channels}/lib/session-control.mjs +0 -0
  813. /package/src/{channels → runtime/channels}/lib/settings.mjs +0 -0
  814. /package/src/{channels → runtime/channels}/lib/whisper-server.mjs +0 -0
  815. /package/src/{memory → runtime/memory}/lib/agent-ipc.mjs +0 -0
  816. /package/src/{memory → runtime/memory}/lib/bridge-trace-queries.mjs +0 -0
  817. /package/src/{memory → runtime/memory}/lib/llm-worker-host.mjs +0 -0
  818. /package/src/{memory → runtime/memory}/lib/memory-cycle.mjs +0 -0
  819. /package/src/{memory → runtime/memory}/lib/memory-extraction.mjs +0 -0
  820. /package/src/{memory → runtime/memory}/lib/memory-maintenance-store.mjs +0 -0
  821. /package/src/{memory → runtime/memory}/lib/memory-recall-id-patch.mjs +0 -0
  822. /package/src/{memory → runtime/memory}/lib/memory-recall-read-query.mjs +0 -0
  823. /package/src/{memory → runtime/memory}/lib/memory-recall-scope-filter.mjs +0 -0
  824. /package/src/{memory → runtime/memory}/lib/memory-retrievers.mjs +0 -0
  825. /package/src/{memory → runtime/memory}/lib/memory-score.mjs +0 -0
  826. /package/src/{memory → runtime/memory}/lib/memory-text-utils.mjs +0 -0
  827. /package/src/{memory → runtime/memory}/lib/model-profile.mjs +0 -0
  828. /package/src/{memory → runtime/memory}/lib/project-id-resolver.mjs +0 -0
  829. /package/src/{search → runtime/search}/lib/cache.mjs +0 -0
  830. /package/src/{search → runtime/search}/lib/formatter.mjs +0 -0
  831. /package/src/{search → runtime/search}/lib/state.mjs +0 -0
  832. /package/src/{shared → runtime/shared}/abort-controller.mjs +0 -0
  833. /package/src/{shared → runtime/shared}/llm/index.mjs +0 -0
  834. /package/src/{shared → runtime/shared}/llm/pid-cleanup.mjs +0 -0
  835. /package/src/{shared → runtime/shared}/llm/usage-log.mjs +0 -0
  836. /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
- }