@roj-ai/sdk 0.1.36 → 0.2.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 (922) hide show
  1. package/dist/bootstrap.d.ts +420 -26
  2. package/dist/bootstrap.d.ts.map +1 -1
  3. package/dist/bootstrap.js +55 -24
  4. package/dist/bootstrap.js.map +1 -1
  5. package/dist/bun-platform/fs.d.ts.map +1 -1
  6. package/dist/bun-platform/fs.js +1 -0
  7. package/dist/bun-platform/fs.js.map +1 -1
  8. package/dist/bun-platform/index.d.ts +4 -1
  9. package/dist/bun-platform/index.d.ts.map +1 -1
  10. package/dist/bun-platform/index.js +7 -1
  11. package/dist/bun-platform/index.js.map +1 -1
  12. package/dist/bun-platform/server-lifecycle.d.ts +30 -0
  13. package/dist/bun-platform/server-lifecycle.d.ts.map +1 -0
  14. package/dist/bun-platform/server-lifecycle.js +182 -0
  15. package/dist/bun-platform/server-lifecycle.js.map +1 -0
  16. package/dist/bun-platform/shell.d.ts +33 -0
  17. package/dist/bun-platform/shell.d.ts.map +1 -0
  18. package/dist/bun-platform/shell.js +322 -0
  19. package/dist/bun-platform/shell.js.map +1 -0
  20. package/dist/config.d.ts +34 -0
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/config.js +97 -0
  23. package/dist/config.js.map +1 -1
  24. package/dist/core/agents/agent.d.ts +42 -7
  25. package/dist/core/agents/agent.d.ts.map +1 -1
  26. package/dist/core/agents/agent.js +202 -87
  27. package/dist/core/agents/agent.js.map +1 -1
  28. package/dist/core/agents/config.d.ts +8 -1
  29. package/dist/core/agents/config.d.ts.map +1 -1
  30. package/dist/core/agents/config.js +5 -1
  31. package/dist/core/agents/config.js.map +1 -1
  32. package/dist/core/agents/retry.d.ts +1 -1
  33. package/dist/core/agents/retry.d.ts.map +1 -1
  34. package/dist/core/agents/retry.js +14 -16
  35. package/dist/core/agents/retry.js.map +1 -1
  36. package/dist/core/agents/state.d.ts +3 -1
  37. package/dist/core/agents/state.d.ts.map +1 -1
  38. package/dist/core/agents/state.js +1 -1
  39. package/dist/core/agents/state.js.map +1 -1
  40. package/dist/core/context/state.d.ts +3 -3
  41. package/dist/core/context/state.js +2 -2
  42. package/dist/core/events/base-event-store.d.ts.map +1 -1
  43. package/dist/core/events/base-event-store.js +22 -14
  44. package/dist/core/events/base-event-store.js.map +1 -1
  45. package/dist/core/events/file.d.ts +39 -1
  46. package/dist/core/events/file.d.ts.map +1 -1
  47. package/dist/core/events/file.js +159 -20
  48. package/dist/core/events/file.js.map +1 -1
  49. package/dist/core/events/types.d.ts +1 -1
  50. package/dist/core/file-store/containment.d.ts +19 -0
  51. package/dist/core/file-store/containment.d.ts.map +1 -0
  52. package/dist/core/file-store/containment.js +62 -0
  53. package/dist/core/file-store/containment.js.map +1 -0
  54. package/dist/core/file-store/file-store.d.ts +22 -2
  55. package/dist/core/file-store/file-store.d.ts.map +1 -1
  56. package/dist/core/file-store/file-store.js +88 -20
  57. package/dist/core/file-store/file-store.js.map +1 -1
  58. package/dist/core/file-store/types.d.ts +13 -1
  59. package/dist/core/file-store/types.d.ts.map +1 -1
  60. package/dist/core/image/image-processor.d.ts.map +1 -1
  61. package/dist/core/image/image-processor.js +3 -1
  62. package/dist/core/image/image-processor.js.map +1 -1
  63. package/dist/core/image/types.d.ts +2 -0
  64. package/dist/core/image/types.d.ts.map +1 -1
  65. package/dist/core/image/vips-resizer.d.ts.map +1 -1
  66. package/dist/core/image/vips-resizer.js +81 -33
  67. package/dist/core/image/vips-resizer.js.map +1 -1
  68. package/dist/core/llm/anthropic.d.ts +0 -1
  69. package/dist/core/llm/anthropic.d.ts.map +1 -1
  70. package/dist/core/llm/anthropic.js +58 -72
  71. package/dist/core/llm/anthropic.js.map +1 -1
  72. package/dist/core/llm/logger.d.ts +14 -2
  73. package/dist/core/llm/logger.d.ts.map +1 -1
  74. package/dist/core/llm/logger.js +161 -36
  75. package/dist/core/llm/logger.js.map +1 -1
  76. package/dist/core/llm/openrouter.d.ts +0 -1
  77. package/dist/core/llm/openrouter.d.ts.map +1 -1
  78. package/dist/core/llm/openrouter.js +53 -66
  79. package/dist/core/llm/openrouter.js.map +1 -1
  80. package/dist/core/llm/provider-request.d.ts +10 -0
  81. package/dist/core/llm/provider-request.d.ts.map +1 -0
  82. package/dist/core/llm/provider-request.js +41 -0
  83. package/dist/core/llm/provider-request.js.map +1 -0
  84. package/dist/core/llm/provider.d.ts +11 -0
  85. package/dist/core/llm/provider.d.ts.map +1 -1
  86. package/dist/core/llm/provider.js +26 -0
  87. package/dist/core/llm/provider.js.map +1 -1
  88. package/dist/core/llm/state.d.ts +2 -2
  89. package/dist/core/llm/state.js +4 -4
  90. package/dist/core/plugins/plugin-builder.d.ts +57 -3
  91. package/dist/core/plugins/plugin-builder.d.ts.map +1 -1
  92. package/dist/core/plugins/plugin-builder.js +68 -14
  93. package/dist/core/plugins/plugin-builder.js.map +1 -1
  94. package/dist/core/preset/preset-builder.d.ts +3 -2
  95. package/dist/core/preset/preset-builder.d.ts.map +1 -1
  96. package/dist/core/preset/preset-builder.js +7 -16
  97. package/dist/core/preset/preset-builder.js.map +1 -1
  98. package/dist/core/sessions/context.d.ts +23 -5
  99. package/dist/core/sessions/context.d.ts.map +1 -1
  100. package/dist/core/sessions/runtime-activity.d.ts +33 -0
  101. package/dist/core/sessions/runtime-activity.d.ts.map +1 -0
  102. package/dist/core/sessions/runtime-activity.js +55 -0
  103. package/dist/core/sessions/runtime-activity.js.map +1 -0
  104. package/dist/core/sessions/schema.d.ts +23 -2
  105. package/dist/core/sessions/schema.d.ts.map +1 -1
  106. package/dist/core/sessions/schema.js +24 -3
  107. package/dist/core/sessions/schema.js.map +1 -1
  108. package/dist/core/sessions/session-manager.d.ts +83 -6
  109. package/dist/core/sessions/session-manager.d.ts.map +1 -1
  110. package/dist/core/sessions/session-manager.js +517 -118
  111. package/dist/core/sessions/session-manager.js.map +1 -1
  112. package/dist/core/sessions/session-store.d.ts +18 -0
  113. package/dist/core/sessions/session-store.d.ts.map +1 -1
  114. package/dist/core/sessions/session-store.js +33 -0
  115. package/dist/core/sessions/session-store.js.map +1 -1
  116. package/dist/core/sessions/session.d.ts +42 -6
  117. package/dist/core/sessions/session.d.ts.map +1 -1
  118. package/dist/core/sessions/session.js +176 -44
  119. package/dist/core/sessions/session.js.map +1 -1
  120. package/dist/core/sessions/state.d.ts +10 -1
  121. package/dist/core/sessions/state.d.ts.map +1 -1
  122. package/dist/core/sessions/state.js +11 -1
  123. package/dist/core/sessions/state.js.map +1 -1
  124. package/dist/core/system.d.ts +9 -0
  125. package/dist/core/system.d.ts.map +1 -1
  126. package/dist/core/system.js +4 -1
  127. package/dist/core/system.js.map +1 -1
  128. package/dist/core/tools/executor.d.ts +1 -1
  129. package/dist/core/wake-key.d.ts +34 -0
  130. package/dist/core/wake-key.d.ts.map +1 -0
  131. package/dist/core/wake-key.js +51 -0
  132. package/dist/core/wake-key.js.map +1 -0
  133. package/dist/index.d.ts +23 -13
  134. package/dist/index.d.ts.map +1 -1
  135. package/dist/index.js +22 -8
  136. package/dist/index.js.map +1 -1
  137. package/dist/lib/archive/archive-inspection.d.ts +48 -0
  138. package/dist/lib/archive/archive-inspection.d.ts.map +1 -0
  139. package/dist/lib/archive/archive-inspection.fixtures.d.ts +7 -0
  140. package/dist/lib/archive/archive-inspection.fixtures.d.ts.map +1 -0
  141. package/dist/lib/archive/archive-inspection.fixtures.js +134 -0
  142. package/dist/lib/archive/archive-inspection.fixtures.js.map +1 -0
  143. package/dist/lib/archive/archive-inspection.js +253 -0
  144. package/dist/lib/archive/archive-inspection.js.map +1 -0
  145. package/dist/lib/archive/index.d.ts +3 -0
  146. package/dist/lib/archive/index.d.ts.map +1 -0
  147. package/dist/lib/archive/index.js +2 -0
  148. package/dist/lib/archive/index.js.map +1 -0
  149. package/dist/lib/logger/console.d.ts +5 -12
  150. package/dist/lib/logger/console.d.ts.map +1 -1
  151. package/dist/lib/logger/console.js +5 -47
  152. package/dist/lib/logger/console.js.map +1 -1
  153. package/dist/lib/logger/file.d.ts +8 -11
  154. package/dist/lib/logger/file.d.ts.map +1 -1
  155. package/dist/lib/logger/file.js +26 -37
  156. package/dist/lib/logger/file.js.map +1 -1
  157. package/dist/lib/logger/index.d.ts +3 -1
  158. package/dist/lib/logger/index.d.ts.map +1 -1
  159. package/dist/lib/logger/index.js +3 -1
  160. package/dist/lib/logger/index.js.map +1 -1
  161. package/dist/lib/logger/jsonl.d.ts +21 -0
  162. package/dist/lib/logger/jsonl.d.ts.map +1 -0
  163. package/dist/lib/logger/jsonl.js +29 -0
  164. package/dist/lib/logger/jsonl.js.map +1 -0
  165. package/dist/lib/logger/logger.d.ts +22 -0
  166. package/dist/lib/logger/logger.d.ts.map +1 -1
  167. package/dist/lib/logger/logger.js +37 -0
  168. package/dist/lib/logger/logger.js.map +1 -1
  169. package/dist/lib/logger/session-log.d.ts +21 -0
  170. package/dist/lib/logger/session-log.d.ts.map +1 -0
  171. package/dist/lib/logger/session-log.js +37 -0
  172. package/dist/lib/logger/session-log.js.map +1 -0
  173. package/dist/lib/utils/concurrency.d.ts +1 -1
  174. package/dist/lib/utils/concurrency.d.ts.map +1 -1
  175. package/dist/lib/utils/concurrency.js +30 -7
  176. package/dist/lib/utils/concurrency.js.map +1 -1
  177. package/dist/lib/utils/fs-batch.d.ts +17 -0
  178. package/dist/lib/utils/fs-batch.d.ts.map +1 -0
  179. package/dist/lib/utils/fs-batch.js +38 -0
  180. package/dist/lib/utils/fs-batch.js.map +1 -0
  181. package/dist/lib/utils/result.d.ts +7 -22
  182. package/dist/lib/utils/result.d.ts.map +1 -1
  183. package/dist/lib/utils/result.js +6 -17
  184. package/dist/lib/utils/result.js.map +1 -1
  185. package/dist/lib/utils/sleep.d.ts +10 -0
  186. package/dist/lib/utils/sleep.d.ts.map +1 -0
  187. package/dist/lib/utils/sleep.js +26 -0
  188. package/dist/lib/utils/sleep.js.map +1 -0
  189. package/dist/platform/fs-revision.d.ts +21 -0
  190. package/dist/platform/fs-revision.d.ts.map +1 -0
  191. package/dist/platform/fs-revision.js +9 -0
  192. package/dist/platform/fs-revision.js.map +1 -0
  193. package/dist/platform/fs.d.ts +104 -1
  194. package/dist/platform/fs.d.ts.map +1 -1
  195. package/dist/platform/git.d.ts +59 -0
  196. package/dist/platform/git.d.ts.map +1 -0
  197. package/dist/platform/git.js +8 -0
  198. package/dist/platform/git.js.map +1 -0
  199. package/dist/platform/index.d.ts +40 -1
  200. package/dist/platform/index.d.ts.map +1 -1
  201. package/dist/platform/index.js +1 -1
  202. package/dist/platform/index.js.map +1 -1
  203. package/dist/platform/llm-call-log.d.ts +80 -0
  204. package/dist/platform/llm-call-log.d.ts.map +1 -0
  205. package/dist/platform/llm-call-log.js +12 -0
  206. package/dist/platform/llm-call-log.js.map +1 -0
  207. package/dist/platform/scheduler.d.ts +32 -0
  208. package/dist/platform/scheduler.d.ts.map +1 -0
  209. package/dist/platform/scheduler.js +46 -0
  210. package/dist/platform/scheduler.js.map +1 -0
  211. package/dist/platform/session-log.d.ts +36 -0
  212. package/dist/platform/session-log.d.ts.map +1 -0
  213. package/dist/platform/session-log.js +12 -0
  214. package/dist/platform/session-log.js.map +1 -0
  215. package/dist/platform/shell.d.ts +83 -0
  216. package/dist/platform/shell.d.ts.map +1 -0
  217. package/dist/platform/shell.js +13 -0
  218. package/dist/platform/shell.js.map +1 -0
  219. package/dist/plugins/agent-status/plugin.d.ts.map +1 -1
  220. package/dist/plugins/agent-status/plugin.js +1 -0
  221. package/dist/plugins/agent-status/plugin.js.map +1 -1
  222. package/dist/plugins/agents/plugin.d.ts.map +1 -1
  223. package/dist/plugins/agents/plugin.js +129 -62
  224. package/dist/plugins/agents/plugin.js.map +1 -1
  225. package/dist/plugins/filesystem/listing.d.ts +3 -0
  226. package/dist/plugins/filesystem/listing.d.ts.map +1 -1
  227. package/dist/plugins/filesystem/listing.js +66 -10
  228. package/dist/plugins/filesystem/listing.js.map +1 -1
  229. package/dist/plugins/filesystem/plugin.d.ts.map +1 -1
  230. package/dist/plugins/filesystem/plugin.js +8 -6
  231. package/dist/plugins/filesystem/plugin.js.map +1 -1
  232. package/dist/plugins/git-status/plugin.d.ts +34 -7
  233. package/dist/plugins/git-status/plugin.d.ts.map +1 -1
  234. package/dist/plugins/git-status/plugin.js +168 -64
  235. package/dist/plugins/git-status/plugin.js.map +1 -1
  236. package/dist/plugins/llm-debug/plugin.d.ts.map +1 -1
  237. package/dist/plugins/llm-debug/plugin.js +1 -0
  238. package/dist/plugins/llm-debug/plugin.js.map +1 -1
  239. package/dist/plugins/logs/plugin.d.ts +1 -4
  240. package/dist/plugins/logs/plugin.d.ts.map +1 -1
  241. package/dist/plugins/logs/plugin.js +7 -0
  242. package/dist/plugins/logs/plugin.js.map +1 -1
  243. package/dist/plugins/mailbox/helpers.d.ts +2 -2
  244. package/dist/plugins/mailbox/helpers.js +1 -1
  245. package/dist/plugins/mailbox/plugin.d.ts.map +1 -1
  246. package/dist/plugins/mailbox/plugin.js +38 -43
  247. package/dist/plugins/mailbox/plugin.js.map +1 -1
  248. package/dist/plugins/mailbox/query.d.ts +7 -2
  249. package/dist/plugins/mailbox/query.d.ts.map +1 -1
  250. package/dist/plugins/mailbox/query.js +14 -7
  251. package/dist/plugins/mailbox/query.js.map +1 -1
  252. package/dist/plugins/mailbox/state.d.ts +5 -4
  253. package/dist/plugins/mailbox/state.d.ts.map +1 -1
  254. package/dist/plugins/mailbox/state.js +6 -5
  255. package/dist/plugins/mailbox/state.js.map +1 -1
  256. package/dist/plugins/resources/filename.d.ts +4 -0
  257. package/dist/plugins/resources/filename.d.ts.map +1 -0
  258. package/dist/plugins/resources/filename.js +18 -0
  259. package/dist/plugins/resources/filename.js.map +1 -0
  260. package/dist/plugins/resources/plugin.d.ts +3 -0
  261. package/dist/plugins/resources/plugin.d.ts.map +1 -1
  262. package/dist/plugins/resources/plugin.js +97 -60
  263. package/dist/plugins/resources/plugin.js.map +1 -1
  264. package/dist/plugins/resources/state.d.ts +1 -1
  265. package/dist/plugins/resources/state.js +1 -1
  266. package/dist/plugins/result-eviction/plugin.d.ts.map +1 -1
  267. package/dist/plugins/result-eviction/plugin.js +6 -1
  268. package/dist/plugins/result-eviction/plugin.js.map +1 -1
  269. package/dist/plugins/services/plugin.d.ts +4 -1
  270. package/dist/plugins/services/plugin.d.ts.map +1 -1
  271. package/dist/plugins/services/plugin.js +251 -100
  272. package/dist/plugins/services/plugin.js.map +1 -1
  273. package/dist/plugins/services/prompt.d.ts.map +1 -1
  274. package/dist/plugins/services/prompt.js +1 -4
  275. package/dist/plugins/services/prompt.js.map +1 -1
  276. package/dist/plugins/services/schema.d.ts +15 -5
  277. package/dist/plugins/services/schema.d.ts.map +1 -1
  278. package/dist/plugins/services/service.d.ts +100 -18
  279. package/dist/plugins/services/service.d.ts.map +1 -1
  280. package/dist/plugins/services/service.js +680 -230
  281. package/dist/plugins/services/service.js.map +1 -1
  282. package/dist/plugins/session-lifecycle/plugin.d.ts +21 -1
  283. package/dist/plugins/session-lifecycle/plugin.d.ts.map +1 -1
  284. package/dist/plugins/session-lifecycle/plugin.js +53 -40
  285. package/dist/plugins/session-lifecycle/plugin.js.map +1 -1
  286. package/dist/plugins/session-state/plugin.d.ts +21 -13
  287. package/dist/plugins/session-state/plugin.d.ts.map +1 -1
  288. package/dist/plugins/session-state/plugin.js +214 -79
  289. package/dist/plugins/session-state/plugin.js.map +1 -1
  290. package/dist/plugins/session-stats/plugin.d.ts.map +1 -1
  291. package/dist/plugins/session-stats/plugin.js +1 -0
  292. package/dist/plugins/session-stats/plugin.js.map +1 -1
  293. package/dist/plugins/shell/executor.d.ts +17 -15
  294. package/dist/plugins/shell/executor.d.ts.map +1 -1
  295. package/dist/plugins/shell/executor.js +130 -195
  296. package/dist/plugins/shell/executor.js.map +1 -1
  297. package/dist/plugins/shell/index.d.ts +2 -2
  298. package/dist/plugins/shell/index.d.ts.map +1 -1
  299. package/dist/plugins/shell/index.js +2 -2
  300. package/dist/plugins/shell/index.js.map +1 -1
  301. package/dist/plugins/shell/plugin.d.ts +5 -4
  302. package/dist/plugins/shell/plugin.d.ts.map +1 -1
  303. package/dist/plugins/shell/plugin.js +4 -8
  304. package/dist/plugins/shell/plugin.js.map +1 -1
  305. package/dist/plugins/skills/discovery.d.ts.map +1 -1
  306. package/dist/plugins/skills/discovery.js +10 -8
  307. package/dist/plugins/skills/discovery.js.map +1 -1
  308. package/dist/plugins/skills/index.d.ts +1 -1
  309. package/dist/plugins/skills/index.d.ts.map +1 -1
  310. package/dist/plugins/skills/plugin.d.ts +1 -1
  311. package/dist/plugins/skills/plugin.d.ts.map +1 -1
  312. package/dist/plugins/skills/plugin.js +23 -30
  313. package/dist/plugins/skills/plugin.js.map +1 -1
  314. package/dist/plugins/skills/prompts.d.ts +3 -3
  315. package/dist/plugins/skills/prompts.d.ts.map +1 -1
  316. package/dist/plugins/skills/prompts.js.map +1 -1
  317. package/dist/plugins/skills/schema.d.ts +4 -2
  318. package/dist/plugins/skills/schema.d.ts.map +1 -1
  319. package/dist/plugins/todo/schema.d.ts +1 -1
  320. package/dist/plugins/uploads/plugin.d.ts +11 -4
  321. package/dist/plugins/uploads/plugin.d.ts.map +1 -1
  322. package/dist/plugins/uploads/plugin.js +891 -225
  323. package/dist/plugins/uploads/plugin.js.map +1 -1
  324. package/dist/plugins/uploads/preprocessor.d.ts +14 -0
  325. package/dist/plugins/uploads/preprocessor.d.ts.map +1 -1
  326. package/dist/plugins/uploads/preprocessor.js +11 -0
  327. package/dist/plugins/uploads/preprocessor.js.map +1 -1
  328. package/dist/plugins/uploads/preprocessors/image-classifier.d.ts +1 -1
  329. package/dist/plugins/uploads/preprocessors/image-classifier.d.ts.map +1 -1
  330. package/dist/plugins/uploads/preprocessors/image-classifier.js +51 -26
  331. package/dist/plugins/uploads/preprocessors/image-classifier.js.map +1 -1
  332. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.d.ts +2 -2
  333. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.d.ts.map +1 -1
  334. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js +41 -16
  335. package/dist/plugins/uploads/preprocessors/markitdown-preprocessor.js.map +1 -1
  336. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.d.ts +1 -1
  337. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.d.ts.map +1 -1
  338. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.js +29 -14
  339. package/dist/plugins/uploads/preprocessors/pdf-preprocessor.js.map +1 -1
  340. package/dist/plugins/uploads/preprocessors/zip-preprocessor.d.ts +1 -1
  341. package/dist/plugins/uploads/preprocessors/zip-preprocessor.d.ts.map +1 -1
  342. package/dist/plugins/uploads/preprocessors/zip-preprocessor.js +62 -34
  343. package/dist/plugins/uploads/preprocessors/zip-preprocessor.js.map +1 -1
  344. package/dist/plugins/uploads/schema.d.ts +25 -2
  345. package/dist/plugins/uploads/schema.d.ts.map +1 -1
  346. package/dist/plugins/uploads/schema.js +24 -3
  347. package/dist/plugins/uploads/schema.js.map +1 -1
  348. package/dist/plugins/uploads/state.d.ts +13 -1
  349. package/dist/plugins/uploads/state.d.ts.map +1 -1
  350. package/dist/plugins/uploads/state.js +4 -1
  351. package/dist/plugins/uploads/state.js.map +1 -1
  352. package/dist/plugins/user-chat/plugin.d.ts +12 -5
  353. package/dist/plugins/user-chat/plugin.d.ts.map +1 -1
  354. package/dist/plugins/user-chat/plugin.js +141 -32
  355. package/dist/plugins/user-chat/plugin.js.map +1 -1
  356. package/dist/plugins/workers/context.d.ts +35 -13
  357. package/dist/plugins/workers/context.d.ts.map +1 -1
  358. package/dist/plugins/workers/context.js +82 -32
  359. package/dist/plugins/workers/context.js.map +1 -1
  360. package/dist/plugins/workers/definition.d.ts +7 -0
  361. package/dist/plugins/workers/definition.d.ts.map +1 -1
  362. package/dist/plugins/workers/definition.js.map +1 -1
  363. package/dist/plugins/workers/index.d.ts +4 -4
  364. package/dist/plugins/workers/index.d.ts.map +1 -1
  365. package/dist/plugins/workers/index.js +2 -2
  366. package/dist/plugins/workers/index.js.map +1 -1
  367. package/dist/plugins/workers/plugin.d.ts +10 -57
  368. package/dist/plugins/workers/plugin.d.ts.map +1 -1
  369. package/dist/plugins/workers/plugin.js +385 -123
  370. package/dist/plugins/workers/plugin.js.map +1 -1
  371. package/dist/plugins/workers/state.d.ts +69 -0
  372. package/dist/plugins/workers/state.d.ts.map +1 -0
  373. package/dist/plugins/workers/state.js +52 -0
  374. package/dist/plugins/workers/state.js.map +1 -0
  375. package/dist/plugins/workers/worker.d.ts +15 -4
  376. package/dist/plugins/workers/worker.d.ts.map +1 -1
  377. package/dist/testing/conformance.d.ts +106 -0
  378. package/dist/testing/conformance.d.ts.map +1 -0
  379. package/dist/testing/conformance.js +1463 -0
  380. package/dist/testing/conformance.js.map +1 -0
  381. package/dist/testing/node-platform.d.ts.map +1 -1
  382. package/dist/testing/node-platform.js +5 -0
  383. package/dist/testing/node-platform.js.map +1 -1
  384. package/dist/testing/test-harness.d.ts +11 -1
  385. package/dist/testing/test-harness.d.ts.map +1 -1
  386. package/dist/testing/test-harness.js +17 -37
  387. package/dist/testing/test-harness.js.map +1 -1
  388. package/dist/testing/wait-helpers.d.ts.map +1 -1
  389. package/dist/testing/wait-helpers.js +1 -3
  390. package/dist/testing/wait-helpers.js.map +1 -1
  391. package/dist/transport/adapter/client-adapter.d.ts +6 -0
  392. package/dist/transport/adapter/client-adapter.d.ts.map +1 -1
  393. package/dist/transport/adapter/client-adapter.js +50 -3
  394. package/dist/transport/adapter/client-adapter.js.map +1 -1
  395. package/dist/transport/adapter/heartbeat.d.ts +16 -0
  396. package/dist/transport/adapter/heartbeat.d.ts.map +1 -0
  397. package/dist/transport/adapter/heartbeat.js +41 -0
  398. package/dist/transport/adapter/heartbeat.js.map +1 -0
  399. package/dist/transport/adapter/server-adapter.d.ts.map +1 -1
  400. package/dist/transport/adapter/server-adapter.js +6 -0
  401. package/dist/transport/adapter/server-adapter.js.map +1 -1
  402. package/dist/transport/http/app.d.ts +3 -30
  403. package/dist/transport/http/app.d.ts.map +1 -1
  404. package/dist/transport/http/app.js +3 -7
  405. package/dist/transport/http/app.js.map +1 -1
  406. package/dist/transport/http/context.d.ts +40 -0
  407. package/dist/transport/http/context.d.ts.map +1 -0
  408. package/dist/transport/http/context.js +17 -0
  409. package/dist/transport/http/context.js.map +1 -0
  410. package/dist/transport/http/fetch-guard.d.ts +49 -0
  411. package/dist/transport/http/fetch-guard.d.ts.map +1 -0
  412. package/dist/transport/http/fetch-guard.js +312 -0
  413. package/dist/transport/http/fetch-guard.js.map +1 -0
  414. package/dist/transport/http/index.d.ts +1 -1
  415. package/dist/transport/http/index.d.ts.map +1 -1
  416. package/dist/transport/http/middleware/bearer-auth.d.ts +1 -1
  417. package/dist/transport/http/middleware/bearer-auth.d.ts.map +1 -1
  418. package/dist/transport/http/middleware/error-handler.d.ts +2 -2
  419. package/dist/transport/http/middleware/error-handler.d.ts.map +1 -1
  420. package/dist/transport/http/path-containment.d.ts +20 -0
  421. package/dist/transport/http/path-containment.d.ts.map +1 -0
  422. package/dist/transport/http/path-containment.js +31 -0
  423. package/dist/transport/http/path-containment.js.map +1 -0
  424. package/dist/transport/http/responses.d.ts +30 -0
  425. package/dist/transport/http/responses.d.ts.map +1 -0
  426. package/dist/transport/http/responses.js +5 -0
  427. package/dist/transport/http/responses.js.map +1 -0
  428. package/dist/transport/http/routes/files.d.ts +1 -1
  429. package/dist/transport/http/routes/files.d.ts.map +1 -1
  430. package/dist/transport/http/routes/files.js +54 -155
  431. package/dist/transport/http/routes/files.js.map +1 -1
  432. package/dist/transport/http/routes/resources.d.ts +1 -1
  433. package/dist/transport/http/routes/resources.d.ts.map +1 -1
  434. package/dist/transport/http/routes/resources.js +92 -57
  435. package/dist/transport/http/routes/resources.js.map +1 -1
  436. package/dist/transport/http/routes/rpc.d.ts +6 -1
  437. package/dist/transport/http/routes/rpc.d.ts.map +1 -1
  438. package/dist/transport/http/routes/rpc.js +51 -21
  439. package/dist/transport/http/routes/rpc.js.map +1 -1
  440. package/dist/transport/http/routes/upload.d.ts +1 -1
  441. package/dist/transport/http/routes/upload.d.ts.map +1 -1
  442. package/dist/transport/http/routes/upload.js +256 -169
  443. package/dist/transport/http/routes/upload.js.map +1 -1
  444. package/dist/user-config.d.ts +34 -7
  445. package/dist/user-config.d.ts.map +1 -1
  446. package/dist/user-config.js +71 -0
  447. package/dist/user-config.js.map +1 -1
  448. package/package.json +17 -7
  449. package/src/bootstrap.ts +119 -35
  450. package/src/bun-platform/fs.ts +1 -0
  451. package/src/bun-platform/index.ts +18 -1
  452. package/src/bun-platform/server-lifecycle.ts +218 -0
  453. package/src/bun-platform/shell.ts +362 -0
  454. package/src/config.ts +130 -0
  455. package/src/core/agents/agent.ts +210 -92
  456. package/src/core/agents/config.ts +8 -0
  457. package/src/core/agents/retry.ts +16 -17
  458. package/src/core/agents/state.ts +2 -0
  459. package/src/core/events/base-event-store.ts +24 -16
  460. package/src/core/events/file.ts +198 -22
  461. package/src/core/file-store/containment.ts +75 -0
  462. package/src/core/file-store/file-store.ts +106 -25
  463. package/src/core/file-store/types.ts +14 -1
  464. package/src/core/image/image-processor.ts +3 -1
  465. package/src/core/image/types.ts +2 -0
  466. package/src/core/image/vips-resizer.ts +102 -37
  467. package/src/core/llm/anthropic.ts +63 -79
  468. package/src/core/llm/logger.ts +175 -37
  469. package/src/core/llm/openrouter.ts +57 -72
  470. package/src/core/llm/provider-request.ts +40 -0
  471. package/src/core/llm/provider.ts +28 -0
  472. package/src/core/plugins/plugin-builder.ts +106 -14
  473. package/src/core/preset/preset-builder.ts +12 -22
  474. package/src/core/sessions/context.ts +18 -0
  475. package/src/core/sessions/runtime-activity.ts +78 -0
  476. package/src/core/sessions/schema.ts +29 -3
  477. package/src/core/sessions/session-manager.ts +560 -140
  478. package/src/core/sessions/session-store.ts +38 -0
  479. package/src/core/sessions/session.ts +187 -47
  480. package/src/core/sessions/state.ts +11 -0
  481. package/src/core/system.ts +15 -0
  482. package/src/core/wake-key.ts +65 -0
  483. package/src/index.ts +30 -12
  484. package/src/lib/archive/archive-inspection.fixtures.ts +138 -0
  485. package/src/lib/archive/archive-inspection.ts +359 -0
  486. package/src/lib/archive/index.ts +17 -0
  487. package/src/lib/logger/console.ts +7 -57
  488. package/src/lib/logger/file.ts +28 -50
  489. package/src/lib/logger/index.ts +3 -1
  490. package/src/lib/logger/jsonl.ts +36 -0
  491. package/src/lib/logger/logger.ts +48 -0
  492. package/src/lib/logger/session-log.ts +42 -0
  493. package/src/lib/utils/concurrency.ts +37 -8
  494. package/src/lib/utils/fs-batch.ts +49 -0
  495. package/src/lib/utils/result.ts +7 -31
  496. package/src/lib/utils/sleep.ts +23 -0
  497. package/src/platform/fs-revision.ts +21 -0
  498. package/src/platform/fs.ts +109 -1
  499. package/src/platform/git.ts +67 -0
  500. package/src/platform/index.ts +51 -1
  501. package/src/platform/llm-call-log.ts +86 -0
  502. package/src/platform/scheduler.ts +71 -0
  503. package/src/platform/session-log.ts +39 -0
  504. package/src/platform/shell.ts +89 -0
  505. package/src/plugins/agent-status/plugin.ts +1 -0
  506. package/src/plugins/agents/plugin.ts +134 -81
  507. package/src/plugins/filesystem/listing.ts +70 -12
  508. package/src/plugins/filesystem/plugin.ts +8 -6
  509. package/src/plugins/git-status/plugin.ts +204 -77
  510. package/src/plugins/llm-debug/plugin.ts +1 -0
  511. package/src/plugins/logs/plugin.ts +9 -0
  512. package/src/plugins/mailbox/plugin.ts +46 -64
  513. package/src/plugins/mailbox/query.ts +15 -7
  514. package/src/plugins/mailbox/state.ts +1 -0
  515. package/src/plugins/resources/filename.ts +19 -0
  516. package/src/plugins/resources/plugin.ts +111 -59
  517. package/src/plugins/result-eviction/plugin.ts +6 -1
  518. package/src/plugins/services/plugin.ts +254 -98
  519. package/src/plugins/services/prompt.ts +1 -6
  520. package/src/plugins/services/schema.ts +17 -3
  521. package/src/plugins/services/service.ts +702 -252
  522. package/src/plugins/session-lifecycle/plugin.ts +56 -41
  523. package/src/plugins/session-state/plugin.ts +242 -88
  524. package/src/plugins/session-stats/plugin.ts +1 -0
  525. package/src/plugins/shell/executor.ts +144 -226
  526. package/src/plugins/shell/index.ts +1 -4
  527. package/src/plugins/shell/plugin.ts +7 -9
  528. package/src/plugins/skills/discovery.ts +10 -8
  529. package/src/plugins/skills/index.ts +1 -1
  530. package/src/plugins/skills/plugin.ts +19 -27
  531. package/src/plugins/skills/prompts.ts +3 -3
  532. package/src/plugins/skills/schema.ts +5 -2
  533. package/src/plugins/uploads/plugin.ts +991 -273
  534. package/src/plugins/uploads/preprocessor.ts +25 -0
  535. package/src/plugins/uploads/preprocessors/image-classifier.ts +56 -25
  536. package/src/plugins/uploads/preprocessors/markitdown-preprocessor.ts +41 -15
  537. package/src/plugins/uploads/preprocessors/pdf-preprocessor.ts +32 -16
  538. package/src/plugins/uploads/preprocessors/zip-preprocessor.ts +67 -38
  539. package/src/plugins/uploads/schema.ts +30 -3
  540. package/src/plugins/uploads/state.ts +12 -0
  541. package/src/plugins/user-chat/plugin.ts +196 -40
  542. package/src/plugins/workers/context.ts +102 -39
  543. package/src/plugins/workers/definition.ts +7 -0
  544. package/src/plugins/workers/index.ts +4 -4
  545. package/src/plugins/workers/plugin.ts +461 -151
  546. package/src/plugins/workers/state.ts +64 -0
  547. package/src/plugins/workers/worker.ts +15 -4
  548. package/src/testing/conformance.ts +1751 -0
  549. package/src/testing/node-platform.ts +5 -0
  550. package/src/testing/test-harness.ts +21 -38
  551. package/src/testing/wait-helpers.ts +1 -4
  552. package/src/transport/adapter/client-adapter.ts +60 -3
  553. package/src/transport/adapter/heartbeat.ts +50 -0
  554. package/src/transport/adapter/server-adapter.ts +6 -0
  555. package/src/transport/http/app.ts +7 -35
  556. package/src/transport/http/context.ts +46 -0
  557. package/src/transport/http/fetch-guard.ts +318 -0
  558. package/src/transport/http/index.ts +1 -1
  559. package/src/transport/http/middleware/bearer-auth.ts +1 -1
  560. package/src/transport/http/middleware/error-handler.ts +1 -1
  561. package/src/transport/http/path-containment.ts +44 -0
  562. package/src/transport/http/responses.ts +20 -0
  563. package/src/transport/http/routes/files.ts +69 -159
  564. package/src/transport/http/routes/resources.ts +124 -93
  565. package/src/transport/http/routes/rpc.ts +63 -26
  566. package/src/transport/http/routes/upload.ts +327 -258
  567. package/src/user-config.ts +93 -7
  568. package/dist/config.test.d.ts +0 -2
  569. package/dist/config.test.d.ts.map +0 -1
  570. package/dist/config.test.js +0 -155
  571. package/dist/config.test.js.map +0 -1
  572. package/dist/core/agent-loop.integration.test.d.ts +0 -2
  573. package/dist/core/agent-loop.integration.test.d.ts.map +0 -1
  574. package/dist/core/agent-loop.integration.test.js +0 -414
  575. package/dist/core/agent-loop.integration.test.js.map +0 -1
  576. package/dist/core/agents/agent-config.test.d.ts +0 -2
  577. package/dist/core/agents/agent-config.test.d.ts.map +0 -1
  578. package/dist/core/agents/agent-config.test.js +0 -194
  579. package/dist/core/agents/agent-config.test.js.map +0 -1
  580. package/dist/core/agents/agent-shutdown.test.d.ts +0 -6
  581. package/dist/core/agents/agent-shutdown.test.d.ts.map +0 -1
  582. package/dist/core/agents/agent-shutdown.test.js +0 -180
  583. package/dist/core/agents/agent-shutdown.test.js.map +0 -1
  584. package/dist/core/agents/agent.test.d.ts +0 -2
  585. package/dist/core/agents/agent.test.d.ts.map +0 -1
  586. package/dist/core/agents/agent.test.js +0 -313
  587. package/dist/core/agents/agent.test.js.map +0 -1
  588. package/dist/core/agents/communicator.d.ts +0 -3
  589. package/dist/core/agents/communicator.d.ts.map +0 -1
  590. package/dist/core/agents/communicator.js +0 -13
  591. package/dist/core/agents/communicator.js.map +0 -1
  592. package/dist/core/agents/handler-events.test.d.ts +0 -5
  593. package/dist/core/agents/handler-events.test.d.ts.map +0 -1
  594. package/dist/core/agents/handler-events.test.js +0 -115
  595. package/dist/core/agents/handler-events.test.js.map +0 -1
  596. package/dist/core/agents/response-sanitizer.test.d.ts +0 -2
  597. package/dist/core/agents/response-sanitizer.test.d.ts.map +0 -1
  598. package/dist/core/agents/response-sanitizer.test.js +0 -101
  599. package/dist/core/agents/response-sanitizer.test.js.map +0 -1
  600. package/dist/core/error-recovery.integration.test.d.ts +0 -2
  601. package/dist/core/error-recovery.integration.test.d.ts.map +0 -1
  602. package/dist/core/error-recovery.integration.test.js +0 -288
  603. package/dist/core/error-recovery.integration.test.js.map +0 -1
  604. package/dist/core/event-sourcing.integration.test.d.ts +0 -2
  605. package/dist/core/event-sourcing.integration.test.d.ts.map +0 -1
  606. package/dist/core/event-sourcing.integration.test.js +0 -154
  607. package/dist/core/event-sourcing.integration.test.js.map +0 -1
  608. package/dist/core/events/file.test.d.ts +0 -2
  609. package/dist/core/events/file.test.d.ts.map +0 -1
  610. package/dist/core/events/file.test.js +0 -284
  611. package/dist/core/events/file.test.js.map +0 -1
  612. package/dist/core/events/memory.test.d.ts +0 -2
  613. package/dist/core/events/memory.test.d.ts.map +0 -1
  614. package/dist/core/events/memory.test.js +0 -502
  615. package/dist/core/events/memory.test.js.map +0 -1
  616. package/dist/core/image/image-processor.test.d.ts +0 -2
  617. package/dist/core/image/image-processor.test.d.ts.map +0 -1
  618. package/dist/core/image/image-processor.test.js +0 -171
  619. package/dist/core/image/image-processor.test.js.map +0 -1
  620. package/dist/core/image/vips-resizer.test.d.ts +0 -2
  621. package/dist/core/image/vips-resizer.test.d.ts.map +0 -1
  622. package/dist/core/image/vips-resizer.test.js +0 -336
  623. package/dist/core/image/vips-resizer.test.js.map +0 -1
  624. package/dist/core/llm/anthropic.test.d.ts +0 -2
  625. package/dist/core/llm/anthropic.test.d.ts.map +0 -1
  626. package/dist/core/llm/anthropic.test.js +0 -464
  627. package/dist/core/llm/anthropic.test.js.map +0 -1
  628. package/dist/core/llm/cache-breakpoints.test.d.ts +0 -2
  629. package/dist/core/llm/cache-breakpoints.test.d.ts.map +0 -1
  630. package/dist/core/llm/cache-breakpoints.test.js +0 -69
  631. package/dist/core/llm/cache-breakpoints.test.js.map +0 -1
  632. package/dist/core/llm/cache-live.test.d.ts +0 -16
  633. package/dist/core/llm/cache-live.test.d.ts.map +0 -1
  634. package/dist/core/llm/cache-live.test.js +0 -137
  635. package/dist/core/llm/cache-live.test.js.map +0 -1
  636. package/dist/core/llm/logger.test.d.ts +0 -7
  637. package/dist/core/llm/logger.test.d.ts.map +0 -1
  638. package/dist/core/llm/logger.test.js +0 -228
  639. package/dist/core/llm/logger.test.js.map +0 -1
  640. package/dist/core/llm/message-sanitization.test.d.ts +0 -2
  641. package/dist/core/llm/message-sanitization.test.d.ts.map +0 -1
  642. package/dist/core/llm/message-sanitization.test.js +0 -181
  643. package/dist/core/llm/message-sanitization.test.js.map +0 -1
  644. package/dist/core/llm/mock.test.d.ts +0 -2
  645. package/dist/core/llm/mock.test.d.ts.map +0 -1
  646. package/dist/core/llm/mock.test.js +0 -318
  647. package/dist/core/llm/mock.test.js.map +0 -1
  648. package/dist/core/llm/model-shortlist-live.test.d.ts +0 -35
  649. package/dist/core/llm/model-shortlist-live.test.d.ts.map +0 -1
  650. package/dist/core/llm/model-shortlist-live.test.js +0 -452
  651. package/dist/core/llm/model-shortlist-live.test.js.map +0 -1
  652. package/dist/core/llm/openrouter-mapping.test.d.ts +0 -2
  653. package/dist/core/llm/openrouter-mapping.test.d.ts.map +0 -1
  654. package/dist/core/llm/openrouter-mapping.test.js +0 -190
  655. package/dist/core/llm/openrouter-mapping.test.js.map +0 -1
  656. package/dist/core/llm/openrouter.test.d.ts +0 -2
  657. package/dist/core/llm/openrouter.test.d.ts.map +0 -1
  658. package/dist/core/llm/openrouter.test.js +0 -377
  659. package/dist/core/llm/openrouter.test.js.map +0 -1
  660. package/dist/core/llm/provider-integration.test.d.ts +0 -12
  661. package/dist/core/llm/provider-integration.test.d.ts.map +0 -1
  662. package/dist/core/llm/provider-integration.test.js +0 -350
  663. package/dist/core/llm/provider-integration.test.js.map +0 -1
  664. package/dist/core/llm/reasoning-details.test.d.ts +0 -2
  665. package/dist/core/llm/reasoning-details.test.d.ts.map +0 -1
  666. package/dist/core/llm/reasoning-details.test.js +0 -144
  667. package/dist/core/llm/reasoning-details.test.js.map +0 -1
  668. package/dist/core/llm/routing-provider.test.d.ts +0 -2
  669. package/dist/core/llm/routing-provider.test.d.ts.map +0 -1
  670. package/dist/core/llm/routing-provider.test.js +0 -94
  671. package/dist/core/llm/routing-provider.test.js.map +0 -1
  672. package/dist/core/llm/snapshot-middleware.test.d.ts +0 -2
  673. package/dist/core/llm/snapshot-middleware.test.d.ts.map +0 -1
  674. package/dist/core/llm/snapshot-middleware.test.js +0 -144
  675. package/dist/core/llm/snapshot-middleware.test.js.map +0 -1
  676. package/dist/core/llm/thinking-blocks.test.d.ts +0 -2
  677. package/dist/core/llm/thinking-blocks.test.d.ts.map +0 -1
  678. package/dist/core/llm/thinking-blocks.test.js +0 -291
  679. package/dist/core/llm/thinking-blocks.test.js.map +0 -1
  680. package/dist/core/multi-agent.integration.test.d.ts +0 -2
  681. package/dist/core/multi-agent.integration.test.d.ts.map +0 -1
  682. package/dist/core/multi-agent.integration.test.js +0 -298
  683. package/dist/core/multi-agent.integration.test.js.map +0 -1
  684. package/dist/core/plugin-hooks.integration.test.d.ts +0 -2
  685. package/dist/core/plugin-hooks.integration.test.d.ts.map +0 -1
  686. package/dist/core/plugin-hooks.integration.test.js +0 -458
  687. package/dist/core/plugin-hooks.integration.test.js.map +0 -1
  688. package/dist/core/reasoning-round-trip.integration.test.d.ts +0 -2
  689. package/dist/core/reasoning-round-trip.integration.test.d.ts.map +0 -1
  690. package/dist/core/reasoning-round-trip.integration.test.js +0 -150
  691. package/dist/core/reasoning-round-trip.integration.test.js.map +0 -1
  692. package/dist/core/session-lifecycle.integration.test.d.ts +0 -2
  693. package/dist/core/session-lifecycle.integration.test.d.ts.map +0 -1
  694. package/dist/core/session-lifecycle.integration.test.js +0 -159
  695. package/dist/core/session-lifecycle.integration.test.js.map +0 -1
  696. package/dist/core/sessions/fork-utils.test.d.ts +0 -2
  697. package/dist/core/sessions/fork-utils.test.d.ts.map +0 -1
  698. package/dist/core/sessions/fork-utils.test.js +0 -129
  699. package/dist/core/sessions/fork-utils.test.js.map +0 -1
  700. package/dist/core/sessions/session-overrides.integration.test.d.ts +0 -2
  701. package/dist/core/sessions/session-overrides.integration.test.d.ts.map +0 -1
  702. package/dist/core/sessions/session-overrides.integration.test.js +0 -154
  703. package/dist/core/sessions/session-overrides.integration.test.js.map +0 -1
  704. package/dist/core/sessions/session.test.d.ts +0 -2
  705. package/dist/core/sessions/session.test.d.ts.map +0 -1
  706. package/dist/core/sessions/session.test.js +0 -1100
  707. package/dist/core/sessions/session.test.js.map +0 -1
  708. package/dist/core/tools/executor.test.d.ts +0 -2
  709. package/dist/core/tools/executor.test.d.ts.map +0 -1
  710. package/dist/core/tools/executor.test.js +0 -144
  711. package/dist/core/tools/executor.test.js.map +0 -1
  712. package/dist/lib/logger/console.test.d.ts +0 -2
  713. package/dist/lib/logger/console.test.d.ts.map +0 -1
  714. package/dist/lib/logger/console.test.js +0 -258
  715. package/dist/lib/logger/console.test.js.map +0 -1
  716. package/dist/lib/never.d.ts +0 -2
  717. package/dist/lib/never.d.ts.map +0 -1
  718. package/dist/lib/never.js +0 -4
  719. package/dist/lib/never.js.map +0 -1
  720. package/dist/lib/utils/concurrency.test.d.ts +0 -2
  721. package/dist/lib/utils/concurrency.test.d.ts.map +0 -1
  722. package/dist/lib/utils/concurrency.test.js +0 -135
  723. package/dist/lib/utils/concurrency.test.js.map +0 -1
  724. package/dist/plugins/agent-status/agent-status.test.d.ts +0 -2
  725. package/dist/plugins/agent-status/agent-status.test.d.ts.map +0 -1
  726. package/dist/plugins/agent-status/agent-status.test.js +0 -136
  727. package/dist/plugins/agent-status/agent-status.test.js.map +0 -1
  728. package/dist/plugins/agents/agents.integration.test.d.ts +0 -2
  729. package/dist/plugins/agents/agents.integration.test.d.ts.map +0 -1
  730. package/dist/plugins/agents/agents.integration.test.js +0 -830
  731. package/dist/plugins/agents/agents.integration.test.js.map +0 -1
  732. package/dist/plugins/agents/supervision.integration.test.d.ts +0 -2
  733. package/dist/plugins/agents/supervision.integration.test.d.ts.map +0 -1
  734. package/dist/plugins/agents/supervision.integration.test.js +0 -215
  735. package/dist/plugins/agents/supervision.integration.test.js.map +0 -1
  736. package/dist/plugins/context-compact/compaction-live.test.d.ts +0 -17
  737. package/dist/plugins/context-compact/compaction-live.test.d.ts.map +0 -1
  738. package/dist/plugins/context-compact/compaction-live.test.js +0 -177
  739. package/dist/plugins/context-compact/compaction-live.test.js.map +0 -1
  740. package/dist/plugins/context-compact/context-compact.integration.test.d.ts +0 -2
  741. package/dist/plugins/context-compact/context-compact.integration.test.d.ts.map +0 -1
  742. package/dist/plugins/context-compact/context-compact.integration.test.js +0 -364
  743. package/dist/plugins/context-compact/context-compact.integration.test.js.map +0 -1
  744. package/dist/plugins/context-compact/context-compactor.test.d.ts +0 -2
  745. package/dist/plugins/context-compact/context-compactor.test.d.ts.map +0 -1
  746. package/dist/plugins/context-compact/context-compactor.test.js +0 -858
  747. package/dist/plugins/context-compact/context-compactor.test.js.map +0 -1
  748. package/dist/plugins/context-compact/history-offloader.test.d.ts +0 -2
  749. package/dist/plugins/context-compact/history-offloader.test.d.ts.map +0 -1
  750. package/dist/plugins/context-compact/history-offloader.test.js +0 -77
  751. package/dist/plugins/context-compact/history-offloader.test.js.map +0 -1
  752. package/dist/plugins/filesystem/filesystem.integration.test.d.ts +0 -2
  753. package/dist/plugins/filesystem/filesystem.integration.test.d.ts.map +0 -1
  754. package/dist/plugins/filesystem/filesystem.integration.test.js +0 -447
  755. package/dist/plugins/filesystem/filesystem.integration.test.js.map +0 -1
  756. package/dist/plugins/filesystem/schema.d.ts +0 -7
  757. package/dist/plugins/filesystem/schema.d.ts.map +0 -1
  758. package/dist/plugins/filesystem/schema.js +0 -2
  759. package/dist/plugins/filesystem/schema.js.map +0 -1
  760. package/dist/plugins/limits-guard/limit-guard.test.d.ts +0 -2
  761. package/dist/plugins/limits-guard/limit-guard.test.d.ts.map +0 -1
  762. package/dist/plugins/limits-guard/limit-guard.test.js +0 -194
  763. package/dist/plugins/limits-guard/limit-guard.test.js.map +0 -1
  764. package/dist/plugins/limits-guard/limits-guard.integration.test.d.ts +0 -2
  765. package/dist/plugins/limits-guard/limits-guard.integration.test.d.ts.map +0 -1
  766. package/dist/plugins/limits-guard/limits-guard.integration.test.js +0 -887
  767. package/dist/plugins/limits-guard/limits-guard.integration.test.js.map +0 -1
  768. package/dist/plugins/llm-debug/llm-debug.integration.test.d.ts +0 -2
  769. package/dist/plugins/llm-debug/llm-debug.integration.test.d.ts.map +0 -1
  770. package/dist/plugins/llm-debug/llm-debug.integration.test.js +0 -157
  771. package/dist/plugins/llm-debug/llm-debug.integration.test.js.map +0 -1
  772. package/dist/plugins/mailbox/mailbox.integration.test.d.ts +0 -2
  773. package/dist/plugins/mailbox/mailbox.integration.test.d.ts.map +0 -1
  774. package/dist/plugins/mailbox/mailbox.integration.test.js +0 -678
  775. package/dist/plugins/mailbox/mailbox.integration.test.js.map +0 -1
  776. package/dist/plugins/resources/resources.integration.test.d.ts +0 -2
  777. package/dist/plugins/resources/resources.integration.test.d.ts.map +0 -1
  778. package/dist/plugins/resources/resources.integration.test.js +0 -62
  779. package/dist/plugins/resources/resources.integration.test.js.map +0 -1
  780. package/dist/plugins/result-eviction/result-eviction.integration.test.d.ts +0 -2
  781. package/dist/plugins/result-eviction/result-eviction.integration.test.d.ts.map +0 -1
  782. package/dist/plugins/result-eviction/result-eviction.integration.test.js +0 -294
  783. package/dist/plugins/result-eviction/result-eviction.integration.test.js.map +0 -1
  784. package/dist/plugins/services/pid-registry.test.d.ts +0 -2
  785. package/dist/plugins/services/pid-registry.test.d.ts.map +0 -1
  786. package/dist/plugins/services/pid-registry.test.js +0 -161
  787. package/dist/plugins/services/pid-registry.test.js.map +0 -1
  788. package/dist/plugins/services/services.integration.test.d.ts +0 -2
  789. package/dist/plugins/services/services.integration.test.d.ts.map +0 -1
  790. package/dist/plugins/services/services.integration.test.js +0 -1057
  791. package/dist/plugins/services/services.integration.test.js.map +0 -1
  792. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.d.ts +0 -2
  793. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.d.ts.map +0 -1
  794. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js +0 -498
  795. package/dist/plugins/session-lifecycle/session-lifecycle.integration.test.js.map +0 -1
  796. package/dist/plugins/session-stats/plugin.test.d.ts +0 -2
  797. package/dist/plugins/session-stats/plugin.test.d.ts.map +0 -1
  798. package/dist/plugins/session-stats/plugin.test.js +0 -145
  799. package/dist/plugins/session-stats/plugin.test.js.map +0 -1
  800. package/dist/plugins/shell/shell.integration.test.d.ts +0 -2
  801. package/dist/plugins/shell/shell.integration.test.d.ts.map +0 -1
  802. package/dist/plugins/shell/shell.integration.test.js +0 -234
  803. package/dist/plugins/shell/shell.integration.test.js.map +0 -1
  804. package/dist/plugins/shell/shell.test.d.ts +0 -2
  805. package/dist/plugins/shell/shell.test.d.ts.map +0 -1
  806. package/dist/plugins/shell/shell.test.js +0 -236
  807. package/dist/plugins/shell/shell.test.js.map +0 -1
  808. package/dist/plugins/skills/discovery.test.d.ts +0 -2
  809. package/dist/plugins/skills/discovery.test.d.ts.map +0 -1
  810. package/dist/plugins/skills/discovery.test.js +0 -312
  811. package/dist/plugins/skills/discovery.test.js.map +0 -1
  812. package/dist/plugins/skills/skills.integration.test.d.ts +0 -2
  813. package/dist/plugins/skills/skills.integration.test.d.ts.map +0 -1
  814. package/dist/plugins/skills/skills.integration.test.js +0 -475
  815. package/dist/plugins/skills/skills.integration.test.js.map +0 -1
  816. package/dist/plugins/todo/todo.integration.test.d.ts +0 -2
  817. package/dist/plugins/todo/todo.integration.test.d.ts.map +0 -1
  818. package/dist/plugins/todo/todo.integration.test.js +0 -605
  819. package/dist/plugins/todo/todo.integration.test.js.map +0 -1
  820. package/dist/plugins/uploads/preprocessors/image-classifier.test.d.ts +0 -2
  821. package/dist/plugins/uploads/preprocessors/image-classifier.test.d.ts.map +0 -1
  822. package/dist/plugins/uploads/preprocessors/image-classifier.test.js +0 -113
  823. package/dist/plugins/uploads/preprocessors/image-classifier.test.js.map +0 -1
  824. package/dist/plugins/uploads/uploads.integration.test.d.ts +0 -2
  825. package/dist/plugins/uploads/uploads.integration.test.d.ts.map +0 -1
  826. package/dist/plugins/uploads/uploads.integration.test.js +0 -639
  827. package/dist/plugins/uploads/uploads.integration.test.js.map +0 -1
  828. package/dist/plugins/user-chat/user-chat.integration.test.d.ts +0 -2
  829. package/dist/plugins/user-chat/user-chat.integration.test.d.ts.map +0 -1
  830. package/dist/plugins/user-chat/user-chat.integration.test.js +0 -754
  831. package/dist/plugins/user-chat/user-chat.integration.test.js.map +0 -1
  832. package/dist/plugins/workers/workers.integration.test.d.ts +0 -2
  833. package/dist/plugins/workers/workers.integration.test.d.ts.map +0 -1
  834. package/dist/plugins/workers/workers.integration.test.js +0 -629
  835. package/dist/plugins/workers/workers.integration.test.js.map +0 -1
  836. package/dist/prompts/macros.test.d.ts +0 -2
  837. package/dist/prompts/macros.test.d.ts.map +0 -1
  838. package/dist/prompts/macros.test.js +0 -80
  839. package/dist/prompts/macros.test.js.map +0 -1
  840. package/dist/testing/test-harness.test.d.ts +0 -2
  841. package/dist/testing/test-harness.test.d.ts.map +0 -1
  842. package/dist/testing/test-harness.test.js +0 -92
  843. package/dist/testing/test-harness.test.js.map +0 -1
  844. package/dist/transport/http/routes/rpc.integration.test.d.ts +0 -2
  845. package/dist/transport/http/routes/rpc.integration.test.d.ts.map +0 -1
  846. package/dist/transport/http/routes/rpc.integration.test.js +0 -189
  847. package/dist/transport/http/routes/rpc.integration.test.js.map +0 -1
  848. package/dist/transport/http/routes/rpc.test.d.ts +0 -2
  849. package/dist/transport/http/routes/rpc.test.d.ts.map +0 -1
  850. package/dist/transport/http/routes/rpc.test.js +0 -316
  851. package/dist/transport/http/routes/rpc.test.js.map +0 -1
  852. package/src/config.test.ts +0 -174
  853. package/src/core/agent-loop.integration.test.ts +0 -503
  854. package/src/core/agents/agent-config.test.ts +0 -240
  855. package/src/core/agents/agent-shutdown.test.ts +0 -236
  856. package/src/core/agents/agent.test.ts +0 -387
  857. package/src/core/agents/communicator.ts +0 -16
  858. package/src/core/agents/handler-events.test.ts +0 -167
  859. package/src/core/agents/response-sanitizer.test.ts +0 -137
  860. package/src/core/error-recovery.integration.test.ts +0 -343
  861. package/src/core/event-sourcing.integration.test.ts +0 -191
  862. package/src/core/events/file.test.ts +0 -436
  863. package/src/core/events/memory.test.ts +0 -741
  864. package/src/core/image/image-processor.test.ts +0 -218
  865. package/src/core/image/vips-resizer.test.ts +0 -388
  866. package/src/core/llm/anthropic.test.ts +0 -546
  867. package/src/core/llm/cache-breakpoints.test.ts +0 -85
  868. package/src/core/llm/cache-live.test.ts +0 -155
  869. package/src/core/llm/logger.test.ts +0 -270
  870. package/src/core/llm/message-sanitization.test.ts +0 -217
  871. package/src/core/llm/mock.test.ts +0 -402
  872. package/src/core/llm/model-shortlist-live.test.ts +0 -577
  873. package/src/core/llm/openrouter-mapping.test.ts +0 -234
  874. package/src/core/llm/openrouter.test.ts +0 -499
  875. package/src/core/llm/provider-integration.test.ts +0 -408
  876. package/src/core/llm/reasoning-details.test.ts +0 -177
  877. package/src/core/llm/routing-provider.test.ts +0 -113
  878. package/src/core/llm/snapshot-middleware.test.ts +0 -168
  879. package/src/core/llm/thinking-blocks.test.ts +0 -345
  880. package/src/core/multi-agent.integration.test.ts +0 -340
  881. package/src/core/plugin-hooks.integration.test.ts +0 -568
  882. package/src/core/reasoning-round-trip.integration.test.ts +0 -188
  883. package/src/core/session-lifecycle.integration.test.ts +0 -202
  884. package/src/core/sessions/fork-utils.test.ts +0 -158
  885. package/src/core/sessions/session-overrides.integration.test.ts +0 -210
  886. package/src/core/sessions/session.test.ts +0 -1736
  887. package/src/core/tools/executor.test.ts +0 -161
  888. package/src/lib/logger/console.test.ts +0 -348
  889. package/src/lib/never.ts +0 -3
  890. package/src/lib/utils/concurrency.test.ts +0 -169
  891. package/src/plugins/agent-status/agent-status.test.ts +0 -164
  892. package/src/plugins/agents/agents.integration.test.ts +0 -976
  893. package/src/plugins/agents/supervision.integration.test.ts +0 -249
  894. package/src/plugins/context-compact/compaction-live.test.ts +0 -221
  895. package/src/plugins/context-compact/context-compact.integration.test.ts +0 -418
  896. package/src/plugins/context-compact/context-compactor.test.ts +0 -1036
  897. package/src/plugins/context-compact/history-offloader.test.ts +0 -100
  898. package/src/plugins/filesystem/filesystem.integration.test.ts +0 -529
  899. package/src/plugins/filesystem/schema.ts +0 -6
  900. package/src/plugins/limits-guard/limit-guard.test.ts +0 -253
  901. package/src/plugins/limits-guard/limits-guard.integration.test.ts +0 -1012
  902. package/src/plugins/llm-debug/llm-debug.integration.test.ts +0 -192
  903. package/src/plugins/mailbox/mailbox.integration.test.ts +0 -794
  904. package/src/plugins/resources/resources.integration.test.ts +0 -68
  905. package/src/plugins/result-eviction/result-eviction.integration.test.ts +0 -332
  906. package/src/plugins/services/pid-registry.test.ts +0 -180
  907. package/src/plugins/services/services.integration.test.ts +0 -1223
  908. package/src/plugins/session-lifecycle/session-lifecycle.integration.test.ts +0 -639
  909. package/src/plugins/session-stats/plugin.test.ts +0 -160
  910. package/src/plugins/shell/shell.integration.test.ts +0 -273
  911. package/src/plugins/shell/shell.test.ts +0 -314
  912. package/src/plugins/skills/discovery.test.ts +0 -395
  913. package/src/plugins/skills/skills.integration.test.ts +0 -580
  914. package/src/plugins/todo/todo.integration.test.ts +0 -687
  915. package/src/plugins/uploads/preprocessors/image-classifier.test.ts +0 -142
  916. package/src/plugins/uploads/uploads.integration.test.ts +0 -831
  917. package/src/plugins/user-chat/user-chat.integration.test.ts +0 -893
  918. package/src/plugins/workers/workers.integration.test.ts +0 -778
  919. package/src/prompts/macros.test.ts +0 -107
  920. package/src/testing/test-harness.test.ts +0 -114
  921. package/src/transport/http/routes/rpc.integration.test.ts +0 -243
  922. package/src/transport/http/routes/rpc.test.ts +0 -372
