mixdog 1.2.2 → 1.2.4

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 (692) hide show
  1. package/README.md +18 -0
  2. package/package.json +2 -1
  3. package/scripts/gate-local.mjs +6 -4
  4. package/scripts/lib/gate-scheduler.mjs +29 -11
  5. package/scripts/probe-provider-catalog.mjs +31 -0
  6. package/scripts/provider-pingpong-live.mjs +599 -0
  7. package/scripts/session-sweep.mjs +5 -25
  8. package/src/agents/advisor/AGENT.md +1 -1
  9. package/src/agents/advisor/agent.json +1 -1
  10. package/src/agents/maintainer/AGENT.md +1 -1
  11. package/src/agents/maintainer/agent.json +1 -1
  12. package/src/agents/reviewer/AGENT.md +2 -4
  13. package/src/agents/security/AGENT.md +1 -2
  14. package/src/agents/writer/AGENT.md +2 -3
  15. package/src/defaults/shipped-history.json +11 -1
  16. package/src/defaults/skills/image/SKILL.md +21 -23
  17. package/src/defaults/skills/setup/SKILL.md +6 -1
  18. package/src/defaults/skills/setup/references/actions.md +44 -22
  19. package/src/defaults/skills/setup/references/surfaces.md +10 -8
  20. package/src/headless-exec.mjs +15 -8
  21. package/src/lib/keychain-cjs.cjs +20 -15
  22. package/src/output-styles/common.md +11 -10
  23. package/src/rules/agent/AGENT.md +6 -4
  24. package/src/rules/lead/LEAD.md +7 -9
  25. package/src/rules/shared/45-destructive.md +4 -0
  26. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
  28. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
  29. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
  30. package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
  31. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
  32. package/src/runtime/agent/orchestrator/config.mjs +5 -0
  33. package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
  34. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
  35. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
  36. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
  37. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
  38. package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
  39. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
  40. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +3 -1
  41. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
  42. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +9 -9
  43. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
  45. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +31 -15
  46. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
  47. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
  48. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
  49. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
  50. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
  51. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
  52. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
  53. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -0
  54. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
  55. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +10 -0
  56. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
  57. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
  58. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +131 -9
  59. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
  60. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +125 -8
  61. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +12 -62
  62. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +117 -41
  63. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  64. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
  65. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
  66. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +39 -5
  67. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  68. package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
  69. package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
  70. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
  71. package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +42 -11
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +109 -6
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +17 -4
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -2
  76. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +73 -7
  77. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +75 -6
  78. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
  79. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
  80. package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
  81. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +29 -5
  82. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
  83. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +36 -13
  84. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +101 -11
  85. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
  86. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
  87. package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
  88. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +19 -14
  89. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +371 -41
  90. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
  91. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +97 -49
  92. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +81 -10
  93. package/src/runtime/agent/orchestrator/providers/gemini.mjs +35 -8
  94. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
  96. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
  97. package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
  98. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +253 -42
  99. package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
  100. package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
  101. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +392 -0
  102. package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
  103. package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
  104. package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
  105. package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
  106. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
  107. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +50 -22
  108. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +133 -21
  109. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
  110. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
  111. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
  112. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  113. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +92 -16
  114. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -13
  115. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
  116. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +133 -62
  117. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
  118. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +5 -2
  119. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +39 -7
  120. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
  121. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
  122. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +1 -1
  123. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +84 -2
  124. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
  125. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
  126. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +155 -0
  127. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +40 -24
  128. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
  129. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
  130. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +183 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +87 -6
  132. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
  133. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
  134. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
  135. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
  136. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
  137. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
  138. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +17 -2
  139. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
  140. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
  141. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
  142. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +28 -5
  143. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
  144. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
  145. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +4 -0
  146. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
  147. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
  148. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
  149. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
  150. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
  151. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
  152. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +72 -24
  153. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
  154. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +50 -16
  155. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -19
  156. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
  157. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -36
  158. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
  159. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
  160. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
  161. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -9
  162. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +181 -0
  163. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +78 -70
  164. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +74 -0
  165. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +150 -10
  166. package/src/runtime/agent/orchestrator/providers/registry.mjs +13 -2
  167. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +7 -1
  168. package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
  169. package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
  170. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +164 -0
  171. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +522 -0
  172. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
  173. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +195 -0
  174. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +104 -0
  175. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
  176. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +24 -0
  177. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
  178. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
  179. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
  180. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
  181. package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
  182. package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
  183. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +16 -3
  184. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
  185. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
  186. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  187. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
  188. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +178 -71
  189. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +102 -12
  190. package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
  191. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
  192. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
  193. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
  194. package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
  195. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
  196. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -11
  197. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
  198. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
  199. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +16 -93
  200. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
  201. package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
  202. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +148 -0
  203. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  204. package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
  205. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
  206. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
  207. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
  208. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +3 -2
  209. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
  210. package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
  211. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
  212. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +89 -1
  213. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
  214. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
  215. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
  216. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -27
  217. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
  218. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
  219. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
  220. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +24 -10
  221. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +135 -0
  222. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +31 -4
  223. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
  224. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
  225. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +10 -10
  226. package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
  227. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
  228. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
  229. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +29 -5
  230. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
  231. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +147 -0
  232. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -5
  233. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
  234. package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
  235. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +23 -2
  236. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
  237. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +54 -13
  238. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
  239. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
  240. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +11 -0
  241. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +22 -0
  242. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
  243. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
  244. package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
  245. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
  246. package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
  247. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +231 -16
  248. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
  249. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
  250. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +47 -17
  251. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +26 -4
  252. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
  253. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +36 -35
  254. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
  255. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +6 -3
  256. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
  257. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
  258. package/src/runtime/agent/orchestrator/session/manager.mjs +4 -10
  259. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
  260. package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
  261. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +17 -1
  262. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
  263. package/src/runtime/agent/orchestrator/session/side-question.mjs +197 -0
  264. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +22 -15
  265. package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
  266. package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
  267. package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
  269. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
  270. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
  271. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
  272. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +44 -37
  273. package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
  274. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
  275. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
  276. package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
  277. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -21
  278. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
  279. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
  280. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
  281. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +4 -2
  282. package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
  283. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
  284. package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
  285. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +53 -115
  286. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
  287. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -1
  288. package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
  289. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
  290. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +17 -10
  291. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
  292. package/src/runtime/agent/orchestrator/session/store.mjs +22 -19
  293. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +12 -12
  294. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +38 -14
  295. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
  296. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
  297. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
  298. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
  299. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +79 -0
  300. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
  301. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
  302. package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
  303. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
  304. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
  305. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
  306. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
  307. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
  308. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +218 -20
  309. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
  310. package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
  311. package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
  312. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
  313. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
  314. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
  315. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
  316. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +247 -49
  317. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
  318. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
  319. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
  320. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
  321. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
  322. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
  323. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
  324. package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
  325. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
  326. package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
  327. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
  328. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
  329. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
  330. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
  331. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
  332. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
  333. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
  334. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
  335. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
  336. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
  337. package/src/runtime/attachments/store.d.mts +9 -0
  338. package/src/runtime/attachments/store.mjs +80 -9
  339. package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
  340. package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
  341. package/src/runtime/computer-bridge/action-schema.mjs +219 -196
  342. package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
  343. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
  344. package/src/runtime/effort-judge/judge-client.mjs +21 -4
  345. package/src/runtime/effort-judge/judge-worker.mjs +4 -1
  346. package/src/runtime/github/tool.mjs +208 -17
  347. package/src/runtime/media/adapters/codex-image.mjs +140 -21
  348. package/src/runtime/media/catalog.mjs +4 -4
  349. package/src/runtime/media/chatgpt-usage.mjs +55 -0
  350. package/src/runtime/media/defaults.mjs +37 -0
  351. package/src/runtime/media/jobs.mjs +12 -2
  352. package/src/runtime/media/lanes.mjs +12 -0
  353. package/src/runtime/media/tool-defs.mjs +15 -4
  354. package/src/runtime/media/tool.mjs +41 -12
  355. package/src/runtime/media/upstream-error.mjs +72 -6
  356. package/src/runtime/memory/index.mjs +1 -0
  357. package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
  358. package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
  359. package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
  360. package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
  361. package/src/runtime/memory/lib/pg/process.mjs +36 -33
  362. package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
  363. package/src/runtime/memory/lib/pg/supervisor.mjs +112 -4
  364. package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
  365. package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
  366. package/src/runtime/office/README.md +1 -1
  367. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  368. package/src/runtime/office/authoring/html-browser.mjs +18 -8
  369. package/src/runtime/office/authoring/html-document-author.mjs +2 -0
  370. package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
  371. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
  372. package/src/runtime/office/authoring/pptx-html-measure.mjs +3 -1
  373. package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
  374. package/src/runtime/office/authoring/xlsx-html-runner.mjs +3 -1
  375. package/src/runtime/office/core/office-actions-read.mjs +3 -0
  376. package/src/runtime/office/core/office-render-preview.mjs +2 -0
  377. package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
  378. package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
  379. package/src/runtime/office/core/office-sessions.mjs +5 -0
  380. package/src/runtime/office/core/office-transactions.mjs +3 -0
  381. package/src/runtime/office/core/office-write-ledger.mjs +94 -0
  382. package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
  383. package/src/runtime/office/index.mjs +29 -0
  384. package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
  385. package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
  386. package/src/runtime/office/pdf/pdf-render.mjs +23 -7
  387. package/src/runtime/office/pdf/pdf-security.mjs +2 -0
  388. package/src/runtime/office/portable/portable-opc.mjs +4 -1
  389. package/src/runtime/office/quality/visual-diff.mjs +2 -0
  390. package/src/runtime/session-search/session-search-ingest.mjs +1 -1
  391. package/src/runtime/shared/agent-reap-state.mjs +13 -0
  392. package/src/runtime/shared/atomic-file.d.mts +1 -1
  393. package/src/runtime/shared/background-tasks.mjs +6 -1
  394. package/src/runtime/shared/bounded-file-read.mjs +13 -0
  395. package/src/runtime/shared/bounded-line-diff.mjs +191 -0
  396. package/src/runtime/shared/browser-launch.mjs +15 -0
  397. package/src/runtime/shared/buffered-appender.mjs +18 -0
  398. package/src/runtime/shared/config.mjs +78 -18
  399. package/src/runtime/shared/err-text.mjs +48 -4
  400. package/src/runtime/shared/file-lock.mjs +6 -5
  401. package/src/runtime/shared/file-permissions.d.mts +6 -1
  402. package/src/runtime/shared/file-permissions.mjs +54 -6
  403. package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
  404. package/src/runtime/shared/llm/anthropic-effort.mjs +6 -0
  405. package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
  406. package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
  407. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
  408. package/src/runtime/shared/loopback-listener.mjs +9 -0
  409. package/src/runtime/shared/model-route-chain.d.mts +8 -0
  410. package/src/runtime/shared/model-route-chain.mjs +48 -0
  411. package/src/runtime/shared/model-route-fallback.mjs +22 -0
  412. package/src/runtime/shared/pid-liveness.mjs +12 -0
  413. package/src/runtime/shared/provider-api-key.mjs +8 -0
  414. package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
  415. package/src/runtime/shared/quiet-progress.d.mts +35 -0
  416. package/src/runtime/shared/quiet-progress.mjs +101 -0
  417. package/src/runtime/shared/quota-resume-store.mjs +32 -1
  418. package/src/runtime/shared/read-row-numbers.mjs +44 -0
  419. package/src/runtime/shared/remote-intent.mjs +2 -42
  420. package/src/runtime/shared/review-diff.mjs +52 -0
  421. package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
  422. package/src/runtime/shared/session-sidebar-host.mjs +38 -0
  423. package/src/runtime/shared/slow-span.mjs +121 -0
  424. package/src/runtime/shared/statusline/statusline-segments.mjs +52 -6
  425. package/src/runtime/shared/tool-card-model/card-header.mjs +7 -1
  426. package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
  427. package/src/runtime/shared/tool-card-model.mjs +5 -2
  428. package/src/runtime/shared/tool-output-budget.mjs +2 -0
  429. package/src/runtime/shared/tool-output-limit.mjs +4 -0
  430. package/src/runtime/shared/tool-primitives.mjs +13 -0
  431. package/src/runtime/shared/tool-result-summary.mjs +22 -1
  432. package/src/runtime/shared/tool-status.mjs +3 -2
  433. package/src/runtime/shared/tool-surface.mjs +20 -6
  434. package/src/runtime/shared/tool-work-units.mjs +54 -11
  435. package/src/runtime/shared/transcript-metadata.mjs +49 -1
  436. package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
  437. package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
  438. package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
  439. package/src/runtime/shared/transcript-writer.mjs +24 -6
  440. package/src/runtime/shared/turn-changes.mjs +269 -100
  441. package/src/runtime/shared/turn-review-reply.mjs +8 -39
  442. package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
  443. package/src/runtime/shared/turn-snapshot.mjs +865 -683
  444. package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
  445. package/src/runtime/shared/user-data-guard.mjs +262 -49
  446. package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
  447. package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
  448. package/src/runtime/shared/worktrees/carry.mjs +533 -0
  449. package/src/runtime/shared/worktrees/contract.mjs +60 -0
  450. package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
  451. package/src/runtime/shared/worktrees/file-recovery.mjs +84 -0
  452. package/src/runtime/shared/worktrees/git-head.mjs +214 -0
  453. package/src/runtime/shared/worktrees/git.mjs +8 -3
  454. package/src/runtime/shared/worktrees/include.mjs +125 -7
  455. package/src/runtime/shared/worktrees/lock.mjs +1 -1
  456. package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
  457. package/src/runtime/shared/worktrees/manager.mjs +525 -31
  458. package/src/runtime/shared/worktrees/merge.mjs +31 -21
  459. package/src/runtime/shared/worktrees/owner.mjs +2 -1
  460. package/src/runtime/shared/worktrees/paths.d.mts +6 -0
  461. package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
  462. package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
  463. package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
  464. package/src/runtime/terminal-bridge/client.mjs +57 -20
  465. package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
  466. package/src/runtime/tidy/apply.mjs +47 -2
  467. package/src/runtime/tidy/run-engines.mjs +11 -5
  468. package/src/session-runtime/agent-tool-routing.mjs +19 -13
  469. package/src/session-runtime/boot/apis.mjs +20 -6
  470. package/src/session-runtime/boot/config.mjs +2 -0
  471. package/src/session-runtime/boot/facade.mjs +4 -0
  472. package/src/session-runtime/boot/infrastructure.mjs +6 -1
  473. package/src/session-runtime/boot/session.mjs +3 -3
  474. package/src/session-runtime/boot/tools.mjs +7 -1
  475. package/src/session-runtime/conversation-import/service.mjs +1 -1
  476. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
  477. package/src/session-runtime/goal-facade-api.mjs +2 -2
  478. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +91 -0
  479. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
  480. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +15 -5
  481. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +137 -26
  482. package/src/session-runtime/internal-tool-executor.mjs +8 -2
  483. package/src/session-runtime/lifecycle/cold-heir.mjs +187 -0
  484. package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
  485. package/src/session-runtime/lifecycle/session-catalog.mjs +25 -18
  486. package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
  487. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +36 -48
  488. package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
  489. package/src/session-runtime/lifecycle/shared.mjs +5 -6
  490. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
  491. package/src/session-runtime/lifecycle/teardown.mjs +70 -14
  492. package/src/session-runtime/lifecycle-api.mjs +1 -0
  493. package/src/session-runtime/mcp-glue/connect.mjs +17 -5
  494. package/src/session-runtime/media-api.mjs +8 -0
  495. package/src/session-runtime/model-route/route-ownership.mjs +60 -0
  496. package/src/session-runtime/model-route/route-persist.mjs +3 -2
  497. package/src/session-runtime/model-route/set-route.mjs +116 -36
  498. package/src/session-runtime/model-route/web-search-route.mjs +7 -2
  499. package/src/session-runtime/model-route-api.mjs +4 -2
  500. package/src/session-runtime/native-web-search/routes.mjs +37 -24
  501. package/src/session-runtime/native-web-search-usage.mjs +51 -0
  502. package/src/session-runtime/native-web-search.mjs +19 -9
  503. package/src/session-runtime/new-session-config.mjs +4 -2
  504. package/src/session-runtime/provider-auth/login.mjs +4 -0
  505. package/src/session-runtime/provider-auth/setup.mjs +4 -0
  506. package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
  507. package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
  508. package/src/session-runtime/provider-models.mjs +1 -0
  509. package/src/session-runtime/provider-usage.mjs +4 -0
  510. package/src/session-runtime/resource-scope-decorate.mjs +10 -3
  511. package/src/session-runtime/route-resolution.mjs +3 -1
  512. package/src/session-runtime/runtime-core.mjs +4 -0
  513. package/src/session-runtime/runtime-facade.mjs +6 -0
  514. package/src/session-runtime/runtime-review-api.mjs +8 -2
  515. package/src/session-runtime/services/agent-task-status.mjs +2 -0
  516. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
  517. package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
  518. package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
  519. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
  520. package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
  521. package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
  522. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
  523. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
  524. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
  525. package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
  526. package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
  527. package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
  528. package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
  529. package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
  530. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +82 -13
  531. package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
  532. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
  533. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
  534. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
  535. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
  536. package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
  537. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  538. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
  539. package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
  540. package/src/session-runtime/services/agent-tool/tag-registry.mjs +18 -10
  541. package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
  542. package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
  543. package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
  544. package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
  545. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  546. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
  547. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
  548. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
  549. package/src/session-runtime/services/agent-tool/worker-index.mjs +74 -15
  550. package/src/session-runtime/services/agent-tool.mjs +7 -0
  551. package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
  552. package/src/session-runtime/services/channel-admin.mjs +19 -3
  553. package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
  554. package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
  555. package/src/session-runtime/services/provider-admin.mjs +158 -15
  556. package/src/session-runtime/session-create/session-options.mjs +7 -5
  557. package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
  558. package/src/session-runtime/session-transcript-purge.mjs +32 -0
  559. package/src/session-runtime/session-transcript.mjs +4 -5
  560. package/src/session-runtime/session-turn-api.mjs +17 -14
  561. package/src/session-runtime/settings-builtin-tools-api.mjs +18 -6
  562. package/src/session-runtime/setup-tool/executor.mjs +57 -9
  563. package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
  564. package/src/session-runtime/setup-tool/settings-contract.mjs +18 -3
  565. package/src/session-runtime/setup-tool/tool-defs.mjs +25 -4
  566. package/src/session-runtime/skills-api.mjs +3 -5
  567. package/src/session-runtime/tool-policy-refresh.mjs +83 -32
  568. package/src/session-runtime/tool-surface.mjs +5 -1
  569. package/src/session-runtime/turn/agent-ops.mjs +49 -2
  570. package/src/session-runtime/turn/compaction-gate.mjs +25 -0
  571. package/src/session-runtime/turn/session-ops.mjs +7 -5
  572. package/src/session-runtime/turn/side-question-ops.mjs +19 -0
  573. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +7 -1
  574. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +12 -3
  575. package/src/session-runtime/turn/turn-run/turn-settle.mjs +18 -2
  576. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  577. package/src/session-runtime/turn/turn-run.mjs +26 -45
  578. package/src/session-runtime/usage-stats-api.mjs +46 -11
  579. package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
  580. package/src/session-runtime/workspace/admission-gate.mjs +44 -15
  581. package/src/session-runtime/workspace/project-branches.mjs +35 -41
  582. package/src/session-runtime/workspace/transition-steps.mjs +215 -116
  583. package/src/session-runtime/workspace/transitions.mjs +428 -73
  584. package/src/standalone/channel-transport.mjs +3 -4
  585. package/src/standalone/daemon-agent-control.mjs +9 -1
  586. package/src/standalone/daemon-desktop-runtime.mjs +32 -1
  587. package/src/standalone/daemon-local-session-bridge.mjs +14 -1
  588. package/src/standalone/daemon-owner.mjs +17 -4
  589. package/src/standalone/daemon-pg-stop.mjs +49 -0
  590. package/src/standalone/daemon-session-control.mjs +88 -0
  591. package/src/standalone/daemon-stop-budget.d.mts +2 -0
  592. package/src/standalone/daemon-stop-budget.mjs +18 -0
  593. package/src/standalone/daemon-stored-session-views.mjs +25 -3
  594. package/src/standalone/daemon-telemetry.mjs +19 -0
  595. package/src/standalone/daemon.mjs +63 -1
  596. package/src/standalone/desktop-service-registry.mjs +5 -0
  597. package/src/standalone/local-session-runtime.mjs +80 -30
  598. package/src/standalone/session-client.mjs +42 -0
  599. package/src/standalone/session-protocol.mjs +14 -0
  600. package/src/standalone/session-proxy/projection.mjs +41 -4
  601. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
  602. package/src/standalone/session-runtime-inline-host.mjs +3 -0
  603. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
  604. package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
  605. package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
  606. package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
  607. package/src/standalone/session-service/agent-tree.mjs +28 -2
  608. package/src/standalone/session-service/entries/session-loads.mjs +16 -5
  609. package/src/standalone/session-service/entries.mjs +1 -0
  610. package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
  611. package/src/standalone/session-service/quota-resume.mjs +28 -13
  612. package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
  613. package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
  614. package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
  615. package/src/standalone/session-service-api.mjs +6 -1
  616. package/src/standalone/session-state-patch.d.mts +2 -1
  617. package/src/standalone/session-state-patch.mjs +41 -1
  618. package/src/standalone/session-tool-output.mjs +82 -0
  619. package/src/tui/App.jsx +25 -0
  620. package/src/tui/app/app-view/floating-panel.jsx +26 -1
  621. package/src/tui/app/app-view.jsx +2 -1
  622. package/src/tui/app/btw-controller.mjs +118 -0
  623. package/src/tui/app/create-app-pickers.mjs +2 -0
  624. package/src/tui/app/provider-setup/provider-items.mjs +8 -0
  625. package/src/tui/app/provider-setup-picker.mjs +15 -3
  626. package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
  627. package/src/tui/app/shell-layout/surfaces.mjs +3 -1
  628. package/src/tui/app/slash-commands.mjs +19 -3
  629. package/src/tui/app/slash-dispatch/session-commands.mjs +68 -6
  630. package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
  631. package/src/tui/app/use-global-key-input.mjs +5 -12
  632. package/src/tui/app/use-prompt-handlers.mjs +11 -0
  633. package/src/tui/components/BtwPanel.jsx +53 -0
  634. package/src/tui/components/QuestionPanel.jsx +275 -0
  635. package/src/tui/components/Spinner.jsx +4 -0
  636. package/src/tui/components/SpinnerByline.jsx +21 -2
  637. package/src/tui/components/question-panel-model.mjs +156 -0
  638. package/src/tui/components/status-line/local-line.mjs +10 -2
  639. package/src/tui/dist/index.mjs +2897 -1722
  640. package/src/tui/session/active-tool-summary.mjs +1 -1
  641. package/src/tui/session/context-state.mjs +4 -5
  642. package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
  643. package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
  644. package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
  645. package/src/tui/session/quota-resume.mjs +140 -61
  646. package/src/tui/session/session-api/commands.mjs +14 -10
  647. package/src/tui/session/session-api/controls.mjs +14 -2
  648. package/src/tui/session/session-api/integrations.mjs +9 -2
  649. package/src/tui/session/session-api/lifecycle/dispose.mjs +3 -9
  650. package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
  651. package/src/tui/session/session-api/lifecycle.mjs +14 -11
  652. package/src/tui/session/session-api/media.mjs +2 -0
  653. package/src/tui/session/session-api/routes.mjs +81 -57
  654. package/src/tui/session/session-api/settings.mjs +9 -3
  655. package/src/tui/session/session-api/worktree.mjs +3 -2
  656. package/src/tui/session/session-api.mjs +1 -0
  657. package/src/tui/session/session-flow/auto-clear.mjs +1 -3
  658. package/src/tui/session/session-flow/drain.mjs +6 -4
  659. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
  660. package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
  661. package/src/tui/session/session-flow/queue.mjs +1 -1
  662. package/src/tui/session/tool-approval.mjs +20 -8
  663. package/src/tui/session/transcript-spill.mjs +14 -7
  664. package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
  665. package/src/tui/session/tui-steering-persist.mjs +3 -5
  666. package/src/tui/session/turn-quiet.mjs +53 -0
  667. package/src/tui/session/turn-stream.mjs +179 -32
  668. package/src/tui/session/turn.mjs +50 -36
  669. package/src/tui/session/worktree-setup-notice.mjs +38 -0
  670. package/src/tui/spinner-meta.mjs +10 -0
  671. package/src/tui/spinner-verbs.mjs +3 -0
  672. package/src/ui/statusline.mjs +13 -3
  673. package/src/workflows/default/WORKFLOW.md +3 -1
  674. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
  675. package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
  676. package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
  677. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -246
  678. package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
  679. package/src/session-runtime/turn/share-ops.mjs +0 -77
  680. package/src/tui/session/cross-surface-share.mjs +0 -406
  681. package/src/tui/session/live-share/delta.mjs +0 -153
  682. package/src/tui/session/live-share/mirror.mjs +0 -106
  683. package/src/tui/session/live-share/owner.mjs +0 -254
  684. package/src/tui/session/live-share/retry.mjs +0 -54
  685. package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
  686. package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
  687. package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
  688. package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
  689. package/src/tui/session/live-share/viewer.mjs +0 -99
  690. package/src/tui/session/live-share/wire.mjs +0 -44
  691. package/src/tui/session/live-share.mjs +0 -154
  692. package/src/tui/session/shared-dir-watch.mjs +0 -69
