mixdog 1.2.1 → 1.2.3

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 (557) hide show
  1. package/README.md +18 -0
  2. package/package.json +2 -1
  3. package/scripts/gate-local.mjs +19 -3
  4. package/scripts/model-catalog-audit.mjs +1 -15
  5. package/scripts/provider-pingpong-live.mjs +509 -0
  6. package/src/agents/advisor/AGENT.md +1 -1
  7. package/src/agents/advisor/agent.json +1 -1
  8. package/src/agents/reviewer/AGENT.md +3 -3
  9. package/src/agents/reviewer/agent.json +1 -1
  10. package/src/defaults/shipped-history.json +6 -0
  11. package/src/defaults/skills/setup/SKILL.md +6 -1
  12. package/src/defaults/skills/setup/references/actions.md +44 -22
  13. package/src/defaults/skills/setup/references/surfaces.md +10 -8
  14. package/src/headless-exec.mjs +15 -8
  15. package/src/lib/keychain-cjs.cjs +7 -4
  16. package/src/output-styles/common.md +11 -10
  17. package/src/repl/slash-commands.mjs +16 -1
  18. package/src/rules/agent/AGENT.md +5 -5
  19. package/src/rules/lead/LEAD.md +5 -5
  20. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
  21. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
  22. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
  23. package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
  24. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
  25. package/src/runtime/agent/orchestrator/config.mjs +5 -0
  26. package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
  27. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
  28. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
  29. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +36 -7
  30. package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +49 -10
  31. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +40 -3
  32. package/src/runtime/agent/orchestrator/mcp/client.mjs +230 -96
  33. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
  34. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
  35. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
  36. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
  37. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
  38. package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
  39. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
  40. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
  41. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +188 -29
  42. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
  43. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
  44. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
  45. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +98 -0
  46. package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
  47. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
  48. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +48 -37
  49. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +10 -7
  50. package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
  51. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
  52. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  53. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
  54. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
  55. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
  56. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +102 -45
  58. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
  59. package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
  60. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
  61. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
  62. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
  63. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
  65. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
  66. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
  67. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +10 -1
  68. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
  69. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +40 -7
  70. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
  71. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
  72. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +88 -21
  73. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +30 -10
  74. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +106 -0
  75. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
  76. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +94 -15
  77. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  78. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
  79. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
  80. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +75 -10
  81. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  82. package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
  83. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +103 -23
  84. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
  85. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
  86. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +32 -6
  87. package/src/runtime/agent/orchestrator/providers/cursor.mjs +27 -3
  88. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +64 -1
  89. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +70 -6
  90. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
  91. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
  92. package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
  93. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +80 -18
  94. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
  95. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +46 -8
  96. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +273 -0
  97. package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
  98. package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
  99. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
  100. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
  101. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
  102. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +369 -112
  103. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +3 -1
  104. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +140 -35
  105. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +70 -24
  106. package/src/runtime/agent/orchestrator/providers/gemini.mjs +80 -29
  107. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  108. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
  109. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +69 -19
  110. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
  111. package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
  112. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +246 -42
  113. package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
  114. package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
  115. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +388 -0
  116. package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
  117. package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
  118. package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
  119. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
  120. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +48 -22
  121. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +119 -18
  122. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
  123. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
  124. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -1
  125. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
  126. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  127. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +33 -1
  128. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
  129. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -0
  130. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +123 -61
  132. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
  133. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +27 -2
  134. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +37 -7
  135. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
  136. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +1 -0
  137. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
  138. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +47 -2
  139. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
  140. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
  141. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +151 -0
  142. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +64 -23
  143. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +79 -33
  144. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
  145. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +172 -0
  146. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
  147. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +144 -15
  148. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
  149. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
  150. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +9 -2
  151. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
  152. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +109 -26
  153. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +27 -6
  154. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +34 -20
  155. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +23 -4
  156. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +37 -28
  157. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
  158. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
  159. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
  160. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +43 -15
  161. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
  162. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
  163. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +5 -2
  164. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
  165. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +7 -3
  166. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
  167. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
  168. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
  169. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
  170. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +37 -4
  171. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +12 -1
  172. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
  173. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +12 -1
  174. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +76 -33
  175. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
  176. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +44 -16
  177. package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
  178. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -16
  179. package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
  180. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
  181. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -35
  182. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
  183. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
  184. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
  185. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
  186. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
  187. package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
  188. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +41 -22
  189. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +170 -0
  190. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +75 -70
  191. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +75 -0
  192. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +720 -0
  193. package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
  194. package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
  195. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +123 -219
  196. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
  197. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
  198. package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
  199. package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
  200. package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
  201. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +157 -0
  202. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +512 -0
  203. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
  204. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +183 -0
  205. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +100 -0
  206. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
  207. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +21 -0
  208. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
  209. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
  210. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
  211. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
  212. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -97
  213. package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
  214. package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
  215. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +14 -3
  216. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
  217. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  218. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
  219. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +176 -71
  220. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +62 -10
  221. package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
  222. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -1
  223. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
  224. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +14 -93
  225. package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
  226. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +120 -0
  227. package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
  228. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
  229. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +2 -1
  230. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
  231. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +91 -1
  232. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
  233. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
  234. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
  235. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -0
  236. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +21 -10
  237. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +132 -0
  238. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +30 -0
  239. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
  240. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +104 -19
  241. package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
  242. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
  243. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -4
  244. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
  245. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +150 -0
  246. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -2
  247. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +30 -2
  248. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +11 -2
  249. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -1
  250. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
  251. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +57 -21
  252. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
  253. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
  254. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
  255. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
  256. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +5 -10
  257. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +208 -14
  258. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +16 -4
  259. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +25 -3
  260. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
  261. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -2
  262. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
  263. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
  264. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
  265. package/src/runtime/agent/orchestrator/session/manager.mjs +2 -1
  266. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
  267. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +168 -29
  268. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
  269. package/src/runtime/agent/orchestrator/session/side-question.mjs +192 -0
  270. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +17 -3
  271. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
  272. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +58 -2
  273. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
  274. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +41 -28
  275. package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
  276. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +12 -1
  277. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +3 -1
  278. package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
  279. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
  280. package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
  281. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +6 -0
  282. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +13 -0
  283. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +13 -1
  284. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +10 -2
  285. package/src/runtime/agent/orchestrator/session/store.mjs +19 -3
  286. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +1 -0
  287. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +1 -1
  288. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
  289. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
  290. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
  291. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +77 -0
  292. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +20 -1
  293. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
  294. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
  295. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
  296. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
  297. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
  298. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
  299. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +14 -10
  300. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +49 -34
  301. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
  302. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
  303. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
  304. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
  305. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
  306. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
  307. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
  308. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
  309. package/src/runtime/computer-bridge/action-schema.mjs +44 -21
  310. package/src/runtime/github/tool.mjs +92 -2
  311. package/src/runtime/memory/index.mjs +1 -0
  312. package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
  313. package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
  314. package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
  315. package/src/runtime/memory/lib/pg/process.mjs +65 -50
  316. package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
  317. package/src/runtime/memory/lib/pg/supervisor.mjs +124 -16
  318. package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
  319. package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
  320. package/src/runtime/office/README.md +2 -2
  321. package/src/runtime/office/authoring/html-document-author.mjs +2 -0
  322. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
  323. package/src/runtime/office/authoring/pptx-html-measure.mjs +2 -0
  324. package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
  325. package/src/runtime/office/authoring/xlsx-html-runner.mjs +2 -0
  326. package/src/runtime/office/core/office-actions-read.mjs +3 -0
  327. package/src/runtime/office/core/office-render-preview.mjs +2 -0
  328. package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
  329. package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
  330. package/src/runtime/office/core/office-sessions.mjs +5 -0
  331. package/src/runtime/office/core/office-transactions.mjs +3 -0
  332. package/src/runtime/office/core/office-write-ledger.mjs +98 -0
  333. package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
  334. package/src/runtime/office/index.mjs +30 -0
  335. package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
  336. package/src/runtime/office/pdf/pdf-render.mjs +23 -7
  337. package/src/runtime/office/pdf/pdf-security.mjs +2 -0
  338. package/src/runtime/office/portable/portable-opc.mjs +4 -1
  339. package/src/runtime/office/quality/visual-diff.mjs +2 -0
  340. package/src/runtime/office/shared/values.mjs +0 -5
  341. package/src/runtime/shared/background-tasks.mjs +92 -14
  342. package/src/runtime/shared/bounded-file-read.mjs +13 -0
  343. package/src/runtime/shared/bounded-line-diff.mjs +182 -0
  344. package/src/runtime/shared/buffered-appender.mjs +18 -0
  345. package/src/runtime/shared/config.mjs +78 -18
  346. package/src/runtime/shared/err-text.mjs +31 -0
  347. package/src/runtime/shared/error-presentation.mjs +159 -19
  348. package/src/runtime/shared/file-permissions.d.mts +6 -1
  349. package/src/runtime/shared/file-permissions.mjs +54 -6
  350. package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
  351. package/src/runtime/shared/llm/anthropic-effort.mjs +129 -134
  352. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
  353. package/src/runtime/shared/llm/model-catalog.mjs +53 -40
  354. package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
  355. package/src/runtime/shared/llm/provider-catalog-registry.mjs +11 -0
  356. package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
  357. package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
  358. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
  359. package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
  360. package/src/runtime/shared/loopback-listener.mjs +9 -0
  361. package/src/runtime/shared/model-display.mjs +13 -0
  362. package/src/runtime/shared/provider-api-key.mjs +2 -0
  363. package/src/runtime/shared/quota-resume-store.mjs +11 -0
  364. package/src/runtime/shared/review-diff.mjs +52 -0
  365. package/src/runtime/shared/session-baseline-store.mjs +960 -0
  366. package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
  367. package/src/runtime/shared/session-sidebar-host.mjs +38 -0
  368. package/src/runtime/shared/slow-span.mjs +114 -0
  369. package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
  370. package/src/runtime/shared/statusline/statusline-segments.mjs +28 -4
  371. package/src/runtime/shared/task-notification-envelope.mjs +2 -2
  372. package/src/runtime/shared/tool-card-model/card-header.mjs +6 -1
  373. package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
  374. package/src/runtime/shared/tool-card-model.mjs +5 -2
  375. package/src/runtime/shared/tool-output-limit.mjs +4 -0
  376. package/src/runtime/shared/tool-primitives.mjs +13 -0
  377. package/src/runtime/shared/tool-result-summary.mjs +8 -1
  378. package/src/runtime/shared/tool-surface.mjs +18 -3
  379. package/src/runtime/shared/tool-work-units.mjs +40 -4
  380. package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
  381. package/src/runtime/shared/transcript-writer.mjs +10 -2
  382. package/src/runtime/shared/turn-changes.mjs +670 -274
  383. package/src/runtime/shared/turn-review-reply.mjs +8 -39
  384. package/src/runtime/shared/turn-snapshot-store.mjs +94 -2
  385. package/src/runtime/shared/turn-snapshot.mjs +986 -690
  386. package/src/runtime/shared/turn-worktree-snapshot.mjs +279 -262
  387. package/src/runtime/shared/user-data-guard.mjs +262 -49
  388. package/src/runtime/shared/worktrees/carry.mjs +531 -0
  389. package/src/runtime/shared/worktrees/contract.mjs +34 -24
  390. package/src/runtime/shared/worktrees/file-recovery.mjs +68 -0
  391. package/src/runtime/shared/worktrees/git-head.mjs +205 -0
  392. package/src/runtime/shared/worktrees/git.mjs +8 -3
  393. package/src/runtime/shared/worktrees/maintenance.mjs +1 -1
  394. package/src/runtime/shared/worktrees/manager.mjs +156 -8
  395. package/src/runtime/shared/worktrees/merge.mjs +31 -21
  396. package/src/runtime/shared/worktrees/paths.d.mts +6 -0
  397. package/src/runtime/shared/worktrees/test-support.mjs +19 -4
  398. package/src/runtime/terminal-bridge/client.mjs +44 -11
  399. package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
  400. package/src/runtime/tidy/apply.mjs +47 -2
  401. package/src/runtime/tidy/run-engines.mjs +11 -5
  402. package/src/session-runtime/agent-tool-routing.mjs +19 -13
  403. package/src/session-runtime/boot/apis.mjs +19 -5
  404. package/src/session-runtime/boot/facade.mjs +1 -0
  405. package/src/session-runtime/boot/infrastructure.mjs +12 -1
  406. package/src/session-runtime/boot/session.mjs +0 -1
  407. package/src/session-runtime/boot/tools.mjs +4 -1
  408. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
  409. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +65 -0
  410. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
  411. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +11 -4
  412. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +115 -18
  413. package/src/session-runtime/internal-tool-executor.mjs +6 -2
  414. package/src/session-runtime/lifecycle/cold-heir.mjs +188 -0
  415. package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
  416. package/src/session-runtime/lifecycle/session-catalog.mjs +14 -3
  417. package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
  418. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +29 -6
  419. package/src/session-runtime/lifecycle/teardown.mjs +73 -8
  420. package/src/session-runtime/lifecycle-api.mjs +1 -0
  421. package/src/session-runtime/mcp-glue/connect.mjs +46 -14
  422. package/src/session-runtime/mcp-glue/server-catalog.mjs +20 -3
  423. package/src/session-runtime/mcp-glue.mjs +3 -0
  424. package/src/session-runtime/mcp-oauth-login.mjs +174 -0
  425. package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
  426. package/src/session-runtime/model-route/set-route.mjs +85 -17
  427. package/src/session-runtime/model-route/web-search-route.mjs +1 -1
  428. package/src/session-runtime/native-web-search/routes.mjs +22 -3
  429. package/src/session-runtime/native-web-search-usage.mjs +51 -0
  430. package/src/session-runtime/native-web-search.mjs +10 -1
  431. package/src/session-runtime/new-session-config.mjs +4 -2
  432. package/src/session-runtime/provider-auth/login.mjs +4 -0
  433. package/src/session-runtime/provider-models/model-meta.mjs +12 -3
  434. package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
  435. package/src/session-runtime/quick-web-search-models.mjs +13 -38
  436. package/src/session-runtime/resource-extension-sync.mjs +4 -0
  437. package/src/session-runtime/resource-mcp-api.mjs +98 -2
  438. package/src/session-runtime/resource-scope-decorate.mjs +10 -3
  439. package/src/session-runtime/runtime-review-api.mjs +21 -2
  440. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
  441. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
  442. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
  443. package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
  444. package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
  445. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +73 -7
  446. package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
  447. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
  448. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
  449. package/src/session-runtime/services/agent-tool/tag-registry.mjs +15 -1
  450. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
  451. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -2
  452. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
  453. package/src/session-runtime/services/agent-tool/worker-index.mjs +46 -7
  454. package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
  455. package/src/session-runtime/services/agent-tool.mjs +3 -0
  456. package/src/session-runtime/services/channel-admin.mjs +19 -3
  457. package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
  458. package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
  459. package/src/session-runtime/services/provider-admin.mjs +81 -15
  460. package/src/session-runtime/session-transcript-purge.mjs +32 -0
  461. package/src/session-runtime/session-turn-api.mjs +14 -5
  462. package/src/session-runtime/settings-builtin-tools-api.mjs +9 -0
  463. package/src/session-runtime/settings-compaction-api.mjs +1 -0
  464. package/src/session-runtime/setup-tool/executor.mjs +36 -6
  465. package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
  466. package/src/session-runtime/setup-tool/settings-contract.mjs +13 -3
  467. package/src/session-runtime/setup-tool/tool-defs.mjs +13 -4
  468. package/src/session-runtime/skills-api.mjs +3 -5
  469. package/src/session-runtime/tool-surface.mjs +5 -1
  470. package/src/session-runtime/turn/compaction-gate.mjs +25 -0
  471. package/src/session-runtime/turn/session-ops.mjs +7 -5
  472. package/src/session-runtime/turn/side-question-ops.mjs +22 -0
  473. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +5 -1
  474. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +8 -3
  475. package/src/session-runtime/turn/turn-run/turn-settle.mjs +10 -0
  476. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  477. package/src/session-runtime/turn/turn-run.mjs +25 -9
  478. package/src/session-runtime/usage-stats-api.mjs +43 -11
  479. package/src/session-runtime/workspace/project-branches.mjs +7 -5
  480. package/src/session-runtime/workspace/transition-steps.mjs +129 -31
  481. package/src/session-runtime/workspace/transitions.mjs +190 -15
  482. package/src/standalone/daemon-agent-control.mjs +9 -1
  483. package/src/standalone/daemon-drain-policy.mjs +8 -0
  484. package/src/standalone/daemon-local-session-bridge.mjs +14 -1
  485. package/src/standalone/daemon-owner.mjs +17 -4
  486. package/src/standalone/daemon-pg-stop.mjs +51 -0
  487. package/src/standalone/daemon-stop-budget.d.mts +2 -0
  488. package/src/standalone/daemon-stop-budget.mjs +18 -0
  489. package/src/standalone/daemon-stored-session-views.mjs +2 -0
  490. package/src/standalone/daemon-telemetry.mjs +74 -0
  491. package/src/standalone/daemon.mjs +64 -8
  492. package/src/standalone/desktop-service-registry.mjs +5 -0
  493. package/src/standalone/local-session-runtime.mjs +70 -19
  494. package/src/standalone/session-client.mjs +42 -0
  495. package/src/standalone/session-protocol.mjs +14 -0
  496. package/src/standalone/session-proxy/projection.mjs +41 -4
  497. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
  498. package/src/standalone/session-runtime-inline-host.mjs +1 -0
  499. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
  500. package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
  501. package/src/standalone/session-service/agent-tree.mjs +12 -0
  502. package/src/standalone/session-service/quota-resume.mjs +8 -0
  503. package/src/standalone/session-service/retention/busy.mjs +15 -1
  504. package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
  505. package/src/standalone/session-service-api.mjs +11 -1
  506. package/src/standalone/session-service.mjs +1 -0
  507. package/src/standalone/session-state-patch.d.mts +2 -1
  508. package/src/standalone/session-state-patch.mjs +41 -1
  509. package/src/tui/App.jsx +25 -0
  510. package/src/tui/app/app-view/floating-panel.jsx +26 -1
  511. package/src/tui/app/app-view.jsx +1 -0
  512. package/src/tui/app/btw-controller.mjs +118 -0
  513. package/src/tui/app/create-app-pickers.mjs +6 -0
  514. package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
  515. package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
  516. package/src/tui/app/extension-pickers.mjs +2 -1
  517. package/src/tui/app/model-options.mjs +11 -16
  518. package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
  519. package/src/tui/app/shell-layout/surfaces.mjs +3 -1
  520. package/src/tui/app/slash-commands.mjs +20 -5
  521. package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
  522. package/src/tui/app/slash-dispatch/session-commands.mjs +19 -6
  523. package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
  524. package/src/tui/app/use-global-key-input.mjs +5 -12
  525. package/src/tui/app/use-prompt-handlers.mjs +11 -0
  526. package/src/tui/components/BtwPanel.jsx +53 -0
  527. package/src/tui/components/QuestionPanel.jsx +275 -0
  528. package/src/tui/components/StatusLine.jsx +2 -0
  529. package/src/tui/components/question-panel-model.mjs +156 -0
  530. package/src/tui/components/status-line/local-line.mjs +5 -2
  531. package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
  532. package/src/tui/dist/index.mjs +3221 -1500
  533. package/src/tui/session/context-state.mjs +4 -2
  534. package/src/tui/session/quota-resume.mjs +46 -14
  535. package/src/tui/session/session-api/commands.mjs +43 -24
  536. package/src/tui/session/session-api/controls.mjs +2 -2
  537. package/src/tui/session/session-api/extensions.mjs +22 -0
  538. package/src/tui/session/session-api/integrations.mjs +16 -2
  539. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  540. package/src/tui/session/session-api/lifecycle.mjs +7 -2
  541. package/src/tui/session/session-api/routes.mjs +71 -7
  542. package/src/tui/session/session-api/settings.mjs +11 -14
  543. package/src/tui/session/session-api.mjs +1 -0
  544. package/src/tui/session/session-flow/drain.mjs +7 -1
  545. package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
  546. package/src/tui/session/tool-approval.mjs +10 -7
  547. package/src/tui/session/transcript-spill.mjs +14 -7
  548. package/src/tui/session/turn-stream.mjs +174 -31
  549. package/src/tui/session/turn.mjs +46 -16
  550. package/src/tui/statusline-ansi-bridge.mjs +1 -1
  551. package/src/ui/statusline-agents.mjs +15 -4
  552. package/src/ui/statusline.mjs +7 -3
  553. package/src/ui/streaming-markdown-heal.mjs +34 -3
  554. package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
  555. package/src/workflows/default/WORKFLOW.md +3 -1
  556. package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
  557. package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