@@ -1,59 +1,29 @@
1
1
  import z from 'zod/v4'
2
- import { agentIdSchema } from '~/core/agents/schema.js'
2
+ import { type AgentId, agentIdSchema } from '~/core/agents/schema.js'
3
3
  import { ValidationErrors } from '~/core/errors.js'
4
- import { createEventsFactory } from '~/core/events/types.js'
5
- import type { BaseEvent } from '~/core/events/types.js'
4
+ import type { FileStore } from '~/core/file-store/types.js'
6
5
  import { definePlugin } from '~/core/plugins/plugin-builder.js'
6
+ import type { SessionRuntimeActivity } from '~/core/sessions/runtime-activity.js'
7
+ import type { SessionId } from '~/core/sessions/schema.js'
8
+ import type { SessionState } from '~/core/sessions/state.js'
7
9
  import { createTool, type ToolDefinition } from '~/core/tools/definition.js'
8
- import { Err, Ok } from '~/lib/utils/result.js'
10
+ import { Err, Ok, type Result } from '~/lib/utils/result.js'
9
11
  import type { Logger } from '../../lib/logger/logger.js'
10
12
  import { WorkerContextImpl } from './context.js'
13
+ import { workerEvents } from './state.js'
14
+ import type { EmitEvent } from './state.js'
11
15
  import type { WorkerCommandDefinition, WorkerDefinition, WorkerSubEvent } from './definition.js'