@@ -3,11 +3,72 @@
3
3
  * to the shared stream state and relayed to the SSE sink. Returns the
4
4
  * message's forward-progress kind for the watchdog.
5
5
  */
6
+ import { randomUUID } from 'node:crypto';
7
+ import { registerCursorNativeCall } from './cursor-native-context.mjs';
8
+ import { appendAgentTrace } from '../agent-trace.mjs';
6
9
  import { decodeMessage } from './cursor-wire-protobuf.mjs';
7
10
  import { MAX_CHECKPOINT_BYTES, cursorInteractionProgress } from './cursor-wire-guards.mjs';
8
11
  import { buildCursorInteractionResponse } from './cursor-wire-interactions.mjs';
9
12
  import { cursorError } from './cursor-wire-transport.mjs';
10
- import { handleExecMessage, handleKvMessage, sendClientMessage } from './cursor-wire-exec.mjs';
13
+ import { handleExecMessage, handleKvMessage, sendClientMessage, sendToolResult } from './cursor-wire-exec.mjs';
14
+
15
+ // Unknown fields seen on every live frame: AgentServerMessage field 8 (timing
16
+ // doubles) and InteractionUpdate field 25 (epoch-ms timestamp). Never traced.
17
+ const NOISE_SERVER_FIELDS = new Set([8]);
18
+ const NOISE_UPDATE_FIELDS = new Set([25]);
19
+ const TRACE_MAX_FIELDS = 8;
20
+ const TRACE_PREVIEW_BYTES = 48;
21
+
22
+ // Records undecoded fields (number, wire type, bounded hex of the raw field)
23
+ // so a new server event such as a mid-turn model fallback can be inspected.
24
+ function traceUnknownFields(trace, sessionId, scope, unknown, noise) {
25
+ const fields = unknown?.filter((field) => !noise.has(field.no));
26
+ if (!fields?.length) return;
27
+ try {
28
+ trace({
29
+ sessionId,
30
+ kind: 'cursor_unknown_field',
31
+ provider: 'cursor',
32
+ payload: {
33
+ scope,
34
+ count: fields.length,
35
+ fields: fields.slice(0, TRACE_MAX_FIELDS).map((field) => ({
36
+ no: field.no,
37
+ wire_type: field.wireType,
38
+ bytes: field.data.byteLength,
39
+ preview_hex: Buffer.from(field.data.subarray(0, TRACE_PREVIEW_BYTES)).toString('hex'),
40
+ })),
41
+ },
42
+ });
43
+ } catch {
44
+ /* best-effort */
45
+ }
46
+ }
47
+
48
+ // Parent edit outcomes are diagnostics, not executable calls or read results.
49
+ function traceNativeEditFailure(trace, sessionId, update) {
50
+ const completed = update.toolCallCompleted;
51
+ const result = completed?.toolCall?.editToolCall?.result;
52
+ if (!result) return;
53
+ const outcome = ['fileNotFound', 'readPermissionDenied', 'writePermissionDenied', 'rejected', 'error'].find(
54
+ (key) => result[key] !== undefined
55
+ );
56
+ if (!outcome) return;
57
+ try {
58
+ trace({
59
+ sessionId,
60
+ kind: 'cursor_native_edit_failure',
61
+ provider: 'cursor',
62
+ payload: {
63
+ callId: (completed.callId || '').slice(0, 256),
64
+ modelCallId: (completed.modelCallId || '').slice(0, 256),
65
+ outcome,
66
+ },
67
+ });
68
+ } catch {
69
+ /* best-effort */
70
+ }
71
+ }
11
72
 
