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
@@ -1,5 +1,7 @@
1
- // One reap timer per settled Lead row: fires at the row's reapAt and removes
2
- // the row only when it still carries that same deadline.
1
+ // One reap timer per settled Lead row: fires at the row's reapAt — never
2
+ // before the row has been listed in the Agents pane for its full visibility
3
+ // window — and removes the row only when it still carries that same deadline.
4
+ import { AGENT_PANE_VISIBLE_MS } from '../../../../runtime/shared/agent-reap-state.mjs';
3
5
  import { clean } from '../helpers.mjs';
4
6
 
5
7
  export function createLeadReapTimers({ removeRow }) {
@@ -18,7 +20,11 @@ export function createLeadReapTimers({ removeRow }) {
18
20
  const reapAt = clean(row?.reapAt);
19
21
  if (!sessionId || !reapAt) return;
20
22
  cancel(sessionId);
21
- const delay = Math.max(0, (Date.parse(reapAt) || 0) - Date.now());
23
+ // The provider reap window may be shorter than the pane window; deleting
24
+ // the row then would drop a finished Lead the pane still has to show.
25
+ const finishedMs = Date.parse(clean(row.finishedAt)) || Date.parse(clean(row.updatedAt)) || 0;
26
+ const deadline = Math.max(Date.parse(reapAt) || 0, finishedMs + AGENT_PANE_VISIBLE_MS);
27
+ const delay = Math.max(0, deadline - Date.now());
22
28
  const handle = setTimeout(() => {
23
29
  reapTimers.delete(sessionId);
24
30
  removeRow(sessionId, reapAt);
@@ -1,34 +1,23 @@
1
1
  // When an active Lead row is no longer believable, and how it settles to idle:
2
- // runtime liveness, the heartbeat sidecar, the stamp freshness window, and the
3
- // terminal reap deadline from config.
4
- import { statSync } from 'node:fs';
5
- import { resolve } from 'node:path';
2
+ // runtime liveness, the daemon's in-memory turn state, the stamp freshness
3
+ // window, and the terminal reap deadline from config.
6
4
  import { clean, runtimeAlive } from '../helpers.mjs';
7
5
  import { createRowLiveness } from '../worker-index/row-liveness.mjs';
8
6
  import { isActiveLeadRow, LEAD_POOL_FRESH_MS } from './lead-rows.mjs';
9
7
 
10
- export function createRowSettlement({ dataDir, cfgMod }) {
8
+ /** `isSessionRunning(sessionId)`: whether that Lead's turn is in flight in
9
+ * this process (every session runs inline in the daemon). */
10
+ export function createRowSettlement({ cfgMod, isSessionRunning = () => false }) {
11
11
  // Lead rows settle to idle exactly like worker rows: same stamps, same
12
12
  // config-driven terminal reap deadline.
13
- const { idleRow } = createRowLiveness({ dataDir, cfgMod });
14
-
15
- function leadHeartbeatFresh(sessionId, now) {
16
- const id = clean(sessionId);
17
- if (!dataDir || !id) return false;
18
- try {
19
- const mtimeMs = statSync(resolve(dataDir, 'sessions', `${id}.hb`)).mtimeMs || 0;
20
- return mtimeMs > 0 && now - mtimeMs <= LEAD_POOL_FRESH_MS;
21
- } catch {
22
- return false;
23
- }
24
- }
13
+ const { idleRow } = createRowLiveness({ cfgMod });
25
14
 
26
15
  function staleActiveLeadRow(row, now) {
27
16
  if (!isActiveLeadRow(row)) return false;
28
17
  // The runtime that stamped the turn is gone: no wall-clock window can make
29
18
  // that row true again, so the panel must not wait one out.
30
19
  if (!runtimeAlive(row.runtimePid)) return true;
31
- if (leadHeartbeatFresh(row.sessionId, now)) return false;
20
+ if (isSessionRunning(clean(row.sessionId))) return false;
32
21
  const updated = Date.parse(clean(row.updatedAt)) || 0;
33
22
  return !(updated > 0 && now - updated <= LEAD_POOL_FRESH_MS);
34
23
  }
@@ -15,11 +15,13 @@ import { ACTIVE_LEAD_STATUS, isActiveLeadRow } from './lead-worker-index/lead-ro
15
15
  import { createLeadIndexFile } from './lead-worker-index/index-file.mjs';
16
16
  import { createRowSettlement } from './lead-worker-index/row-settlement.mjs';
17
17
  import { createLeadReapTimers } from './lead-worker-index/reap-timers.mjs';
18
+ import { createForgottenLeads } from './lead-worker-index/forgotten-leads.mjs';
18
19
 
19
- export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession }) {
20
+ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession, isSessionRunning }) {
20
21
  const activeLeadSessions = new Set();
21
22
  const index = createLeadIndexFile({ dataDir });
22
- const settlement = createRowSettlement({ dataDir, cfgMod });
23
+ const forgotten = createForgottenLeads(dataDir);
24
+ const settlement = createRowSettlement({ cfgMod, isSessionRunning });
23
25
  const reaps = createLeadReapTimers({ removeRow: (sessionId, reapAt) => removeLeadWorkerRow(sessionId, reapAt) });
24
26
 
25
27
  function removeLeadWorkerRow(sessionId, expectedReapAt = '') {
@@ -36,8 +38,25 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
36
38
  return true;
37
39
  }
38
40
 
41
+ /** A deleted Lead leaves the pool now, running or not, and never returns. A
42
+ * turn still unwinding after the delete settles by upserting its idle row —
43
+ * possibly through another index instance of this process — so the guard is
44
+ * process-wide (forgotten-leads.mjs). */
45
+ function forgetLeadSession(sessionId) {
46
+ const id = clean(sessionId);
47
+ if (!id) return false;
48
+ forgotten.forget(id);
49
+ reaps.cancel(id);
50
+ activeLeadSessions.delete(id);
51
+ index.write((byKey) => {
52
+ byKey.delete(id);
53
+ });
54
+ return true;
55
+ }
56
+
39
57
  function upsertLeadSession(session, extra = {}) {
40
58
  if (!session?.id || typeof workerRowFromSession !== 'function') return false;
59
+ if (forgotten.isForgotten(session.id)) return false;
41
60
  const owner = clean(session.owner).toLowerCase();
42
61
  const agent = clean(session.agent).toLowerCase();
43
62
  if (owner === 'agent' || (agent && agent !== 'lead')) return false;
@@ -54,20 +73,31 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
54
73
  updatedAt: new Date(now).toISOString(),
55
74
  });
56
75
  if (!row) return false;
76
+ const settled = !ACTIVE_LEAD_STATUS.test(status) && !ACTIVE_LEAD_STATUS.test(stage);
57
77
  const normalized = {
58
78
  ...row,
79
+ // The pane lists a settled Lead for a fixed window from this stamp.
80
+ finishedAt: settled ? row.finishedAt || new Date(now).toISOString() : row.finishedAt,
59
81
  // Liveness identity of the runtime that owns this status. A row stamped
60
82
  // by a process that no longer exists is recovered on the next boot.
61
83
  runtimePid: process.pid,
62
84
  reapAt: reapMs == null ? null : new Date(now + reapMs).toISOString(),
63
85
  };
64
- index.write((byKey) => byKey.set(session.id, normalized));
65
- if (ACTIVE_LEAD_STATUS.test(status) || ACTIVE_LEAD_STATUS.test(stage)) {
66
- activeLeadSessions.add(session.id);
67
- reaps.cancel(session.id);
68
- } else {
86
+ // Re-run against the locked fresh document at persist time: a delete that
87
+ // lands (here or in another instance) between this call and the write must
88
+ // still win over the queued row.
89
+ index.write(
90
+ (byKey) => {
91
+ if (!forgotten.isForgotten(session.id)) byKey.set(session.id, normalized);
92
+ },
93
+ { rerun: true }
94
+ );
95
+ if (settled) {
69
96
  activeLeadSessions.delete(session.id);
70
97
  reaps.schedule(normalized);
98
+ } else {
99
+ activeLeadSessions.add(session.id);
100
+ reaps.cancel(session.id);
71
101
  }
72
102
  return true;
73
103
  }
@@ -95,6 +125,7 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
95
125
  const now = Date.now();
96
126
  index.write((byKey) => {
97
127
  for (const id of ids) {
128
+ if (forgotten.isForgotten(id)) continue;
98
129
  const current = byKey.get(id);
99
130
  if (!current || !isActiveLeadRow(current)) continue;
100
131
  byKey.set(id, settlement.idleLeadRow(current, now, true));
@@ -133,29 +164,66 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
133
164
  recoverStaleLeadRows();
134
165
  function flushLeadIndexOnExit() {
135
166
  flushActiveLeadRows();
136
- // Writes are persisted by an async queue; the loop is gone at exit.
167
+ // Writes are persisted by an async queue; the loop is gone at exit. This
168
+ // is the best-effort last resort: a persist still running is left alone
169
+ // (the graceful shutdown path drains before exit).
137
170
  index.flushSync();
138
171
  }
139
172
  const unregisterExitFlush = registerExitFlush(flushLeadIndexOnExit);
140
173
  let disposed = false;
174
+ let disposePromise = null;
175
+
176
+ function teardown() {
177
+ reaps.cancelAll();
178
+ unregisterExitFlush();
179
+ }
180
+
181
+ async function drainThenTeardown() {
182
+ await index.flush();
183
+ teardown();
184
+ }
141
185
 
142
186
  /** Persist queued rows, drop owned reap timers, unregister. `settle` (a real
143
187
  * teardown) also idles this runtime's own active Lead rows; a dispose that
144
- * keeps background work (idle eviction) leaves them for the next owner. */
188
+ * keeps background work (idle eviction) leaves them for the next owner.
189
+ * If the sync flush cannot run (our async writer holds the lock), the exit
190
+ * hook stays until the async drain settles. */
145
191
  function dispose({ settle = false } = {}) {
146
192
  if (disposed) return;
147
193
  disposed = true;
194
+ let flushed = false;
148
195
  try {
149
196
  if (settle) flushActiveLeadRows();
150
- index.flushSync();
151
- } finally {
152
- reaps.cancelAll();
153
- unregisterExitFlush();
197
+ flushed = index.flushSync();
198
+ } catch {}
199
+ if (flushed) {
200
+ teardown();
201
+ return;
202
+ }
203
+ disposePromise = drainThenTeardown().catch(reopenAfterFailedDrain);
204
+ }
205
+
206
+ /** A failed drain tears nothing down; allow a later dispose to retry it. */
207
+ function reopenAfterFailedDrain() {
208
+ disposed = false;
209
+ disposePromise = null;
210
+ }
211
+
212
+ function disposeAsync({ settle = false } = {}) {
213
+ if (!disposePromise) {
214
+ disposed = true;
215
+ if (settle) flushActiveLeadRows();
216
+ disposePromise = drainThenTeardown().catch((error) => {
217
+ reopenAfterFailedDrain();
218
+ throw error;
219
+ });
154
220
  }
221
+ return disposePromise;
155
222
  }
156
223
 
157
224
  return {
158
225
  dispose,
226
+ disposeAsync,
159
227
  leadWorkerIndexPath: index.path,
160
228
  readLeadWorkerRows: index.read,
161
229
  /** Resolves once every queued Lead index write is on disk. */
@@ -163,6 +231,7 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
163
231
  upsertLeadSession,
164
232
  updateLeadWorkerCwd,
165
233
  removeLeadWorkerRow,
234
+ forgetLeadSession,
166
235
  flushActiveLeadRows,
167
236
  recoverStaleLeadRows,
168
237
  };
@@ -0,0 +1,82 @@
1
+ // One-off model selection for a spawn the user explicitly pinned to a model.
2
+ // The agent's preset route stays the default; this only runs when `model` is
3
+ // passed. The query is matched against the live provider catalog — exact id,
4
+ // then exact display name, then every query word — and a catalog miss retries
5
+ // once on a refreshed catalog. One match runs; several or none fail with
6
+ // candidates instead of substituting another model.
7
+ import { clean } from './helpers.mjs';
8
+
9
+ const CANDIDATE_LIMIT = 8;
10
+
11
+ const norm = (value) =>
12
+ String(value || '')
13
+ .toLowerCase()
14
+ .replace(/[^a-z0-9]+/g, '');
15
+ const terms = (value) =>
16
+ String(value || '')
17
+ .toLowerCase()
18
+ .split(/\s+/)
19
+ .map(norm)
20
+ .filter(Boolean);
21
+ const label = (row) => `${row.provider}/${row.id}`;
22
+
23
+ function providerRows(rows, provider) {
24
+ if (!provider) return rows;
25
+ const wanted = norm(provider);
26
+ const exact = rows.filter((row) => norm(row.provider) === wanted);
27
+ return exact.length ? exact : rows.filter((row) => norm(row.provider).includes(wanted));
28
+ }
29
+
30
+ function matchModels(rows, query) {
31
+ const wanted = norm(query);
32
+ const words = terms(query);
33
+ // Nothing to match on ("???"): `[].every` would accept every row.
34
+ if (!words.length) return [];
35
+ const tiers = [
36
+ (row) => norm(row.id) === wanted,
37
+ (row) => norm(row.display) === wanted,
38
+ (row) => words.every((word) => `${norm(row.id)} ${norm(row.display)}`.includes(word)),
39
+ ];
40
+ for (const test of tiers) {
41
+ const hits = rows.filter(test);
42
+ if (hits.length) return hits;
43
+ }
44
+ return [];
45
+ }
46
+
47
+ function candidates(rows) {
48
+ const shown = rows.slice(0, CANDIDATE_LIMIT).map(label).join(', ');
49
+ return rows.length > CANDIDATE_LIMIT ? `${shown}, … (${rows.length} total)` : shown;
50
+ }
51
+
52
+ /** Resolve args.provider/args.model to one exact catalog route. Without a
53
+ * catalog (headless/daemon surfaces) exact provider + model pass through. */
54
+ export async function resolveRequestedModel(args, listProviderModels) {
55
+ const model = clean(args.model);
56
+ const provider = clean(args.provider);
57
+ if (!model) {
58
+ if (provider) throw new Error('agent spawn: provider requires model');
59
+ return args;
60
+ }
61
+ if (typeof listProviderModels !== 'function') {
62
+ if (!provider) throw new Error('agent spawn: model requires provider on this surface');
63
+ // Punctuation alone names no model; the catalog path rejects it the same way.
64
+ if (!terms(model).length) throw new Error(`agent spawn: model "${model}" for provider "${provider}" not found`);
65
+ return args;
66
+ }
67
+ let pool = providerRows(await listProviderModels(), provider);
68
+ let hits = matchModels(pool, model);
69
+ if (!hits.length) {
70
+ pool = providerRows(await listProviderModels({ force: true }), provider);
71
+ hits = matchModels(pool, model);
72
+ }
73
+ if (hits.length === 1) return { ...args, provider: hits[0].provider, model: hits[0].id };
74
+ const scope = provider ? ` for provider "${provider}"` : '';
75
+ if (hits.length > 1) {
76
+ throw new Error(`agent spawn: model "${model}"${scope} is ambiguous: ${candidates(hits)}; pass the exact one`);
77
+ }
78
+ if (!pool.length) {
79
+ throw new Error(`agent spawn: provider "${provider}" has no available models`);
80
+ }
81
+ throw new Error(`agent spawn: model "${model}"${scope} not found; available: ${candidates(pool)}`);
82
+ }
@@ -1,4 +1,5 @@
1
1
  import {
2
+ isAgentProgressWatchdogAbortError,
2
3
  resolveAgentWatchdogPolicy,
3
4
  resolveHandoffMessageStartIndex,
4
5
  turnPartialHandoff,
@@ -15,6 +16,7 @@ import {
15
16
  terminalResultHook,
16
17
  } from './job-task-reconcile.mjs';
17
18
  import { createTurnReviewCollector } from './turn-review.mjs';
19
+ import { settledWorkerStatus } from './worker-index/row-liveness.mjs';
18
20
 
19
21
  // `send` to an existing worker: resolve the live session, run one follow-up
20
22
  // turn under the progress watchdog, and reconcile the job/worker row. Busy
@@ -28,7 +30,6 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
28
30
  if (!sessionId) throw new Error(`agent send: target "${target}" not found`);
29
31
  const session = mgr.getSession(sessionId);
30
32
  if (!session || session.closed) throw new Error(`agent send: session "${sessionId}" is closed`);
31
- registry.cancelReap(sessionId);
32
33
  const prompt = await resolvePrompt(args, session.cwd || defaultCwd);
33
34
  return { args, session, sessionId, prompt };
34
35
  }
@@ -82,13 +83,18 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
82
83
  const tag = registry.tagForSession(sessionId);
83
84
  // Queued sends run as follow-up turns inside this same askSession call;
84
85
  // the watchdog sweep re-stamps turnStartedAt at each turn boundary.
85
- const watchdog = spawnFlow.startProgressIdleWatchdog(sessionId, resolveAgentWatchdogPolicy(sendAgent), sendAgent, {
86
+ const watchdogPolicy = resolveAgentWatchdogPolicy(
87
+ sendAgent,
88
+ spawnFlow.agentWatchdogOverrides({ agent: sendAgent, provider: session.provider, model: session.model })
89
+ );
90
+ const watchdog = spawnFlow.startProgressIdleWatchdog(sessionId, watchdogPolicy, sendAgent, {
86
91
  onTurnStart: spawnFlow.turnStartStamper(session, tag),
87
92
  onProgress: spawnFlow.progressStamper(session, tag),
88
93
  });
89
94
  const turnReview = createTurnReviewCollector(session, tag, sendAgent, notifyContext || {});
90
95
  const completionValue = completionValueFor({ session, tag, sessionId, sendAgent });
91
96
  let finalStatus = 'idle';
97
+ let stalled = false;
92
98
  registry.upsertWorkerSessionDeferred(session, tag, {
93
99
  status: 'running',
94
100
  stage: 'running',
@@ -129,6 +135,7 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
129
135
  settleCancelled(error);
130
136
  throw error;
131
137
  }
138
+ stalled = isAgentProgressWatchdogAbortError(error);
132
139
  const partial = watchdogPartialHandoffFromError(error, mgr.getSession(sessionId), handoffMsgStart);
133
140
  if (partial) {
134
141
  finalStatus = 'idle';
@@ -152,12 +159,10 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
152
159
  turnReview.complete();
153
160
  watchdog?.stop?.();
154
161
  registry.upsertWorkerSessionDeferred(session, tag, {
155
- status: finalStatus,
156
- stage: finalStatus,
162
+ ...settledWorkerStatus(finalStatus, stalled),
157
163
  finishedAt: new Date().toISOString(),
158
164
  });
159
165
  reconcileJobFinally(job, finalStatus);
160
- registry.scheduleReap(sessionId);
161
166
  // Same lifecycle as a fresh spawn: the transcript/tag stays resumable,
162
167
  // while heavy process-local runtime state is reclaimed immediately.
163
168
  try {
@@ -166,11 +171,24 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
166
171
  }
167
172
  }
168
173
 
174
+ // An explicit model on a reused tag goes through the session's own route
175
+ // API, which saves it and applies it from the session's next turn: the
176
+ // dispatched prompt when the session is idle, a later one while it is busy.
177
+ async function applyRequestedRoute(prepared) {
178
+ const { session, sessionId, route } = prepared;
179
+ if (!canUseSessionSurface(session) || typeof sessionSurface.setRoute !== 'function') {
180
+ throw new Error(`agent spawn: this surface cannot change the model of reused session "${sessionId}"`);
181
+ }
182
+ await sessionSurface.setRoute({ session, route });
183
+ return { ...prepared, session: mgr.getSession(sessionId) || session };
184
+ }
185
+
169
186
  // Shared send dispatch for an already-resolved live session. Used by the
170
187
  // `send` branch AND by the `spawn` branch when an explicit tag maps to a
171
188
  // live session (reuse path). Busy sessions queue the prompt; idle ones run a
172
189
  // background send job that continues the existing session (context kept).
173
- async function dispatchToExistingSession(prepared, notifyContext, extras = {}) {
190
+ async function dispatchToExistingSession(requested, notifyContext, extras = {}) {
191
+ const prepared = requested.route ? await applyRequestedRoute(requested) : requested;
174
192
  const { session, sessionId, prompt } = prepared;
175
193
  const tag = registry.tagForSession(sessionId);
176
194
  if (canUseSessionSurface(session) && views.isSessionBusy(sessionId)) {
@@ -53,7 +53,9 @@ export function createJobStarter({ mgr, notifyStatusChange, notifySessionComplet
53
53
  const currentMeta = task?.meta || jobMeta;
54
54
  if (currentMeta?.sessionId) {
55
55
  try {
56
- Promise.resolve(mgr.closeSession(currentMeta.sessionId, 'agent-task-cancel')).catch(() => {});
56
+ Promise.resolve(mgr.closeSession(currentMeta.sessionId, 'agent-task-cancel', { tombstone: false })).catch(
57
+ () => {}
58
+ );
57
59
  } catch {}
58
60
  }
59
61
  setImmediate(notifyStatusChange);
@@ -4,7 +4,7 @@
4
4
  * route, and the transport prewarm. The validated spawn plan and the session
5
5
  * spec it produces live in ./spawn-plan.mjs.
6
6
  */
7
- import { presetKey, writeAgentStatuslineRoute } from '../helpers.mjs';
7
+ import { presetKey, readAgentFirstResponseTimeoutMs, writeAgentStatuslineRoute } from '../helpers.mjs';
8
8
  import { resolveAgentWatchdogPolicy } from '../../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
9
9
  import { prepareAgentSession } from '../../../../runtime/agent/orchestrator/agent-runtime/session-builder.mjs';
10
10
  import { getProvider } from '../../../../runtime/agent/orchestrator/providers/registry.mjs';
@@ -55,7 +55,6 @@ export function createSpawnPreparer({
55
55
  resolveTag,
56
56
  wantsSessionScan,
57
57
  bindTag,
58
- cancelReap,
59
58
  ensureProvider,
60
59
  sessionSurface = null,
61
60
  refreshTagsFromSessions,
@@ -71,6 +70,19 @@ export function createSpawnPreparer({
71
70
  wantsSessionScan,
72
71
  });
73
72
 
73
+ /** Watchdog inputs for one agent run: the agent definition's own
74
+ * first-response deadline and the provider's first-response budget for the
75
+ * routed model (headers, and first output), handed to
76
+ * resolveAgentWatchdogPolicy. A provider on the shared window names none. */
77
+ function agentWatchdogOverrides({ agent, provider, model }) {
78
+ const budget = getProvider(provider)?.firstResponseBudget?.(model);
79
+ return {
80
+ firstResponseTimeoutMs: readAgentFirstResponseTimeoutMs(agent, dataDir, STANDALONE_SOURCE_ROOT) ?? undefined,
81
+ providerFirstByteTimeoutMs: budget?.transportMs,
82
+ providerFirstOutputTimeoutMs: budget?.semanticMs,
83
+ };
84
+ }
85
+
74
86
  /** Shared post-create wiring. Lead sessions write a gateway-session route on
75
87
  * create; agent sessions are built through prepareAgentSession()/the remote
76
88
  * runtime, so mirror that registration here or the vendored L1/L2
@@ -79,7 +91,6 @@ export function createSpawnPreparer({
79
91
  const { agent, presetName, preset, tag } = plan;
80
92
  writeAgentStatuslineRoute(session.id, preset);
81
93
  bindTag(tag, session, { ...presetDescriptor(agent, preset, presetName), status: 'idle', stage: 'idle' });
82
- cancelReap(session.id);
83
94
  }
84
95
 
85
96
  async function createSpawnedSession(plan, spec, prepState) {
@@ -127,7 +138,10 @@ export function createSpawnPreparer({
127
138
  presetName: plan.presetName,
128
139
  workerCwd: effectiveCwd || plan.workerCwd,
129
140
  prompt: plan.prompt,
130
- watchdogPolicy: resolveAgentWatchdogPolicy(plan.agent),
141
+ watchdogPolicy: resolveAgentWatchdogPolicy(
142
+ plan.agent,
143
+ agentWatchdogOverrides({ agent: plan.agent, provider: plan.preset.provider, model: plan.preset.model })
144
+ ),
131
145
  };
132
146
  }
133
147
 
@@ -136,5 +150,5 @@ export function createSpawnPreparer({
136
150
  return prepareSpawnInProcess(args, callerCwd, context, prepState);
137
151
  }
138
152
 
139
- return { prepareSpawn, prepareSpawnInProcess, createSpawnedSession };
153
+ return { prepareSpawn, prepareSpawnInProcess, createSpawnedSession, agentWatchdogOverrides };
140
154
  }
@@ -15,11 +15,13 @@ import {
15
15
  import { abnormalEmptyFinishError } from '../render.mjs';
16
16
  import { createProgressWatchdogRegistry } from '../../agent-watchdog-registry.mjs';
17
17
  import {
18
+ isAgentProgressWatchdogAbortError,
18
19
  resolveHandoffMessageStartIndex,
19
20
  turnPartialHandoff,
20
21
  watchdogPartialHandoffFromError,
21
22
  watchdogStoppedHandoff,
22
23
  } from '../../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
24
+ import { settledWorkerStatus } from '../worker-index/row-liveness.mjs';
23
25
  import { saveSessionAsync } from '../../../../runtime/agent/orchestrator/session/store.mjs';
24
26
  import { presetDescriptor } from './spawn-prep.mjs';
25
27
  import { workerStageForStatus } from '../worker-rows.mjs';
@@ -35,7 +37,6 @@ export function createSpawnRunner({
35
37
  notifyStatusChange = () => {},
36
38
  notifySessionCompletion,
37
39
  emitSubagentEvent,
38
- scheduleReap,
39
40
  sessionSurface = null,
40
41
  createTurnReviewCollector,
41
42
  }) {
@@ -128,6 +129,7 @@ export function createSpawnRunner({
128
129
  const turnReview = createTurnReviewCollector(session, tag, agent, notifyContext || {});
129
130
  const completionValue = completionValueFor(prepared);
130
131
  let finalStatus = 'idle';
132
+ let stalled = false;
131
133
  // SubagentStart: a worker session is about to run its first turn.
132
134
  emitSubagentEvent('start', agent, { session_id: session.id, tag });
133
135
  upsertWorkerSessionDeferred(session, tag, {
@@ -189,6 +191,7 @@ export function createSpawnRunner({
189
191
  settleCancelled(error);
190
192
  throw error;
191
193
  }
194
+ stalled = isAgentProgressWatchdogAbortError(error);
192
195
  const partial = watchdogPartialHandoffFromError(error, mgr.getSession(session.id), handoffMsgStart);
193
196
  if (partial) {
194
197
  finalStatus = 'idle';
@@ -211,13 +214,11 @@ export function createSpawnRunner({
211
214
  watchdog?.stop?.();
212
215
  upsertWorkerSessionDeferred(session, tag, {
213
216
  ...presetDescriptor(agent, preset, presetName),
214
- status: finalStatus,
215
- stage: finalStatus,
217
+ ...settledWorkerStatus(finalStatus, stalled),
216
218
  finishedAt: new Date().toISOString(),
217
219
  });
218
220
  setImmediate(notifyStatusChange);
219
221
  reconcileJobFinally(job, finalStatus);
220
- scheduleReap(session.id);
221
222
  // SubagentStop: worker finished (terminal), regardless of outcome.
222
223
  emitSubagentEvent('stop', agent, { session_id: session.id, tag, status: finalStatus });
223
224
  // Keep the durable session/tag for same-tag follow-ups, but release every
@@ -14,7 +14,7 @@ export function createSpawnFlow(deps) {
14
14
  notifyStatusChange: deps.notifyStatusChange ?? (() => {}),
15
15
  notifySessionCompletion: deps.notifySessionCompletion,
16
16
  });
17
- const { prepareSpawn, prepareSpawnInProcess } = createSpawnPreparer(deps);
17
+ const { prepareSpawn, prepareSpawnInProcess, agentWatchdogOverrides } = createSpawnPreparer(deps);
18
18
  const runner = createSpawnRunner(deps);
19
19
  const { closePreparedSpawn, startDeferredSpawnJob } = createDeferredSpawn({
20
20
  ...deps,
@@ -35,6 +35,7 @@ export function createSpawnFlow(deps) {
35
35
  progressStamper: runner.progressStamper,
36
36
  prepareSpawn,
37
37
  prepareSpawnInProcess,
38
+ agentWatchdogOverrides,
38
39
  runSpawn: runner.runSpawn,
39
40
  };
40
41
  }
@@ -41,6 +41,9 @@ export function resolveAgentSpawnPreset(config, args = {}) {
41
41
  type: 'agent',
42
42
  provider: agentRoute.provider,
43
43
  model: agentRoute.model,
44
+ ...(config.agents?.[agentName]?.fallbacks?.length
45
+ ? { fallbacks: config.agents[agentName].fallbacks.map(normalizeAgentRoute) }
46
+ : {}),
44
47
  effort: agentRoute.effort,
45
48
  fast: agentRoute.fast === true,
46
49
  ...(agentRoute.autoEffort === false ? { autoEffort: false } : {}),
@@ -61,15 +61,13 @@ export function createTagLookup({ tags, mgr, readWorkerRows, reaper, getLiveSess
61
61
  };
62
62
  for (const row of readWorkerRows(context)) addIndexRow(row);
63
63
  if (scanSessions) {
64
- const pendingTerminal = [];
65
64
  for (const session of mgr.listSessions({ includeClosed: false }) || []) {
66
65
  if (session?.closed === true) continue;
67
66
  const tag = agentTagOf(session);
68
67
  if (tag && reaper.tombstoneBlocksScan(session, tag, tombstones)) continue;
69
68
  add(session, tag);
70
- if (tag) reaper.scanUpsertSession(session, tag, tombstones, pendingTerminal);
69
+ if (tag) reaper.scanUpsertSession(session, tag, tombstones);
71
70
  }
72
- reaper.settleScannedTerminalRows(pendingTerminal);
73
71
  }
74
72
  for (const [tag, sessionId] of tags.entries()) {
75
73
  const session = getLiveSession(sessionId);
@@ -18,7 +18,6 @@ export function createTagRefresh({ tags, tagMaps, mgr, reaper, refreshTagsFromIn
18
18
  // Tags missing from the index are exactly the ones a reap just removed, so
19
19
  // the tombstone (not the still-open session record) decides whether this
20
20
  // scan may re-bind them.
21
- const pendingTerminal = [];
22
21
  for (const session of mgr.listSessions({ includeClosed: false }) || []) {
23
22
  if (isLeadPoolAgent(session?.agent)) continue;
24
23
  if (session?.closed === true) continue;
@@ -27,8 +26,7 @@ export function createTagRefresh({ tags, tagMaps, mgr, reaper, refreshTagsFromIn
27
26
  if (!sessionMatchesContext(session, context)) continue;
28
27
  if (reaper.tombstoneBlocksScan(session, tag, tombstones)) continue;
29
28
  tagMaps.bind(tag, session);
30
- reaper.scanUpsertSession(session, tag, tombstones, pendingTerminal);
29
+ reaper.scanUpsertSession(session, tag, tombstones);
31
30
  }
32
- reaper.settleScannedTerminalRows(pendingTerminal);
33
31
  };
34
32
  }