12
16
  import { generateWorkerId, type WorkerEntry, WorkerId, type WorkerId as WorkerIdType, workerIdSchema } from './worker.js'
13
17
 
14
- export const workerEvents = createEventsFactory({
15
- events: {
16
- worker_started: z.object({
17
- workerId: workerIdSchema,
18
- agentId: agentIdSchema,
19
- workerType: z.string(),
20
- config: z.unknown(),
21
- }),
22
- worker_sub_event: z.object({
23
- workerId: workerIdSchema,
24
- workerType: z.string(),
25
- subEvent: z.record(z.string(), z.unknown()).and(z.object({
26
- type: z.string(),
27
- })),
28
- }),
29
- worker_status_changed: z.object({
30
- workerId: workerIdSchema,
31
- fromStatus: z.enum(['running', 'paused', 'completed', 'failed', 'cancelled']),
32
- toStatus: z.enum(['running', 'paused', 'completed', 'failed', 'cancelled']),
33
- reason: z.string().optional(),
34
- }),
35
- worker_completed: z.object({
36
- workerId: workerIdSchema,
37
- result: z.object({
38
- status: z.string(),
39
- resultsPath: z.string().optional(),
40
- summary: z.string(),
41
- data: z.unknown().optional(),
42
- }),
43
- }),
44
- worker_failed: z.object({
45
- workerId: workerIdSchema,
46
- error: z.string(),
47
- resumable: z.boolean(),
48
- }),
49
- },
50
- })
51
18
 