12
73
  // Relays one interaction update to the SSE stream and returns its progress.
13
74
  function applyInteractionUpdate(update, state, filter, emit) {
@@ -45,9 +106,32 @@ function applyCheckpointUpdate(update, conversation, state) {
45
106
  }
46
107
 
47
108
  // Announces a newly pending native/MCP tool call as a completion chunk once.
48
- function announcePendingToolCall(state, pending, emit) {
49
- if (state.pending.some((entry) => entry.toolCallId === pending.toolCallId)) return;
109
+ function announcePendingToolCall(state, pending, emit, bridge, ownerSessionId) {
110
+ state.executions ??= new Map();
111
+ const executions = state.executions;
112
+ const execId = pending.exec.execId ?? pending.exec.id;
113
+ const previous = execId !== undefined ? executions.get(execId) : undefined;
114
+ if (previous) {
115
+ if (previous.completedResult) {
116
+ sendToolResult(
117
+ bridge,
118
+ { ...previous, exec: pending.exec },
119
+ previous.completedResult.result,
120
+ previous.completedResult.ok
121
+ );
122
+ }
123
+ return;
124
+ }
125
+ // A parent call can issue distinct executions; each needs its own local result.
126
+ if ([...executions.values(), ...state.pending].some((entry) => entry.toolCallId === pending.toolCallId)) {
127
+ pending.toolCallId = randomUUID();
128
+ }
129
+ if (execId !== undefined) executions.set(execId, pending);
130
+ registerCursorNativeCall(ownerSessionId, pending, executions);
50
131
  state.pending.push(pending);
132
+ // Native execs may await their result before the server completes a step.
133
+ // The bridge hands off only after all currently received frames are whole.
134
+ if (pending.native) state.batchBoundaryReady = true;
51
135
  emit({
52
136
  tool_calls: [
53
137
  {
@@ -62,11 +146,30 @@ function announcePendingToolCall(state, pending, emit) {
62
146
 
63
147
  /**
64
148
  * @param {Uint8Array} bytes one Connect frame payload
65
- * @param {object} ctx { state, filter, emit, conversation, tools, cloudRule, bridge }
149
+ * @param {object} ctx { state, filter, emit, conversation, tools, cloudRule, bridge, sessionId?, trace? }
66
150
  * @returns {'work'|'park'|'none'|string} progress kind for the watchdog
67
151
  */
68
- export function processServerMessage(bytes, { state, filter, emit, conversation, tools, cloudRule, bridge }) {
152
+ export function processServerMessage(
153
+ bytes,
154
+ {
155
+ state,
156
+ filter,
157
+ emit,
158
+ conversation,
159
+ tools,
160
+ cloudRule,
161
+ bridge,
162
+ sessionId = '',
163
+ ownerSessionId = '',
164
+ trace = appendAgentTrace,
165
+ }
166
+ ) {
69
167
  const message = decodeMessage('AgentServerMessage', bytes);
168
+ traceUnknownFields(trace, sessionId, 'agent_server_message', message.$unknown, NOISE_SERVER_FIELDS);
169
+ if (message.interactionUpdate) {
170
+ traceUnknownFields(trace, sessionId, 'interaction_update', message.interactionUpdate.$unknown, NOISE_UPDATE_FIELDS);
171
+ traceNativeEditFailure(trace, sessionId, message.interactionUpdate);
172
+ }
70
173
  if (message.interactionUpdate) return applyInteractionUpdate(message.interactionUpdate, state, filter, emit);
71
174
  if (message.kvServerMessage) {
72
175
  handleKvMessage(bridge, message.kvServerMessage, conversation);
@@ -78,7 +181,7 @@ export function processServerMessage(bytes, { state, filter, emit, conversation,
78
181
  }
79
182
  if (message.execServerMessage) {
80
183
  const handled = handleExecMessage(bridge, message.execServerMessage, tools, cloudRule, (pending) =>
81
- announcePendingToolCall(state, pending, emit)
184
+ announcePendingToolCall(state, pending, emit, bridge, ownerSessionId)
82
185
  );
83
186
  return handled === false ? 'park' : 'work';
84
187
  }
@@ -42,6 +42,7 @@ import {
42
42
  import { handleExecMessage, heartbeatFrame, sendToolResult } from './cursor-wire-exec.mjs';
43
43
  import { completionChunk, createStreamSink } from './cursor-wire-stream-sink.mjs';
44
44
  import { createBridgeController } from './cursor-wire-stream-bridge.mjs';
45
+ import { TRANSPORT_SCOPE_DISPOSED } from './transport-scope.mjs';
45
46
 
46
47
  export { clearModelCache, getCursorModels, getCursorUsage } from './cursor-wire-models.mjs';
47
48
 
@@ -117,6 +118,8 @@ globalThis.__mixdogCloseProviderConnectionsForSession = (sessionId, reason) => {
117
118
  _priorCursorSessionCloseHook?.(sessionId, reason);
118
119
  } finally {
119
120
  closeCursorRunsForSession(sessionId, reason);
121
+ // A disposed transport scope never sends again: drop its conversation.
122
+ if (reason === TRANSPORT_SCOPE_DISPOSED && sessionId) conversations.delete(conversationKey([], sessionId));
120
123
  }
121
124
  };
122
125
  const _priorCursorDrainHook = globalThis.__mixdogDrainProviderConnections;
@@ -325,11 +328,12 @@ function createPendingToolBatchResponse(active, model, key) {
325
328
  }
326
329
 
327
330
  // Stream state shared by the sink, the message router and the bridge controller.
328
- function freshStreamState(sawTurnEnded) {
331
+ function freshStreamState(sawTurnEnded, executions) {
329
332
  return {
330
333
  outputTokens: 0,
331
334
  contextTokens: null,
332
335
  pending: [],
336
+ executions,
333
337
  closed: false,
334
338
  sawEnd: false,
335
339
  sawTurnEnded: sawTurnEnded === true,
@@ -357,7 +361,9 @@ function createStreamResponse({
357
361
  // Owning session, carried into the stored run so a session close can find
358
362
  // and tear down the pending batch's bridge/heartbeat.
359
363
  sessionId = '',
364
+ ownerSessionId = sessionId,
360
365
  sawTurnEnded = false,
366
+ executions = new Map(),
361
367
  restart = null,
362
368
  sleep = undefined,
363
369
  onStageChange = null,
@@ -373,7 +379,7 @@ function createStreamResponse({
373
379
  const stream = new ReadableStream({
374
380
  start(controller) {
375
381
  const filter = thinkingFilter();
376
- const state = freshStreamState(sawTurnEnded);
382
+ const state = freshStreamState(sawTurnEnded, executions);
377
383
  const tuning = resolveCursorStreamTuning();
378
384
  watchdog = createCursorStreamWatchdog({
379
385
  idleTimeoutMs: tuning.idleTimeoutMs,
@@ -397,7 +403,7 @@ function createStreamResponse({
397
403
  watchdog,
398
404
  sink,
399
405
  tuning,
400
- run: { key, conversation, tools, cloudRule, modelParameters, maxMode, sessionId },
406
+ run: { key, conversation, tools, cloudRule, modelParameters, maxMode, sessionId, ownerSessionId },
401
407
  runs,
402
408
  restart,
403
409
  sleep,
@@ -446,6 +452,7 @@ function resumeRun(active, toolResults, userText, model, key) {
446
452
  }
447
453
  const payload = { ...result, content: String(result.content ?? '') };
448
454
  if (pendingUserText && pending.exec.execId === lastExecId) {
455
+ if (pending.native?.resultType === 'readResult') pending.nativeUserMessage = pendingUserText;
449
456
  payload.content += `\n\n<user_message>\n${pendingUserText}\n</user_message>`;
450
457
  userTextDelivered = true;
451
458
  }
@@ -468,7 +475,11 @@ function noUserMessageResponse() {
468
475
  });
469
476
  }
470
477
 
471
- export async function handleChatCompletion(body, accessToken, { onStageChange = null, getAccessToken = null } = {}) {
478
+ export async function handleChatCompletion(
479
+ body,
480
+ accessToken,
481
+ { onStageChange = null, getAccessToken = null, resetActiveRun = false, ownerSessionId = '' } = {}
482
+ ) {
472
483
  await warmCursorClientVersion();
473
484
  const parsed = parseMessages(body.messages);
474
485
  if (
@@ -489,6 +500,7 @@ export async function handleChatCompletion(body, accessToken, { onStageChange =
489
500
  const cloudRule = parsed.systems.join('\n\n') || undefined;
490
501
  const active = activeRuns.get(key);
491
502
  if (
503
+ !resetActiveRun &&
492
504
  active &&
493
505
  parsed.toolResults.length &&
494
506
  active.bridge.alive &&
@@ -528,6 +540,7 @@ export async function handleChatCompletion(body, accessToken, { onStageChange =
528
540
  maxMode,
529
541
  key,
530
542
  sessionId,
543
+ ownerSessionId,
531
544
  onStageChange,
532
545
  restart: async ({ fromCheckpoint, reason, error }) => {
533
546
  if (reason === 'throttle') {
@@ -12,6 +12,7 @@ import { preparePdfTextForProvider } from './media-normalization.mjs';
12
12
  import { consumeCompatChatCompletionStream } from './openai-compat-stream.mjs';
13
13
  import { retryAfterMsFromError } from './retry-classifier.mjs';
14
14
  import { ensureChatToolPairs } from './lib/wire-pairing.mjs';
15
+ import { acceptedWireTools } from './lib/claude-bridge-schema.mjs';
15
16
  import { cursorTokenExpiry, exchangeCursorToken, resolveCursorOAuthAccessToken } from './cursor-auth.mjs';
16
17
  import {
17
18
  canonicalCursorModelId,
@@ -48,6 +49,7 @@ function toCursorMessages(messages, providerName, { nativePdf } = {}) {
48
49
  ...toolMessage,
49
50
  mixdog_tool_error: message.toolKind === 'error' || message.isError === true,
50
51
  ...(media.length ? { mixdog_tool_media: media } : {}),
52
+ ...(message.readWindow?.lineClipped === true ? { mixdog_read_window: { lineClipped: true } } : {}),
51
53
  });
52
54
  }
53
55
  return output;
@@ -544,6 +546,9 @@ function selectCursorVariant(group, { effort = null, fast = false } = {}) {
544
546
  class CursorProviderBase {
545
547
  // Cursor's chat wire has no document block: PDFs lower to text.
546
548
  nativePdf = false;
549
+ // Native read results are judged as exact source windows, so the tool
550
+ // finalizer reports their clipped lines next to the text.
551
+ consumesReadWindows = true;
547
552
 
548
553
  static inputExcludesCache = false;
549
554
  // The in-place stream retry budget is the whole recovery: a spent budget
@@ -639,6 +644,13 @@ class CursorProviderBase {
639
644
  const response = await runtime.handleChatCompletion(body, accessToken, {
640
645
  onStageChange: sendOpts.onStageChange,
641
646
  getAccessToken: (options) => this._accessToken({ signal, ...options }),
647
+ // A deliberate history reset must reach Cursor's private parked run,
648
+ // not just the orchestrator's providerState.
649
+ resetActiveRun: Boolean(sendOpts.cacheBreakIntent),
650
+ // Native read/edit capabilities are process-local. An explicit empty
651
+ // executor (the model-proxy host: tools run in the server daemon)
652
+ // keeps every call an ordinary Mixdog tool call.
653
+ ownerSessionId: String(sendOpts.toolExecutionSessionId ?? (sendOpts.sessionId || '')),
642
654
  });
643
655
  try {
644
656
  sendOpts.onStageChange?.('streaming');
@@ -693,10 +705,18 @@ class CursorProviderBase {
693
705
  const runtime = await this._runtime();
694
706
  let accessToken = await this._accessToken({ signal });
695
707
  let cursorSelection = await this._resolveCursorModel(model, sendOpts, runtime, accessToken);
708
+ // The Cursor run and conversation (checkpoint, pending tool batch) live
709
+ // under this scope; a forked request keeps its own (transport-scope.mjs).
696
710
  const sessionScope = String(
697
- sendOpts.sessionId || sendOpts.providerCacheKey || sendOpts.promptCacheKey || `cursor-call:${randomUUID()}`
711
+ sendOpts.transportScope ||
712
+ sendOpts.sessionId ||
713
+ sendOpts.providerCacheKey ||
714
+ sendOpts.promptCacheKey ||
715
+ `cursor-call:${randomUUID()}`
698
716
  );
699
- const openAiTools = tools?.length ? toOpenAITools(tools) : undefined;
717
+ const openAiTools = tools?.length
718
+ ? toOpenAITools(acceptedWireTools(tools, 'openai', sendOpts.onToolExcluded, '[cursor] tool'))
719
+ : undefined;
700
720
  const dispatch = async () => {
701
721
  noteRequestServiceTier(cursorSelectionIsFast(cursorSelection) ? 'fast' : '');
702
722
  // Every attempt (retries included) prepares right before it lowers.
@@ -9,7 +9,7 @@ export const CUSTOM_PROVIDER_PROTOCOLS = Object.freeze(['openai-chat', 'openai-r
9
9
  export const CUSTOM_PROVIDER_SCHEMA_VERSION = 2;
10
10
  // Ranked weakest → strongest.
11
11
  export const CUSTOM_REASONING_LEVELS = CUSTOM_EFFORT_LEVELS;
12
- export const CUSTOM_REASONING_WIRE_FORMATS = Object.freeze(['standard', 'deepseek']);
12
+ export const CUSTOM_REASONING_WIRE_FORMATS = Object.freeze(['standard', 'deepseek', 'together', 'vllm']);
13
13
  export const CUSTOM_PROVIDER_AUTH_MODES = Object.freeze(['key', 'none']);
14
14
  export const CUSTOM_MODEL_OVERRIDE_LIMIT = 500;
15
15
 
@@ -74,10 +74,22 @@ const V2_TOP_LEVEL_KEYS = new Set([
74
74
  'auth',
75
75
  'discovery',
76
76
  'modelOverrides',
77
+ 'wires',
78
+ 'modelWires',
77
79
  'id',
78
80
  'apiKey',
81
+ 'apiKeyEnv',
79
82
  'preconnect',
80
83
  ]);
84
+ export const CUSTOM_API_KEY_ENV_RE = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
85
+
86
+ // Env var name that supplies the key, or '' when unset (undefined / null).
87
+ function normalizeApiKeyEnv(raw) {
88
+ if (raw === undefined || raw === null) return '';
89
+ if (typeof raw !== 'string' || !CUSTOM_API_KEY_ENV_RE.test(raw))
90
+ fail('apiKeyEnv must be a valid environment variable name');
91
+ return raw;
92
+ }
81
93
  const MAX_BASE_URL = 2048;
82
94
 
83
95
  function onlyKnownKeys(value, allowed, label) {
@@ -229,6 +241,49 @@ function normalizeOverrides(raw, protocol, legacy) {
229
241
  return out;
230
242
  }
231
243
 
244
+ // The wire each OpenAI-compatible protocol speaks (wire-route.mjs WIRES).
245
+ export const CUSTOM_PROTOCOL_WIRES = Object.freeze({
246
+ 'openai-chat': 'chat',
247
+ 'openai-responses': 'responses',
248
+ anthropic: 'messages',
249
+ });
250
+ // Wires a user-defined OpenAI-compatible endpoint can be declared to serve.
251
+ export const CUSTOM_PROVIDER_WIRES = Object.freeze(['chat', 'responses', 'messages']);
252
+
253
+ // `wires`: the wires the endpoint serves (the protocol's own wire included);
254
+ // absent = the protocol's wire only. Anthropic-protocol providers speak one wire.
255
+ function normalizeWires(raw, protocol) {
256
+ if (raw === undefined) return null;
257
+ if (protocol === 'anthropic') fail("wires requires an 'openai-chat' or 'openai-responses' protocol");
258
+ if (!Array.isArray(raw) || raw.length === 0) fail('wires must be a non-empty array');
259
+ const seen = new Set();
260
+ for (const wire of raw) {
261
+ if (!CUSTOM_PROVIDER_WIRES.includes(wire)) fail(`wires has unsupported wire: ${String(wire)}`);
262
+ if (seen.has(wire)) fail(`wires has duplicate wire: ${wire}`);
263
+ seen.add(wire);
264
+ }
265
+ if (!seen.has(CUSTOM_PROTOCOL_WIRES[protocol]))
266
+ fail(`wires must include the protocol wire: ${CUSTOM_PROTOCOL_WIRES[protocol]}`);
267
+ return CUSTOM_PROVIDER_WIRES.filter((wire) => seen.has(wire));
268
+ }
269
+
270
+ // `modelWires`: per-model wire override, each one of the served wires.
271
+ function normalizeModelWires(raw, protocol, wires) {
272
+ if (raw === undefined) return {};
273
+ if (protocol === 'anthropic') fail("modelWires requires an 'openai-chat' or 'openai-responses' protocol");
274
+ if (!isPlainObject(raw)) fail('modelWires must be an object');
275
+ const keys = Object.keys(raw);
276
+ if (keys.length > CUSTOM_MODEL_OVERRIDE_LIMIT) fail(`at most ${CUSTOM_MODEL_OVERRIDE_LIMIT} model wires are allowed`);
277
+ const served = wires || [CUSTOM_PROTOCOL_WIRES[protocol]];
278
+ const out = {};
279
+ for (const key of keys) {
280
+ const id = modelIdKey(key, 'modelWires key');
281
+ if (!served.includes(raw[key])) fail(`modelWires[${id}] must be one of the served wires: ${served.join(', ')}`);
282
+ out[id] = raw[key];
283
+ }
284
+ return out;
285
+ }
286
+
232
287
  // Legacy (pre-v2) `models: [{ id, name?, contextWindow?, maxOutputTokens? }]`
233
288
  // become manual, visible overrides; their presence hides newly discovered ids.
234
289
  function migrateLegacy(input) {
@@ -268,6 +323,8 @@ export function normalizeCustomProviderConfig(input) {
268
323
  // v2 fields without the version would be silently dropped by migration.
269
324
  if (input.modelOverrides !== undefined || input.discovery !== undefined)
270
325
  fail('modelOverrides and discovery require schemaVersion 2');
326
+ if (input.wires !== undefined || input.modelWires !== undefined)
327
+ fail('wires and modelWires require schemaVersion 2');
271
328
  source = migrateLegacy(input);
272
329
  } else if (Number.isInteger(version) && version > CUSTOM_PROVIDER_SCHEMA_VERSION)
273
330
  fail(`unsupported schemaVersion ${version}; update mixdog to use this provider`);
@@ -293,10 +350,13 @@ export function normalizeCustomProviderConfig(input) {
293
350
  if (!CUSTOM_PROVIDER_PROTOCOLS.includes(protocol)) fail(`unsupported protocol: ${protocol}`);
294
351
  const auth = source.auth === undefined || source.auth === null ? 'key' : text(source.auth);
295
352
  if (!CUSTOM_PROVIDER_AUTH_MODES.includes(auth)) fail(`invalid auth: ${String(source.auth)}`);
353
+ const apiKeyEnv = normalizeApiKeyEnv(source.apiKeyEnv);
296
354
  const discovery = source.discovery === undefined ? {} : source.discovery;
297
355
  if (!isPlainObject(discovery)) fail('discovery must be an object');
298
356
  onlyKnownKeys(discovery, DISCOVERY_KEYS, 'discovery');
299
357
  const newModelsHidden = optionalBoolean(discovery.newModelsHidden, 'discovery.newModelsHidden') ?? false;
358
+ const wires = normalizeWires(source.wires, protocol);
359
+ const modelWires = normalizeModelWires(source.modelWires, protocol, wires);
300
360
  return {
301
361
  type: 'custom',
302
362
  schemaVersion: CUSTOM_PROVIDER_SCHEMA_VERSION,
@@ -305,8 +365,11 @@ export function normalizeCustomProviderConfig(input) {
305
365
  baseURL: normalizeBaseURL(source.baseURL),
306
366
  enabled: source.enabled !== false,
307
367
  auth,
368
+ ...(apiKeyEnv && auth === 'key' ? { apiKeyEnv } : {}),
308
369
  discovery: { newModelsHidden },
309
370
  modelOverrides: normalizeOverrides(source.modelOverrides, protocol, legacy),
371
+ ...(wires ? { wires } : {}),
372
+ ...(Object.keys(modelWires).length ? { modelWires } : {}),
310
373
  };
311
374
  }
312
375
 
@@ -323,6 +386,14 @@ function catalogLevels(row) {
323
386
  return levels.size ? [...levels].sort(byRank) : null;
324
387
  }
325
388
 
389
+ function reasoningLevelFields(levels) {
390
+ if (!levels) return {};
391
+ return {
392
+ reasoningOptions: levels.length ? [{ type: 'effort', values: [...levels] }] : [],
393
+ reasoningLevels: [...levels],
394
+ };
395
+ }
396
+
326
397
  function effectiveRow(base, override, { providerId, discovered, newModelsHidden }) {
327
398
  const ov = override || {};
328
399
  const reasoning = ov.reasoning || {};
@@ -350,12 +421,7 @@ function effectiveRow(base, override, { providerId, discovered, newModelsHidden
350
421
  hidden,
351
422
  manual: ov.manual === true,
352
423
  supportsReasoning: levels ? levels.some((level) => level !== 'none') : base.supportsReasoning === true,
353
- ...(levels
354
- ? {
355
- reasoningOptions: levels.length ? [{ type: 'effort', values: [...levels] }] : [],
356
- reasoningLevels: [...levels],
357
- }
358
- : {}),
424
+ ...reasoningLevelFields(levels),
359
425
  customReasoning: { wireFormat: reasoning.wireFormat ?? 'standard', wireValues, replay },
360
426
  ...(replay ? { reasoningContentField: 'reasoning_content' } : {}),
361
427
  };
@@ -5,7 +5,19 @@
5
5
  // under the custom id so model routes and provider identity stay `custom-…`.
6
6
 
7
7
  import { resolveProviderApiKey } from '../../../shared/provider-api-key.mjs';
8
- import { effectiveCustomModelRows, normalizeCustomProviderConfig } from './custom-provider-config.mjs';
8
+ import {
9
+ CUSTOM_PROTOCOL_WIRES,
10
+ effectiveCustomModelRows,
11
+ normalizeCustomProviderConfig,
12
+ } from './custom-provider-config.mjs';
13
+ import {
14
+ customWireProfile,
15
+ providerOffersWire,
16
+ registerWireProfile,
17
+ resolveWireRoute,
18
+ sendOnRoute,
19
+ } from './wire-route.mjs';
20
+ import { withInclusiveUsage } from './lib/inclusive-usage.mjs';
9
21
  import { ANTHROPIC_VERSION } from './lib/anthropic-models.mjs';
10
22
  import { enrichModels } from './model-catalog.mjs';
11
23
  import { fetchCompatModelItems, listCompatModels } from './openai-compat-models.mjs';
@@ -45,6 +57,22 @@ function withCustomModels(Base, discover) {
45
57
  _customKey() {
46
58
  return this._customKeyless ? '' : resolveProviderApiKey(this.name, this.config);
47
59
  }
60
+ // Env mode with the variable unset: fail before any request is sent.
61
+ _assertCustomKey() {
62
+ const name = this.customConfig?.apiKeyEnv;
63
+ if (name && !this._customKeyless && !resolveProviderApiKey(this.name, this.config))
64
+ throw new Error(`API key environment variable ${name} is not set`);
65
+ }
66
+ // A 401 reload must not fall back to the stale key once the variable is
67
+ // gone; with a new value the base reload picks it up for the retry.
68
+ reloadApiKey() {
69
+ this._assertCustomKey();
70
+ return super.reloadApiKey();
71
+ }
72
+ async send(...args) {
73
+ this._assertCustomKey();
74
+ return super.send(...args);
75
+ }
48
76
  _customRows() {
49
77
  return effectiveCustomModelRows(this.customConfig, this._customDiscovered || [], { providerId: this.name });
50
78
  }
@@ -57,6 +85,7 @@ function withCustomModels(Base, discover) {
57
85
  async listModels({ signal = null, throwOnError = false } = {}) {
58
86
  let failure = null;
59
87
  try {
88
+ this._assertCustomKey();
60
89
  this._customDiscovered = await discover(this, signal);
61
90
  this.customDiscoveryError = null;
62
91
  } catch (error) {
@@ -112,10 +141,14 @@ export async function createCustomProvider(id, config) {
112
141
  // `auth: 'none'` is authoritative: a supplied/injected key is ignored and
113
142
  // `keyless` makes the engine omit every credential header.
114
143
  const keyless = cfg.auth === 'none';
115
- const apiKey = keyless ? '' : config.apiKey || '';
144
+ // Env mode: the named variable is the only key source.
145
+ let apiKey = '';
146
+ if (cfg.apiKeyEnv) apiKey = process.env[cfg.apiKeyEnv] || '';
147
+ else if (!keyless) apiKey = config.apiKey || '';
116
148
  const engine = {
117
149
  baseURL: cfg.baseURL,
118
150
  apiKey: apiKey || undefined,
151
+ ...(cfg.apiKeyEnv ? { apiKeyEnv: cfg.apiKeyEnv } : {}),
119
152
  ...(keyless ? { keyless: true } : {}),
120
153
  ...(config.preconnect === false ? { preconnect: false } : {}),
121
154
  };
@@ -129,14 +162,45 @@ export async function createCustomProvider(id, config) {
129
162
  provider.nativePdf = false;
130
163
  } else {
131
164
  const { OpenAICompatProvider } = await import('./openai-compat.mjs');
132
- const responses = cfg.protocol === 'openai-responses';
165
+ // The wires the endpoint is declared to serve (default: the protocol's
166
+ // own) and the per-model `modelWires` override pick each model's wire
167
+ // through the shared wire-route table, pinned per session like a gateway.
168
+ registerWireProfile(
169
+ providerId,
170
+ customWireProfile({ protocolWire: CUSTOM_PROTOCOL_WIRES[cfg.protocol], wires: cfg.wires })
171
+ );
172
+ let messagesEngine = null;
173
+ if (providerOffersWire(providerId, 'messages')) {
174
+ const { AnthropicProvider } = await import('./anthropic.mjs');
175
+ // The Anthropic SDK appends /v1/messages itself; the endpoint's /v1 base maps to it.
176
+ messagesEngine = new AnthropicProvider({
177
+ ...engine,
178
+ name: providerId,
179
+ baseURL: cfg.baseURL.replace(/\/v1$/i, ''),
180
+ });
181
+ messagesEngine.nativePdf = false;
182
+ }
133
183
  class CompatBase extends OpenAICompatProvider {
184
+ messagesEngine = messagesEngine;
134
185
  _fetchModelItems({ signal = null } = {}) {
135
186
  return fetchCompatModelItems(this, { signal, keyless: this._customKeyless });
136
187
  }
137
- _doSend(messages, model, tools, sendOpts) {
138
- if (!responses) return super._doSend(messages, model, tools, sendOpts);
139
- return super._doSend(messages, model, tools, { ...(sendOpts || {}), compatWireApi: 'responses' });
188
+ resolveWireRoute(model, ctx = {}) {
189
+ return resolveWireRoute(this.name, model, { ...ctx, override: cfg.modelWires?.[model] ?? null });
190
+ }
191
+ send(messages, model, tools, sendOpts) {
192
+ const useModel = model || this.defaultModel;
193
+ // The resolved route is the only wire authority: a caller's own wire
194
+ // switches never reach the engine. A custom provider declares the
195
+ // wires its endpoint serves, so a clear "unsupported" refusal moves
196
+ // the send to another declared wire once (sendOnRoute).
197
+ return sendOnRoute(this, useModel, tools, sendOpts, messages, (wire, history, opts) => {
198
+ if (wire === 'messages' && this.messagesEngine) {
199
+ return withInclusiveUsage(() => this.messagesEngine.send(history, useModel, tools, opts));
200
+ }
201
+ if (wire === 'responses') return super.send(history, model, tools, { ...opts, compatWireApi: 'responses' });
202
+ return super.send(history, model, tools, opts);
203
+ });
140
204
  }
141
205
  }
142
206
  const Custom = withCustomModels(CompatBase, (self, signal) =>
@@ -144,6 +208,11 @@ export async function createCustomProvider(id, config) {
144
208
  );
145
209
  provider = new Custom(providerId, engine);
146
210
  }
211
+ // The bound Messages engine reads the parent's model rows, so a routed
212
+ // Messages request carries the same row-driven thinking/effort as the
213
+ // Anthropic protocol.
214
+ if (provider.messagesEngine)
215
+ provider.messagesEngine.getCachedModelInfo = (model) => provider.getCachedModelInfo(model);
147
216
  provider.customConfig = cfg;
148
217
  provider._customKeyless = keyless;
149
218
  provider._applyCustomRows(provider._customRows());
@@ -4,6 +4,8 @@
4
4
  // effort to a supported level and serializes it for the provider protocol.
5
5
  // First-party providers never route through here.
6
6
 
7
+ import { isTogetherBaseURL } from './openai-compat-reasoning-field.mjs';
8
+
7
9
  export const CUSTOM_EFFORT_LEVELS = Object.freeze(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']);
8
10
  const RANK = new Map(CUSTOM_EFFORT_LEVELS.map((level, index) => [level, index]));
9
11
 
@@ -63,16 +65,30 @@ export function snapCustomEffort(levels, effort) {
63
65
  }
64
66
 
65
67
  const EMPTY = Object.freeze({ level: null, fields: {}, thinking: null, replay: false });
68
+ // Chat-only extensions on top of the standard `reasoning_effort`.
69
+ const CHAT_ONLY_WIRE_FORMATS = new Set(['deepseek', 'together', 'vllm']);
70
+
71
+ /**
72
+ * The effective wire format of a row: its declared format, else `together`
73
+ * when the provider's own base URL is Together AI (whose hybrid models toggle
74
+ * reasoning with a `reasoning.enabled` flag), else `standard`.
75
+ */
76
+ export function customWireFormat(model, baseURL) {
77
+ const declared = model?.customReasoning?.wireFormat;
78
+ if (CHAT_ONLY_WIRE_FORMATS.has(declared)) return declared;
79
+ return isTogetherBaseURL(baseURL) ? 'together' : 'standard';
80
+ }
66
81
 
67
82
  /**
68
- * @param {{ protocol: 'openai-chat'|'openai-responses'|'anthropic', model: object|null, effort: string|null|undefined }} input
83
+ * @param {{ protocol: 'openai-chat'|'openai-responses'|'anthropic', model: object|null, effort: string|null|undefined, baseURL?: string }} input
69
84
  * @returns {{ level: string|null, fields: object, thinking: 'on'|'off'|null, replay: boolean }}
70
85
  */
71
- export function resolveCustomReasoning({ protocol, model, effort } = {}) {
86
+ export function resolveCustomReasoning({ protocol, model, effort, baseURL } = {}) {
72
87
  const custom = model?.customReasoning || {};
73
- const wireFormat = custom.wireFormat === 'deepseek' ? 'deepseek' : 'standard';
74
- // DeepSeek's `thinking` extension exists only on the Chat wire.
75
- if (wireFormat === 'deepseek' && protocol !== 'openai-chat') return { ...EMPTY, fields: {} };
88
+ const wireFormat = protocol === 'openai-chat' ? customWireFormat(model, baseURL) : 'standard';
89
+ // The `thinking` / `reasoning.enabled` / chat_template_kwargs extensions
90
+ // exist only on the Chat wire.
91
+ if (CHAT_ONLY_WIRE_FORMATS.has(custom.wireFormat) && protocol !== 'openai-chat') return { ...EMPTY, fields: {} };
76
92
  const level = snapCustomEffort(customEffortLevels(model), effort);
77
93
  let thinking = null;
78
94
  if (level !== null) thinking = level === 'none' ? 'off' : 'on';
@@ -86,6 +102,18 @@ export function resolveCustomReasoning({ protocol, model, effort } = {}) {
86
102
  level === 'none'
87
103
  ? { thinking: { type: 'disabled' } }
88
104
  : { thinking: { type: 'enabled' }, reasoning_effort: value };
105
+ } else if (wireFormat === 'together') {
106
+ // Together: `reasoning.enabled` toggles hybrid models (those that can
107
+ // be turned off); `reasoning_effort` sets the depth of the others.
108
+ if (level === 'none') fields = { reasoning: { enabled: false } };
109
+ else {
110
+ fields = { reasoning_effort: value };
111
+ if (customEffortLevels(model)?.includes('none')) fields.reasoning = { enabled: true };
112
+ }
113
+ } else if (wireFormat === 'vllm') {
114
+ // vLLM switches thinking through the chat template.
115
+ fields = { chat_template_kwargs: { enable_thinking: level !== 'none' } };
116
+ if (level !== 'none') fields.reasoning_effort = value;
89
117
  } else {
90
118
  fields = { reasoning_effort: value };
91
119
  }
@@ -101,7 +129,6 @@ export function resolveCustomReasoning({ protocol, model, effort } = {}) {
101
129
  // An explicit replay flag wins over the catalog's reasoning_content field.
102
130
  const replayFlag =
103
131
  typeof custom.replay === 'boolean' ? custom.replay : model?.reasoningContentField === 'reasoning_content';
104
- const replay =
105
- protocol === 'openai-chat' && replayFlag && thinking !== 'off' && !/reasoner/i.test(String(model?.id || ''));
132
+ const replay = protocol === 'openai-chat' && replayFlag && thinking !== 'off';
106
133
  return { level, fields, thinking, replay };
107
134
  }