@@ -15,10 +15,12 @@ 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
20
  export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession }) {
20
21
  const activeLeadSessions = new Set();
21
22
  const index = createLeadIndexFile({ dataDir });
23
+ const forgotten = createForgottenLeads(dataDir);
22
24
  const settlement = createRowSettlement({ dataDir, cfgMod });
23
25
  const reaps = createLeadReapTimers({ removeRow: (sessionId, reapAt) => removeLeadWorkerRow(sessionId, reapAt) });
24
26
 
@@ -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;
@@ -61,7 +80,15 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
61
80
  runtimePid: process.pid,
62
81
  reapAt: reapMs == null ? null : new Date(now + reapMs).toISOString(),
63
82
  };
64
- index.write((byKey) => byKey.set(session.id, normalized));
83
+ // Re-run against the locked fresh document at persist time: a delete that
84
+ // lands (here or in another instance) between this call and the write must
85
+ // still win over the queued row.
86
+ index.write(
87
+ (byKey) => {
88
+ if (!forgotten.isForgotten(session.id)) byKey.set(session.id, normalized);
89
+ },
90
+ { rerun: true }
91
+ );
65
92
  if (ACTIVE_LEAD_STATUS.test(status) || ACTIVE_LEAD_STATUS.test(stage)) {
66
93
  activeLeadSessions.add(session.id);
67
94
  reaps.cancel(session.id);
@@ -95,6 +122,7 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
95
122
  const now = Date.now();
96
123
  index.write((byKey) => {
97
124
  for (const id of ids) {
125
+ if (forgotten.isForgotten(id)) continue;
98
126
  const current = byKey.get(id);
99
127
  if (!current || !isActiveLeadRow(current)) continue;
100
128
  byKey.set(id, settlement.idleLeadRow(current, now, true));
@@ -133,29 +161,66 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
133
161
  recoverStaleLeadRows();
134
162
  function flushLeadIndexOnExit() {
135
163
  flushActiveLeadRows();
136
- // Writes are persisted by an async queue; the loop is gone at exit.
164
+ // Writes are persisted by an async queue; the loop is gone at exit. This
165
+ // is the best-effort last resort: a persist still running is left alone
166
+ // (the graceful shutdown path drains before exit).
137
167
  index.flushSync();
138
168
  }
139
169
  const unregisterExitFlush = registerExitFlush(flushLeadIndexOnExit);
140
170
  let disposed = false;
171
+ let disposePromise = null;
172
+
173
+ function teardown() {
174
+ reaps.cancelAll();
175
+ unregisterExitFlush();
176
+ }
177
+
178
+ async function drainThenTeardown() {
179
+ await index.flush();
180
+ teardown();
181
+ }
141
182
 
142
183
  /** Persist queued rows, drop owned reap timers, unregister. `settle` (a real
143
184
  * 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. */
185
+ * keeps background work (idle eviction) leaves them for the next owner.
186
+ * If the sync flush cannot run (our async writer holds the lock), the exit
187
+ * hook stays until the async drain settles. */
145
188
  function dispose({ settle = false } = {}) {
146
189
  if (disposed) return;
147
190
  disposed = true;
191
+ let flushed = false;
148
192
  try {
149
193
  if (settle) flushActiveLeadRows();
150
- index.flushSync();
151
- } finally {
152
- reaps.cancelAll();
153
- unregisterExitFlush();
194
+ flushed = index.flushSync();
195
+ } catch {}
196
+ if (flushed) {
197
+ teardown();
198
+ return;
199
+ }
200
+ disposePromise = drainThenTeardown().catch(reopenAfterFailedDrain);
201
+ }
202
+
203
+ /** A failed drain tears nothing down; allow a later dispose to retry it. */
204
+ function reopenAfterFailedDrain() {
205
+ disposed = false;
206
+ disposePromise = null;
207
+ }
208
+
209
+ function disposeAsync({ settle = false } = {}) {
210
+ if (!disposePromise) {
211
+ disposed = true;
212
+ if (settle) flushActiveLeadRows();
213
+ disposePromise = drainThenTeardown().catch((error) => {
214
+ reopenAfterFailedDrain();
215
+ throw error;
216
+ });
154
217
  }
218
+ return disposePromise;
155
219
  }
156
220
 
157
221
  return {
158
222
  dispose,
223
+ disposeAsync,
159
224
  leadWorkerIndexPath: index.path,
160
225
  readLeadWorkerRows: index.read,
161
226
  /** Resolves once every queued Lead index write is on disk. */
@@ -163,6 +228,7 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
163
228
  upsertLeadSession,
164
229
  updateLeadWorkerCwd,
165
230
  removeLeadWorkerRow,
231
+ forgetLeadSession,
166
232
  flushActiveLeadRows,
167
233
  recoverStaleLeadRows,
168
234
  };
@@ -1,12 +1,14 @@
1
1
  import {
2
2
  resolveAgentWatchdogPolicy,
3
3
  resolveHandoffMessageStartIndex,
4
+ turnPartialHandoff,
4
5
  watchdogPartialHandoffFromError,
5
6
  watchdogStoppedHandoff,
6
7
  } from '../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
7
8
  import { clean, normalizeAgentName, resolvePrompt } from './helpers.mjs';
8
9
  import { abnormalEmptyFinishError, renderResult } from './render.mjs';
9
10
  import {
11
+ reconcileJobCancelled,
10
12
  reconcileJobFinally,
11
13
  reconcileJobStreamStalled,
12
14
  reconcileJobWatchdogPartial,
@@ -93,6 +95,18 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
93
95
  turnStartedAt: new Date().toISOString(),
94
96
  });
95
97
  let handoffMsgStart = 0;
98
+ // A cancelled turn reports the output it produced before it stopped.
99
+ const settleCancelled = (error, result = null) => {
100
+ finalStatus = 'cancelled';
101
+ reconcileJobCancelled(job, {
102
+ tag,
103
+ sessionId,
104
+ agent: session.agent || null,
105
+ provider: session.provider,
106
+ model: session.model,
107
+ content: turnPartialHandoff(error, mgr.getSession(sessionId), handoffMsgStart) || result?.content || '',
108
+ });
109
+ };
96
110
  try {
97
111
  handoffMsgStart = resolveHandoffMessageStartIndex(mgr.getSession(sessionId));
98
112
  const turnHooks = buildTurnHooks({ sessionId, notifyContext, job, turnReview, completionValue });
@@ -100,6 +114,10 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
100
114
  // Early preview no longer suppresses the canonical body notification;
101
115
  // notifyTaskCompletion fires once with output via resolve/reconcile.
102
116
  const finalValue = completionValue(result);
117
+ if (job?.status === 'cancelled') {
118
+ settleCancelled(null, result);
119
+ return finalValue;
120
+ }
103
121
  if (finalValue.error) {
104
122
  finalStatus = 'error';
105
123
  if (job) job._terminalResultValue = finalValue;
@@ -107,6 +125,10 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
107
125
  }
108
126
  return finalValue;
109
127
  } catch (error) {
128
+ if (job?.status === 'cancelled') {
129
+ settleCancelled(error);
130
+ throw error;
131
+ }
110
132
  const partial = watchdogPartialHandoffFromError(error, mgr.getSession(sessionId), handoffMsgStart);
111
133
  if (partial) {
112
134
  finalStatus = 'idle';
@@ -123,10 +145,6 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
123
145
  reconcileJobWatchdogPartial(job, value);
124
146
  return value;
125
147
  }
126
- if (job?.status === 'cancelled') {
127
- finalStatus = 'cancelled';
128
- throw error;
129
- }
130
148
  finalStatus = 'error';
131
149
  reconcileJobStreamStalled(job, error);
132
150
  throw error;
@@ -44,6 +44,8 @@ export function createJobStarter({ mgr, notifyStatusChange, notifySessionComplet
44
44
  meta: jobMeta,
45
45
  resultType: 'agent_task_result',
46
46
  renderResult: (result) => renderResult(result),
47
+ // Cancellation reaches the owner once, with the worker's partial output.
48
+ notifyOnCancel: true,
47
49
  cancel: () => {
48
50
  try {
49
51
  admissionController.abort(new Error('agent task cancelled before resource admission'));
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import { createNotify } from '../notify.mjs';
8
8
  import {
9
+ reconcileJobCancelled,
9
10
  reconcileJobFinally,
10
11
  reconcileJobStreamStalled,
11
12
  reconcileJobWatchdogPartial,
@@ -15,11 +16,13 @@ import { abnormalEmptyFinishError } from '../render.mjs';
15
16
  import { createProgressWatchdogRegistry } from '../../agent-watchdog-registry.mjs';
16
17
  import {
17
18
  resolveHandoffMessageStartIndex,
19
+ turnPartialHandoff,
18
20
  watchdogPartialHandoffFromError,
19
21
  watchdogStoppedHandoff,
20
22
  } from '../../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
21
23
  import { saveSessionAsync } from '../../../../runtime/agent/orchestrator/session/store.mjs';
22
24
  import { presetDescriptor } from './spawn-prep.mjs';
25
+ import { workerStageForStatus } from '../worker-rows.mjs';
23
26
 
24
27
  // Mid-turn worker persistence cadence. The watchdog sweep runs every second;
25
28
  // a transcript save is far more expensive than a bookkeeping stamp, so the
@@ -68,7 +71,7 @@ export function createSpawnRunner({
68
71
  const messages = Number(progress?.messages) || 0;
69
72
  upsertWorkerSessionDeferred(session, tag, {
70
73
  status: 'running',
71
- stage: progress.stage || 'running',
74
+ stage: workerStageForStatus('running', progress.stage),
72
75
  ...(messages > 0 ? { messages } : {}),
73
76
  });
74
77
  // The canonical runtime owns persistence; this session is only its descriptor.
@@ -135,6 +138,16 @@ export function createSpawnRunner({
135
138
  });
136
139
  notifyStatusChange();
137
140
  let handoffMsgStart = 0;
141
+ // A cancelled turn reports the output it produced before it stopped.
142
+ const settleCancelled = (error, result = null) => {
143
+ finalStatus = 'cancelled';
144
+ reconcileJobCancelled(job, {
145
+ tag,
146
+ sessionId: session.id,
147
+ ...presetDescriptor(agent, preset, presetName),
148
+ content: turnPartialHandoff(error, mgr.getSession(session.id), handoffMsgStart) || result?.content || '',
149
+ });
150
+ };
138
151
  try {
139
152
  handoffMsgStart = resolveHandoffMessageStartIndex(mgr.getSession(session.id));
140
153
  const turnHooks = {
@@ -157,6 +170,10 @@ export function createSpawnRunner({
157
170
  // notifyTaskCompletion is left to fire exactly once with output via the
158
171
  // resolve/reconcile/finally path.
159
172
  const finalValue = completionValue(result);
173
+ if (job?.status === 'cancelled') {
174
+ settleCancelled(null, result);
175
+ return finalValue;
176
+ }
160
177
  // Non-job return path (or job path where the terminal-result reconcile
161
178
  // already ran): if the finish was abnormal-empty, surface it as a thrown
162
179
  // error so finalStatus becomes 'error' and the caller's error path (and
@@ -168,6 +185,10 @@ export function createSpawnRunner({
168
185
  }
169
186
  return finalValue;
170
187
  } catch (error) {
188
+ if (job?.status === 'cancelled') {
189
+ settleCancelled(error);
190
+ throw error;
191
+ }
171
192
  const partial = watchdogPartialHandoffFromError(error, mgr.getSession(session.id), handoffMsgStart);
172
193
  if (partial) {
173
194
  finalStatus = 'idle';
@@ -182,10 +203,6 @@ export function createSpawnRunner({
182
203
  reconcileJobWatchdogPartial(job, value);
183
204
  return value;
184
205
  }
185
- if (job?.status === 'cancelled') {
186
- finalStatus = 'cancelled';
187
- throw error;
188
- }
189
206
  finalStatus = 'error';
190
207
  reconcileJobStreamStalled(job, error);
191
208
  throw error;
@@ -29,7 +29,7 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
29
29
  workerRowFromSession: index.workerRowFromSession,
30
30
  });
31
31
 
32
- const { upsertLeadSession, updateLeadWorkerCwd } = leadIndex;
32
+ const { upsertLeadSession, updateLeadWorkerCwd, forgetLeadSession } = leadIndex;
33
33
 
34
34
  function dispose(options) {
35
35
  try {
@@ -39,6 +39,17 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
39
39
  }
40
40
  }
41
41
 
42
+ /** Drain every queued index write (batches included) without disposing. */
43
+ async function flushIndexWrites() {
44
+ await Promise.all([index.flushWorkerIndexWrites(), leadIndex.flushLeadWorkerIndexWrites()]);
45
+ }
46
+
47
+ async function disposeAsync(options) {
48
+ const results = await Promise.allSettled([index.disposeAsync(), leadIndex.disposeAsync(options)]);
49
+ const failed = results.find((result) => result.status === 'rejected');
50
+ if (failed) throw failed.reason;
51
+ }
52
+
42
53
  function getLiveSession(sessionId) {
43
54
  if (!sessionId) return null;
44
55
  const session = mgr.getSession(sessionId);
@@ -95,6 +106,8 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
95
106
 
96
107
  return {
97
108
  dispose,
109
+ disposeAsync,
110
+ flushIndexWrites,
98
111
  readAllTagTombstones: index.readAllTagTombstones,
99
112
  readTagTombstones: index.readTagTombstones,
100
113
  readWorkerRows,
@@ -104,6 +117,7 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
104
117
  upsertWorkerSessionDeferred,
105
118
  upsertLeadSession,
106
119
  updateLeadWorkerCwd,
120
+ forgetLeadSession,
107
121
  removeWorkerRow,
108
122
  refreshTagsFromIndex,
109
123
  tags,
@@ -11,8 +11,15 @@ const ACTIVE_WORKER_STATUS =
11
11
  /^(?:connecting|requesting|streaming|tool[-_\s]?running|running|queued|pending|starting|cancelling)$/i;
12
12
  const WORKER_POOL_FRESH_MS = 2 * 60 * 1000;
13
13
 
14
+ const CANCELLED_WORKER_STATUS = /^(?:cancelled|canceled|killed|cancel[-_\s]?(?:unconfirmed|pending))$/i;
15
+
16
+ /** `status` decides; `stage` is the runtime phase copied in by the progress
17
+ * sweep and only decides for a row with no status. A cancel in either field
18
+ * is not work (bare `cancelling` still is). */
14
19
  export const isActiveWorkerRow = (row) =>
15
- ACTIVE_WORKER_STATUS.test(clean(row?.status)) || ACTIVE_WORKER_STATUS.test(clean(row?.stage));
20
+ !CANCELLED_WORKER_STATUS.test(clean(row?.status)) &&
21
+ !CANCELLED_WORKER_STATUS.test(clean(row?.stage)) &&
22
+ ACTIVE_WORKER_STATUS.test(clean(row?.status) || clean(row?.stage));
16
23
 
17
24
  /** A persisted approval wait whose runtime is gone: the in-memory wait died
18
25
  * with that process (daemon restart), so the flag must not stick. */
@@ -2,7 +2,7 @@
2
2
  // The one row shape of the worker index: coercing whatever a stored file or a
3
3
  // caller hands in, and projecting a live session into a row.
4
4
  import { agentTagOf, clean, positiveInt } from '../helpers.mjs';
5
- import { isLeadPoolAgent } from '../worker-rows.mjs';
5
+ import { isLeadPoolAgent, workerStageForStatus } from '../worker-rows.mjs';
6
6
 
7
7
  /** An explicit boolean wins; otherwise the session's own fast flag (true) or unknown. */
8
8
  function fastFlag(explicit, sessionFast) {
@@ -72,7 +72,7 @@ export function workerRowFromSession(session, fallbackTag = '', extra = {}, getS
72
72
  if (!tag || !sessionId) return null;
73
73
  const runtime = getSessionRuntime(sessionId);
74
74
  const status = clean(extra.status) || (session?.closed === true ? 'closed' : clean(session?.status) || 'idle');
75
- const stage = clean(extra.stage) || clean(runtime?.stage) || status;
75
+ const stage = clean(extra.stage) || workerStageForStatus(status, runtime?.stage);
76
76
  const nowIso = new Date().toISOString();
77
77
  return {
78
78
  tag,
@@ -157,6 +157,7 @@ export function createWorkerRowStore(file) {
157
157
  flush: queue.flush,
158
158
  /** Exit path: persist what is still queued, synchronously. */
159
159
  flushSync: queue.flushSync,
160
+ hasUnpersisted: queue.hasUnpersisted,
160
161
  invalidate: () => {
161
162
  dirty = true;
162
163
  },
@@ -183,7 +184,15 @@ export function acquireWorkerRowStore(file) {
183
184
  if (released) return;
184
185
  released = true;
185
186
  entry.refs -= 1;
186
- if (entry.refs === 0 && sharedStores.get(key) === entry) sharedStores.delete(key);
187
+ const dropIfIdle = () => {
188
+ if (entry.refs === 0 && !entry.store.hasUnpersisted() && sharedStores.get(key) === entry) {
189
+ sharedStores.delete(key);
190
+ }
191
+ };
192
+ // A store still holding unpersisted writes stays shared (a new holder
193
+ // must see them) until its queue drains.
194
+ if (entry.refs === 0 && entry.store.hasUnpersisted()) entry.store.flush().then(dropIfIdle, () => {});
195
+ else dropIfIdle();
187
196
  },
188
197
  };
189
198
  }
@@ -173,7 +173,9 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
173
173
  function flushWorkerIndexOnExit() {
174
174
  batch.flush();
175
175
  flushActiveWorkerRows();
176
- // Writes are persisted by an async queue; the loop is gone at exit.
176
+ // Writes are persisted by an async queue; the loop is gone at exit. This
177
+ // is the best-effort last resort: a persist still running is left alone
178
+ // (the graceful shutdown path drains before exit).
177
179
  store.flushSync();
178
180
  }
179
181
 
@@ -181,25 +183,62 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
181
183
  const unregisterExitFlush = registerExitFlush(flushWorkerIndexOnExit);
182
184
  const unregisterApprovalWaits = registerApprovalWaitWriter(file, setAwaitingUser);
183
185
  let disposed = false;
186
+ let disposePromise = null;
187
+
188
+ function teardown() {
189
+ unregisterExitFlush();
190
+ unregisterApprovalWaits();
191
+ releaseStore();
192
+ }
193
+
194
+ async function drainThenTeardown() {
195
+ batch.flush();
196
+ await store.flush();
197
+ teardown();
198
+ }
184
199
 
185
200
  /** Persist queued rows, then release the exit registration. Active rows are
186
201
  * NOT settled: they are keyed by process pid, which every inline runtime in
187
- * the daemon shares, so settling here would idle other runtimes' workers. */
202
+ * the daemon shares, so settling here would idle other runtimes' workers.
203
+ * When the sync flush cannot run (this process's async writer holds the
204
+ * lock) the exit hook and store ref stay until the async drain settles. */
188
205
  function dispose() {
189
206
  if (disposed) return;
190
207
  disposed = true;
208
+ let flushed = false;
191
209
  try {
192
210
  batch.flush();
193
- store.flushSync();
194
- } finally {
195
- unregisterExitFlush();
196
- unregisterApprovalWaits();
197
- releaseStore();
211
+ flushed = store.flushSync();
212
+ } catch {}
213
+ if (flushed) {
214
+ teardown();
215
+ return;
216
+ }
217
+ disposePromise = drainThenTeardown().catch(reopenAfterFailedDrain);
218
+ }
219
+
220
+ /** A failed drain tears nothing down; allow a later dispose to retry it. */
221
+ function reopenAfterFailedDrain() {
222
+ disposed = false;
223
+ disposePromise = null;
224
+ }
225
+
226
+ /** Awaitable dispose: drain everything, then tear down. A failed drain
227
+ * rejects and leaves the registrations in place. */
228
+ function disposeAsync() {
229
+ if (!disposePromise) {
230
+ disposed = true;
231
+ disposePromise = drainThenTeardown().catch((error) => {
232
+ reopenAfterFailedDrain();
233
+ throw error;
234
+ });
198
235
  }
236
+ return disposePromise;
199
237
  }
200
238
 
201
239
  return {
202
240
  dispose,
241
+ disposeAsync,
203
242
  workerIndexPath: () => file,
204
243
  invalidateWorkerRowsCache: store.invalidate,
205
244
  readAllWorkerRows: store.readAll,
@@ -1,4 +1,5 @@
1
1
  import { agentTagOf, clean, positiveInt, stampMs } from './helpers.mjs';
2
+ import { ACTIVE_STAGES } from './tool-def.mjs';
2
3
 
3
4
  import { TAG_TOMBSTONE_TTL_MS, tagTombstoneKey } from '../../../runtime/shared/agent-reap-state.mjs';
4
5
  export { TAG_TOMBSTONE_TTL_MS, tagTombstoneKey };
@@ -27,6 +28,22 @@ export function isTerminalWorkerStatus(status) {
27
28
  );
28
29
  }
29
30
 
31
+ const WORKING_WORKER_STATUS =
32
+ /^(?:connecting|requesting|streaming|tool[-_\s]?running|running|queued|pending|starting|cancelling)$/i;
33
+ const WORKING_WORKER_STAGES = new Set([...ACTIVE_STAGES, 'resource_wait']);
34
+
35
+ /** The `stage` to store beside a worker `status`, from a stage read off the
36
+ * live runtime. That stage is the runtime's own phase, so mid-work it can say
37
+ * `idle`/`done`/`error` (a fresh or just-settled runtime entry) while the
38
+ * worker is still running. Stored next to a working status it made a mixed
39
+ * row that readers classified as finished, so a working status keeps a
40
+ * working stage and falls back to the status itself. */
41
+ export function workerStageForStatus(status, runtimeStage) {
42
+ const stage = clean(runtimeStage);
43
+ if (!WORKING_WORKER_STATUS.test(clean(status))) return stage || clean(status);
44
+ return WORKING_WORKER_STAGES.has(stage.toLowerCase()) ? stage : clean(status);
45
+ }
46
+
30
47
  export function recoverTagTombstoneOwner(row, sessions) {
31
48
  if (clean(row.parentSessionId || row.ownerSessionId)) return row;
32
49
  const pid = positiveInt(row.clientHostPid);
@@ -147,7 +147,10 @@ export function createStandaloneAgent({
147
147
  recoverWorkers,
148
148
  upsertLeadSession: registry.upsertLeadSession,
149
149
  updateLeadWorkerCwd: registry.updateLeadWorkerCwd,
150
+ forgetLeadSession: registry.forgetLeadSession,
150
151
  closeAll: closeFlow.closeAll,
151
152
  dispose: (options) => registry.dispose(options),
153
+ disposeAsync: (options) => registry.disposeAsync(options),
154
+ flushIndexWrites: () => registry.flushIndexWrites(),
152
155
  };
153
156
  }
@@ -26,6 +26,8 @@ import { normalizeAutomationAttachments } from '../../runtime/shared/automation-
26
26
  import { migrateCodexModelRef } from '../../runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs';
27
27
  import { hasEnabledAutomation } from '../../runtime/shared/automation-presence.mjs';
28
28
  import { resolveScheduleTimezone, validateScheduleCron } from '../../runtime/shared/schedule-time.mjs';
29
+ import { pgClusterExists } from '../../runtime/memory/lib/pg/adapter.mjs';
30
+ import { resolvePluginData } from '../../runtime/shared/plugin-paths.mjs';
29
31
  import { readHookPublicBase } from '../../runtime/channels/lib/webhook/relay-tunnel.mjs';
30
32
  import { WEBHOOK_TEST_FIELD, WEBHOOK_TEST_HEADER } from '../../runtime/channels/lib/webhook/request-handler.mjs';
31
33
 
@@ -463,10 +465,20 @@ export async function testWebhook(name) {
463
465
  // and webhooks run sessions, so they must not require Discord/Telegram
464
466
  // tokens or an explicit remote toggle.
465
467
  async function checkActiveAutomation() {
466
- const [schedules, webhooks] = await Promise.all([listSchedules(), listWebhooks()]);
468
+ const { schedules, webhooks } = await readAutomationRows();
467
469
  return hasEnabledAutomation({ schedules, webhooks });
468
470
  }
469
471
 
472
+ // Read-only views (channel setup, the automation probe) never bring
473
+ // PostgreSQL up for the first time: before initdb ran no schedule or webhook
474
+ // can exist, and that first start — runtime download/extract plus initdb — is
475
+ // seconds of work no catalog read should wait on. Writes still start it.
476
+ async function readAutomationRows() {
477
+ if (!pgClusterExists(resolvePluginData())) return { schedules: [], webhooks: [] };
478
+ const [schedules, webhooks] = await Promise.all([listSchedules(), listWebhooks()]);
479
+ return { schedules, webhooks };
480
+ }
481
+
470
482
  // Every session runtime in the process asks this at boot. Concurrent callers
471
483
  // join one in-flight check and a settled answer is reused for ttlMs, so N
472
484
  // runtimes booting together cost one PG query (and at most one PG boot)
@@ -519,8 +531,12 @@ export function hasActiveAutomation() {
519
531
  return automationProbe.probe();
520
532
  }
521
533
 
534
+ // The daemon opens both stores in the background once ready (it settles
535
+ // hasActiveAutomation), so on an existing cluster this read joins a
536
+ // PostgreSQL start already under way instead of being the one that starts it.
522
537
  export async function channelSetup(config = null) {
523
538
  const cfg = normalizeChannelsConfig(config || readSection('channels'));
539
+ const { schedules, webhooks } = await readAutomationRows();
524
540
  return {
525
541
  webhook: {
526
542
  ...(cfg.webhook || {}),
@@ -528,7 +544,7 @@ export async function channelSetup(config = null) {
528
544
  // connects and mints its hook identity).
529
545
  publicUrl: readHookPublicBase(),
530
546
  },
531
- schedules: await listSchedules(),
532
- webhooks: await listWebhooks(),
547
+ schedules,
548
+ webhooks,
533
549
  };
534
550
  }
@@ -41,6 +41,9 @@ export function createMemoryCalls({ state, cwd, start, discovery, registry }) {
41
41
  ...(transcriptCwd ? { cwd: transcriptCwd } : {}),
42
42
  });
43
43
  }
44
+ async function forgetTranscripts(filePaths = []) {
45
+ return await requestMemoryPath('/transcript/forget', { filePaths }, { timeoutMs: 10_000 });
46
+ }
44
47
  async function recordTraceEvents(events = []) {
45
48
  return await requestMemoryPath('/admin/trace-record', { events }, { timeoutMs: 5_000 });
46
49
  }
@@ -120,6 +123,7 @@ export function createMemoryCalls({ state, cwd, start, discovery, registry }) {
120
123
  retain,
121
124
  appendEntry,
122
125
  ingestTranscript,
126
+ forgetTranscripts,
123
127
  recordTraceEvents,
124
128
  handleToolCall,
125
129
  buildSessionCoreMemoryPayload,
@@ -91,6 +91,7 @@ function createStandaloneMemoryRuntime({ entry, dataDir, cwd = process.cwd() } =
91
91
  warmupEmbedding: calls.warmupEmbedding,
92
92
  appendEntry: calls.appendEntry,
93
93
  ingestTranscript: calls.ingestTranscript,
94
+ forgetTranscripts: calls.forgetTranscripts,
94
95
  recordTraceEvents: calls.recordTraceEvents,
95
96
  moduleUrl: pathToFileURL(entry).href,
96
97
  };