52
- export type WorkerStartedEvent = (typeof workerEvents)['Events']['worker_started']
53
- export type WorkerSubEventEmittedEvent = (typeof workerEvents)['Events']['worker_sub_event']
54
- export type WorkerStatusChangedEvent = (typeof workerEvents)['Events']['worker_status_changed']
55
- export type WorkerCompletedEvent = (typeof workerEvents)['Events']['worker_completed']
56
- export type WorkerFailedEvent = (typeof workerEvents)['Events']['worker_failed']
19
+ /** Most workers a single session runtime runs at once. */
20
+ export const MAX_CONCURRENT_WORKERS = 10
21
+
22
+ /** Default bound on waiting for a stopped worker's `execute()` to return. */
23
+ export const WORKER_STOP_TIMEOUT_MS = 5000
24
+
25
+ /** Default bound on draining the context effects a stopped worker left in flight. */
26
+ export const WORKER_EFFECT_DRAIN_TIMEOUT_MS = 5000
57
27
 
58
28
  /**
59
29
  * Session-wide worker configuration.
@@ -61,6 +31,10 @@ export type WorkerFailedEvent = (typeof workerEvents)['Events']['worker_failed']
61
31
  export interface WorkerPresetConfig {
62
32
  /** Available worker definitions */
63
33
  workers: WorkerDefinition[]
