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,10 +3,10 @@
3
3
  * Sessions are saved to disk so CLI and MCP server can share state,
4
4
  * and sessions survive server restarts (resume).
5
5
  */
6
- import { writeFileSync } from 'node:fs';
6
+ import { closeSync, fsyncSync, openSync, writeFileSync } from 'node:fs';
7
7
  import * as fsp from 'node:fs/promises';
8
8
  import { randomBytes } from 'node:crypto';
9
- import { sessionPath } from './store/paths-heartbeat.mjs';
9
+ import { sessionPath } from './store/session-paths.mjs';
10
10
  import {
11
11
  guardedSaveOptions as _guardedSaveOptions,
12
12
  cancelSessionWrites as _cancelSessionWrites,
@@ -30,17 +30,6 @@ export {
30
30
  _upsertSessionSummary,
31
31
  _removeSessionSummary,
32
32
  } from './store-summary-index.mjs';
33
- export {
34
- publishHeartbeat,
35
- deleteHeartbeat,
36
- publishSessionPresence,
37
- deleteSessionPresence,
38
- readSessionPresenceMtime,
39
- isSessionPresenceOwnerDead,
40
- readSessionHeartbeatOwnerPid,
41
- isSessionHeartbeatOwnerDead,
42
- isProcessAlive,
43
- } from './store/paths-heartbeat.mjs';
44
33
  import { _sessionForDisk, _ensureLifecycleFields } from './store/serialize.mjs';
45
34
  import {
46
35
  _cacheSessionSummary,
@@ -55,11 +44,9 @@ import {
55
44
  withdrawPendingOwnCommit as _withdrawPendingOwnCommit,
56
45
  recordOwnSessionCommit as _recordOwnSessionCommit,
57
46
  } from './store/canonical-reader.mjs';
58
- // Durable lifecycle reads, heartbeat freshness and live-cache reclamation are
59
- // owned by dedicated modules; re-exported so prior importers of store.mjs
60
- // stay unchanged.
47
+ // Durable lifecycle reads and live-cache reclamation are owned by dedicated
48
+ // modules; re-exported so prior importers of store.mjs stay unchanged.
61
49
  export { readSessionLifecycleFromDisk, readSessionLifecycleStateFromDisk } from './store/lifecycle-read.mjs';
62
- export { readSessionHeartbeatMtime } from './store/liveness-veto.mjs';
63
50
  export { evictLiveSession, evictIdleLiveSessions } from './store/live-cache-eviction.mjs';
64
51
  import {
65
52
  setLiveSession,
@@ -354,7 +341,15 @@ function _doSaveSync(payload) {
354
341
  attempted = JSON.stringify(disk);
355
342
  // The lifecycle these exact bytes carry, recorded with the commit stamp.
356
343
  const lifecycle = _lifecycleOfSessionDocument(disk);
357
- writeFileSync(tmp, attempted, 'utf-8');
344
+ // fsync before the rename: without it an OS crash can publish the
345
+ // renamed file with its data blocks never written (all-NUL record).
346
+ const fd = openSync(tmp, 'w');
347
+ try {
348
+ writeFileSync(fd, attempted, 'utf-8');
349
+ fsyncSync(fd);
350
+ } finally {
351
+ closeSync(fd);
352
+ }
358
353
  if (_shouldDrop(id, opts, attempt)) {
359
354
  _discardSaveTmp(tmp);
360
355
  if (mayMutate()) _recordSaveDrop(id, epoch);
@@ -636,7 +631,14 @@ async function _doSave(payload) {
636
631
  attempted = JSON.stringify(disk);
637
632
  // Captured before the await: the lifecycle of exactly these bytes.
638
633
  const lifecycle = _lifecycleOfSessionDocument(disk);
639
- await fsp.writeFile(tmp, attempted, 'utf-8');
634
+ // fsync before the rename (see _doSaveSync).
635
+ const handle = await fsp.open(tmp, 'w');
636
+ try {
637
+ await handle.writeFile(attempted, 'utf-8');
638
+ await handle.sync();
639
+ } finally {
640
+ await handle.close();
641
+ }
640
642
  // Second check: between the temp write and the rename, closeSession()
641
643
  // may have planted a tombstone. Re-check on disk; if a newer tombstone
642
644
  // now exists, discard our temp file rather than let rename clobber it.
@@ -706,6 +708,7 @@ export { loadSession } from './store/load-session.mjs';
706
708
  // Hard delete + owned-agent enumeration live in store/session-delete.mjs;
707
709
  // re-exported here so prior importers of store.mjs stay unchanged.
708
710
  export { deleteSession, listOwnedAgentSessionIds } from './store/session-delete.mjs';
711
+ export { fenceSessionWrites } from './store/live-state.mjs';
709
712
 
710
713
  // Listing / summaries live in store/listing.mjs and the stale sweep in
711
714
  // store/sweep/stale-sweep.mjs; re-exported here so importers keep one
@@ -78,7 +78,12 @@ export async function executeBatchCall(batch, call, callIndex) {
78
78
  // Read entries are stat-validated; scoped entries retain dependency
79
79
  // invalidation and their bounded TTL. A miss proceeds to execution.
80
80
  function lookupCaches(batch, call, exec) {
81
- const cached = lookupToolResultReuse({ sessionId: batch.sessionId, call, cwd: batch.cwd });
81
+ const cached = lookupToolResultReuse({
82
+ sessionId: batch.sessionId,
83
+ call,
84
+ cwd: batch.cwd,
85
+ sessionRef: batch.sessionRef,
86
+ });
82
87
  if (cached?.kind === 'read') exec.readCacheHit = cached.entry;
83
88
  else if (cached?.kind === 'scoped') exec.scopedCacheHit = cached.entry;
84
89
  }
@@ -115,9 +120,7 @@ async function executeLive(batch, call, callIndex, exec) {
115
120
  // this session never received the discarded body.
116
121
  let discardedRead = false;
117
122
  if (eager !== undefined && eager.mutationEpoch < epoch.mutation && isEagerDispatchable(call.name, tools)) {
118
- const stale = _isReadTool(call.name)
119
- ? mutationAffectsRead(epoch, eager.mutationEpoch, call, batch.cwd)
120
- : true;
123
+ const stale = _isReadTool(call.name) ? mutationAffectsRead(epoch, eager.mutationEpoch, call, batch.cwd) : true;
121
124
  if (stale) {
122
125
  discardedRead = _isReadTool(call.name);
123
126
  pending.delete(call.id);
@@ -176,14 +179,10 @@ async function executeSerially(batch, call, exec, suppressReadUnchangedStub = fa
176
179
  exec.executionStartedAt = Date.now();
177
180
  exec.serialExecutionStartedAt = exec.executionStartedAt;
178
181
  exec.localSearchTelemetry = {};
179
- exec.result = await executeToolFn(
180
- call.name,
181
- call.arguments,
182
- cwd,
183
- sessionId,
184
- sessionRef,
185
- { ...invocationOptions(batch, call, exec), ...(suppressReadUnchangedStub ? { suppressReadUnchangedStub: true } : {}) }
186
- );
182
+ exec.result = await executeToolFn(call.name, call.arguments, cwd, sessionId, sessionRef, {
183
+ ...invocationOptions(batch, call, exec),
184
+ ...(suppressReadUnchangedStub ? { suppressReadUnchangedStub: true } : {}),
185
+ });
187
186
  exec.toolEndedAt = Date.now();
188
187
  classifyExecuted(call, exec);
189
188
  }
@@ -208,6 +207,7 @@ function invocationOptions(batch, call, exec) {
208
207
  iteration: batch.iterations,
209
208
  localSearchTelemetry: exec.localSearchTelemetry || {},
210
209
  resultTelemetry: exec.resultTelemetry,
210
+ ...(call.wireCall ? { bridgeWireCall: call.wireCall } : {}),
211
211
  };
212
212
  }
213
213
 
@@ -15,6 +15,8 @@ import { crossTurnSignature, isEditProgressTool } from '../loop/completion-guard
15
15
  import { isEagerDispatchable, isToolCallDedupEligible, parseNativeToolSearchPayload } from '../loop/tool-helpers.mjs';
16
16
  import { restoreToolCallBodyForId } from '../loop/stored-tool-args.mjs';
17
17
  import { stageToolResult } from './state.mjs';
18
+ import { providerConsumesReadWindows } from '../../providers/registry.mjs';
19
+ import { remoteReadWindowReport } from '../../tools/builtin/external-tool-adapters.mjs';
18
20
  import { toolMetaPatchFromMessage } from '../transcript-restore/tool-result-status.mjs';
19
21
  import {
20
22
  compactToolResultImage,
@@ -42,12 +44,30 @@ export async function finalizeBatchResults(batch) {
42
44
  for (const state of offloadStates) {
43
45
  if (state?.result && typeof state.result === 'object') state.result = await compactResultImages(state.result);
44
46
  }
47
+ await reportReadWindows(batch);
45
48
  for (let index = 0; index < batch.completed.length; index += 1) {
46
49
  postProcessCompleted(batch, batch.completed[index], offloadStates[index]);
47
50
  batch.throwIfAborted();
48
51
  }
49
52
  }
50
53
 
54
+ // A provider that declares `consumesReadWindows` (also through a remote/proxy
55
+ // stand-in) only receives the read text. Its read results carry the
56
+ // structured clip report next to the text, for every serving path (live,
57
+ // eager or cached). Failure fails closed.
58
+ async function reportReadWindows(batch) {
59
+ if (!providerConsumesReadWindows(batch.sessionRef?.provider)) return;
60
+ for (const completed of batch.completed) {
61
+ if (!completed.executeOk || !_isReadTool(completed.call.name)) continue;
62
+ try {
63
+ const report = await remoteReadWindowReport(completed.call.arguments, batch.cwd, completed.result);
64
+ if (report) completed.readWindow = report;
65
+ } catch {
66
+ completed.readWindow = { lineClipped: true };
67
+ }
68
+ }
69
+ }
70
+
51
71
  // An image no provider can take is replaced by fixed text here, before it can
52
72
  // reach the transcript and fail every later send.
53
73
  const unsupportedImageText = (mimeType) => `[image omitted: ${mimeType} is not a supported image type]`;
@@ -57,7 +77,10 @@ const UNDECODABLE_IMAGE_TEXT = '[image omitted: could not be decoded]';
57
77
  // inline image is fully decoded (not only large ones); with no decoder
58
78
  // installed the image is kept as is.
59
79
  async function rejectedImageText(base64, rawMime) {
60
- const mimeType = String(rawMime || 'image/png').split(';')[0].trim().toLowerCase();
80
+ const mimeType = String(rawMime || 'image/png')
81
+ .split(';')[0]
82
+ .trim()
83
+ .toLowerCase();
61
84
  if (!SUPPORTED_IMAGE_MIME_TYPES.has(mimeType)) return unsupportedImageText(mimeType);
62
85
  try {
63
86
  await resizeImageBuffer(Buffer.from(base64, 'base64'), mimeType.split('/')[1]);
@@ -73,8 +96,8 @@ async function rejectedImageText(base64, rawMime) {
73
96
  // the result reaches the read cache or the transcript; stored history is never
74
97
  // revisited.
75
98
  export async function compactResultImages(result) {
76
- const parts = Array.isArray(result) ? result : Array.isArray(result?.content) ? result.content : null;
77
- if (!parts) return result;
99
+ const parts = Array.isArray(result) ? result : result?.content;
100
+ if (!Array.isArray(parts)) return result;
78
101
  let changed = false;
79
102
  const next = [];
80
103
  for (const part of parts) {
@@ -101,16 +124,16 @@ export async function compactResultImages(result) {
101
124
  if (dims.originalWidth !== dims.displayWidth || dims.originalHeight !== dims.displayHeight) {
102
125
  next.push({ type: 'text', text: supersedingImageMetadataText(dims) });
103
126
  }
104
- next.push(
105
- source
106
- ? { ...part, source: { ...source, data: compacted.data, media_type: compacted.mimeType } }
107
- : {
108
- ...part,
109
- data: compacted.data,
110
- mimeType: compacted.mimeType,
111
- ...(part.mediaType ? { mediaType: compacted.mimeType } : {}),
112
- }
113
- );
127
+ if (source) {
128
+ next.push({ ...part, source: { ...source, data: compacted.data, media_type: compacted.mimeType } });
129
+ } else {
130
+ next.push({
131
+ ...part,
132
+ data: compacted.data,
133
+ mimeType: compacted.mimeType,
134
+ ...(part.mediaType ? { mediaType: compacted.mimeType } : {}),
135
+ });
136
+ }
114
137
  }
115
138
  if (!changed) return result;
116
139
  return Array.isArray(result) ? next : { ...result, content: next };
@@ -281,6 +304,7 @@ function completedToolResult(completed, result, postprocessStartedAt) {
281
304
  toolKind: completed.resultKind,
282
305
  toolTiming: toolTiming(completed, postprocessStartedAt),
283
306
  ...(completed.nativeToolSearch ? { nativeToolSearch: completed.nativeToolSearch } : {}),
307
+ ...(completed.readWindow ? { readWindow: completed.readWindow } : {}),
284
308
  ...(uiDiff !== null ? { uiDiff } : {}),
285
309
  ...toolMetaPatchFromMessage(completed.result),
286
310
  };
@@ -319,7 +343,7 @@ function stagePostProcessingFailure(batch, completed, postErr, postprocessStarte
319
343
  if (sessionRef?._scopedCacheOutcomeByCallId instanceof Map && call?.id) {
320
344
  sessionRef._scopedCacheOutcomeByCallId.delete(call.id);
321
345
  }
322
- if (call?.id) restoreToolCallBodyForId(batch.assistantTurnMsg, batch.calls, call.id);
346
+ if (call?.id) restoreToolCallBodyForId(batch.assistantTurnMsg, batch.wireCalls, call.id);
323
347
  const message = `Error: tool result post-processing failed for "${call.name}": ${postErr instanceof Error ? postErr.message : String(postErr)}`;
324
348
  traceAgentToolFailure({
325
349
  sessionId: batch.sessionId,
@@ -3,7 +3,12 @@
3
3
  // and the repeat-failure / argument-shape guards. `skip` is the staged tool
4
4
  // message for a resolved call, or null when the call may execute.
5
5
  import { appendAgentTrace } from '../../agent-trace.mjs';
6
- import { _argShapeSig, _repeatFailureSig, _repeatFailurePatternWouldContinue } from '../loop/tool-classify.mjs';
6
+ import {
7
+ _argShapeSig,
8
+ _repeatFailureSig,
9
+ _repeatFailurePatternWouldContinue,
10
+ requiresReadBody,
11
+ } from '../loop/tool-classify.mjs';
7
12
  import { preDispatchDenyForSession } from '../loop/pre-dispatch-deny.mjs';
8
13
  import { crossTurnSignature, crossTurnDedupStub } from '../loop/completion-guards.mjs';
9
14
  import { isToolCallDedupEligible } from '../loop/tool-helpers.mjs';
@@ -27,7 +32,7 @@ export function preDispatchSkip(batch, call) {
27
32
  'error'
28
33
  );
29
34
  }
30
- if (plan.duplicateCallIds.has(call.id)) {
35
+ if (plan.duplicateCallIds.has(call.id) && !requiresReadBody(call.name, sessionRef)) {
31
36
  const firstId = plan.dupFirstId.get(call.id);
32
37
  // Explicitly NOT a success: no tool executed for this call. 'skipped'
33
38
  // keeps the transcript/UI non-error while the unresolved-tool-failure
@@ -43,7 +48,7 @@ export function preDispatchSkip(batch, call) {
43
48
  let ctSig = null;
44
49
  if (isToolCallDedupEligible(call.name, tools)) {
45
50
  ctSig = crossTurnSignature(call.name, call.arguments);
46
- const stub = crossTurnStub(batch, call, ctSig);
51
+ const stub = requiresReadBody(call.name, sessionRef) ? null : crossTurnStub(batch, call, ctSig);
47
52
  if (stub !== null) return skipped(stub, 'skipped', ctSig);
48
53
  }
49
54
  const sigs = {
@@ -60,7 +65,13 @@ export function preDispatchSkip(batch, call) {
60
65
  function crossTurnStub(batch, call, ctSig) {
61
66
  const prior = batch.crossTurnCalls.get(ctSig);
62
67
  if (!prior || prior.firstIteration >= batch.iterations) return null;
63
- const cached = lookupToolResultReuse({ sessionId: batch.sessionId, call, cwd: batch.cwd, touch: false });
68
+ const cached = lookupToolResultReuse({
69
+ sessionId: batch.sessionId,
70
+ call,
71
+ cwd: batch.cwd,
72
+ touch: false,
73
+ sessionRef: batch.sessionRef,
74
+ });
64
75
  if (!cached || !prior.toolUseId || cached.entry.firstToolUseId !== prior.toolUseId) {
65
76
  batch.crossTurnCalls.delete(ctSig);
66
77
  return null;
@@ -46,7 +46,7 @@ export async function recordCallOutcome(batch, call, exec, sigs, ctSig) {
46
46
  // otherwise hide behind a `[mixdog compacted …]` placeholder). Restored
47
47
  // immediately so an abort or post-processing throw cannot leave it
48
48
  // compacted; early-skipped calls stay compacted.
49
- if (executed && failed && call?.id) restoreToolCallBodyForId(batch.assistantTurnMsg, batch.calls, call.id);
49
+ if (executed && failed && call?.id) restoreToolCallBodyForId(batch.assistantTurnMsg, batch.wireCalls, call.id);
50
50
  if (sessionId && _stripMcpPrefix(call.name) === 'apply_patch') {
51
51
  if (exec.executeOk && exec.resultKind === 'normal') invalidateAfterPatch(sessionId, call, cwd);
52
52
  // Mutation tools invalidate even on returned-error/partial-fail — the
@@ -4,11 +4,17 @@
4
4
  // live here so processToolBatch can hand them back.
5
5
  import { executeTool } from '../loop/tool-exec.mjs';
6
6
  import { planToolBatch } from './plan.mjs';
7
+ import { bridgeClassificationTools, resolveExecutionToolCalls } from '../loop/tool-call-resolution.mjs';
7
8
 
8
9
  export function createBatchState(ctx) {
9
- const { calls, tools, assistantTurnMsg, sessionRef } = ctx;
10
+ const { assistantTurnMsg, sessionRef } = ctx;
11
+ // Bridged call_tool requests run as their targets from here on; the wire
12
+ // calls stay authoritative for the transcript and failed-argument restore.
13
+ const calls = resolveExecutionToolCalls(ctx.calls, sessionRef);
14
+ const tools = bridgeClassificationTools(ctx.tools, calls);
10
15
  return {
11
16
  calls,
17
+ wireCalls: ctx.calls,
12
18
  messages: ctx.messages,
13
19
  tools,
14
20
  cwd: ctx.cwd,
@@ -19,8 +19,10 @@ import { getPluginData } from '../config.mjs';
19
19
  import { countSplitLines, normalizeOutputPath } from '../tools/builtin/path-utils.mjs';
20
20
  import { classifyResultKind } from './result-classification.mjs';
21
21
  import { registerSessionPurgeHook } from './store.mjs';
22
+ import { SETUP_OUTPUT_MAX_BYTES } from '../../../shared/tool-output-limit.mjs';
22
23
 
23
24
  const TOOL_RESULT_OFFLOAD_THRESHOLD_CHARS = 50_000;
25
+ const TOOL_RESULT_SETUP_THRESHOLD_CHARS = SETUP_OUTPUT_MAX_BYTES;
24
26
  const TOOL_RESULT_PREVIEW_CHARS = 512;
25
27
  const TOOL_RESULT_SHELL_THRESHOLD_CHARS = 30_000;
26
28
  const TOOL_RESULT_SEARCH_THRESHOLD_CHARS = 50_000;
@@ -61,6 +63,7 @@ const INLINE_THRESHOLD_BY_TOOL = new Map([
61
63
  ['bash_session', TOOL_RESULT_SHELL_THRESHOLD_CHARS],
62
64
  ['terminal', TOOL_RESULT_SHELL_THRESHOLD_CHARS],
63
65
  ['task', TOOL_RESULT_SHELL_THRESHOLD_CHARS],
66
+ ['setup', TOOL_RESULT_SETUP_THRESHOLD_CHARS],
64
67
  ]);
65
68
 
66
69
  function getOffloadThreshold(toolName) {
@@ -554,6 +557,7 @@ export const _internals = {
554
557
  TOOL_RESULT_SHELL_THRESHOLD_CHARS,
555
558
  TOOL_RESULT_SEARCH_THRESHOLD_CHARS,
556
559
  TOOL_RESULT_GREP_THRESHOLD_CHARS,
560
+ TOOL_RESULT_SETUP_THRESHOLD_CHARS,
557
561
  getOffloadThreshold,
558
562
  TOOL_RESULT_PREVIEW_CHARS,
559
563
  TOOL_RESULT_MESSAGE_MAX_CHARS,
@@ -0,0 +1,79 @@
1
+ // A provider 400 that names one tool's input schema (Anthropic
2
+ // `tools.3.custom.input_schema`, OpenAI `Invalid schema for function 'x'` /
3
+ // `tools[3].parameters`, Gemini `function_declarations[3]`): which tool of the
4
+ // request it is, so the session can drop it instead of failing every turn.
5
+ import { providerToolExclusionReason } from './loop/provider-tool-exclusions.mjs';
6
+ import { providerNativeToolPrefixCount } from '../runtime-core/provider-request-tools.mjs';
7
+
8
+ const MAX_REASON_CHARS = 240;
9
+
10
+ const text = (value) => (typeof value === 'string' ? value : '');
11
+
12
+ // Provider-structured places a rejection names its field, best evidence first:
13
+ // OpenAI `param` (also nested under `error`), Anthropic / OpenAI `error.message`,
14
+ // Google `details[].fieldViolations[].field`, then a JSON body, then the
15
+ // error's own message.
16
+ function evidence(error) {
17
+ const nested = [error?.error, error?.providerError, error?.response?.data?.error, error?.response?.data];
18
+ const violations = [error?.details, error?.error?.details, error?.errorDetails]
19
+ .flatMap((details) => (Array.isArray(details) ? details : []))
20
+ .flatMap((detail) => (Array.isArray(detail?.fieldViolations) ? detail.fieldViolations : []))
21
+ .flatMap((violation) => [text(violation?.field), text(violation?.description)]);
22
+ const bodies = [error?.body, error?.responseBody].map((body) => {
23
+ if (typeof body !== 'string') return [];
24
+ try {
25
+ const parsed = JSON.parse(body);
26
+ return [text(parsed?.error?.param), text(parsed?.error?.message), text(parsed?.message)];
27
+ } catch {
28
+ return [body];
29
+ }
30
+ });
31
+ return [
32
+ error?.param,
33
+ ...nested.map((entry) => entry?.param),
34
+ ...nested.map((entry) => entry?.message),
35
+ ...violations,
36
+ ...bodies.flat(),
37
+ error?.message,
38
+ error?.cause?.message,
39
+ ].filter((entry) => typeof entry === 'string' && entry);
40
+ }
41
+
42
+ // One piece of evidence -> which tool: a wire index (`byIndex`, with the
43
+ // OpenAI Responses hosted-tool offset when `shifted`) or a function name.
44
+ function target(entry) {
45
+ let match = /\btools\.(\d+)\.(?:custom\.)?input_schema/.exec(entry);
46
+ if (match) return { index: Number(match[1]) };
47
+ match = /\btools(?:\[(\d+)\]|\.(\d+))\.(?:function\.)?parameters/.exec(entry);
48
+ if (match) return { index: Number(match[1] ?? match[2]), shifted: true };
49
+ match = /\b(?:function_declarations|functionDeclarations)(?:\[(\d+)\]|\.(\d+))/.exec(entry);
50
+ if (match) return { index: Number(match[1] ?? match[2]) };
51
+ match = /Invalid schema for function ['"`]([^'"`]+)['"`]/.exec(entry);
52
+ if (match) return { name: match[1] };
53
+ return null;
54
+ }
55
+
56
+ /** `{ name, pointer, reason }` of the tool a schema 400 points at, or null (any
57
+ * other error, or a tool that is not part of the request's own tools). */
58
+ export function rejectedToolSchema(error, { sendTools, sessionRef, opts }) {
59
+ if ((error?.httpStatus ?? error?.status ?? error?.statusCode) !== 400) return null;
60
+ const tools = Array.isArray(sendTools) ? sendTools : [];
61
+ const nativeCount = providerNativeToolPrefixCount(tools);
62
+ // The wire list: the request's tools minus those the wire left out.
63
+ const wire = tools.filter((tool) => !providerToolExclusionReason(sessionRef, tool?.name));
64
+ const hosted =
65
+ sessionRef?.wireRoute?.wire !== 'chat' && Array.isArray(opts?.nativeTools) ? opts.nativeTools.length : 0;
66
+ const entries = evidence(error);
67
+ let name = '';
68
+ for (const entry of entries) {
69
+ const found = target(entry);
70
+ if (!found) continue;
71
+ const shift = found.shifted ? hosted : 0;
72
+ const tool = found.name ? wire.find((t) => t?.name === found.name) : wire[found.index - shift];
73
+ name = typeof tool?.name === 'string' ? tool.name : '';
74
+ if (name) break;
75
+ }
76
+ if (!name || tools.findIndex((t) => t?.name === name) < nativeCount) return null;
77
+ const detail = entries.join(' ').replace(/\s+/g, ' ').trim().slice(0, MAX_REASON_CHARS);
78
+ return { name, pointer: '/', reason: `the provider rejected it with HTTP 400: ${detail}` };
79
+ }
@@ -37,8 +37,24 @@ import {
37
37
  isTranscriptCancelledStatusText,
38
38
  } from '../../../../shared/tool-execution-contract.mjs';
39
39
  import { toolResultTerminalStatus } from '../../../../shared/tool-status.mjs';
40
- import { transcriptRouteMetadataFields } from '../../../../shared/transcript-metadata.mjs';
40
+ import { transcriptAttachmentFields, transcriptRouteMetadataFields } from '../../../../shared/transcript-metadata.mjs';
41
41
  import { isImportedMessage } from '../imported-message.mjs';
42
+ import { isContextAckMessage } from '../compact/user-message-kind.mjs';
43
+
44
+ /** A failed turn's recorded end: its route, reason and quota stop, the same
45
+ * fields the live turndone carries. */
46
+ function restoredFailureFields(value) {
47
+ if (value.status !== 'failed') return {};
48
+ const errorKind = value.errorKind && typeof value.errorKind === 'object' ? value.errorKind : null;
49
+ const quota = value.quota && typeof value.quota === 'object' ? value.quota : null;
50
+ return {
51
+ ...transcriptRouteMetadataFields(value),
52
+ ...(typeof value.detail === 'string' && value.detail ? { detail: value.detail } : {}),
53
+ ...(typeof value.errorDetails === 'string' && value.errorDetails ? { errorDetails: value.errorDetails } : {}),
54
+ ...(errorKind && typeof errorKind.kind === 'string' ? { errorKind: { ...errorKind } } : {}),
55
+ ...(quota && typeof quota.provider === 'string' ? { quota: { ...quota } } : {}),
56
+ };
57
+ }
42
58
 
43
59
  function restoredTranscriptMetadata(message) {
44
60
  const value = message?.meta?.transcript;
@@ -53,6 +69,10 @@ function restoredTranscriptMetadata(message) {
53
69
  if (typeof completionValue.checkpointId === 'string' && completionValue.checkpointId) {
54
70
  completion.checkpointId = completionValue.checkpointId;
55
71
  }
72
+ Object.assign(completion, restoredFailureFields(completionValue));
73
+ const attemptId = completionValue.attemptId || value.attemptId;
74
+ if (typeof attemptId === 'string' && attemptId) completion.attemptId = attemptId;
75
+ if (Number.isFinite(Number(completionValue.at))) completion.at = Number(completionValue.at);
56
76
  }
57
77
  return {
58
78
  // The stable message id lets a live view map a compaction's dropped
@@ -63,6 +83,9 @@ function restoredTranscriptMetadata(message) {
63
83
  ...(typeof value.sender === 'string' && value.sender ? { sender: value.sender } : {}),
64
84
  ...(typeof value.device === 'string' && value.device ? { device: value.device } : {}),
65
85
  ...(typeof value.checkpointId === 'string' && value.checkpointId ? { checkpointId: value.checkpointId } : {}),
86
+ // The attachments this prompt carried, by content hash: a restored row
87
+ // opens/downloads them by id from the attachment store.
88
+ ...transcriptAttachmentFields(value),
66
89
  // Skills this user turn explicitly loaded (header selection or `$name`).
67
90
  ...(Array.isArray(value.appliedSkills) && value.appliedSkills.length
68
91
  ? { appliedSkills: value.appliedSkills.filter((name) => typeof name === 'string' && name) }
@@ -71,24 +94,45 @@ function restoredTranscriptMetadata(message) {
71
94
  };
72
95
  }
73
96
 
97
+ function restoredTurnDoneItem(completion, metadata, nextId, finalAssistantId = '') {
98
+ const at = Number.isFinite(completion.at) ? completion.at : metadata.at;
99
+ return {
100
+ kind: 'turndone',
101
+ id: nextId(),
102
+ ...completion,
103
+ ...(completion.status === 'done' && finalAssistantId ? { finalAssistantId } : {}),
104
+ ...(Number.isFinite(at) ? { at } : {}),
105
+ ...(metadata.messageId ? { messageId: metadata.messageId } : {}),
106
+ };
107
+ }
108
+
74
109
  function restoredAssistantTranscriptItems(message, nextId) {
75
110
  const text = (typeof message?.content === 'string' ? message.content : toolResultText(message?.content)).trim();
76
111
  if (!text) return [];
77
112
  const { completion, ...metadata } = restoredTranscriptMetadata(message);
78
113
  const items = [{ kind: 'assistant', id: nextId(), text, ...metadata }];
79
- if (completion) {
80
- items.push({
81
- kind: 'turndone',
82
- id: nextId(),
83
- ...completion,
84
- ...(completion.status === 'done' ? { finalAssistantId: items[0].id } : {}),
85
- ...(metadata.at ? { at: metadata.at } : {}),
86
- ...(metadata.messageId ? { messageId: metadata.messageId } : {}),
87
- });
114
+ // A failed end follows the message's tool calls (restoreTranscriptRange).
115
+ if (completion && completion.status !== 'failed') {
116
+ items.push(restoredTurnDoneItem(completion, metadata, nextId, items[0].id));
88
117
  }
89
118
  return items;
90
119
  }
91
120
 
121
+ /** The failed end recorded on a message that holds no reply text before it:
122
+ * the prompt itself, a tool call or a tool result. */
123
+ function restoredFailedTurnItems(message, nextId) {
124
+ const { completion, ...metadata } = restoredTranscriptMetadata(message);
125
+ const previous = Array.isArray(message?.meta?.transcript?.previousCompletions)
126
+ ? message.meta.transcript.previousCompletions
127
+ : [];
128
+ const items = previous.flatMap((value) => {
129
+ const historical = restoredTranscriptMetadata({ meta: { transcript: { completion: value, at: value?.at } } });
130
+ return historical.completion ? [restoredTurnDoneItem(historical.completion, historical, nextId)] : [];
131
+ });
132
+ if (completion?.status === 'failed') items.push(restoredTurnDoneItem(completion, metadata, nextId));
133
+ return items;
134
+ }
135
+
92
136
  // Restored tool cards: stored assistant messages keep their (compacted)
93
137
  // tool_calls and the follow-up role:'tool' results. Rebuild one transcript
94
138
  // tool item per call and attach its result by tool_call_id, so a reopened
@@ -289,13 +333,17 @@ function restoredMessageItemUpperBound(message) {
289
333
  const boundaries =
290
334
  (Array.isArray(message?.meta?.sessionInheritances) ? message.meta.sessionInheritances.length : 0) +
291
335
  (Array.isArray(message?.meta?.modelSwitches) ? message.meta.modelSwitches.length : 0);
292
- if (message?.role === 'user') return 1 + boundaries;
293
- if (message?.role !== 'assistant') return boundaries;
336
+ const completionCount =
337
+ Number(Boolean(message?.meta?.transcript?.completion)) +
338
+ (Array.isArray(message?.meta?.transcript?.previousCompletions)
339
+ ? message.meta.transcript.previousCompletions.length
340
+ : 0);
341
+ if (message?.role === 'user') return 1 + completionCount + boundaries;
342
+ if (message?.role !== 'assistant') return completionCount + boundaries;
294
343
  const calls = restoredMessageToolCalls(message);
295
344
  const content = message?.content;
296
345
  const hasContent = typeof content === 'string' ? content.length > 0 : Array.isArray(content) && content.length > 0;
297
- const hasCompletion = Boolean(message?.meta?.transcript?.completion);
298
- return Number(hasContent) + Number(hasCompletion) + calls.length + boundaries;
346
+ return Number(hasContent) + completionCount + calls.length + boundaries;
299
347
  }
300
348
 
301
349
  // One restored tool card for a parsed notification/completion envelope.
@@ -404,12 +452,14 @@ function restoreTranscriptRange(messages, start, sessionId) {
404
452
  const restoredId = () => `hist_${sessionId}_${index}_${++part}`;
405
453
  if (message?.role === 'user') {
406
454
  items.push(...restoredUserTranscriptItems(message, restoredId));
407
- } else if (message?.role === 'assistant') {
455
+ } else if (message?.role === 'assistant' && !isContextAckMessage(message, messages[index - 1])) {
408
456
  items.push(...restoredAssistantTranscriptItems(message, restoredId));
409
457
  items.push(...restoredToolCallItems(message, restoredId, pendingToolCalls));
410
458
  } else if (message?.role === 'tool') {
411
459
  attachRestoredToolResult(message, pendingToolCalls);
412
460
  }
461
+ const eventStart = items.length;
462
+ items.push(...restoredFailedTurnItems(message, restoredId));
413
463
  for (const boundary of Array.isArray(message?.meta?.sessionInheritances) ? message.meta.sessionInheritances : []) {
414
464
  if (!boundary?.sessionId || !boundary?.provider || !boundary?.modelId) continue;
415
465
  items.push({
@@ -427,6 +477,13 @@ function restoreTranscriptRange(messages, start, sessionId) {
427
477
  if (!boundary?.provider || !boundary?.modelId) continue;
428
478
  items.push(modelSwitchItem(restoredId(), boundary));
429
479
  }
480
+ if (message?.meta?.transcript?.previousCompletions?.length) {
481
+ const events = items.slice(eventStart);
482
+ if (events.every((item) => Number.isFinite(item.at))) {
483
+ events.sort((left, right) => left.at - right.at);
484
+ items.splice(eventStart, events.length, ...events);
485
+ }
486
+ }
430
487
  }
431
488
  return mergeRestoredToolItems(items);
432
489
  }
@@ -0,0 +1,45 @@
1
+ // The failed-turn record shared by the live turn close (tui/session/turn.mjs)
2
+ // and the durable turn end (manager/ask-turn-failure.mjs), so a reopened
3
+ // session shows the same failure, reason and quota stop as the live one.
4
+ import { errText } from '../../../shared/err-text.mjs';
5
+ import { safeErrorDetails } from '../../../shared/error-presentation.mjs';
6
+ import { providerErrorKind } from '../providers/provider-error-kind.mjs';
7
+ import { toolErrorDisplay } from './transcript-restore/tool-result-text.mjs';
8
+
9
+ /**
10
+ * `{ providerKind, errorKind, quota, detail, errorDetails }` for one turn
11
+ * error. `quota` is null unless the pool validated an exhaustion or the
12
+ * provider named the real reset time; `route` fills its provider/model.
13
+ */
14
+ export function turnFailureRecord(error, route = {}) {
15
+ // Presentation only: legacy untyped failure text may still name a usage limit.
16
+ const providerKind = providerErrorKind(error, { legacyQuotaWording: true });
17
+ const errorKind = {
18
+ kind: providerKind.kind,
19
+ code: providerKind.code,
20
+ status: providerKind.status,
21
+ retryAfterMs: providerKind.retryAfterMs,
22
+ resetAt: providerKind.resetAt,
23
+ };
24
+ const exhausted = error?.quotaExhausted;
25
+ const resetKnown = providerKind.kind === 'quota_exhausted' && Number.isFinite(providerKind.resetAt);
26
+ let quota = null;
27
+ if ((exhausted && typeof exhausted === 'object') || resetKnown) {
28
+ const source = exhausted && typeof exhausted === 'object' ? exhausted : {};
29
+ let resetAt = null;
30
+ if (Number.isFinite(source.resetAt)) resetAt = source.resetAt;
31
+ else if (Number.isFinite(providerKind.resetAt)) resetAt = providerKind.resetAt;
32
+ quota = {
33
+ provider: String(source.provider || route.provider || ''),
34
+ model: String(source.model || route.model || ''),
35
+ resetAt,
36
+ };
37
+ }
38
+ return {
39
+ providerKind,
40
+ errorKind,
41
+ quota,
42
+ detail: toolErrorDisplay(error, 'turn').replace(/^Error:\s*/i, ''),
43
+ errorDetails: safeErrorDetails(errText(error)),
44
+ };
45
+ }