visionclaw 0.1.218 → 0.1.219-dev.codex-issue-2805-worker-runtime.1

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 (595) hide show
  1. package/dist/agent/api-proxy.d.ts +0 -16
  2. package/dist/agent/api-proxy.d.ts.map +1 -1
  3. package/dist/agent/api-proxy.js +9 -8
  4. package/dist/agent/api-proxy.js.map +1 -1
  5. package/dist/agent/browser-launcher.d.ts +3 -0
  6. package/dist/agent/browser-launcher.d.ts.map +1 -1
  7. package/dist/agent/browser-launcher.js +101 -43
  8. package/dist/agent/browser-launcher.js.map +1 -1
  9. package/dist/agent/coding-conventions.d.ts +8 -0
  10. package/dist/agent/coding-conventions.d.ts.map +1 -0
  11. package/dist/agent/coding-conventions.js +19 -0
  12. package/dist/agent/coding-conventions.js.map +1 -0
  13. package/dist/agent/command-handlers.d.ts.map +1 -1
  14. package/dist/agent/command-handlers.js +4 -16
  15. package/dist/agent/command-handlers.js.map +1 -1
  16. package/dist/agent/context-action-restart-fallback.d.ts.map +1 -1
  17. package/dist/agent/context-action-restart-fallback.js +9 -3
  18. package/dist/agent/context-action-restart-fallback.js.map +1 -1
  19. package/dist/agent/context-refresh.d.ts.map +1 -1
  20. package/dist/agent/context-refresh.js +0 -7
  21. package/dist/agent/context-refresh.js.map +1 -1
  22. package/dist/agent/context.d.ts +2 -4
  23. package/dist/agent/context.d.ts.map +1 -1
  24. package/dist/agent/context.js +12 -21
  25. package/dist/agent/context.js.map +1 -1
  26. package/dist/agent/engine-fallback.d.ts +0 -35
  27. package/dist/agent/engine-fallback.d.ts.map +1 -1
  28. package/dist/agent/engine-fallback.js +4 -3
  29. package/dist/agent/engine-fallback.js.map +1 -1
  30. package/dist/agent/engine-switch.d.ts +19 -38
  31. package/dist/agent/engine-switch.d.ts.map +1 -1
  32. package/dist/agent/engine-switch.js +46 -111
  33. package/dist/agent/engine-switch.js.map +1 -1
  34. package/dist/agent/engines/browser-tool-policy.d.ts +12 -1
  35. package/dist/agent/engines/browser-tool-policy.d.ts.map +1 -1
  36. package/dist/agent/engines/browser-tool-policy.js +17 -2
  37. package/dist/agent/engines/browser-tool-policy.js.map +1 -1
  38. package/dist/agent/engines/claude/executor-shell-groups.d.ts +11 -0
  39. package/dist/agent/engines/claude/executor-shell-groups.d.ts.map +1 -0
  40. package/dist/agent/engines/claude/executor-shell-groups.js +22 -0
  41. package/dist/agent/engines/claude/executor-shell-groups.js.map +1 -0
  42. package/dist/agent/engines/claude/session.d.ts +13 -4
  43. package/dist/agent/engines/claude/session.d.ts.map +1 -1
  44. package/dist/agent/engines/claude/session.js +165 -84
  45. package/dist/agent/engines/claude/session.js.map +1 -1
  46. package/dist/agent/engines/pi/shared/usage.d.ts +5 -0
  47. package/dist/agent/engines/pi/shared/usage.d.ts.map +1 -1
  48. package/dist/agent/engines/pi/shared/usage.js +22 -3
  49. package/dist/agent/engines/pi/shared/usage.js.map +1 -1
  50. package/dist/agent/engines/pi/tools.d.ts +3 -10
  51. package/dist/agent/engines/pi/tools.d.ts.map +1 -1
  52. package/dist/agent/engines/pi/tools.js +6 -17
  53. package/dist/agent/engines/pi/tools.js.map +1 -1
  54. package/dist/agent/engines/pi-coding/executor-shell.d.ts +4 -0
  55. package/dist/agent/engines/pi-coding/executor-shell.d.ts.map +1 -0
  56. package/dist/agent/engines/pi-coding/executor-shell.js +175 -0
  57. package/dist/agent/engines/pi-coding/executor-shell.js.map +1 -0
  58. package/dist/agent/engines/pi-coding/session.d.ts +4 -4
  59. package/dist/agent/engines/pi-coding/session.d.ts.map +1 -1
  60. package/dist/agent/engines/pi-coding/session.js +118 -66
  61. package/dist/agent/engines/pi-coding/session.js.map +1 -1
  62. package/dist/agent/engines/pi-coding/tools.d.ts +2 -5
  63. package/dist/agent/engines/pi-coding/tools.d.ts.map +1 -1
  64. package/dist/agent/engines/pi-coding/tools.js +7 -5
  65. package/dist/agent/engines/pi-coding/tools.js.map +1 -1
  66. package/dist/agent/engines/session-types.d.ts +8 -8
  67. package/dist/agent/engines/session-types.d.ts.map +1 -1
  68. package/dist/agent/external-context/interrupt.d.ts +0 -2
  69. package/dist/agent/external-context/interrupt.d.ts.map +1 -1
  70. package/dist/agent/external-context/interrupt.js +0 -1
  71. package/dist/agent/external-context/interrupt.js.map +1 -1
  72. package/dist/agent/external-context/registry.d.ts +0 -2
  73. package/dist/agent/external-context/registry.d.ts.map +1 -1
  74. package/dist/agent/external-context/registry.js +2 -4
  75. package/dist/agent/external-context/registry.js.map +1 -1
  76. package/dist/agent/external-context/runtime.d.ts.map +1 -1
  77. package/dist/agent/external-context/runtime.js +15 -14
  78. package/dist/agent/external-context/runtime.js.map +1 -1
  79. package/dist/agent/external-context/types.d.ts +0 -2
  80. package/dist/agent/external-context/types.d.ts.map +1 -1
  81. package/dist/agent/fast-responder.d.ts +4 -20
  82. package/dist/agent/fast-responder.d.ts.map +1 -1
  83. package/dist/agent/fast-responder.js +28 -42
  84. package/dist/agent/fast-responder.js.map +1 -1
  85. package/dist/agent/interrupt-handler.d.ts +0 -6
  86. package/dist/agent/interrupt-handler.d.ts.map +1 -1
  87. package/dist/agent/interrupt-handler.js +5 -47
  88. package/dist/agent/interrupt-handler.js.map +1 -1
  89. package/dist/agent/lab-run-system-prompt.d.ts.map +1 -1
  90. package/dist/agent/lab-run-system-prompt.js +4 -1
  91. package/dist/agent/lab-run-system-prompt.js.map +1 -1
  92. package/dist/agent/lifecycle-trace.d.ts.map +1 -1
  93. package/dist/agent/lifecycle-trace.js +6 -5
  94. package/dist/agent/lifecycle-trace.js.map +1 -1
  95. package/dist/agent/loop.d.ts +8 -2
  96. package/dist/agent/loop.d.ts.map +1 -1
  97. package/dist/agent/loop.js +291 -156
  98. package/dist/agent/loop.js.map +1 -1
  99. package/dist/agent/memory-protocol.d.ts +2 -2
  100. package/dist/agent/memory-protocol.d.ts.map +1 -1
  101. package/dist/agent/memory-protocol.js +3 -15
  102. package/dist/agent/memory-protocol.js.map +1 -1
  103. package/dist/agent/memory-store.d.ts +58 -0
  104. package/dist/agent/memory-store.d.ts.map +1 -0
  105. package/dist/agent/memory-store.js +152 -0
  106. package/dist/agent/memory-store.js.map +1 -0
  107. package/dist/agent/model-provider.d.ts +18 -5
  108. package/dist/agent/model-provider.d.ts.map +1 -1
  109. package/dist/agent/model-provider.js +58 -18
  110. package/dist/agent/model-provider.js.map +1 -1
  111. package/dist/agent/nightly-maintenance/dreaming-batch.d.ts +184 -0
  112. package/dist/agent/nightly-maintenance/dreaming-batch.d.ts.map +1 -0
  113. package/dist/agent/nightly-maintenance/dreaming-batch.js +192 -0
  114. package/dist/agent/nightly-maintenance/dreaming-batch.js.map +1 -0
  115. package/dist/agent/nightly-maintenance/dreaming-files.d.ts +48 -0
  116. package/dist/agent/nightly-maintenance/dreaming-files.d.ts.map +1 -0
  117. package/dist/agent/nightly-maintenance/dreaming-files.js +109 -0
  118. package/dist/agent/nightly-maintenance/dreaming-files.js.map +1 -0
  119. package/dist/agent/nightly-maintenance/dreaming-ledger.d.ts +62 -0
  120. package/dist/agent/nightly-maintenance/dreaming-ledger.d.ts.map +1 -0
  121. package/dist/agent/nightly-maintenance/dreaming-ledger.js +146 -0
  122. package/dist/agent/nightly-maintenance/dreaming-ledger.js.map +1 -0
  123. package/dist/agent/nightly-maintenance/dreaming-planner.d.ts +86 -0
  124. package/dist/agent/nightly-maintenance/dreaming-planner.d.ts.map +1 -0
  125. package/dist/agent/nightly-maintenance/dreaming-planner.js +304 -0
  126. package/dist/agent/nightly-maintenance/dreaming-planner.js.map +1 -0
  127. package/dist/agent/nightly-maintenance/dreaming-runner.d.ts +93 -0
  128. package/dist/agent/nightly-maintenance/dreaming-runner.d.ts.map +1 -0
  129. package/dist/agent/nightly-maintenance/dreaming-runner.js +156 -0
  130. package/dist/agent/nightly-maintenance/dreaming-runner.js.map +1 -0
  131. package/dist/agent/nightly-maintenance/dreaming-sources.d.ts +115 -0
  132. package/dist/agent/nightly-maintenance/dreaming-sources.d.ts.map +1 -0
  133. package/dist/agent/nightly-maintenance/dreaming-sources.js +270 -0
  134. package/dist/agent/nightly-maintenance/dreaming-sources.js.map +1 -0
  135. package/dist/agent/nightly-maintenance/index.d.ts +28 -8
  136. package/dist/agent/nightly-maintenance/index.d.ts.map +1 -1
  137. package/dist/agent/nightly-maintenance/index.js +42 -15
  138. package/dist/agent/nightly-maintenance/index.js.map +1 -1
  139. package/dist/agent/nightly-maintenance/skill-learning-gate.js +1 -1
  140. package/dist/agent/nightly-maintenance/skill-learning-gate.js.map +1 -1
  141. package/dist/agent/nightly-maintenance/vocabulary-processor.d.ts +1 -1
  142. package/dist/agent/nightly-maintenance/vocabulary-processor.d.ts.map +1 -1
  143. package/dist/agent/owner-channel-resolver.d.ts +2 -0
  144. package/dist/agent/owner-channel-resolver.d.ts.map +1 -1
  145. package/dist/agent/owner-channel-resolver.js +4 -0
  146. package/dist/agent/owner-channel-resolver.js.map +1 -1
  147. package/dist/agent/product-identity.d.ts +5 -4
  148. package/dist/agent/product-identity.d.ts.map +1 -1
  149. package/dist/agent/product-identity.js +7 -6
  150. package/dist/agent/product-identity.js.map +1 -1
  151. package/dist/agent/public-activity.js +1 -1
  152. package/dist/agent/public-activity.js.map +1 -1
  153. package/dist/agent/runtime-context.d.ts +27 -0
  154. package/dist/agent/runtime-context.d.ts.map +1 -0
  155. package/dist/agent/runtime-context.js +60 -0
  156. package/dist/agent/runtime-context.js.map +1 -0
  157. package/dist/agent/runtime-disclosure-policy.d.ts +6 -0
  158. package/dist/agent/runtime-disclosure-policy.d.ts.map +1 -0
  159. package/dist/agent/runtime-disclosure-policy.js +16 -0
  160. package/dist/agent/runtime-disclosure-policy.js.map +1 -0
  161. package/dist/agent/runtime-surface.d.ts +15 -4
  162. package/dist/agent/runtime-surface.d.ts.map +1 -1
  163. package/dist/agent/runtime-surface.js +0 -1
  164. package/dist/agent/runtime-surface.js.map +1 -1
  165. package/dist/agent/session-manager.d.ts +30 -126
  166. package/dist/agent/session-manager.d.ts.map +1 -1
  167. package/dist/agent/session-manager.js +60 -484
  168. package/dist/agent/session-manager.js.map +1 -1
  169. package/dist/agent/state.d.ts +42 -2
  170. package/dist/agent/state.d.ts.map +1 -1
  171. package/dist/agent/state.js +21 -11
  172. package/dist/agent/state.js.map +1 -1
  173. package/dist/agent/stream-handler.d.ts +6 -13
  174. package/dist/agent/stream-handler.d.ts.map +1 -1
  175. package/dist/agent/stream-handler.js +8 -62
  176. package/dist/agent/stream-handler.js.map +1 -1
  177. package/dist/agent/system-prompt.d.ts +2 -0
  178. package/dist/agent/system-prompt.d.ts.map +1 -1
  179. package/dist/agent/system-prompt.js +21 -20
  180. package/dist/agent/system-prompt.js.map +1 -1
  181. package/dist/agent/tool-usage.d.ts.map +1 -1
  182. package/dist/agent/tool-usage.js +0 -1
  183. package/dist/agent/tool-usage.js.map +1 -1
  184. package/dist/agent/transcript/transcript-backfill.js +3 -3
  185. package/dist/agent/transcript/transcript-backfill.js.map +1 -1
  186. package/dist/agent/transcript/transcript-indexer.d.ts +3 -31
  187. package/dist/agent/transcript/transcript-indexer.d.ts.map +1 -1
  188. package/dist/agent/transcript/transcript-indexer.js +58 -57
  189. package/dist/agent/transcript/transcript-indexer.js.map +1 -1
  190. package/dist/agent/transcript-parsers/trivial-tools.d.ts.map +1 -1
  191. package/dist/agent/transcript-parsers/trivial-tools.js +0 -2
  192. package/dist/agent/transcript-parsers/trivial-tools.js.map +1 -1
  193. package/dist/agent/transcript-parsers/types.d.ts +1 -1
  194. package/dist/agent/transcript-summarizer.d.ts +14 -0
  195. package/dist/agent/transcript-summarizer.d.ts.map +1 -1
  196. package/dist/agent/transcript-summarizer.js +69 -45
  197. package/dist/agent/transcript-summarizer.js.map +1 -1
  198. package/dist/agent/usage/usage-report-queue.d.ts.map +1 -1
  199. package/dist/agent/usage/usage-report-queue.js +53 -52
  200. package/dist/agent/usage/usage-report-queue.js.map +1 -1
  201. package/dist/agent/usage/usage-report-types.d.ts +1 -1
  202. package/dist/agent/usage/usage-report-types.d.ts.map +1 -1
  203. package/dist/agent/vocabulary-glossary.d.ts +3 -3
  204. package/dist/agent/wake-cycle-runner.d.ts +22 -17
  205. package/dist/agent/wake-cycle-runner.d.ts.map +1 -1
  206. package/dist/agent/wake-cycle-runner.js +190 -320
  207. package/dist/agent/wake-cycle-runner.js.map +1 -1
  208. package/dist/builtin-skills/owner-manual/SKILL.md +2 -2
  209. package/dist/calendar/occurrence-ownership.d.ts.map +1 -1
  210. package/dist/calendar/occurrence-ownership.js +6 -5
  211. package/dist/calendar/occurrence-ownership.js.map +1 -1
  212. package/dist/calendar/scheduler.d.ts.map +1 -1
  213. package/dist/calendar/scheduler.js +4 -3
  214. package/dist/calendar/scheduler.js.map +1 -1
  215. package/dist/channels/interface.d.ts +8 -2
  216. package/dist/channels/interface.d.ts.map +1 -1
  217. package/dist/channels/interface.js +8 -1
  218. package/dist/channels/interface.js.map +1 -1
  219. package/dist/channels/manager.d.ts +12 -0
  220. package/dist/channels/manager.d.ts.map +1 -1
  221. package/dist/channels/manager.js +97 -8
  222. package/dist/channels/manager.js.map +1 -1
  223. package/dist/channels/queue.d.ts.map +1 -1
  224. package/dist/channels/queue.js +8 -0
  225. package/dist/channels/queue.js.map +1 -1
  226. package/dist/channels/telegram.d.ts.map +1 -1
  227. package/dist/channels/telegram.js +28 -2
  228. package/dist/channels/telegram.js.map +1 -1
  229. package/dist/channels/tui.d.ts +14 -1
  230. package/dist/channels/tui.d.ts.map +1 -1
  231. package/dist/channels/tui.js +64 -2
  232. package/dist/channels/tui.js.map +1 -1
  233. package/dist/channels/unavailable-target.d.ts +20 -0
  234. package/dist/channels/unavailable-target.d.ts.map +1 -0
  235. package/dist/channels/unavailable-target.js +82 -0
  236. package/dist/channels/unavailable-target.js.map +1 -0
  237. package/dist/cli/index.d.ts +2 -2
  238. package/dist/cli/index.d.ts.map +1 -1
  239. package/dist/cli/index.js +22 -53
  240. package/dist/cli/index.js.map +1 -1
  241. package/dist/config/index.d.ts +13 -7
  242. package/dist/config/index.d.ts.map +1 -1
  243. package/dist/config/index.js +51 -64
  244. package/dist/config/index.js.map +1 -1
  245. package/dist/config/types.d.ts +28 -7
  246. package/dist/config/types.d.ts.map +1 -1
  247. package/dist/config/types.js +22 -20
  248. package/dist/config/types.js.map +1 -1
  249. package/dist/conversations/lazy-runtime.d.ts +5 -0
  250. package/dist/conversations/lazy-runtime.d.ts.map +1 -0
  251. package/dist/conversations/lazy-runtime.js +12 -0
  252. package/dist/conversations/lazy-runtime.js.map +1 -0
  253. package/dist/conversations/runtime.d.ts +17 -0
  254. package/dist/conversations/runtime.d.ts.map +1 -0
  255. package/dist/conversations/runtime.js +92 -0
  256. package/dist/conversations/runtime.js.map +1 -0
  257. package/dist/conversations/scheduler.d.ts +57 -0
  258. package/dist/conversations/scheduler.d.ts.map +1 -0
  259. package/dist/conversations/scheduler.js +175 -0
  260. package/dist/conversations/scheduler.js.map +1 -0
  261. package/dist/data-processing/pipeline.d.ts +0 -2
  262. package/dist/data-processing/pipeline.d.ts.map +1 -1
  263. package/dist/data-processing/pipeline.js +19 -24
  264. package/dist/data-processing/pipeline.js.map +1 -1
  265. package/dist/data-processing/restructure.d.ts +0 -2
  266. package/dist/data-processing/restructure.d.ts.map +1 -1
  267. package/dist/data-processing/restructure.js +6 -9
  268. package/dist/data-processing/restructure.js.map +1 -1
  269. package/dist/data-processing/types.d.ts +2 -9
  270. package/dist/data-processing/types.d.ts.map +1 -1
  271. package/dist/data-processing/types.js +2 -13
  272. package/dist/data-processing/types.js.map +1 -1
  273. package/dist/email/email-route-store.d.ts.map +1 -1
  274. package/dist/email/email-route-store.js +6 -5
  275. package/dist/email/email-route-store.js.map +1 -1
  276. package/dist/i18n/messages.d.ts +26 -2
  277. package/dist/i18n/messages.d.ts.map +1 -1
  278. package/dist/i18n/messages.js +30 -5
  279. package/dist/i18n/messages.js.map +1 -1
  280. package/dist/index.js.map +1 -1
  281. package/dist/logger.d.ts +11 -0
  282. package/dist/logger.d.ts.map +1 -1
  283. package/dist/logger.js +49 -1
  284. package/dist/logger.js.map +1 -1
  285. package/dist/obs/mini-app/status.d.ts.map +1 -1
  286. package/dist/obs/mini-app/status.js +0 -1
  287. package/dist/obs/mini-app/status.js.map +1 -1
  288. package/dist/onboarding/onboarding-service-client.d.ts +1 -0
  289. package/dist/onboarding/onboarding-service-client.d.ts.map +1 -1
  290. package/dist/onboarding/onboarding-service-client.js.map +1 -1
  291. package/dist/onboarding/remote-set-owner.d.ts.map +1 -1
  292. package/dist/onboarding/remote-set-owner.js +0 -1
  293. package/dist/onboarding/remote-set-owner.js.map +1 -1
  294. package/dist/onboarding/set-owner.d.ts +1 -1
  295. package/dist/onboarding/set-owner.d.ts.map +1 -1
  296. package/dist/onboarding/set-owner.js +3 -6
  297. package/dist/onboarding/set-owner.js.map +1 -1
  298. package/dist/reconfigure.d.ts.map +1 -1
  299. package/dist/reconfigure.js +1 -32
  300. package/dist/reconfigure.js.map +1 -1
  301. package/dist/reset.d.ts.map +1 -1
  302. package/dist/reset.js +3 -1
  303. package/dist/reset.js.map +1 -1
  304. package/dist/threads/active-threads-store.d.ts.map +1 -1
  305. package/dist/threads/active-threads-store.js +8 -27
  306. package/dist/threads/active-threads-store.js.map +1 -1
  307. package/dist/threads/dreaming-execution.d.ts +10 -0
  308. package/dist/threads/dreaming-execution.d.ts.map +1 -0
  309. package/dist/threads/dreaming-execution.js +78 -0
  310. package/dist/threads/dreaming-execution.js.map +1 -0
  311. package/dist/threads/execution-authority.d.ts +43 -0
  312. package/dist/threads/execution-authority.d.ts.map +1 -0
  313. package/dist/threads/execution-authority.js +75 -0
  314. package/dist/threads/execution-authority.js.map +1 -0
  315. package/dist/threads/execution-budget.d.ts +107 -0
  316. package/dist/threads/execution-budget.d.ts.map +1 -0
  317. package/dist/threads/execution-budget.js +257 -0
  318. package/dist/threads/execution-budget.js.map +1 -0
  319. package/dist/threads/execution-host.d.ts +17 -0
  320. package/dist/threads/execution-host.d.ts.map +1 -0
  321. package/dist/threads/execution-host.js +66 -0
  322. package/dist/threads/execution-host.js.map +1 -0
  323. package/dist/threads/execution-scheduler.d.ts +162 -0
  324. package/dist/threads/execution-scheduler.d.ts.map +1 -0
  325. package/dist/threads/execution-scheduler.js +413 -0
  326. package/dist/threads/execution-scheduler.js.map +1 -0
  327. package/dist/threads/execution-snapshot.d.ts +91 -0
  328. package/dist/threads/execution-snapshot.d.ts.map +1 -0
  329. package/dist/threads/execution-snapshot.js +146 -0
  330. package/dist/threads/execution-snapshot.js.map +1 -0
  331. package/dist/threads/execution-store.d.ts +374 -0
  332. package/dist/threads/execution-store.d.ts.map +1 -0
  333. package/dist/threads/execution-store.js +910 -0
  334. package/dist/threads/execution-store.js.map +1 -0
  335. package/dist/threads/execution-thread-error.d.ts +9 -0
  336. package/dist/threads/execution-thread-error.d.ts.map +1 -0
  337. package/dist/threads/execution-thread-error.js +12 -0
  338. package/dist/threads/execution-thread-error.js.map +1 -0
  339. package/dist/threads/executor-exit.d.ts +18 -0
  340. package/dist/threads/executor-exit.d.ts.map +1 -0
  341. package/dist/threads/executor-exit.js +21 -0
  342. package/dist/threads/executor-exit.js.map +1 -0
  343. package/dist/threads/foreground-task.d.ts +91 -0
  344. package/dist/threads/foreground-task.d.ts.map +1 -0
  345. package/dist/threads/foreground-task.js +191 -0
  346. package/dist/threads/foreground-task.js.map +1 -0
  347. package/dist/threads/foreman-business.d.ts +9 -0
  348. package/dist/threads/foreman-business.d.ts.map +1 -0
  349. package/dist/threads/foreman-business.js +117 -0
  350. package/dist/threads/foreman-business.js.map +1 -0
  351. package/dist/threads/foreman-client.d.ts +18 -0
  352. package/dist/threads/foreman-client.d.ts.map +1 -0
  353. package/dist/threads/foreman-client.js +51 -0
  354. package/dist/threads/foreman-client.js.map +1 -0
  355. package/dist/threads/foreman-delivery.d.ts +5 -0
  356. package/dist/threads/foreman-delivery.d.ts.map +1 -0
  357. package/dist/threads/foreman-delivery.js +21 -0
  358. package/dist/threads/foreman-delivery.js.map +1 -0
  359. package/dist/threads/foreman-execution.d.ts +32 -0
  360. package/dist/threads/foreman-execution.d.ts.map +1 -0
  361. package/dist/threads/foreman-execution.js +90 -0
  362. package/dist/threads/foreman-execution.js.map +1 -0
  363. package/dist/threads/foreman-host.d.ts +77 -0
  364. package/dist/threads/foreman-host.d.ts.map +1 -0
  365. package/dist/threads/foreman-host.js +891 -0
  366. package/dist/threads/foreman-host.js.map +1 -0
  367. package/dist/threads/foreman-protocol.d.ts +242 -0
  368. package/dist/threads/foreman-protocol.d.ts.map +1 -0
  369. package/dist/threads/foreman-protocol.js +116 -0
  370. package/dist/threads/foreman-protocol.js.map +1 -0
  371. package/dist/threads/foreman-store.d.ts +151 -0
  372. package/dist/threads/foreman-store.d.ts.map +1 -0
  373. package/dist/threads/foreman-store.js +299 -0
  374. package/dist/threads/foreman-store.js.map +1 -0
  375. package/dist/threads/generic-execution.d.ts +25 -0
  376. package/dist/threads/generic-execution.d.ts.map +1 -0
  377. package/dist/threads/generic-execution.js +86 -0
  378. package/dist/threads/generic-execution.js.map +1 -0
  379. package/dist/threads/init-thread-dir.d.ts +2 -2
  380. package/dist/threads/init-thread-dir.d.ts.map +1 -1
  381. package/dist/threads/init-thread-dir.js +6 -6
  382. package/dist/threads/init-thread-dir.js.map +1 -1
  383. package/dist/threads/ipc.d.ts +108 -2
  384. package/dist/threads/ipc.d.ts.map +1 -1
  385. package/dist/threads/ipc.js +14 -2
  386. package/dist/threads/ipc.js.map +1 -1
  387. package/dist/threads/lab-run-thread.d.ts +3 -5
  388. package/dist/threads/lab-run-thread.d.ts.map +1 -1
  389. package/dist/threads/lab-run-thread.js +3 -5
  390. package/dist/threads/lab-run-thread.js.map +1 -1
  391. package/dist/threads/lab-runtime-policy.d.ts +26 -21
  392. package/dist/threads/lab-runtime-policy.d.ts.map +1 -1
  393. package/dist/threads/lab-runtime-policy.js +31 -126
  394. package/dist/threads/lab-runtime-policy.js.map +1 -1
  395. package/dist/threads/process-group.d.ts +41 -0
  396. package/dist/threads/process-group.d.ts.map +1 -0
  397. package/dist/threads/process-group.js +161 -0
  398. package/dist/threads/process-group.js.map +1 -0
  399. package/dist/threads/relay-adapter.d.ts +8 -0
  400. package/dist/threads/relay-adapter.d.ts.map +1 -1
  401. package/dist/threads/relay-adapter.js +26 -1
  402. package/dist/threads/relay-adapter.js.map +1 -1
  403. package/dist/threads/supervisor.d.ts +191 -57
  404. package/dist/threads/supervisor.d.ts.map +1 -1
  405. package/dist/threads/supervisor.js +766 -427
  406. package/dist/threads/supervisor.js.map +1 -1
  407. package/dist/threads/task-workspace.d.ts +8 -0
  408. package/dist/threads/task-workspace.d.ts.map +1 -0
  409. package/dist/threads/task-workspace.js +52 -0
  410. package/dist/threads/task-workspace.js.map +1 -0
  411. package/dist/threads/worker-entry.d.ts.map +1 -1
  412. package/dist/threads/worker-entry.js +314 -34
  413. package/dist/threads/worker-entry.js.map +1 -1
  414. package/dist/threads/worker-execution-runtime.d.ts +75 -0
  415. package/dist/threads/worker-execution-runtime.d.ts.map +1 -0
  416. package/dist/threads/worker-execution-runtime.js +142 -0
  417. package/dist/threads/worker-execution-runtime.js.map +1 -0
  418. package/dist/threads/worker-execution.d.ts +35 -0
  419. package/dist/threads/worker-execution.d.ts.map +1 -0
  420. package/dist/threads/worker-execution.js +2 -0
  421. package/dist/threads/worker-execution.js.map +1 -0
  422. package/dist/threads/worker-runtime-policy.d.ts +42 -0
  423. package/dist/threads/worker-runtime-policy.d.ts.map +1 -0
  424. package/dist/threads/worker-runtime-policy.js +98 -0
  425. package/dist/threads/worker-runtime-policy.js.map +1 -0
  426. package/dist/tools/adapter-tool.d.ts +12 -0
  427. package/dist/tools/adapter-tool.d.ts.map +1 -0
  428. package/dist/tools/adapter-tool.js +2 -0
  429. package/dist/tools/adapter-tool.js.map +1 -0
  430. package/dist/tools/data-service.d.ts +2 -2
  431. package/dist/tools/delegation.d.ts +121 -0
  432. package/dist/tools/delegation.d.ts.map +1 -0
  433. package/dist/tools/delegation.js +106 -0
  434. package/dist/tools/delegation.js.map +1 -0
  435. package/dist/tools/dream-memory.d.ts +122 -0
  436. package/dist/tools/dream-memory.d.ts.map +1 -0
  437. package/dist/tools/dream-memory.js +513 -0
  438. package/dist/tools/dream-memory.js.map +1 -0
  439. package/dist/tools/email.d.ts +1 -1
  440. package/dist/tools/execution-control.d.ts +31 -0
  441. package/dist/tools/execution-control.d.ts.map +1 -0
  442. package/dist/tools/execution-control.js +71 -0
  443. package/dist/tools/execution-control.js.map +1 -0
  444. package/dist/tools/index.d.ts +5 -7
  445. package/dist/tools/index.d.ts.map +1 -1
  446. package/dist/tools/index.js +7 -13
  447. package/dist/tools/index.js.map +1 -1
  448. package/dist/tools/mcp-manager.d.ts +1 -1
  449. package/dist/tools/memory.d.ts +1 -1
  450. package/dist/tools/memory.d.ts.map +1 -1
  451. package/dist/tools/memory.js +69 -45
  452. package/dist/tools/memory.js.map +1 -1
  453. package/dist/tools/notify.d.ts +5 -0
  454. package/dist/tools/notify.d.ts.map +1 -1
  455. package/dist/tools/notify.js +45 -10
  456. package/dist/tools/notify.js.map +1 -1
  457. package/dist/tools/skill.d.ts +1 -1
  458. package/dist/tools/totp.d.ts +1 -1
  459. package/dist/tui/client.d.ts +1 -16
  460. package/dist/tui/client.d.ts.map +1 -1
  461. package/dist/tui/client.js +0 -4
  462. package/dist/tui/client.js.map +1 -1
  463. package/dist/tui/index.d.ts.map +1 -1
  464. package/dist/tui/index.js +0 -41
  465. package/dist/tui/index.js.map +1 -1
  466. package/dist/tui/protocol.d.ts +2 -1
  467. package/dist/tui/protocol.d.ts.map +1 -1
  468. package/dist/tui/protocol.js +2 -1
  469. package/dist/tui/protocol.js.map +1 -1
  470. package/dist/tui/renderer.d.ts.map +1 -1
  471. package/dist/tui/renderer.js +0 -5
  472. package/dist/tui/renderer.js.map +1 -1
  473. package/dist/tui/request-store.d.ts +1 -1
  474. package/dist/tui/request-store.d.ts.map +1 -1
  475. package/dist/tui/request-store.js +2 -2
  476. package/dist/tui/request-store.js.map +1 -1
  477. package/dist/tui/server.d.ts.map +1 -1
  478. package/dist/tui/server.js +137 -25
  479. package/dist/tui/server.js.map +1 -1
  480. package/dist/utils/claude-transcripts.d.ts +6 -0
  481. package/dist/utils/claude-transcripts.d.ts.map +1 -1
  482. package/dist/utils/claude-transcripts.js +8 -2
  483. package/dist/utils/claude-transcripts.js.map +1 -1
  484. package/dist/utils/restart.d.ts.map +1 -1
  485. package/dist/utils/restart.js +6 -0
  486. package/dist/utils/restart.js.map +1 -1
  487. package/dist-agent/bundle.cjs +2 -2
  488. package/package.json +1 -1
  489. package/dist/agent/mailbox.d.ts +0 -50
  490. package/dist/agent/mailbox.d.ts.map +0 -1
  491. package/dist/agent/mailbox.js +0 -124
  492. package/dist/agent/mailbox.js.map +0 -1
  493. package/dist/agent/nightly-maintenance/memory-dreaming-sweep.d.ts +0 -77
  494. package/dist/agent/nightly-maintenance/memory-dreaming-sweep.d.ts.map +0 -1
  495. package/dist/agent/nightly-maintenance/memory-dreaming-sweep.js +0 -158
  496. package/dist/agent/nightly-maintenance/memory-dreaming-sweep.js.map +0 -1
  497. package/dist/agent/nightly-maintenance/memory-dreaming.d.ts +0 -116
  498. package/dist/agent/nightly-maintenance/memory-dreaming.d.ts.map +0 -1
  499. package/dist/agent/nightly-maintenance/memory-dreaming.js +0 -458
  500. package/dist/agent/nightly-maintenance/memory-dreaming.js.map +0 -1
  501. package/dist/builtin-skills/catalog/phone-adb-automation/SKILL.md +0 -412
  502. package/dist/builtin-skills/catalog/phone-adb-automation/phone_input.sh +0 -132
  503. package/dist/builtin-skills/catalog/phone-adb-automation/phone_launch.sh +0 -166
  504. package/dist/builtin-skills/catalog/phone-adb-automation/phone_screenshot.sh +0 -87
  505. package/dist/builtin-skills/catalog/phone-adb-automation/phone_security_kbd.py +0 -174
  506. package/dist/builtin-skills/catalog/phone-adb-automation/phone_setup.sh +0 -274
  507. package/dist/builtin-skills/catalog/phone-adb-automation/phone_swipe.sh +0 -111
  508. package/dist/builtin-skills/catalog/phone-adb-automation/phone_tap.sh +0 -87
  509. package/dist/builtin-skills/catalog/phone-adb-automation/phone_ui_parse.py +0 -176
  510. package/dist/builtin-skills/catalog/phone-adb-automation/phone_wake_unlock.sh +0 -67
  511. package/dist/builtin-skills/macos-automation/SKILL.md +0 -132
  512. package/dist/builtin-skills/transcribe-audio/SKILL.md +0 -122
  513. package/dist/builtin-skills/visionclaw-manual/SKILL.md +0 -337
  514. package/dist/obs/rdp/icons/icons/app_windows.svg +0 -4
  515. package/dist/obs/rdp/icons/icons/clip_get.svg +0 -4
  516. package/dist/obs/rdp/icons/icons/clip_send.svg +0 -4
  517. package/dist/obs/rdp/icons/icons/clip_shared.svg +0 -4
  518. package/dist/obs/rdp/icons/icons/clipboard.svg +0 -4
  519. package/dist/obs/rdp/icons/icons/clipboard_shared.svg +0 -4
  520. package/dist/obs/rdp/icons/icons/control.svg +0 -4
  521. package/dist/obs/rdp/icons/icons/desktop.svg +0 -4
  522. package/dist/obs/rdp/icons/icons/display.svg +0 -4
  523. package/dist/obs/rdp/icons/icons/launchpad.svg +0 -4
  524. package/dist/obs/rdp/icons/icons/mission_control.svg +0 -4
  525. package/dist/obs/rdp/icons/icons/screenshot.svg +0 -4
  526. package/dist/obs/rdp/icons/icons/zoom_actual.svg +0 -4
  527. package/dist/obs/rdp/icons/icons/zoom_fit.svg +0 -4
  528. package/dist/obs/rdp/icons/icons/zoom_in.svg +0 -4
  529. package/dist/obs/rdp/icons/icons/zoom_out.svg +0 -4
  530. package/dist/realtime/assets/index.html +0 -1058
  531. package/dist/realtime/assets/samples/alloy.mp3 +0 -0
  532. package/dist/realtime/assets/samples/ash.mp3 +0 -0
  533. package/dist/realtime/assets/samples/ballad.mp3 +0 -0
  534. package/dist/realtime/assets/samples/cedar.mp3 +0 -0
  535. package/dist/realtime/assets/samples/coral.mp3 +0 -0
  536. package/dist/realtime/assets/samples/echo.mp3 +0 -0
  537. package/dist/realtime/assets/samples/marin.mp3 +0 -0
  538. package/dist/realtime/assets/samples/sage.mp3 +0 -0
  539. package/dist/realtime/assets/samples/shimmer.mp3 +0 -0
  540. package/dist/realtime/assets/samples/verse.mp3 +0 -0
  541. package/dist/threads/task-contracts.d.ts +0 -194
  542. package/dist/threads/task-contracts.d.ts.map +0 -1
  543. package/dist/threads/task-contracts.js +0 -82
  544. package/dist/threads/task-contracts.js.map +0 -1
  545. package/dist/threads/task-sidecar.d.ts +0 -143
  546. package/dist/threads/task-sidecar.d.ts.map +0 -1
  547. package/dist/threads/task-sidecar.js +0 -309
  548. package/dist/threads/task-sidecar.js.map +0 -1
  549. package/dist/threads/task-store.d.ts +0 -172
  550. package/dist/threads/task-store.d.ts.map +0 -1
  551. package/dist/threads/task-store.js +0 -594
  552. package/dist/threads/task-store.js.map +0 -1
  553. package/dist/threads/thread-task-context.d.ts +0 -40
  554. package/dist/threads/thread-task-context.d.ts.map +0 -1
  555. package/dist/threads/thread-task-context.js +0 -159
  556. package/dist/threads/thread-task-context.js.map +0 -1
  557. package/dist/threads/thread-task-controller.d.ts +0 -122
  558. package/dist/threads/thread-task-controller.d.ts.map +0 -1
  559. package/dist/threads/thread-task-controller.js +0 -276
  560. package/dist/threads/thread-task-controller.js.map +0 -1
  561. package/dist/threads/thread-task-runtime.d.ts +0 -320
  562. package/dist/threads/thread-task-runtime.d.ts.map +0 -1
  563. package/dist/threads/thread-task-runtime.js +0 -843
  564. package/dist/threads/thread-task-runtime.js.map +0 -1
  565. package/dist/tools/switch-session.d.ts +0 -15
  566. package/dist/tools/switch-session.d.ts.map +0 -1
  567. package/dist/tools/switch-session.js +0 -88
  568. package/dist/tools/switch-session.js.map +0 -1
  569. package/dist/tools/thread-tasks.d.ts +0 -10
  570. package/dist/tools/thread-tasks.d.ts.map +0 -1
  571. package/dist/tools/thread-tasks.js +0 -88
  572. package/dist/tools/thread-tasks.js.map +0 -1
  573. package/dist-agent/assets/index.html +0 -1058
  574. package/dist-agent/assets/samples/alloy.mp3 +0 -0
  575. package/dist-agent/assets/samples/ash.mp3 +0 -0
  576. package/dist-agent/assets/samples/ballad.mp3 +0 -0
  577. package/dist-agent/assets/samples/cedar.mp3 +0 -0
  578. package/dist-agent/assets/samples/coral.mp3 +0 -0
  579. package/dist-agent/assets/samples/echo.mp3 +0 -0
  580. package/dist-agent/assets/samples/marin.mp3 +0 -0
  581. package/dist-agent/assets/samples/sage.mp3 +0 -0
  582. package/dist-agent/assets/samples/shimmer.mp3 +0 -0
  583. package/dist-agent/assets/samples/verse.mp3 +0 -0
  584. package/dist-agent/playwriter-relay.cjs +0 -95
  585. package/dist-agent/realtime/assets/index.html +0 -1058
  586. package/dist-agent/realtime/assets/samples/alloy.mp3 +0 -0
  587. package/dist-agent/realtime/assets/samples/ash.mp3 +0 -0
  588. package/dist-agent/realtime/assets/samples/ballad.mp3 +0 -0
  589. package/dist-agent/realtime/assets/samples/cedar.mp3 +0 -0
  590. package/dist-agent/realtime/assets/samples/coral.mp3 +0 -0
  591. package/dist-agent/realtime/assets/samples/echo.mp3 +0 -0
  592. package/dist-agent/realtime/assets/samples/marin.mp3 +0 -0
  593. package/dist-agent/realtime/assets/samples/sage.mp3 +0 -0
  594. package/dist-agent/realtime/assets/samples/shimmer.mp3 +0 -0
  595. package/dist-agent/realtime/assets/samples/verse.mp3 +0 -0