34
+ /** Bound on waiting for `execute()` to return when stopping. Defaults to WORKER_STOP_TIMEOUT_MS. */
35
+ stopTimeoutMs?: number
36
+ /** Bound on draining in-flight context effects after a stop. Defaults to WORKER_EFFECT_DRAIN_TIMEOUT_MS. */
37
+ effectDrainTimeoutMs?: number
64
38
  }
65
39
 
66
40
  /**
@@ -75,10 +49,6 @@ export interface WorkerAgentConfig {
75
49
  // Types moved from executor.ts
76
50
  // ============================================================================
77
51
 
78
- /**
79
- * Event emitter callback - emits events without sessionId (added automatically).
80
- */
81
- export type EmitEvent = (event: Omit<BaseEvent<string>, 'sessionId'>) => Promise<void>
82
52
 
83
53
  /**
84
54
  * Represents a running worker instance.
@@ -89,6 +59,12 @@ interface RunningWorker {
89
59
  definition: WorkerDefinition
90
60
  context: WorkerContextImpl<unknown, WorkerSubEvent>
91
61
  promise: Promise<void>
62
+ releaseLease: () => void
63
+ executionControl: WorkerExecutionControl
64
+ }
65
+
66
+ interface WorkerExecutionControl {
67
+ suppressTerminalEvent: boolean
92
68
  }
93
69
 
94
70
  // ============================================================================
@@ -100,38 +76,233 @@ async function executeWorker(
100
76
  definition: WorkerDefinition,
101
77
  config: unknown,
102
78
  context: WorkerContextImpl<unknown, WorkerSubEvent>,
103
- emitEvent: EmitEvent,
104
79
  runningWorkers: Map<WorkerIdType, RunningWorker>,
105
80
  logger: Logger,
81
+ releaseLease: () => void,
82
+ executionControl: WorkerExecutionControl,
83
+ effectDrainTimeoutMs: number,
106
84
  ): Promise<void> {
107
85
  try {
108
86
  const result = await definition.execute(config, context)
87
+ if (executionControl.suppressTerminalEvent) return
109
88
 
110
89
  if (result.ok) {
111
- await emitEvent(workerEvents.create('worker_completed', {
90
+ const persisted = await context.persistTerminal(workerEvents.create('worker_completed', {
112
91
  workerId,
113
92
  result: result.value,
114
93
  }))
115
- logger.info('Worker completed', { workerId, result: result.value.summary })
94
+ if (persisted) logger.info('Worker completed', { workerId, result: result.value.summary })
116
95
  } else {
117
- await emitEvent(workerEvents.create('worker_failed', {
96
+ const persisted = await context.persistTerminal(workerEvents.create('worker_failed', {
118
97
  workerId,
119
98
  error: result.error.message,
120
99
  resumable: result.error.resumable,
121
100
  }))
122
- logger.warn('Worker failed', { workerId, error: result.error.message, resumable: result.error.resumable })
101
+ if (persisted) logger.warn('Worker failed', { workerId, error: result.error.message, resumable: result.error.resumable })
123
102
  }
124
103
  } catch (error) {
104
+ if (executionControl.suppressTerminalEvent) return
125
105
  const message = error instanceof Error ? error.message : String(error)
126
- await emitEvent(workerEvents.create('worker_failed', {
106
+ const persisted = await context.persistTerminal(workerEvents.create('worker_failed', {
127
107
  workerId,
128
108
  error: message,
129
109
  resumable: false,
130
110
  }))
131
- logger.error('Worker threw exception', error instanceof Error ? error : undefined, { workerId })
111
+ if (persisted) logger.error('Worker threw exception', error instanceof Error ? error : undefined, { workerId })
132
112
  } finally {
133
- runningWorkers.delete(workerId)
113
+ // Bounded like the stop path: a stalled append must not hold the runtime lease forever.
114
+ const drained = await awaitWithin(context.waitForEffects(), effectDrainTimeoutMs)
115
+ if (!drained) context.releaseEffectLeases()
116
+ // A stop may already have replaced this entry with a relaunch; only drop our own.
117
+ if (runningWorkers.get(workerId)?.context === context) runningWorkers.delete(workerId)
118
+ releaseLease()
119
+ }
120
+ }
121
+
122
+ // ============================================================================
123
+ // Bounded worker stop
124
+ // ============================================================================
125
+
126
+ interface StopTimeouts {
127
+ stopTimeoutMs: number
128
+ effectDrainTimeoutMs: number
129
+ }
130
+
131
+ function resolveStopTimeouts(pluginConfig: WorkerPresetConfig): StopTimeouts {
132
+ return {
133
+ stopTimeoutMs: pluginConfig.stopTimeoutMs ?? WORKER_STOP_TIMEOUT_MS,
134
+ effectDrainTimeoutMs: pluginConfig.effectDrainTimeoutMs ?? WORKER_EFFECT_DRAIN_TIMEOUT_MS,
135
+ }
136
+ }
137
+
138
+ /** Await `work`, giving up after `timeoutMs`. Returns false when the wait timed out. */
139
+ async function awaitWithin(work: Promise<unknown>, timeoutMs: number): Promise<boolean> {
140
+ let timeoutId: ReturnType<typeof setTimeout> | undefined
141
+ const timeout = new Promise<boolean>((resolve) => {
142
+ timeoutId = setTimeout(() => resolve(false), timeoutMs)
143
+ })
144
+ try {
145
+ return await Promise.race([work.then(() => true, () => true), timeout])
146
+ } finally {
147
+ if (timeoutId) clearTimeout(timeoutId)
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Stop workers and give back their runtime leases, on a deadline.
153
+ *
154
+ * Shared by cancel, pause and session close so the three cannot drift: a worker
155
+ * that ignores cancellation must never pin the runtime, so both the execution
156
+ * wait and the effect drain are bounded and the leases are force-released once
157
+ * either bound expires.
158
+ *
159
+ * Giving up on the body does not stop it. A worker whose `execute()` outlived
160
+ * `stopTimeoutMs` keeps running with a live FileStore after its map entry is
161
+ * gone, so it is recorded in `abandonedWorkers` and `resume` refuses to launch a
162
+ * second body beside it until the first one finally returns.
163
+ */
164
+ async function stopWorkers(
165
+ workers: readonly RunningWorker[],
166
+ runningWorkers: Map<WorkerIdType, RunningWorker>,
167
+ abandonedWorkers: Set<WorkerIdType>,
168
+ timeouts: StopTimeouts,
169
+ ): Promise<void> {
170
+ if (workers.length === 0) return
171
+
172
+ for (const worker of workers) {
173
+ worker.executionControl.suppressTerminalEvent = true
174
+ worker.context.invalidate()
175
+ }
176
+
177
+ const exited = await awaitWithin(Promise.allSettled(workers.map((worker) => worker.promise)), timeouts.stopTimeoutMs)
178
+ const drained = await awaitWithin(
179
+ Promise.allSettled(workers.map((worker) => worker.context.waitForEffects())),
180
+ timeouts.effectDrainTimeoutMs,
181
+ )
182
+ if (!exited || !drained) {
183
+ for (const worker of workers) worker.releaseLease()
184
+ }
185
+ // The `worker:<id>` lease is not the only one a stalled write holds.
186
+ if (!drained) {
187
+ for (const worker of workers) worker.context.releaseEffectLeases()
188
+ }
189
+ if (!exited) {
190
+ for (const worker of workers) {
191
+ abandonedWorkers.add(worker.workerId)
192
+ void worker.promise.then(() => abandonedWorkers.delete(worker.workerId))
193
+ }
194
+ }
195
+
196
+ for (const worker of workers) {
197
+ if (runningWorkers.get(worker.workerId) === worker) runningWorkers.delete(worker.workerId)
198
+ }
199
+ }
200
+
201
+ /** Explain why a worker is not available for an operation that needs it running. */
202
+ function describeUnavailableWorker(workerId: WorkerIdType, entry: WorkerEntry | undefined): string {
203
+ if (!entry) return `Worker not found: ${workerId}`
204
+ if (entry.status === 'paused') return `Worker is paused: ${workerId} — resume it first`
205
+ if (entry.status !== 'running') return `Worker is ${entry.status}: ${workerId}`
206
+ // Projection says running but no body is resident — the relaunch has not landed yet.
207
+ return `Worker is stopped and pending relaunch: ${workerId}`
208
+ }
209
+
210
+ interface LaunchWorkerParams {
211
+ sessionId: SessionId
212
+ agentId: AgentId
213
+ workerId: WorkerId
214
+ definition: WorkerDefinition
215
+ config: unknown
216
+ initialState: unknown
217
+ /** Whether `execute()` is being re-entered for a worker that already ran. */
218
+ resumed: boolean
219
+ files: FileStore
220
+ emitEvent: EmitEvent
221
+ getSessionState: () => SessionState
222
+ reserveMailboxMessageSequence: () => number
223
+ scheduleAgent: (agentId: AgentId) => void
224
+ runtimeActivity: SessionRuntimeActivity
225
+ runningWorkers: Map<WorkerIdType, RunningWorker>
226
+ /** Bound on draining the effects this run leaves in flight when it returns. */
227
+ effectDrainTimeoutMs: number
228
+ logger: Logger
229
+ }
230
+
231
+ /**
232
+ * Start a worker in the current runtime.
233
+ *
234
+ * The concurrency cap lives here so the unattended relaunch at boot cannot
235
+ * exceed what `spawn` allows.
236
+ */
237
+ function launchWorker({
238
+ sessionId,
239
+ agentId,
240
+ workerId,
241
+ definition,
242
+ config,
243
+ initialState,
244
+ resumed,
245
+ files,
246
+ emitEvent,
247
+ getSessionState,
248
+ reserveMailboxMessageSequence,
249
+ scheduleAgent,
250
+ runtimeActivity,
251
+ runningWorkers,
252
+ effectDrainTimeoutMs,
253
+ logger,
254
+ }: LaunchWorkerParams): Result<void, string> {
255
+ if (runningWorkers.size >= MAX_CONCURRENT_WORKERS) {
256
+ return Err(`Max concurrent workers reached (${MAX_CONCURRENT_WORKERS})`)
134
257
  }
258
+ const releaseLease = runtimeActivity.tryAcquire(`worker:${workerId}`)
259
+ if (!releaseLease) return Err('Session runtime is no longer accepting workers')
260
+
261
+ const workerLogger = logger.child({ workerId, workerType: definition.type })
262
+ const workerContext = new WorkerContextImpl({
263
+ sessionId,
264
+ workerId,
265
+ agentId,
266
+ workerType: definition.type,
267
+ files,
268
+ emitEvent,
269
+ getSessionState,
270
+ reserveMailboxMessageSequence,
271
+ acquireEffectLease: () => runtimeActivity.tryAcquire(`worker:${workerId}:effect`),
272
+ reducer: definition.reduce,
273
+ initialState,
274
+ resumed,
275
+ logger: workerLogger,
276
+ schedule: () => scheduleAgent(agentId),
277
+ })
278
+
279
+ const executionControl: WorkerExecutionControl = { suppressTerminalEvent: false }
280
+ const promise = executeWorker(
281
+ workerId,
282
+ definition,
283
+ config,
284
+ workerContext,
285
+ runningWorkers,
286
+ logger,
287
+ releaseLease,
288
+ executionControl,
289
+ effectDrainTimeoutMs,
290
+ ).catch((error) => {
291
+ logger.error('Unhandled error in worker execution', error instanceof Error ? error : undefined, {
292
+ workerId,
293
+ })
294
+ })
295
+
296
+ runningWorkers.set(workerId, {
297
+ workerId,
298
+ workerType: definition.type,
299
+ definition,
300
+ context: workerContext,
301
+ promise,
302
+ releaseLease,
303
+ executionControl,
304
+ })
305
+ return Ok(undefined)
135
306
  }
136
307
 
137
308
  // ============================================================================
@@ -182,7 +353,7 @@ export const workerPlugin = definePlugin('workers')
182
353
 
183
354
  case 'worker_sub_event': {
184
355
  const worker = workers.get(event.workerId)
185
- if (!worker) return workers
356
+ if (!worker || !Object.hasOwn(worker, 'state')) return workers
186
357
 
187
358
  const definition = workerDefs.find((w) => w.type === event.workerType)
188
359
  const newState = definition ? definition.reduce(worker.state, event.subEvent) : worker.state
@@ -201,11 +372,22 @@ export const workerPlugin = definePlugin('workers')
201
372
  if (!worker) return workers
202
373
 
203
374
  const newWorkers = new Map(workers)
204
- newWorkers.set(event.workerId, {
205
- ...worker,
206
- status: event.toStatus,
207
- updatedAt: event.timestamp,
208
- })
375
+ if (event.toStatus === 'running' || event.toStatus === 'paused') {
376
+ newWorkers.set(event.workerId, {
377
+ ...worker,
378
+ status: event.toStatus,
379
+ updatedAt: event.timestamp,
380
+ })
381
+ } else {
382
+ newWorkers.set(event.workerId, {
383
+ id: worker.id,
384
+ agentId: worker.agentId,
385
+ workerType: worker.workerType,
386
+ status: event.toStatus,
387
+ createdAt: worker.createdAt,
388
+ updatedAt: event.timestamp,
389
+ })
390
+ }
209
391
  return newWorkers
210
392
  }
211
393
 
@@ -215,8 +397,16 @@ export const workerPlugin = definePlugin('workers')
215
397
 
216
398
  const newWorkers = new Map(workers)
217
399
  newWorkers.set(event.workerId, {
218
- ...worker,
400
+ id: worker.id,
401
+ agentId: worker.agentId,
402
+ workerType: worker.workerType,
219
403
  status: 'completed',
404
+ result: {
405
+ status: event.result.status,
406
+ resultsPath: event.result.resultsPath,
407
+ summary: event.result.summary,
408
+ },
409
+ createdAt: worker.createdAt,
220
410
  updatedAt: event.timestamp,
221
411
  })
222
412
  return newWorkers
@@ -228,8 +418,12 @@ export const workerPlugin = definePlugin('workers')
228
418
 
229
419
  const newWorkers = new Map(workers)
230
420
  newWorkers.set(event.workerId, {
231
- ...worker,
421
+ id: worker.id,
422
+ agentId: worker.agentId,
423
+ workerType: worker.workerType,
232
424
  status: 'failed',
425
+ error: { message: event.error, resumable: event.resumable },
426
+ createdAt: worker.createdAt,
233
427
  updatedAt: event.timestamp,
234
428
  })
235
429
  return newWorkers
@@ -242,7 +436,12 @@ export const workerPlugin = definePlugin('workers')
242
436
  })