@@ -1,843 +0,0 @@
1
- /**
2
- * ThreadTaskRuntime (issue #1996, PR 3): the one object the live loop talks
3
- * to. It owns this process's {@link ThreadTaskStore} and
4
- * {@link ThreadTaskController} for the thread it serves — the default thread
5
- * in the main process, a business thread in its worker.
6
- *
7
- * Hot-path rule: every method is fail-safe. A store, controller or model
8
- * error is logged and swallowed; it must never break message handling, a
9
- * wake or a reply. The cost of a failure is a missed task update that the
10
- * next run can still recover from the persisted events, never a lost message.
11
- */
12
- import { randomUUID } from "node:crypto";
13
- import path from "node:path";
14
- import { getConfigDir } from "../config/index.js";
15
- import { DEFAULT_THREAD_ID } from "../channels/interface.js";
16
- import { getMessageDedupKey } from "../channels/message-dedup.js";
17
- import { EXTERNAL_WAKE_KIND } from "../channels/queue.js";
18
- import { logger } from "../logger.js";
19
- import { OPEN_TASK_STATUSES } from "./task-contracts.js";
20
- import { createSidecarModel } from "./task-sidecar.js";
21
- import { ThreadTaskStore, messageEventKey } from "./task-store.js";
22
- import { ThreadTaskController } from "./thread-task-controller.js";
23
- import { renderThreadTaskContext } from "./thread-task-context.js";
24
- import { taskContinuationRouting } from "../agent/reply-target.js";
25
- /** Execution events are batched harder than owner messages; each run is a model call. */
26
- const LIVE_CONTROLLER_DEFAULTS = {
27
- batchDelayMs: 30_000,
28
- maxBatchEvents: 40,
29
- callTimeoutMs: 60_000,
30
- budget: { maxCalls: 12, windowMs: 10 * 60_000 },
31
- // Execution events alone never use the last 4 calls of the window, so an
32
- // owner message still gets a run during a long busy wake.
33
- ownerReserve: 4,
34
- };
35
- /**
36
- * How long a fast reply waits for the sidecar before it settles for
37
- * "received". Added in front of the fast responder's own 5 s budget.
38
- */
39
- export const REGISTRATION_WAIT_MS = 6_000;
40
- /**
41
- * How long a lifecycle boundary waits for the sidecar to catch up (#1996 PR 4).
42
- * Wake end is short because the next message waits behind it; compaction,
43
- * refresh and handoff are already slow.
44
- */
45
- export const RECONCILE_WAIT_MS = { wakeEnd: 5_000, handoff: 8_000, boundary: 10_000 };
46
- /** Newest unfolded events read for the context block. */
47
- const UNFOLDED_CONTEXT_EVENTS = 200;
48
- /** `meta.kind` of a queued resume (PR 5). A system row: no fast reply, watchdog or gate reply. */
49
- export const TASK_RESUME_KIND = "thread-task-resume";
50
- const RESUME_SENDER = "thread-task-resume";
51
- /**
52
- * At most this many resumes are queued per pass. One wake works one task at
53
- * a time; the next pass after it queues the next one.
54
- */
55
- const RESUMES_PER_PASS = 1;
56
- /** Unfolded events read at `/stop` to tell pre-stop tasks from later ones. */
57
- const STOP_EVENTS = 1_000;
58
- /** A resume pass waits for the sidecar to catch up; if it cannot, it retries after this. */
59
- export const RESUME_RETRY_MS = 60_000;
60
- function errorMessage(error) {
61
- return error instanceof Error ? error.message : String(error);
62
- }
63
- export class ThreadTaskRuntime {
64
- threadId;
65
- store;
66
- controller;
67
- /**
68
- * Latest event seq when this process started. A task whose last committed
69
- * change came from events up to here was moved by a previous process.
70
- */
71
- startSeq;
72
- /** Resumes this process accepted, by task id: a resume runs once per task per process. Released when its message goes back on the queue. */
73
- resumesAccepted = new Set();
74
- closed = false;
75
- resumeHooks = null;
76
- resumeRetry = null;
77
- resumeRunning = false;
78
- constructor(threadId, store, controller, startSeq, inProgressAtStart) {
79
- this.threadId = threadId;
80
- this.store = store;
81
- this.controller = controller;
82
- this.startSeq = startSeq;
83
- if (inProgressAtStart > 0) {
84
- logger.system(`[thread-tasks] thread=${threadId}: ${inProgressAtStart} task(s) were in progress when the previous process stopped`);
85
- }
86
- }
87
- /**
88
- * Open the thread's store next to its queue.db, take the writer slot and
89
- * start the controller (which picks up events a previous process left).
90
- * Returns null instead of throwing: without a runtime the agent runs
91
- * exactly as before.
92
- */
93
- static start(options) {
94
- let store;
95
- try {
96
- store = new ThreadTaskStore({
97
- threadId: options.threadId,
98
- writerId: options.writerId,
99
- // Same file the MessageQueue owner opens, whichever process this is.
100
- dbPath: options.dbPath ?? path.join(getConfigDir(), "queue.db"),
101
- claimWriter: true,
102
- });
103
- // Read before the controller starts: it may move these tasks on, and
104
- // nothing after start() may throw and leave its timer running.
105
- const startSeq = store.latestSeq();
106
- const inProgressAtStart = store.listTasks(["in_progress"]).length;
107
- const controller = new ThreadTaskController({
108
- store,
109
- model: options.model ?? createSidecarModel(options.config),
110
- ...LIVE_CONTROLLER_DEFAULTS,
111
- ...options.controller,
112
- });
113
- const runtime = new ThreadTaskRuntime(options.threadId, store, controller, startSeq, inProgressAtStart);
114
- controller.start();
115
- return runtime;
116
- }
117
- catch (error) {
118
- logger.err(`[thread-tasks] disabled for thread=${options.threadId}: ${errorMessage(error)}`);
119
- try {
120
- store?.close();
121
- }
122
- catch {
123
- // Already closed or never opened.
124
- }
125
- return null;
126
- }
127
- }
128
- /**
129
- * Persist owner messages as events. Idempotent per message (queue dedup
130
- * key), so a redelivered message, the watchdog and the wake path can all
131
- * call it. Returns false if any message could not be recorded.
132
- */
133
- recordMessages(messages, options = {}) {
134
- if (this.closed || messages.length === 0)
135
- return !this.closed;
136
- let ok = true;
137
- let appended = false;
138
- for (const msg of messages) {
139
- try {
140
- appended = this.store.appendMessageEvent(msg).appended || appended;
141
- }
142
- catch (error) {
143
- ok = false;
144
- logger.err(`[thread-tasks] could not record message ${msg.id} thread=${this.threadId}: ${errorMessage(error)}`);
145
- }
146
- }
147
- if (appended && options.notify !== false)
148
- this.safeNotify(true);
149
- return ok;
150
- }
151
- /** Persist an execution event (response, tool result, todo update, status report). */
152
- recordExecution(input) {
153
- if (this.closed)
154
- return;
155
- try {
156
- if (this.store.appendEvent(input).appended)
157
- this.safeNotify(false);
158
- }
159
- catch (error) {
160
- logger.warn(`[thread-tasks] could not record ${input.kind} thread=${this.threadId}: ${errorMessage(error)}`);
161
- }
162
- }
163
- /**
164
- * Record the messages, then wait up to `waitMs` for the sidecar to consume
165
- * them. `registered` lists the open tasks the commit tied to these messages;
166
- * empty means a reply may only acknowledge receipt.
167
- *
168
- * A run that started before these events cannot commit them (it snapshotted
169
- * its batch), and a batch is a contiguous prefix, so the message may need
170
- * more than one run: an execution-event backlog in front of it is folded
171
- * first. The loop therefore waits for this message's events to be consumed,
172
- * not for a single run, and stops as soon as the deadline passes or a run
173
- * fails (the controller keeps retrying those events on its own schedule).
174
- */
175
- async registerMessages(messages, waitMs = REGISTRATION_WAIT_MS) {
176
- const recorded = this.recordMessages(messages, { notify: false });
177
- if (!recorded || this.closed)
178
- return { recorded, registered: [] };
179
- try {
180
- const target = this.store.latestSeq();
181
- const deadline = Date.now() + waitMs;
182
- while (!this.isClosed() && this.store.getPosition() < target) {
183
- const remaining = deadline - Date.now();
184
- if (remaining <= 0)
185
- break;
186
- let timer;
187
- const timeout = new Promise((resolve) => { timer = setTimeout(() => { resolve("timeout"); }, remaining); });
188
- const outcome = await Promise.race([this.controller.runOnce(), timeout]).finally(() => { clearTimeout(timer); });
189
- // Only a commit or a conflict re-read is worth another pass; anything
190
- // else (deadline, budget, fence, failure) is retried by the controller.
191
- if (outcome === "timeout" || (outcome.status !== "committed" && outcome.status !== "conflict"))
192
- break;
193
- }
194
- return { recorded, registered: this.tasksForMessages(messages) };
195
- }
196
- catch (error) {
197
- logger.warn(`[thread-tasks] registration run failed thread=${this.threadId}: ${errorMessage(error)}`);
198
- return { recorded, registered: [] };
199
- }
200
- }
201
- /** `close()` may run while a wait awaits; a method read is not narrowed away. */
202
- isClosed() {
203
- return this.closed;
204
- }
205
- /** Open tasks already tied to any of these messages (no model call). */
206
- tasksForMessages(messages) {
207
- try {
208
- const eventIds = new Set();
209
- for (const msg of messages) {
210
- const event = this.store.getEventByKey(messageEventKey(getMessageDedupKey(msg)));
211
- if (event)
212
- eventIds.add(event.id);
213
- }
214
- if (eventIds.size === 0)
215
- return [];
216
- return this.store.listOpenTasks().filter((task) => task.sourceEventIds.some((id) => eventIds.has(id)));
217
- }
218
- catch (error) {
219
- logger.warn(`[thread-tasks] lookup failed thread=${this.threadId}: ${errorMessage(error)}`);
220
- return [];
221
- }
222
- }
223
- /** Tasks of this thread for the query tool; `[]` on error. */
224
- listTasks(statuses = OPEN_TASK_STATUSES) {
225
- try {
226
- return this.store.listTasks(statuses);
227
- }
228
- catch (error) {
229
- logger.warn(`[thread-tasks] list failed thread=${this.threadId}: ${errorMessage(error)}`);
230
- return [];
231
- }
232
- }
233
- /**
234
- * Let the sidecar fold every event up to the latest one (the explicit
235
- * position of this boundary), waiting at most `waitMs`. No events past the
236
- * position means no model call. On timeout, budget exhaustion or failure
237
- * the events simply stay unconsumed: the controller keeps retrying them,
238
- * and {@link contextBlock} shows them raw to the next recovery.
239
- */
240
- async reconcile(phase, waitMs) {
241
- let target = 0;
242
- let position = 0;
243
- try {
244
- target = this.store.latestSeq();
245
- position = this.store.getPosition();
246
- const deadline = Date.now() + waitMs;
247
- while (!this.closed && position < target) {
248
- const remaining = deadline - Date.now();
249
- if (remaining <= 0)
250
- break;
251
- let timer;
252
- const timeout = new Promise((resolve) => { timer = setTimeout(() => { resolve("timeout"); }, remaining); });
253
- const outcome = await Promise.race([this.controller.runOnce(), timeout]).finally(() => { clearTimeout(timer); });
254
- position = this.store.getPosition();
255
- // Only a commit or a conflict re-read is worth another pass; anything
256
- // else (timeout, budget, failure, fence) is retried by the controller.
257
- if (outcome === "timeout" || (outcome.status !== "committed" && outcome.status !== "conflict"))
258
- break;
259
- }
260
- }
261
- catch (error) {
262
- logger.warn(`[thread-tasks] ${phase} reconcile failed thread=${this.threadId}: ${errorMessage(error)}`);
263
- }
264
- if (position < target) {
265
- logger.info(`[thread-tasks] ${phase} reconcile left ${target - position} event seq(s) unfolded thread=${this.threadId}`);
266
- }
267
- return { reached: position >= target, target, position };
268
- }
269
- /**
270
- * Tasks a previous process left `in_progress`: their last change came from
271
- * events recorded before this process started. That includes a task those
272
- * events only move to `in_progress` when this process folds them at
273
- * startup (the sidecar batches, so a crash usually leaves some). Once this
274
- * process's own events move the task, it is no longer interrupted.
275
- * TODO: a startup fold whose batch also holds events of this process
276
- * stamps the task with the later seq and drops the flag early.
277
- */
278
- interruptedTaskIds() {
279
- return new Set(this.store.listTasks(["in_progress"])
280
- .filter((task) => task.lastEventSeq <= this.startSeq)
281
- .map((task) => task.id));
282
- }
283
- /** The recovery context for this thread, or null when it owes nothing. Never throws. */
284
- contextBlock() {
285
- try {
286
- const position = this.store.getPosition();
287
- return renderThreadTaskContext({
288
- openTasks: this.store.listOpenTasks(),
289
- unfoldedEvents: this.store.readLatestEventsAfter(position, UNFOLDED_CONTEXT_EVENTS),
290
- unfoldedTotal: this.store.latestSeq() - position,
291
- interruptedTaskIds: this.interruptedTaskIds(),
292
- });
293
- }
294
- catch (error) {
295
- logger.warn(`[thread-tasks] context unavailable thread=${this.threadId}: ${errorMessage(error)}`);
296
- return null;
297
- }
298
- }
299
- /**
300
- * Queue a resume for the next runnable task (PR 5), so the thread keeps
301
- * working without a new owner message. Crash-safe in three steps:
302
- * reserve the delivery record (`recovery:<task>:v<version>`), enqueue a
303
- * system message whose id is that key, then mark it delivered. A crash
304
- * before the enqueue leaves a reservation that the next pass re-sends; a
305
- * crash after it is harmless because the queue dedups the id. A resume
306
- * that was already delivered is never queued again for the same version.
307
- *
308
- * Never throws. Returns what it queued.
309
- */
310
- deliverResumes(queue, now = Date.now()) {
311
- if (this.closed)
312
- return { queued: [] };
313
- const queued = [];
314
- try {
315
- // Re-send reservations a previous pass made but did not deliver.
316
- for (const record of this.store.listUndeliveredRecoveries()) {
317
- const task = this.store.getTask(record.taskId);
318
- if (this.enqueueResume(queue, record.idempotencyKey, task, record.taskVersion))
319
- queued.push(record.idempotencyKey);
320
- }
321
- if (queued.length < RESUMES_PER_PASS) {
322
- // Work the previous process left in progress comes first. Its resume
323
- // may have been replayed already (then it is accepted and skipped).
324
- const interrupted = [...this.interruptedTaskIds()]
325
- .filter((id) => !this.resumesAccepted.has(id))
326
- .map((id) => this.store.getTask(id))
327
- .filter((task) => task !== undefined);
328
- for (const task of [...interrupted, ...this.store.listRunnableTasks(now)]) {
329
- if (queued.length >= RESUMES_PER_PASS)
330
- break;
331
- const reservation = this.store.reserveRecoveryDelivery({ taskId: task.id, taskVersion: task.version });
332
- if (!reservation.ok) {
333
- logger.warn(`[thread-tasks] resume not reserved thread=${this.threadId}: ${reservation.reason}`);
334
- break;
335
- }
336
- // Already delivered for this version: a wake took it and made no
337
- // recorded progress. Do not loop on it; progress bumps the version.
338
- if (!reservation.value.reserved)
339
- continue;
340
- if (this.enqueueResume(queue, reservation.value.record.idempotencyKey, task, task.version)) {
341
- queued.push(reservation.value.record.idempotencyKey);
342
- }
343
- }
344
- }
345
- return { queued };
346
- }
347
- catch (error) {
348
- logger.warn(`[thread-tasks] resume pass failed thread=${this.threadId}: ${errorMessage(error)}`);
349
- return { queued };
350
- }
351
- }
352
- /**
353
- * Whether a dequeued resume may still run (the re-check before execution).
354
- * Yes when its task is still pending at the version it was queued for and
355
- * is due: a cancel, modification, wait or block since then makes it stale.
356
- * Also yes, once per task per process, when a previous process left the
357
- * task `in_progress` ({@link interruptedTaskIds}): that is a resume replayed
358
- * after a crash, or one queued for the interrupted task. Its version is not
359
- * compared, because folding the previous process's last events at startup
360
- * bumps it.
361
- *
362
- * The "once" test is against {@link resumesAccepted}, which a requeue
363
- * releases ({@link releaseResume}): an accepted resume whose message went
364
- * back on the queue must still run when it is dequeued again, or the
365
- * interrupted task keeps its only recovery row forever.
366
- * Fail-closed: any error means no.
367
- */
368
- isResumeRunnable(msg, now = Date.now()) {
369
- try {
370
- const taskId = msg.meta?.taskId;
371
- const taskVersion = msg.meta?.taskVersion;
372
- if (typeof taskId !== "string" || typeof taskVersion !== "number")
373
- return false;
374
- const task = this.store.getTask(taskId);
375
- if (!task)
376
- return false;
377
- // Left in progress by a previous process: once, whatever the version.
378
- if (task.status === "in_progress" && this.interruptedTaskIds().has(task.id)) {
379
- return !this.resumesAccepted.has(task.id);
380
- }
381
- // Pending, or unfinished by an earlier wake of this process: unchanged
382
- // since it was queued. Any progress, wait, block or cancel bumps the version.
383
- return (task.status === "pending" || task.status === "in_progress")
384
- && task.version === taskVersion
385
- && (task.runAfter === undefined || task.runAfter <= now);
386
- }
387
- catch (error) {
388
- logger.warn(`[thread-tasks] resume check failed thread=${this.threadId}: ${errorMessage(error)}`);
389
- return false;
390
- }
391
- }
392
- /**
393
- * The re-check at dequeue: {@link isResumeRunnable}, and if yes, record
394
- * that this process is now working on the task so a second copy of its
395
- * resume is stale.
396
- */
397
- acceptResume(msg, now = Date.now()) {
398
- if (!this.isResumeRunnable(msg, now))
399
- return false;
400
- this.resumesAccepted.add(msg.meta?.taskId);
401
- return true;
402
- }
403
- /**
404
- * The resume was accepted but its message went back on the queue (a failed
405
- * inject, an orphaned injection, a failed wake). Takes the acceptance back
406
- * so the next dequeue may run it. Safe for any message: not a resume, or
407
- * never accepted, does nothing. #2664 review P1-B.
408
- */
409
- releaseResume(messages) {
410
- for (const msg of messages) {
411
- const taskId = msg.meta?.taskId;
412
- if (!isTaskResumeMessage(msg) || typeof taskId !== "string")
413
- continue;
414
- if (this.resumesAccepted.delete(taskId)) {
415
- logger.info(`[thread-tasks] resume released back to the queue thread=${this.threadId} task=${taskId}`);
416
- }
417
- }
418
- }
419
- /** Install the loop's hooks. Resumes are only queued once this is set. */
420
- enableResumes(hooks) {
421
- this.resumeHooks = hooks;
422
- }
423
- /**
424
- * The owner sent `/stop` (option B, owner 10-04): cancel every unfinished
425
- * task of this thread. Cancelled is a stored status, so nothing queued
426
- * starts on its own, a restart cannot bring it back, and resumes already
427
- * queued are retired at dequeue.
428
- *
429
- * The open tasks are cancelled at once. A message sent just before
430
- * `/stop` may not be folded yet: the sidecar then folds up to the stop
431
- * (bounded by `waitMs`) and the tasks those events created are cancelled
432
- * too. Tasks from messages after the `/stop` are kept. Returns every
433
- * cancelled task, for the reply. Never throws.
434
- * TODO: a fold that misses `waitMs` (or more than {@link STOP_EVENTS}
435
- * unfolded events) can still create a task from a pre-stop message later.
436
- */
437
- async cancelOpenTasks(waitMs = RECONCILE_WAIT_MS.wakeEnd, queue) {
438
- if (this.closed)
439
- return { cancelled: [], droppedQueued: 0 };
440
- let beforeStop;
441
- let cancelled;
442
- let droppedQueued = 0;
443
- try {
444
- // Queue rows first, at this boundary: a message the interrupt debounce
445
- // has not recorded yet is not an event and owns no task, so nothing
446
- // below would ever see it. Left in place, the next wake reads it as a
447
- // new request and runs it (#2664 review P1-A).
448
- droppedQueued = this.dropQueuedMessages(queue);
449
- beforeStop = new Set(this.store.readUnconsumedEvents(STOP_EVENTS).map((event) => event.id));
450
- cancelled = this.cancelTasks(this.store.listOpenTasks());
451
- }
452
- catch (error) {
453
- logger.warn(`[thread-tasks] /stop cancel failed thread=${this.threadId}: ${errorMessage(error)}`);
454
- return { cancelled: [], droppedQueued };
455
- }
456
- if (beforeStop.size === 0)
457
- return { cancelled, droppedQueued };
458
- await this.reconcile("stop", waitMs);
459
- if (this.isClosed())
460
- return { cancelled, droppedQueued };
461
- try {
462
- // A task's first source event is the one that created it.
463
- const late = this.store.listOpenTasks().filter((task) => beforeStop.has(task.sourceEventIds[0] ?? ""));
464
- return { cancelled: [...cancelled, ...this.cancelTasks(late)], droppedQueued };
465
- }
466
- catch (error) {
467
- logger.warn(`[thread-tasks] /stop cancel failed thread=${this.threadId}: ${errorMessage(error)}`);
468
- return { cancelled, droppedQueued };
469
- }
470
- }
471
- /**
472
- * Drop queued owner messages: rows not claimed by a wake, that are not
473
- * system rows (a resume, or the stop command itself) and that the task
474
- * sidecar would read as owner input. Returns how many were dropped.
475
- * Fail-safe: a row that cannot be read is left alone.
476
- */
477
- dropQueuedMessages(queue) {
478
- if (!queue)
479
- return 0;
480
- let dropped = 0;
481
- for (const msg of queue.snapshot()) {
482
- if (msg.channel === "system" || !isTaskRelevantMessage(msg))
483
- continue;
484
- try {
485
- // Handled, not just removed: a provider retry of the same message
486
- // would otherwise be accepted again as a request after the stop.
487
- if (queue.remove(msg.id)) {
488
- queue.markHandled(msg);
489
- dropped += 1;
490
- }
491
- }
492
- catch (error) {
493
- logger.warn(`[thread-tasks] could not drop queued message ${msg.id} thread=${this.threadId}: ${errorMessage(error)}`);
494
- }
495
- }
496
- if (dropped > 0)
497
- logger.system(`[thread-tasks] /stop dropped ${dropped} queued message(s) thread=${this.threadId}`);
498
- return dropped;
499
- }
500
- /**
501
- * Commit `cancelled` for these tasks without consuming any event, so the
502
- * sidecar still folds everything. Read and commit run in one synchronous
503
- * stretch, so no sidecar commit lands between them; a sidecar call in
504
- * flight hits a version conflict and re-reads.
505
- */
506
- cancelTasks(tasks) {
507
- if (tasks.length === 0)
508
- return [];
509
- const position = this.store.getPosition();
510
- const result = this.store.commit({
511
- expectedPosition: position,
512
- throughSeq: position,
513
- changes: tasks.map((task) => ({ op: "update", taskId: task.id, expectedVersion: task.version, patch: { status: "cancelled" } })),
514
- });
515
- if (!result.ok) {
516
- logger.warn(`[thread-tasks] /stop cancel rejected thread=${this.threadId}: ${result.reason} ${result.detail}`);
517
- return [];
518
- }
519
- logger.system(`[thread-tasks] /stop cancelled ${tasks.length} task(s) thread=${this.threadId}`);
520
- return [...tasks];
521
- }
522
- /**
523
- * Fold the events up to now, then queue the next runnable task. Called at
524
- * wake end and at startup; never throws and never blocks the caller's
525
- * loop. Without the fold a task the wake just finished could still look
526
- * pending, so a pass that cannot catch up delivers nothing and retries
527
- * after {@link RESUME_RETRY_MS} instead. A fold that needs a slow sidecar
528
- * call therefore starts the next task about a minute later, not at once.
529
- */
530
- async requestResume(waitMs = RECONCILE_WAIT_MS.wakeEnd) {
531
- const hooks = this.resumeHooks;
532
- if (!hooks || this.closed || this.resumeRunning)
533
- return { queued: [] };
534
- this.resumeRunning = true;
535
- this.clearResumeRetry();
536
- try {
537
- const reconciled = await this.reconcile("wake_end", waitMs);
538
- if (this.isClosed())
539
- return { queued: [] };
540
- // Events that arrived during the fold (another wake ran and ended; its
541
- // own pass was dropped because this one was running) may cancel or
542
- // finish the task this pass would queue: fold them first.
543
- if (!reconciled.reached || this.store.latestSeq() > reconciled.target) {
544
- this.scheduleResumeRetry();
545
- return { queued: [] };
546
- }
547
- // Busy: usually a wake, whose end starts the next pass; but nightly
548
- // maintenance is busy too and has no wake end, so retry either way.
549
- if (hooks.isBusy() || hooks.isGated()) {
550
- this.scheduleResumeRetry();
551
- return { queued: [] };
552
- }
553
- const outcome = this.deliverResumes(hooks.queue);
554
- if (outcome.queued.length > 0)
555
- hooks.wake();
556
- // By design (owner 10-03): a not-yet-due task waits; its due or
557
- // unblock wake comes from the existing calendar / event-trigger
558
- // messages to this thread. Thread tasks never schedule wakes.
559
- return outcome;
560
- }
561
- catch (error) {
562
- logger.warn(`[thread-tasks] resume request failed thread=${this.threadId}: ${errorMessage(error)}`);
563
- return { queued: [] };
564
- }
565
- finally {
566
- this.resumeRunning = false;
567
- }
568
- }
569
- scheduleResumeRetry() {
570
- if (this.closed || this.resumeRetry)
571
- return;
572
- this.resumeRetry = setTimeout(() => {
573
- this.resumeRetry = null;
574
- void this.requestResume();
575
- }, RESUME_RETRY_MS);
576
- this.resumeRetry.unref();
577
- }
578
- clearResumeRetry() {
579
- if (this.resumeRetry)
580
- clearTimeout(this.resumeRetry);
581
- this.resumeRetry = null;
582
- }
583
- /** Enqueue one reserved resume and mark it delivered. False when nothing was handed over. */
584
- enqueueResume(queue, key, task, version) {
585
- if (!task) {
586
- // TODO: a reservation whose task row is gone stays reserved; harmless,
587
- // the next pass skips it again.
588
- return false;
589
- }
590
- // `enqueue` returns false for an id it already holds or handled: that
591
- // resume reached the queue before a crash, so marking it is still right.
592
- queue.enqueue(resumeMessage(this.threadId, key, task, version));
593
- const marked = this.store.markRecoveryDelivered(key);
594
- if (!marked.ok) {
595
- logger.warn(`[thread-tasks] resume ${key} queued but not marked thread=${this.threadId}: ${marked.reason}`);
596
- return false;
597
- }
598
- this.recordExecution({
599
- idempotencyKey: key,
600
- kind: "recovery",
601
- payload: { text: `Resumed: ${task.title}`, data: { taskId: task.id, taskVersion: version } },
602
- });
603
- logger.system(`[thread-tasks] queued resume thread=${this.threadId} task=${task.id} v${version}`);
604
- return true;
605
- }
606
- /** Events not yet folded into tasks (the sidecar is behind or failing). */
607
- pendingEventCount() {
608
- try {
609
- return this.store.readUnconsumedEvents(1_000).length;
610
- }
611
- catch {
612
- return 0;
613
- }
614
- }
615
- async close(graceMs) {
616
- if (this.closed)
617
- return;
618
- this.closed = true;
619
- this.clearResumeRetry();
620
- try {
621
- await this.controller.close(graceMs);
622
- }
623
- catch (error) {
624
- logger.warn(`[thread-tasks] controller close failed thread=${this.threadId}: ${errorMessage(error)}`);
625
- }
626
- try {
627
- this.store.close();
628
- }
629
- catch {
630
- // Closing twice or after a failed open is harmless.
631
- }
632
- }
633
- safeNotify(immediate) {
634
- try {
635
- this.controller.notify({ immediate });
636
- }
637
- catch (error) {
638
- logger.warn(`[thread-tasks] notify failed thread=${this.threadId}: ${errorMessage(error)}`);
639
- }
640
- }
641
- }
642
- /**
643
- * The queue row for a resume. Its id is the delivery key, so the queue's
644
- * own dedup refuses a second copy. `system` keeps it out of fast replies,
645
- * the watchdog, activity cards and gate replies; the reply target travels
646
- * with the task, not with this row.
647
- */
648
- function resumeMessage(threadId, key, task, version) {
649
- // Replies go where the task came from, like any task continuation.
650
- const routing = task.replyTarget
651
- ? taskContinuationRouting({ sender: RESUME_SENDER, delivery: task.replyTarget })
652
- : { meta: {} };
653
- return {
654
- id: key,
655
- channel: "system",
656
- sender: RESUME_SENDER,
657
- text: `[Thread task resume] Continue the queued task "${task.title}" (id ${task.id}). ` +
658
- "Its requirements and checkpoint are in the Thread Tasks block. Check the checkpoint and results first; never redo a step listed as done. " +
659
- "If it is no longer wanted or cannot start yet, report that instead of doing it.",
660
- attachments: [],
661
- timestamp: new Date().toISOString(),
662
- ...routing,
663
- meta: { ...routing.meta, kind: TASK_RESUME_KIND, taskId: task.id, taskVersion: version },
664
- ...(threadId !== DEFAULT_THREAD_ID ? { threadId } : {}),
665
- };
666
- }
667
- /** True for a queued thread-task resume row. */
668
- export function isTaskResumeMessage(msg) {
669
- return msg.channel === "system" && msg.meta?.kind === TASK_RESUME_KIND;
670
- }
671
- /**
672
- * The re-check before execution, at every place a wake takes rows off the
673
- * queue: a resume whose task was cancelled, changed, put on hold or already
674
- * started since it was queued is retired unexecuted. Without a runtime (the
675
- * switch was turned off) every resume is stale. Returns true when retired.
676
- */
677
- export function retireStaleResume(queue, runtime, msg) {
678
- if (!isTaskResumeMessage(msg) || runtime?.acceptResume(msg) === true)
679
- return false;
680
- logger.system(`[thread-tasks] dropping stale resume ${msg.id}`);
681
- queue.markHandled(msg);
682
- return true;
683
- }
684
- /**
685
- * Messages the task store tracks: anything from a real channel. System
686
- * messages (heartbeats, internal continuations) and external-wake markers
687
- * carry no owner request. Email and group chats are included; the sidecar
688
- * decides whether they hold a request.
689
- */
690
- export function isTaskRelevantMessage(msg) {
691
- return msg.channel !== "system" && msg.meta?.kind !== EXTERNAL_WAKE_KIND;
692
- }
693
- /**
694
- * The end-of-wake handoff (issue #1996 PR 1 rule): a claim is released as
695
- * handled only after its message is a durable task event, so the follow-up
696
- * belongs to the task store instead of vanishing with the queue row.
697
- *
698
- * Fail-safe: if recording fails the claims are still released. The agent
699
- * already processed them in this wake; replaying them would redo the work.
700
- * The error is logged. `handled` never means a task is completed.
701
- */
702
- export function releaseClaimsAfterRecording(queue, runtime) {
703
- if (runtime) {
704
- try {
705
- runtime.recordMessages(queue.currentCycleClaims().filter(isTaskRelevantMessage));
706
- }
707
- catch (error) {
708
- logger.err(`[thread-tasks] could not record claims before release: ${errorMessage(error)}`);
709
- }
710
- }
711
- queue.markAllInFlightHandled();
712
- }
713
- /**
714
- * Wake end. A wake cut short by an engine failover restart leaves its claims
715
- * in flight for the replacement process (issue #2519) and folds nothing.
716
- * Otherwise release the claims, fold this wake's events into the
717
- * checkpoints and queue the next runnable task (PR 5). Not awaited: the
718
- * session keeps its transcript, so the loop need not hold the next message
719
- * for it. Bounded; leftovers stay unconsumed and the next wake's context
720
- * shows them raw.
721
- */
722
- export function endWakeThreadTasks(queue, runtime, options) {
723
- if (options.failoverRestartPending)
724
- return;
725
- releaseClaimsAfterRecording(queue, runtime);
726
- void runtime?.requestResume();
727
- }
728
- /** Per-event caps; the sidecar clips again, this keeps the event log small. */
729
- const EXECUTION_TEXT_CHARS = 1_500;
730
- const TOOL_OUTPUT_CHARS = 400;
731
- function clipText(text, max) {
732
- return text.length <= max ? text : `${text.slice(0, max)}… [${text.length - max} more chars]`;
733
- }
734
- /**
735
- * Provider tool-call ids are not unique for the life of a thread: some
736
- * providers number them per response (`functions.notify_user:0`). A stream
737
- * emits each result once, so the key only has to be unique; a process nonce
738
- * plus a counter makes it so.
739
- */
740
- const EXECUTION_KEY_NONCE = randomUUID().slice(0, 8);
741
- let executionKeySeq = 0;
742
- function executionKey(prefix, toolUseId) {
743
- executionKeySeq += 1;
744
- return `${prefix}:${toolUseId}:${EXECUTION_KEY_NONCE}-${executionKeySeq}`;
745
- }
746
- /** Tools whose results say nothing about task progress. */
747
- const NOISE_TOOLS = new Set(["wait", "finish", "TodoWrite", "TaskCreate", "TaskUpdate", "TaskList", "TaskGet"]);
748
- function baseToolName(name) {
749
- return name.replace(/^mcp__[^_]+(?:_[^_]+)*__/, "");
750
- }
751
- /**
752
- * Engine-neutral execution events. Both engines feed the same stream
753
- * handler, so these are called from there. Each id is unique per call, so
754
- * keys never collide across wakes or retries.
755
- */
756
- export const executionEvents = {
757
- toolResult(toolUseId, toolName, output, isError) {
758
- const name = baseToolName(toolName);
759
- // Some providers stream tool calls without an id; a shared empty key
760
- // would dedup every later one away, so those results are not recorded.
761
- if (NOISE_TOOLS.has(name) || !toolUseId)
762
- return null;
763
- return {
764
- idempotencyKey: executionKey("tool", toolUseId),
765
- kind: "tool_result",
766
- payload: { data: { tool: name, ok: !isError, output: clipText(output, TOOL_OUTPUT_CHARS) } },
767
- };
768
- },
769
- todos(toolUseId, todos) {
770
- if (!toolUseId)
771
- return null;
772
- return {
773
- idempotencyKey: executionKey("todo", toolUseId),
774
- kind: "todo_update",
775
- payload: { data: { todos: todos.map((todo) => ({ content: clipText(todo.content, 200), status: todo.status })) } },
776
- };
777
- },
778
- response(turnId, text) {
779
- const trimmed = text.trim();
780
- if (!trimmed)
781
- return null;
782
- return { idempotencyKey: `response:${turnId}`, kind: "assistant_response", payload: { text: clipText(trimmed, EXECUTION_TEXT_CHARS) } };
783
- },
784
- /** What the agent told the owner through notify_user: an explicit status report. */
785
- statusReport(toolUseId, message) {
786
- const trimmed = message.trim();
787
- if (!trimmed || !toolUseId)
788
- return null;
789
- return { idempotencyKey: executionKey("report", toolUseId), kind: "status_report", payload: { text: clipText(trimmed, EXECUTION_TEXT_CHARS) } };
790
- },
791
- };
792
- /**
793
- * The fast responder's reading of a batch, as one candidate event. It shares
794
- * the message's dedup key, so the sidecar's origin key matches the message's
795
- * and the same task is never created twice. Only for a single-message batch:
796
- * a brief over several messages cannot be keyed to the right one, and the
797
- * messages themselves are already events.
798
- */
799
- export function fastResponderCandidate(messages, brief) {
800
- const relevant = messages.filter(isTaskRelevantMessage);
801
- const first = relevant.length === 1 ? relevant[0] : undefined;
802
- const text = typeof brief === "string" ? brief.trim() : "";
803
- if (!first || !text)
804
- return null;
805
- const dedupKey = getMessageDedupKey(first);
806
- return {
807
- idempotencyKey: `candidate:${dedupKey}`,
808
- kind: "fast_responder_candidate",
809
- source: { channel: first.channel, sender: first.sender, messageId: first.id, dedupKey },
810
- payload: { text: clipText(text, EXECUTION_TEXT_CHARS) },
811
- };
812
- }
813
- /** Record the fast responder's brief as a candidate event. Never throws. */
814
- export function recordFastResponderCandidate(messages, brief) {
815
- try {
816
- recordExecutionEvent(fastResponderCandidate(messages, brief));
817
- }
818
- catch (error) {
819
- logger.warn(`[thread-tasks] could not record fast-responder candidate: ${errorMessage(error)}`);
820
- }
821
- }
822
- /** Record an execution event on the process runtime, if there is one. Never throws. */
823
- export function recordExecutionEvent(input) {
824
- if (input)
825
- current?.recordExecution(input);
826
- }
827
- /** The process runtime's recovery context, or null without a runtime (then nothing is injected). */
828
- export function buildThreadTaskContext() {
829
- return current?.contextBlock() ?? null;
830
- }
831
- /** Bounded reconcile on the process runtime; resolves immediately without one. */
832
- export async function reconcileThreadTasks(phase, waitMs = RECONCILE_WAIT_MS.boundary) {
833
- await current?.reconcile(phase, waitMs);
834
- }
835
- /** The runtime for this process, set once by the loop. Tools and hooks read it. */
836
- let current = null;
837
- export function setThreadTaskRuntime(runtime) {
838
- current = runtime;
839
- }
840
- export function getThreadTaskRuntime() {
841
- return current;
842
- }
843
- //# sourceMappingURL=thread-task-runtime.js.map