243
437
  .context(async (ctx) => {
244
438
  const runningWorkers = new Map<WorkerIdType, RunningWorker>()
245
- return { runningWorkers, logger: ctx.logger }
439
+ // Claimed synchronously by `resume` so the emit it awaits cannot let a second
440
+ // resume through and overwrite the live entry, leaking its lease.
441
+ const pendingLaunches = new Set<WorkerIdType>()
442
+ // Workers whose `execute()` outlived its stop deadline and may still be running.
443
+ const abandonedWorkers = new Set<WorkerIdType>()
444
+ return { runningWorkers, pendingLaunches, abandonedWorkers, logger: ctx.logger }
246
445
  })
247
446
  .agentConfig<WorkerAgentConfig>()
248
447
  .method('spawn', {
@@ -273,6 +472,10 @@ export const workerPlugin = definePlugin('workers')
273
472
  const validConfig = validationResult.data
274
473
  const workerId = generateWorkerId()
275
474
  const { runningWorkers, logger } = ctx.pluginContext
475
+ // Refuse before persisting a start we already know we cannot honour.
476
+ if (runningWorkers.size >= MAX_CONCURRENT_WORKERS) {
477
+ return Err(ValidationErrors.invalid(`Max concurrent workers reached (${MAX_CONCURRENT_WORKERS})`))
478
+ }
276
479
 
277
480
  // Emit worker started event
278
481
  await ctx.emitEvent(workerEvents.create('worker_started', {
@@ -282,51 +485,44 @@ export const workerPlugin = definePlugin('workers')
282
485
  config: validConfig,
283
486
  }))
284
487
 
285
- // Create context
286
- const workerContext = new WorkerContextImpl({
488
+ const sessionId = ctx.sessionId
489
+ const agentId = input.agentId
490
+ const files = ctx.files.session
491
+ const emitEvent = ctx.emitEvent
492
+ const getSessionState = ctx.getSessionState
493
+ const reserveMailboxMessageSequence = ctx.reserveMailboxMessageSequence
494
+ const scheduleAgent = ctx.scheduleAgent
495
+ const runtimeActivity = ctx.runtimeActivity
496
+ const launched = launchWorker({
287
497
  sessionId: ctx.sessionId,
288
498
  workerId,
289
- agentId: input.agentId,
290
- workerType: definition.type,
291
- files: ctx.files.session,
292
- emitEvent: ctx.emitEvent,
293
- getSessionState: () => ctx.sessionState,
294
- reducer: definition.reduce as (state: unknown, event: WorkerSubEvent) => unknown,
295
- initialState: definition.initialState(validConfig),
296
- logger: logger.child({ workerId, workerType: definition.type }),
297
- schedule: () => ctx.scheduleAgent(input.agentId),
298
- })
299
-
300
- // Enforce max concurrent workers (default: 10)
301
- const MAX_CONCURRENT_WORKERS = 10
302
- if (runningWorkers.size >= MAX_CONCURRENT_WORKERS) {
303
- return Err(ValidationErrors.invalid(`Max concurrent workers reached (${MAX_CONCURRENT_WORKERS})`))
304
- }
305
-
306
- // Start worker execution with error boundary
307
- const promise = executeWorker(
308
- workerId,
499
+ agentId,
309
500
  definition,
310
- validConfig,
311
- workerContext,
312
- ctx.emitEvent,
501
+ config: validConfig,
502
+ initialState: definition.initialState(validConfig),
503
+ resumed: false,
504
+ files,
505
+ emitEvent,
506
+ getSessionState,
507
+ reserveMailboxMessageSequence,
508
+ scheduleAgent,
509
+ runtimeActivity,
313
510
  runningWorkers,
511
+ effectDrainTimeoutMs: resolveStopTimeouts(ctx.pluginConfig).effectDrainTimeoutMs,
314
512
  logger,
315
- ).catch((err) => {
316
- logger.error('Unhandled error in worker execution', err instanceof Error ? err : undefined, { workerId })
317
- })
318
-
319
- // Track running worker
320
- runningWorkers.set(workerId, {
321
- workerId,
322
- workerType: definition.type,
323
- definition,
324
- context: workerContext,
325
- promise,
326
513
  })
514
+ if (!launched.ok) {
515
+ // The pre-check can go stale across the emit above; keep the projection truthful.
516
+ await ctx.emitEvent(workerEvents.create('worker_failed', {
517
+ workerId,
518
+ error: launched.error,
519
+ resumable: true,
520
+ }))
521
+ return Err(ValidationErrors.invalid(launched.error))
522
+ }
327
523
 
328
524
  logger.info('Worker started', {
329
- sessionId: ctx.sessionId,
525
+ sessionId,
330
526
  workerId,
331
527
  workerType: definition.type,
332
528
  agentId: input.agentId,
@@ -335,6 +531,59 @@ export const workerPlugin = definePlugin('workers')
335
531
  return Ok({ workerId })
336
532
  },
337
533
  })
534
+ .sessionHook('onSessionReady', async (ctx) => {
535
+ const { runningWorkers, logger } = ctx.pluginContext
536
+ const files = ctx.files.session
537
+ const emitEvent = ctx.emitEvent
538
+ const getSessionState = ctx.getSessionState
539
+ const reserveMailboxMessageSequence = ctx.reserveMailboxMessageSequence
540
+ const scheduleAgent = ctx.scheduleAgent
541
+ const runtimeActivity = ctx.runtimeActivity
542
+ const { effectDrainTimeoutMs } = resolveStopTimeouts(ctx.pluginConfig)
543
+ // A relaunch that does not happen must not leave the projection claiming `running`
544
+ // — park the worker instead, which keeps its state and lets `resume` pick it up.
545
+ const parkStoppedWorker = async (workerId: WorkerIdType): Promise<void> => {
546
+ await ctx.emitEvent(workerEvents.create('worker_status_changed', {
547
+ workerId,
548
+ fromStatus: 'running',
549
+ toStatus: 'paused',
550
+ }))
551
+ }
552
+ for (const worker of ctx.pluginState.values()) {
553
+ // Paused workers stay stopped — `workers.resume` relaunches them on demand.
554
+ if (worker.status !== 'running') continue
555
+ if (!Object.hasOwn(worker, 'config') || !Object.hasOwn(worker, 'state')) continue
556
+ if (runningWorkers.has(worker.id)) continue
557
+ const definition = ctx.pluginConfig.workers.find((candidate) => candidate.type === worker.workerType)
558
+ if (!definition) {
559
+ logger.warn('Cannot resume worker with missing definition', { workerId: worker.id, workerType: worker.workerType })
560
+ await parkStoppedWorker(worker.id)
561
+ continue
562
+ }
563
+ const launched = launchWorker({
564
+ sessionId: ctx.sessionId,
565
+ agentId: worker.agentId,
566
+ workerId: worker.id,
567
+ definition,
568
+ config: worker.config,
569
+ initialState: worker.state,
570
+ resumed: true,
571
+ files,
572
+ emitEvent,
573
+ getSessionState,
574
+ reserveMailboxMessageSequence,
575
+ scheduleAgent,
576
+ runtimeActivity,
577
+ runningWorkers,
578
+ effectDrainTimeoutMs,
579
+ logger,
580
+ })
581
+ if (!launched.ok) {
582
+ logger.warn('Cannot relaunch worker', { workerId: worker.id, workerType: worker.workerType, reason: launched.error })
583
+ await parkStoppedWorker(worker.id)
584
+ }
585
+ }
586
+ })
338
587
  .method('getStatus', {
339
588
  input: z.object({
340
589
  sessionId: z.string(),
@@ -351,8 +600,13 @@ export const workerPlugin = definePlugin('workers')
351
600
  return Err(ValidationErrors.invalid(`Worker not found: ${input.workerId}`))
352
601
  }
353
602
 
354
- const definition = ctx.pluginConfig.workers.find((w) => w.type === worker.workerType)
355
- const state = definition?.summarizeState ? definition.summarizeState(worker.state) : worker.state
603
+ let state: unknown
604
+ if (worker.status === 'running' || worker.status === 'paused') {
605
+ const definition = ctx.pluginConfig.workers.find((w) => w.type === worker.workerType)
606
+ state = definition?.summarizeState ? definition.summarizeState(worker.state) : worker.state
607
+ } else {
608
+ state = worker.result ?? worker.error
609
+ }
356
610
 
357
611
  return Ok({
358
612
  status: worker.status,
@@ -373,7 +627,9 @@ export const workerPlugin = definePlugin('workers')
373
627
  const workerId = WorkerId(input.workerId)
374
628
  const worker = ctx.pluginContext.runningWorkers.get(workerId)
375
629
  if (!worker) {
376
- return Err(ValidationErrors.invalid(`Worker not running: ${input.workerId}`))
630
+ // Commands run against a live context, and starting one here would silently
631
+ // undo an explicit pause — the caller resumes first.
632
+ return Err(ValidationErrors.invalid(describeUnavailableWorker(workerId, ctx.pluginState.get(workerId))))
377
633
  }
378
634
 
379
635
  if (!worker.definition.handleCommand) {
@@ -397,19 +653,21 @@ export const workerPlugin = definePlugin('workers')
397
653
  output: z.object({}),
398
654
  handler: async (ctx, input) => {
399
655
  const workerId = WorkerId(input.workerId)
400
- const worker = ctx.pluginContext.runningWorkers.get(workerId)
401
- if (!worker) {
402
- return Err(ValidationErrors.invalid(`Worker not running: ${input.workerId}`))
656
+ const { runningWorkers, abandonedWorkers } = ctx.pluginContext
657
+ const worker = runningWorkers.get(workerId)
658
+ const workerEntry = ctx.pluginState.get(workerId)
659
+ // The projection decides, not the map: a completed worker lingers there for the
660
+ // whole of its effect drain, and cancelling it would overwrite its real result.
661
+ if (!workerEntry || (workerEntry.status !== 'running' && workerEntry.status !== 'paused')) {
662
+ return Err(ValidationErrors.invalid(describeUnavailableWorker(workerId, workerEntry)))
403
663
  }
404
664
 
405
- worker.context.cancel()
406
-
407
- const workerEntry = ctx.pluginState.get(workerId)
408
- const fromStatus = workerEntry?.status ?? 'running'
665
+ // Bounded, so a worker that ignores cancellation cannot hold the runtime open.
666
+ if (worker) await stopWorkers([worker], runningWorkers, abandonedWorkers, resolveStopTimeouts(ctx.pluginConfig))
409
667
 
410
668
  await ctx.emitEvent(workerEvents.create('worker_status_changed', {
411
669
  workerId,
412
- fromStatus,
670
+ fromStatus: workerEntry.status,
413
671
  toStatus: 'cancelled',
414
672
  }))
415
673
 
@@ -425,9 +683,10 @@ export const workerPlugin = definePlugin('workers')
425
683
  output: z.object({}),
426
684
  handler: async (ctx, input) => {
427
685
  const workerId = WorkerId(input.workerId)
428
- const worker = ctx.pluginContext.runningWorkers.get(workerId)
686
+ const { runningWorkers, abandonedWorkers } = ctx.pluginContext
687
+ const worker = runningWorkers.get(workerId)
429
688
  if (!worker) {
430
- return Err(ValidationErrors.invalid(`Worker not running: ${input.workerId}`))
689
+ return Err(ValidationErrors.invalid(describeUnavailableWorker(workerId, ctx.pluginState.get(workerId))))
431
690
  }
432
691
 
433
692
  const workerEntry = ctx.pluginState.get(workerId)
@@ -437,7 +696,10 @@ export const workerPlugin = definePlugin('workers')
437
696
  return Err(ValidationErrors.invalid(`Worker not in running state: ${fromStatus}`))
438
697
  }
439
698
 
699
+ // Pausing stops the run instead of spinning it: a parked worker must not keep
700
+ // the runtime resident. `resume` re-enters execute() with the replayed state.
440
701
  worker.context.pause()
702
+ await stopWorkers([worker], runningWorkers, abandonedWorkers, resolveStopTimeouts(ctx.pluginConfig))
441
703
 
442
704
  await ctx.emitEvent(workerEvents.create('worker_status_changed', {
443
705
  workerId,
@@ -457,46 +719,94 @@ export const workerPlugin = definePlugin('workers')
457
719
  output: z.object({}),
458
720
  handler: async (ctx, input) => {
459
721
  const workerId = WorkerId(input.workerId)
460
- const worker = ctx.pluginContext.runningWorkers.get(workerId)
461
- if (!worker) {
462
- return Err(ValidationErrors.invalid(`Worker not running: ${input.workerId}`))
463
- }
464
-
722
+ const { runningWorkers, pendingLaunches, abandonedWorkers, logger } = ctx.pluginContext
465
723
  const workerEntry = ctx.pluginState.get(workerId)
466
- const fromStatus = workerEntry?.status ?? 'paused'
467
-
468
- if (fromStatus !== 'paused') {
469
- return Err(ValidationErrors.invalid(`Worker not in paused state: ${fromStatus}`))
724
+ if (!workerEntry) {
725
+ return Err(ValidationErrors.invalid(`Worker not found: ${input.workerId}`))
470
726
  }
727
+ if (workerEntry.status !== 'paused') {
728
+ return Err(ValidationErrors.invalid(`Worker not in paused state: ${workerEntry.status}`))
729
+ }
730
+ if (!Object.hasOwn(workerEntry, 'config') || !Object.hasOwn(workerEntry, 'state')) {
731
+ return Err(ValidationErrors.invalid(`Worker is no longer resumable: ${input.workerId}`))
732
+ }
733
+ const definition = ctx.pluginConfig.workers.find((candidate) => candidate.type === workerEntry.workerType)
734
+ if (!definition) {
735
+ return Err(ValidationErrors.invalid(`Unknown worker type: ${workerEntry.workerType}`))
736
+ }
737
+ // Nothing runs a paused worker any more, so resume relaunches it — and must
738
+ // never overwrite a live entry, whose lease would then leak. The claim below
739
+ // is therefore taken in the same synchronous block as the checks: everything
740
+ // from here to `pendingLaunches.add` must stay free of `await`.
741
+ if (runningWorkers.has(workerId)) {
742
+ return Err(ValidationErrors.invalid(`Worker is already running: ${input.workerId}`))
743
+ }
744
+ if (pendingLaunches.has(workerId)) {
745
+ return Err(ValidationErrors.invalid(`Worker is already resuming: ${input.workerId}`))
746
+ }
747
+ if (abandonedWorkers.has(workerId)) {
748
+ return Err(ValidationErrors.invalid(
749
+ `Worker did not stop within its deadline and may still be running: ${input.workerId}`,
750
+ ))
751
+ }
752
+ if (runningWorkers.size + pendingLaunches.size >= MAX_CONCURRENT_WORKERS) {
753
+ return Err(ValidationErrors.invalid(`Max concurrent workers reached (${MAX_CONCURRENT_WORKERS})`))
754
+ }
755
+ pendingLaunches.add(workerId)
756
+
757
+ try {
758
+ // The status event goes first: a worker that finishes instantly would otherwise
759
+ // have its terminal projection overwritten by this event.
760
+ await ctx.emitEvent(workerEvents.create('worker_status_changed', {
761
+ workerId,
762
+ fromStatus: 'paused',
763
+ toStatus: 'running',
764
+ }))
765
+
766
+ const launched = launchWorker({
767
+ sessionId: ctx.sessionId,
768
+ agentId: workerEntry.agentId,
769
+ workerId,
770
+ definition,
771
+ config: workerEntry.config,
772
+ initialState: workerEntry.state,
773
+ resumed: true,
774
+ files: ctx.files.session,
775
+ emitEvent: ctx.emitEvent,
776
+ getSessionState: ctx.getSessionState,
777
+ reserveMailboxMessageSequence: ctx.reserveMailboxMessageSequence,
778
+ scheduleAgent: ctx.scheduleAgent,
779
+ runtimeActivity: ctx.runtimeActivity,
780
+ runningWorkers,
781
+ effectDrainTimeoutMs: resolveStopTimeouts(ctx.pluginConfig).effectDrainTimeoutMs,
782
+ logger,
783
+ })
784
+ if (!launched.ok) {
785
+ // Park it again rather than fail it: both triggers are transient, and a
786
+ // `worker_failed` would drop the state and config that keep it resumable.
787
+ await ctx.emitEvent(workerEvents.create('worker_status_changed', {
788
+ workerId,
789
+ fromStatus: 'running',
790
+ toStatus: 'paused',
791
+ reason: launched.error,
792
+ }))
793
+ return Err(ValidationErrors.invalid(launched.error))
794
+ }
471
795
 
472
- worker.context.resume()
473
-
474
- await ctx.emitEvent(workerEvents.create('worker_status_changed', {
475
- workerId,
476
- fromStatus,
477
- toStatus: 'running',
478
- }))
479
-
480
- return Ok({})
796
+ return Ok({})
797
+ } finally {
798
+ pendingLaunches.delete(workerId)
799
+ }
481
800
  },
482
801
  })
483
802
  .sessionHook('onSessionClose', async (ctx) => {
484
- const { runningWorkers, logger } = ctx.pluginContext
803
+ const { runningWorkers, abandonedWorkers, logger } = ctx.pluginContext
485
804
  if (runningWorkers.size === 0) return
805
+ const closingWorkers = [...runningWorkers.values()]
486
806
 
487
- logger.info('Cancelling running workers on session close', { count: runningWorkers.size })
488
-
489
- // Cancel all running workers
490
- for (const worker of runningWorkers.values()) {
491
- worker.context.cancel()
492
- }
807
+ logger.info('Cancelling running workers on session close', { count: closingWorkers.length })
493
808
 
494
- // Await all worker promises with a timeout (5s)
495
- const timeout = new Promise<void>((resolve) => setTimeout(resolve, 5000))
496
- await Promise.race([
497
- Promise.allSettled([...runningWorkers.values()].map((w) => w.promise)),
498
- timeout,
499
- ])
809
+ await stopWorkers(closingWorkers, runningWorkers, abandonedWorkers, resolveStopTimeouts(ctx.pluginConfig))
500
810
 
501
811
  runningWorkers.clear()
502
812
  })
@@ -613,7 +923,7 @@ export const workerPlugin = definePlugin('workers')
613
923
  }),
614
924
  createTool({
615
925
  name: 'worker_cancel',
616
- description: 'Cancel a running worker. The worker will stop execution.',
926
+ description: 'Cancel a running or paused worker. It stops for good and cannot be resumed.',
617
927
  input: z.object({
618
928
  workerId: workerIdSchema,
619
929
  }),
@@ -630,7 +940,7 @@ export const workerPlugin = definePlugin('workers')
630
940
  }),
631
941
  createTool({
632
942
  name: 'worker_pause',
633
- description: 'Pause a running worker. The worker can be resumed later.',
943
+ description: 'Pause a running worker. It stops where it is; worker_resume restarts it from the progress it had recorded.',
634
944
  input: z.object({
635
945
  workerId: workerIdSchema,
636
946
  }),
@@ -647,7 +957,7 @@ export const workerPlugin = definePlugin('workers')
647
957
  }),
648
958
  createTool({
649
959
  name: 'worker_resume',
650
- description: 'Resume a paused worker.',
960
+ description: 'Resume a paused worker. It restarts from the progress it had recorded.',
651
961
  input: z.object({
652
962
  workerId: workerIdSchema,
653
963
  }),